]> git.saurik.com Git - wxWidgets.git/blame - src/os2/radiobox.cpp
fix for generating set/kill focus events for wxRadioBox (also fixes TABbing in a...
[wxWidgets.git] / src / os2 / radiobox.cpp
CommitLineData
0e320a79
DW
1/////////////////////////////////////////////////////////////////////////////
2// Name: radiobox.cpp
3// Purpose: wxRadioBox
cdf1e714 4// Author: David Webster
0e320a79 5// Modified by:
cdf1e714 6// Created: 10/12/99
0e320a79 7// RCS-ID: $Id$
cdf1e714
DW
8// Copyright: (c) David Webster
9// Licence: wxWindows licence
0e320a79
DW
10/////////////////////////////////////////////////////////////////////////////
11
cdf1e714
DW
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifndef WX_PRECOMP
16 #include <stdio.h>
17 #include "wx/setup.h"
b59c98dd
SN
18 #include "wx/wxchar.h"
19 #include "wx/string.h"
cdf1e714
DW
20 #include "wx/bitmap.h"
21 #include "wx/brush.h"
22 #include "wx/radiobox.h"
0e320a79
DW
23#endif
24
cdf1e714 25#include "wx/os2/private.h"
0e320a79 26
0e320a79 27IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
0e320a79 28
cdf1e714
DW
29// ---------------------------------------------------------------------------
30// private functions
31// ---------------------------------------------------------------------------
32
33// wnd proc for radio buttons
3c299c3a
DW
34MRESULT EXPENTRY wxRadioBtnWndProc( HWND hWnd
35 ,UINT uMessage
36 ,MPARAM wParam
37 ,MPARAM lParam
38 );
f289196b
DW
39MRESULT EXPENTRY wxRadioBoxWndProc( HWND hWnd
40 ,UINT uMessage
41 ,MPARAM wParam
42 ,MPARAM lParam
43 );
cdf1e714
DW
44
45// ---------------------------------------------------------------------------
46// global vars
47// ---------------------------------------------------------------------------
48
49// the pointer to standard radio button wnd proc
f289196b
DW
50extern void wxAssociateWinWithHandle( HWND hWnd
51 ,wxWindowOS2* pWin
52 );
3c299c3a 53static WXFARPROC fnWndProcRadioBtn = NULL;
f289196b 54static WXFARPROC fnWndProcRadioBox = NULL;
cdf1e714
DW
55
56// ===========================================================================
57// implementation
58// ===========================================================================
59
60// ---------------------------------------------------------------------------
61// wxRadioBox
62// ---------------------------------------------------------------------------
63
3c299c3a
DW
64// Radio box item
65wxRadioBox::wxRadioBox()
0367c1c0 66{
3c299c3a
DW
67 m_nSelectedButton = -1;
68 m_nNoItems = 0;
69 m_nNoRowsOrCols = 0;
70 m_ahRadioButtons = NULL;
71 m_nMajorDim = 0;
72 m_pnRadioWidth = NULL;
73 m_pnRadioHeight = NULL;
74} // end of wxRadioBox::wxRadioBox
0367c1c0 75
3c299c3a 76wxRadioBox::~wxRadioBox()
0367c1c0 77{
3c299c3a 78 m_isBeingDeleted = TRUE;
0367c1c0 79
3c299c3a 80 if (m_ahRadioButtons)
cdf1e714 81 {
3c299c3a
DW
82 int i;
83 for (i = 0; i < m_nNoItems; i++)
84 ::WinDestroyWindow((HWND)m_ahRadioButtons[i]);
85 delete[] m_ahRadioButtons;
cdf1e714 86 }
3c299c3a
DW
87 if (m_pnRadioWidth)
88 delete[] m_pnRadioWidth;
89 if (m_pnRadioHeight)
90 delete[] m_pnRadioHeight;
91} // end of wxRadioBox::~wxRadioBox
92
93void wxRadioBox::AdjustButtons(
94 int nX
95, int nY
96, int nWidth
97, int nHeight
d8a3f66c 98, int nSizeFlags
3c299c3a 99)
cdf1e714 100{
3c299c3a
DW
101 wxSize vMaxSize;
102 int nXOffset = nX;
103 int nYOffset = nY + nHeight;
104 int nCx1;
105 int nCy1;
106 int nStartX;
107 int nStartY;
108 int nMaxWidth;
109 int nMaxHeight;
110 int nTotWidth;
111 int nTotHeight;
112
113 wxGetCharSize( m_hWnd
114 ,&nCx1
115 ,&nCy1
116 ,&GetFont()
117 );
118 vMaxSize = GetMaxButtonSize();
119 nMaxWidth = vMaxSize.x;
120 nMaxHeight = vMaxSize.y;
121
122 nXOffset += nCx1;
123 nYOffset -= (nMaxHeight + ((3*nCy1)/2));
124
125 nStartX = nXOffset;
126 nStartY = nYOffset;
127
128 for (int i = 0; i < m_nNoItems; i++)
cdf1e714 129 {
3c299c3a
DW
130 //
131 // The last button in the row may be wider than the other ones as the
132 // radiobox may be wider than the sum of the button widths (as it
133 // happens, for example, when the radiobox label is very long)
134 //
135 bool bIsLastInTheRow;
136
137 if (m_windowStyle & wxRA_SPECIFY_COLS)
138 {
139 //
140 // Item is the last in its row if it is a multiple of the number of
141 // columns or if it is just the last item
142 //
143 int n = i + 1;
cdf1e714 144
3c299c3a
DW
145 bIsLastInTheRow = ((n % m_nMajorDim) == 0) || (n == m_nNoItems);
146 }
147 else // winRA_SPECIFY_ROWS
148 {
149 //
150 // Item is the last in the row if it is in the last columns
151 //
152 bIsLastInTheRow = i >= (m_nNoItems/m_nMajorDim) * m_nMajorDim;
153 }
cdf1e714 154
3c299c3a
DW
155 //
156 // Is this the start of new row/column?
157 //
158 if (i && (i % m_nMajorDim == 0))
cdf1e714 159 {
3c299c3a 160 if (m_windowStyle & wxRA_SPECIFY_ROWS)
cdf1e714 161 {
cdf1e714 162
3c299c3a
DW
163 //
164 // Start of new column
165 //
166 nYOffset = nStartY;
167 nXOffset += nMaxWidth + nCx1;
168 }
169 else // start of new row
170 {
171 nXOffset = nStartX;
172 nYOffset -= nMaxHeight;
173 if (m_pnRadioWidth[0] > 0L)
174 nYOffset -= nCy1/2;
cdf1e714
DW
175 }
176 }
177
3c299c3a 178 int nWidthBtn;
cdf1e714 179
3c299c3a 180 if (bIsLastInTheRow)
cdf1e714 181 {
3c299c3a
DW
182 //
183 // Make the button go to the end of radio box
184 //
185 nWidthBtn = nStartX + nWidth - nXOffset - (2 * nCx1);
186 if (nWidthBtn < nMaxWidth)
187 nWidthBtn = nMaxWidth;
188 }
189 else
190 {
191 //
192 // Normal button, always of the same size
193 //
194 nWidthBtn = nMaxWidth;
cdf1e714 195 }
cdf1e714 196
3c299c3a
DW
197 //
198 // Make all buttons of the same, maximal size - like this they
199 // cover the radiobox entirely and the radiobox tooltips are always
200 // shown (otherwise they are not when the mouse pointer is in the
201 // radiobox part not beYInt32ing to any radiobutton)
202 //
203 ::WinSetWindowPos( (HWND)m_ahRadioButtons[i]
204 ,HWND_TOP
205 ,(LONG)nXOffset
206 ,(LONG)nYOffset
207 ,(LONG)nWidthBtn
208 ,(LONG)nMaxHeight
209 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
210 );
211 //
212 // Where do we put the next button?
213 //
214 if (m_windowStyle & wxRA_SPECIFY_ROWS)
215 {
216 //
217 // Below this one
218 //
219 nYOffset -= nMaxHeight;
220 if (m_pnRadioWidth[0] > 0)
221 nYOffset -= nCy1/2;
222 }
223 else
224 {
225 //
226 // To the right of this one
227 //
228 nXOffset += nWidthBtn + nCx1;
229 }
cdf1e714 230 }
3c299c3a 231} // end of wxRadioBox::AdjustButtons
cdf1e714 232
3c299c3a
DW
233void wxRadioBox::Command (
234 wxCommandEvent& rEvent
235)
236{
237 SetSelection (rEvent.GetInt());
238 ProcessCommand(rEvent);
239} // end of wxRadioBox::Command
cdf1e714 240
3c299c3a
DW
241bool wxRadioBox::ContainsHWND(
242 WXHWND hWnd
243) const
0e320a79 244{
3c299c3a
DW
245 size_t nCount = GetCount();
246 size_t i;
247
248 for (i = 0; i < nCount; i++)
249 {
250 if (GetRadioButtons()[i] == hWnd)
251 return TRUE;
252 }
253 return FALSE;
254} // end of wxRadioBox::ContainsHWND
255
256bool wxRadioBox::Create(
257 wxWindow* pParent
258, wxWindowID vId
259, const wxString& rsTitle
260, const wxPoint& rPos
261, const wxSize& rSize
262, int nNum
263, const wxString asChoices[]
264, int nMajorDim
265, long lStyle
3c299c3a 266, const wxValidator& rVal
3c299c3a
DW
267, const wxString& rsName
268)
0e320a79 269{
3c299c3a
DW
270 wxColour vColour;
271 LONG lColor;
272
273 vColour.Set(wxString("BLACK"));
b389a12d 274 m_backgroundColour = pParent->GetBackgroundColour();
3c299c3a 275 m_nSelectedButton = -1;
b389a12d 276 m_nNoItems = 0;
3c299c3a
DW
277
278 m_nMajorDim = nMajorDim == 0 ? nNum : nMajorDim;
279 m_nNoRowsOrCols = nMajorDim;
280
281 //
282 // Common initialization
283 //
b9b1d6c8
DW
284 if (!CreateControl( pParent
285 ,vId
286 ,rPos
287 ,rSize
288 ,lStyle
b9b1d6c8 289 ,rVal
b9b1d6c8
DW
290 ,rsName
291 ))
b389a12d 292 return FALSE;
3c299c3a 293 if (!OS2CreateControl( "STATIC"
f289196b 294 ,SS_GROUPBOX
3c299c3a
DW
295 ,rPos
296 ,rSize
297 ,rsTitle
298 ))
b389a12d 299 return FALSE;
cdf1e714 300
f289196b 301 wxAssociateWinWithHandle(m_hWnd, this);
3c299c3a
DW
302#if RADIOBTN_PARENT_IS_RADIOBOX
303 HWND hWndParent = GetHwnd();
304#else
305 HWND hWndParent = GetHwndOf(pParent);
306#endif
307 HFONT hFont;
cdf1e714 308
3c299c3a 309 //
cdf1e714 310 // Some radio boxes test consecutive id.
3c299c3a 311 //
b389a12d 312 m_nNoItems = nNum;
cdf1e714 313 (void)NewControlId();
3c299c3a
DW
314 m_ahRadioButtons = new WXHWND[nNum];
315 m_pnRadioWidth = new int[nNum];
316 m_pnRadioHeight = new int[nNum];
317
3c299c3a 318 for (int i = 0; i < nNum; i++)
cdf1e714 319 {
3c299c3a
DW
320 m_pnRadioWidth[i] = m_pnRadioHeight[i] = -1;
321
322 long lStyleBtn = BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE;
323 int nNewId = NewControlId();
324
325 if (i == 0 && lStyle == 0)
326 lStyleBtn |= WS_GROUP;
327
328 HWND hWndBtn = (WXHWND)::WinCreateWindow ( GetHwndOf(pParent)
329 ,WC_BUTTON
330 ,asChoices[i]
331 ,lStyleBtn
332 ,0, 0, 0, 0
333 ,GetWinHwnd(pParent)
334 ,HWND_TOP
335 ,(HMENU)nNewId
336 ,NULL
337 ,NULL
338 );
5d44b24e 339 lColor = (LONG)vColour.GetPixel();
3c299c3a
DW
340 ::WinSetPresParam( hWndBtn
341 ,PP_FOREGROUNDCOLOR
342 ,sizeof(LONG)
343 ,(PVOID)&lColor
344 );
5d44b24e
DW
345 lColor = (LONG)m_backgroundColour.GetPixel();
346
347 ::WinSetPresParam( hWndBtn
348 ,PP_BACKGROUNDCOLOR
349 ,sizeof(LONG)
350 ,(PVOID)&lColor
351 );
3c299c3a 352 if (!hWndBtn)
cdf1e714 353 {
3c299c3a 354 return FALSE;
cdf1e714 355 }
3c299c3a
DW
356 m_ahRadioButtons[i] = (WXHWND)hWndBtn;
357 SubclassRadioButton((WXHWND)hWndBtn);
f289196b 358 wxAssociateWinWithHandle(hWndBtn, this);
3c299c3a 359 wxOS2SetFont( hWndBtn
f289196b 360 ,*wxSMALL_FONT
3c299c3a
DW
361 );
362 ::WinSetWindowULong(hWndBtn, QWL_USER, (ULONG)this);
363 m_aSubControls.Add(nNewId);
cdf1e714 364 }
0e320a79 365
3c299c3a 366 //
cdf1e714 367 // Create a dummy radio control to end the group.
3c299c3a
DW
368 //
369 (void)::WinCreateWindow ( GetHwndOf(pParent)
370 ,WC_BUTTON
371 ,""
372 ,WS_GROUP | BS_AUTORADIOBUTTON
373 ,0, 0, 0, 0
374 ,GetWinHwnd(pParent)
375 ,HWND_TOP
376 ,(HMENU)NewControlId()
377 ,NULL
378 ,NULL
379 );
f289196b
DW
380 SetFont(*wxSMALL_FONT);
381 fnWndProcRadioBox = (WXFARPROC)::WinSubclassWindow( GetHwnd()
382 ,(PFNWP)wxRadioBoxWndProc
383 );
384 ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
5d44b24e 385 lColor = (LONG)vColour.GetPixel();
3c299c3a
DW
386 ::WinSetPresParam( m_hWnd
387 ,PP_FOREGROUNDCOLOR
388 ,sizeof(LONG)
389 ,(PVOID)&lColor
390 );
f289196b
DW
391 ::WinSetPresParam( m_hWnd
392 ,PP_BORDERDARKCOLOR
393 ,sizeof(LONG)
394 ,(PVOID)&lColor
395 );
5d44b24e
DW
396 lColor = (LONG)m_backgroundColour.GetPixel();
397
398 ::WinSetPresParam( m_hWnd
399 ,PP_BACKGROUNDCOLOR
400 ,sizeof(LONG)
401 ,(PVOID)&lColor
402 );
f289196b
DW
403 ::WinSetPresParam( m_hWnd
404 ,PP_BORDERLIGHTCOLOR
405 ,sizeof(LONG)
406 ,(PVOID)&lColor
407 );
b389a12d
DW
408 SetXComp(0);
409 SetYComp(0);
cdf1e714 410 SetSelection(0);
3c299c3a
DW
411 SetSize( rPos.x
412 ,rPos.y
413 ,rSize.x
414 ,rSize.y
415 );
cdf1e714 416 return TRUE;
3c299c3a 417} // end of wxRadioBox::Create
0e320a79 418
3c299c3a 419wxSize wxRadioBox::DoGetBestSize() const
0e320a79 420{
3c299c3a
DW
421 return (GetTotalButtonSize(GetMaxButtonSize()));
422} // end of WinGuiBase_CRadioBox::DoGetBestSize
423
424void wxRadioBox::DoSetSize(
425 int nX
426, int nY
427, int nWidth
428, int nHeight
429, int nSizeFlags
430)
431{
432 int nCurrentX;
433 int nCurrentY;
434 int nWidthOld;
435 int nHeightOld;
436 int nXx = nX;
437 int nYy = nY;
438#if RADIOBTN_PARENT_IS_RADIOBOX
439 int nXOffset = 0;
440 int nYOffset = 0;
441#else
442 int nXOffset = nXx;
443 int nYOffset = nYy;
444#endif
445 int nCx1;
446 int nCy1;
447 wxSize vMaxSize = GetMaxButtonSize();
448 int nMaxWidth;
449 int nMaxHeight;
450 wxSize vTotSize;
451 int nTotWidth;
452 int nTotHeight;
453 int nStartX;
454 int nStartY;
455
456 m_nSizeFlags = nSizeFlags;
457 GetPosition( &nCurrentX
458 ,&nCurrentY
459 );
460 GetSize( &nWidthOld
461 ,&nHeightOld
462 );
463
464 if (nX == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
465 nXx = nCurrentX;
466 if (nY == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
467 nYy = nCurrentY;
b389a12d
DW
468 if (nYy < 0)
469 nYy = 0;
470 if (nXx < 0)
471 nXx = 0;
3c299c3a
DW
472
473 wxGetCharSize( m_hWnd
474 ,&nCx1
475 ,&nCy1
476 ,&GetFont()
477 );
478
479 //
480 // Attempt to have a look coherent with other platforms: We compute the
481 // biggest toggle dim, then we align all items according this value.
482 //
483 vMaxSize = GetMaxButtonSize();
484 nMaxWidth = vMaxSize.x;
485 nMaxHeight = vMaxSize.y;
486
487 vTotSize = GetTotalButtonSize(vMaxSize);
488 nTotWidth = vTotSize.x;
489 nTotHeight = vTotSize.y;
490
491 //
492 // Only change our width/height if asked for
493 //
494 if (nWidth == -1)
495 {
496 if (nSizeFlags & wxSIZE_AUTO_WIDTH )
497 nWidth = nTotWidth;
498 else
499 nWidth = nWidthOld;
500 }
cdf1e714 501
3c299c3a 502 if (nHeight == -1)
cdf1e714 503 {
3c299c3a
DW
504 if (nSizeFlags & wxSIZE_AUTO_HEIGHT)
505 nHeight = nTotHeight;
506 else
507 nHeight = nHeightOld;
cdf1e714
DW
508 }
509
3c299c3a 510 wxWindowOS2* pParent = (wxWindowOS2*)GetParent();
cdf1e714 511
3c299c3a
DW
512 if (pParent)
513 {
d8a3f66c
DW
514 int nOS2Height = GetOS2ParentHeight(pParent);
515
516 nYy = nOS2Height - (nYy + nHeight);
3c299c3a
DW
517 nYOffset = nYy + nHeight;
518 }
519 else
520 {
521 RECTL vRect;
0e320a79 522
3c299c3a
DW
523 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
524 nYy = vRect.yTop - (nYy + nHeight);
525 }
526 ::WinSetWindowPos( GetHwnd()
527 ,HWND_TOP
528 ,(LONG)nXx
529 ,(LONG)nYy
530 ,(LONG)nWidth
531 ,(LONG)nHeight
532 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
533 );
534
535 //
536 // Now position all the buttons: the current button will be put at
537 // wxPoint(x_offset, y_offset) and the new row/column will start at
538 // startX/startY. The size of all buttons will be the same wxSize(maxWidth,
539 // maxHeight) except for the buttons in the last column which should extend
540 // to the right border of radiobox and thus can be wider than this.
541 //
542 // Also, remember that wxRA_SPECIFY_COLS means that we arrange buttons in
543 // left to right order and m_majorDim is the number of columns while
544 // wxRA_SPECIFY_ROWS means that the buttons are arranged top to bottom and
545 // m_majorDim is the number of rows.
546 //
547 nXOffset += nCx1;
548 nYOffset -= (nMaxHeight + ((3*nCy1)/2));
549
550 nStartX = nXOffset;
551 nStartY = nYOffset;
552
553 for (int i = 0; i < m_nNoItems; i++)
554 {
555 //
556 // The last button in the row may be wider than the other ones as the
557 // radiobox may be wider than the sum of the button widths (as it
558 // happens, for example, when the radiobox label is very long)
559 //
560 bool bIsLastInTheRow;
561
562 if (m_windowStyle & wxRA_SPECIFY_COLS)
563 {
564 //
565 // Item is the last in its row if it is a multiple of the number of
566 // columns or if it is just the last item
567 //
568 int n = i + 1;
0367c1c0 569
3c299c3a
DW
570 bIsLastInTheRow = ((n % m_nMajorDim) == 0) || (n == m_nNoItems);
571 }
572 else // winRA_SPECIFY_ROWS
573 {
574 //
575 // Item is the last in the row if it is in the last columns
576 //
577 bIsLastInTheRow = i >= (m_nNoItems/m_nMajorDim) * m_nMajorDim;
578 }
0367c1c0 579
3c299c3a
DW
580 //
581 // Is this the start of new row/column?
582 //
583 if (i && (i % m_nMajorDim == 0))
584 {
585 if (m_windowStyle & wxRA_SPECIFY_ROWS)
586 {
587
588 //
589 // Start of new column
590 //
591 nYOffset = nStartY;
592 nXOffset += nMaxWidth + nCx1;
593 }
594 else // start of new row
595 {
596 nXOffset = nStartX;
597 nYOffset -= nMaxHeight;
598 if (m_pnRadioWidth[0] > 0L)
599 nYOffset -= nCy1/2;
600 }
601 }
602
603 int nWidthBtn;
604
605 if (bIsLastInTheRow)
606 {
607 //
608 // Make the button go to the end of radio box
609 //
610 nWidthBtn = nStartX + nWidth - nXOffset - (2 * nCx1);
611 if (nWidthBtn < nMaxWidth)
612 nWidthBtn = nMaxWidth;
613 }
614 else
615 {
616 //
617 // Normal button, always of the same size
618 //
619 nWidthBtn = nMaxWidth;
620 }
cdf1e714 621
3c299c3a
DW
622 //
623 // Make all buttons of the same, maximal size - like this they
624 // cover the radiobox entirely and the radiobox tooltips are always
625 // shown (otherwise they are not when the mouse pointer is in the
626 // radiobox part not beinting to any radiobutton)
627 //
628 ::WinSetWindowPos( (HWND)m_ahRadioButtons[i]
629 ,HWND_TOP
630 ,(LONG)nXOffset
631 ,(LONG)nYOffset
632 ,(LONG)nWidthBtn
633 ,(LONG)nMaxHeight
634 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
635 );
b389a12d 636 GetParent()->Refresh();
3c299c3a
DW
637 //
638 // Where do we put the next button?
639 //
640 if (m_windowStyle & wxRA_SPECIFY_ROWS)
641 {
642 //
643 // Below this one
644 //
645 nYOffset -= nMaxHeight;
646 if (m_pnRadioWidth[0] > 0)
647 nYOffset -= nCy1/2;
648 }
649 else
650 {
651 //
652 // To the right of this one
653 //
654 nXOffset += nWidthBtn + nCx1;
655 }
656 }
657} // end of wxRadioBox::DoSetSize
0e320a79 658
3c299c3a
DW
659void wxRadioBox::Enable(
660 int nItem
661, bool bEnable
662)
0e320a79 663{
3c299c3a
DW
664 wxCHECK_RET( nItem >= 0 && nItem < m_nNoItems,
665 wxT("invalid item in wxRadioBox::Enable()") );
cdf1e714 666
3c299c3a
DW
667 ::WinEnableWindow((HWND) m_ahRadioButtons[nItem], bEnable);
668} // end of wxRadioBox::Enable
0e320a79 669
3c299c3a
DW
670bool wxRadioBox::Enable(
671 bool bEnable
672)
0e320a79 673{
3c299c3a
DW
674 if ( !wxControl::Enable(bEnable) )
675 return FALSE;
676 for (int i = 0; i < m_nNoItems; i++)
677 ::WinEnableWindow((HWND)m_ahRadioButtons[i], bEnable);
678 return TRUE;
679} // end of wxRadioBox::Enable
0e320a79 680
3c299c3a
DW
681int wxRadioBox::FindString(
682 const wxString& rsStr
683) const
0e320a79 684{
3c299c3a 685 for (int i = 0; i < m_nNoItems; i++)
cdf1e714 686 {
3c299c3a 687 if (rsStr == wxGetWindowText(m_ahRadioButtons[i]) )
cdf1e714
DW
688 return i;
689 }
cdf1e714 690 return wxNOT_FOUND;
3c299c3a 691} // end of wxRadioBox::FindString
cdf1e714 692
3c299c3a 693int wxRadioBox::GetColumnCount() const
0e320a79 694{
3c299c3a
DW
695 return GetNumHor();
696} // end of wxRadioBox::GetColumnCount
0e320a79 697
3c299c3a 698int wxRadioBox::GetCount() const
0e320a79 699{
3c299c3a
DW
700 return m_nNoItems;
701} // end of wxRadioBox::GetCount
0e320a79 702
3c299c3a
DW
703wxString wxRadioBox::GetLabel(
704 int nItem
705) const
0e320a79 706{
3c299c3a 707 wxCHECK_MSG(nItem >= 0 && nItem < m_nNoItems, wxT(""), wxT("invalid radiobox index") );
cdf1e714 708
3c299c3a
DW
709 return wxGetWindowText(m_ahRadioButtons[nItem]);
710} // end of wxRadioBox::GetLabel
cdf1e714 711
3c299c3a
DW
712wxSize wxRadioBox::GetMaxButtonSize() const
713{
714 int nWidthMax = 0;
715 int nHeightMax = 0;
cdf1e714 716
3c299c3a 717 for (int i = 0 ; i < m_nNoItems; i++)
cdf1e714 718 {
3c299c3a
DW
719 int nWidth;
720 int nHeight;
721
722 if (m_pnRadioWidth[i] < 0L)
cdf1e714 723 {
3c299c3a
DW
724 GetTextExtent( wxGetWindowText(m_ahRadioButtons[i])
725 ,&nWidth
726 ,&nHeight
727 );
728
729 //
730 // Adjust the size to take into account the radio box itself
731 // FIXME this is totally bogus!
732 //
733 nWidth += RADIO_SIZE;
734 nHeight *= 3;
735 nHeight /= 2;
cdf1e714
DW
736 }
737 else
738 {
3c299c3a
DW
739 nWidth = m_pnRadioWidth[i];
740 nHeight = m_pnRadioHeight[i];
cdf1e714 741 }
3c299c3a
DW
742 if (nWidthMax < nWidth )
743 nWidthMax = nWidth;
744 if (nHeightMax < nHeight )
745 nHeightMax = nHeight;
746 }
747 return(wxSize( nWidthMax
748 ,nHeightMax
749 )
750 );
751} // end of wxRadioBox::GetMaxButtonSize
cdf1e714 752
3c299c3a
DW
753int wxRadioBox::GetNumHor() const
754{
755 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
756 {
757 return (m_nNoItems + m_nMajorDim - 1)/m_nMajorDim;
758 }
759 else
760 {
761 return m_nMajorDim;
762 }
763} // end of wxRadioBox::GetNumHor
764
765int wxRadioBox::GetNumVer() const
766{
767 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
768 {
769 return m_nMajorDim;
cdf1e714 770 }
3c299c3a
DW
771 else
772 {
773 return (m_nNoItems + m_nMajorDim - 1)/m_nMajorDim;
774 }
775} // end of wxRadioBox::GetNumVer
cdf1e714 776
3c299c3a
DW
777void wxRadioBox::GetPosition(
778 int* pnX
779, int* pnY
780) const
781{
782 wxWindowOS2* pParent = GetParent();
783 RECT vRect = { -1, -1, -1, -1 };;
784 POINTL vPoint;
785 int i;
786
787 for (i = 0; i < m_nNoItems; i++)
788 wxFindMaxSize( m_ahRadioButtons[i]
789 ,&vRect
790 );
cdf1e714 791 if (m_hWnd)
3c299c3a
DW
792 wxFindMaxSize( m_hWnd
793 ,&vRect
794 );
795
796 //
797 // Since we now have the absolute screen coords, if there's a parent we
798 // must subtract its top left corner
799 //
800 vPoint.x = vRect.xLeft;
801 vPoint.y = vRect.yTop;
802 if (pParent)
cdf1e714 803 {
3c299c3a 804 SWP vSwp;
cdf1e714 805
3c299c3a
DW
806 ::WinQueryWindowPos((HWND)pParent->GetHWND(), &vSwp);
807 vPoint.x = vSwp.x;
808 vPoint.y = vSwp.y;
809 }
cdf1e714 810
3c299c3a
DW
811 //
812 // We may be faking the client origin. So a window that's really at (0, 30)
813 // may appear (to wxWin apps) to be at (0, 0).
814 //
815 if (GetParent())
816 {
817 wxPoint vPt(GetParent()->GetClientAreaOrigin());
cdf1e714 818
3c299c3a
DW
819 vPoint.x = vPt.x;
820 vPoint.y = vPt.y;
821 }
822 *pnX = vPoint.x;
823 *pnX = vPoint.y;
824} // end of wxRadioBox::GetPosition
cdf1e714 825
3c299c3a
DW
826int wxRadioBox::GetRowCount() const
827{
828 return GetNumVer();
829} // end of wxRadioBox::GetRowCount
cdf1e714 830
3c299c3a
DW
831// Get single selection, for single choice list items
832int wxRadioBox::GetSelection() const
833{
834 return m_nSelectedButton;
835} // end of wxRadioBox::GetSelection
cdf1e714 836
3c299c3a
DW
837void wxRadioBox::GetSize(
838 int* pnWidth
839, int* pnHeight
840) const
841{
842 RECT vRect;
843 int i;
cdf1e714 844
3c299c3a
DW
845 vRect.xLeft = -1;
846 vRect.xRight = -1;
847 vRect.yTop = -1;
848 vRect.yBottom = -1;
849
850 if (m_hWnd)
851 wxFindMaxSize( m_hWnd
852 ,&vRect
853 );
854
855 for (i = 0; i < m_nNoItems; i++)
856 wxFindMaxSize( m_ahRadioButtons[i]
857 ,&vRect
858 );
859
860 *pnWidth = vRect.xRight - vRect.xLeft;
861 *pnHeight = vRect.yBottom - vRect.yTop;
862} // end of wxRadioBox::GetSize
cdf1e714 863
3c299c3a
DW
864// Find string for position
865wxString wxRadioBox::GetString(
866 int nNum
867) const
868{
869 return wxGetWindowText(m_ahRadioButtons[nNum]);
870} // end of wxRadioBox::GetString
871
872// For single selection items only
873wxString wxRadioBox::GetStringSelection() const
874{
875 wxString sResult;
876 int nSel = GetSelection();
877
878 if (nSel > -1)
879 sResult = GetString(nSel);
880 return sResult;
881} // end of wxRadioBox::GetStringSelection
882
883wxSize wxRadioBox::GetTotalButtonSize(
884 const wxSize& rSizeBtn
885) const
886{
887 int nCx1;
888 int nCy1;
889 int nExtraHeight;
890 int nHeight;
891 int nWidth;
892 int nWidthLabel;
893
894 wxGetCharSize( m_hWnd
895 ,&nCx1
896 ,&nCy1
897 ,(wxFont*)&GetFont()
898 );
899 nExtraHeight = nCy1;
900
901 nHeight = GetNumVer() * rSizeBtn.y + (2 * nCy1);
902 nWidth = GetNumHor() * (rSizeBtn.x + nCx1) + nCx1;
903
904 //
905 // And also wide enough for its label
906 //
907 GetTextExtent( GetTitle()
908 ,&nWidthLabel
909 ,NULL
910 );
911 nWidthLabel += RADIO_SIZE;
912 if (nWidthLabel > nWidth)
913 nWidth = nWidthLabel;
914
915 return(wxSize( nWidth
916 ,nHeight
917 )
918 );
919} // end of wxRadioBox::GetTotalButtonSize
920
921WXHBRUSH wxRadioBox::OnCtlColor(
922 WXHDC hwinDC
923, WXHWND hWnd
924, WXUINT uCtlColor
925, WXUINT uMessage
926, WXWPARAM wParam
927, WXLPARAM lParam
928)
929{
930 HPS hPS = (HPS)hwinDC; // pass in a PS handle in OS/2
931
932 if (GetParent()->GetTransparentBackground())
933 ::GpiSetBackMix(hPS, BM_LEAVEALONE);
934 else
935 ::GpiSetBackMix(hPS, BM_OVERPAINT);
936
937 wxColour vColBack = GetBackgroundColour();
cdf1e714 938
3c299c3a
DW
939 ::GpiSetBackColor(hPS, vColBack.GetPixel());
940 ::GpiSetColor(hPS, vColBack.GetPixel());
941
942
943 wxBrush* pBrush = wxTheBrushList->FindOrCreateBrush( vColBack
944 ,wxSOLID
945 );
946 return ((WXHBRUSH)pBrush->GetResourceHandle());
947} // end of wxRadioBox::OnCtlColor
948
949bool wxRadioBox::OS2Command(
950 WXUINT uCmd
951, WXWORD wId
952)
953{
954 int nSelectedButton = -1;
955
956 if (uCmd == BN_CLICKED)
cdf1e714 957 {
3c299c3a
DW
958 if (wId == GetId())
959 return TRUE;
960
961
962 for (int i = 0; i < m_nNoItems; i++)
cdf1e714 963 {
3c299c3a 964 if (wId == wxGetWindowId(m_ahRadioButtons[i]))
cdf1e714 965 {
3c299c3a
DW
966 nSelectedButton = i;
967 break;
cdf1e714
DW
968 }
969 }
3c299c3a 970 if (nSelectedButton == -1)
cdf1e714 971 {
3c299c3a 972 //
f289196b
DW
973 // Just ignore it
974 //
3c299c3a 975 return FALSE;
cdf1e714 976 }
3c299c3a 977 if (nSelectedButton != m_nSelectedButton)
cdf1e714 978 {
3c299c3a
DW
979 m_nSelectedButton = nSelectedButton;
980 SendNotificationEvent();
cdf1e714 981 }
3c299c3a 982 return TRUE;
cdf1e714 983 }
3c299c3a
DW
984 else
985 return FALSE;
986} // end of wxRadioBox::OS2Command
0e320a79 987
3c299c3a 988void wxRadioBox::SendNotificationEvent()
0e320a79 989{
3c299c3a
DW
990 wxCommandEvent vEvent( wxEVT_COMMAND_RADIOBOX_SELECTED
991 ,m_windowId
992 );
cdf1e714 993
3c299c3a
DW
994 vEvent.SetInt( m_nSelectedButton );
995 vEvent.SetString( GetString(m_nSelectedButton) );
996 vEvent.SetEventObject(this);
997 ProcessCommand(vEvent);
998} // end of wxRadioBox::SendNotificationEvent
0e320a79
DW
999
1000void wxRadioBox::SetFocus()
1001{
3c299c3a 1002 if (m_nNoItems > 0)
cdf1e714 1003 {
3c299c3a
DW
1004 if (m_nSelectedButton == -1)
1005 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[0]);
cdf1e714 1006 else
3c299c3a 1007 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[m_nSelectedButton]);
cdf1e714 1008 }
3c299c3a 1009} // end of wxRadioBox::SetFocus
0e320a79 1010
3c299c3a
DW
1011bool wxRadioBox::SetFont(
1012 const wxFont& rFont
1013)
0e320a79 1014{
3c299c3a
DW
1015 if (!wxControl::SetFont(rFont))
1016 {
1017 //
1018 // Nothing to do
1019 //
cdf1e714 1020 return FALSE;
3c299c3a
DW
1021 }
1022 //
1023 // Also set the font of our radio buttons
1024 //
1025 WXHFONT hFont = wxFont(rFont).GetResourceHandle();
cdf1e714 1026
3c299c3a 1027 for (int n = 0; n < (int)m_nNoItems; n++)
cdf1e714 1028 {
3c299c3a 1029 HWND hWndBtn = (HWND)m_ahRadioButtons[n];
cdf1e714 1030
3c299c3a
DW
1031 wxOS2SetFont( hWndBtn
1032 ,rFont
1033 );
1034 ::WinInvalidateRect(hWndBtn, NULL, FALSE);
1035 }
cdf1e714 1036 return TRUE;
3c299c3a 1037} // end of wxRadioBox::SetFont
0e320a79 1038
3c299c3a
DW
1039void wxRadioBox::SetSelection(
1040 int nNum
1041)
0e320a79 1042{
3c299c3a 1043 wxCHECK_RET( (nNum >= 0) && (nNum < m_nNoItems), wxT("invalid radiobox index") );
cdf1e714 1044
3c299c3a
DW
1045 if (m_nSelectedButton >= 0 && m_nSelectedButton < m_nNoItems)
1046 ::WinSendMsg((HWND)m_ahRadioButtons[m_nSelectedButton], BM_SETCHECK, (MPARAM)0, (MPARAM)0);
0e320a79 1047
3c299c3a
DW
1048 ::WinSendMsg((HWND)m_ahRadioButtons[nNum], BM_SETCHECK, (MPARAM)1, (MPARAM)0);
1049 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[nNum]);
1050 m_nSelectedButton = nNum;
1051} // end of wxRadioBox::SetSelection
0e320a79 1052
3c299c3a
DW
1053void wxRadioBox::SetString(
1054 int nItem
1055, const wxString& rsLabel
1056)
0e320a79 1057{
3c299c3a 1058 wxCHECK_RET( nItem >= 0 && nItem < m_nNoItems, wxT("invalid radiobox index") );
cdf1e714 1059
3c299c3a
DW
1060 m_pnRadioWidth[nItem] = m_pnRadioHeight[nItem] = -1;
1061 ::WinSetWindowText((HWND)m_ahRadioButtons[nItem], rsLabel.c_str());
1062} // end of wxRadioBox::SetString
cdf1e714 1063
3c299c3a
DW
1064bool wxRadioBox::SetStringSelection(
1065 const wxString& rsStr
1066)
cdf1e714 1067{
3c299c3a 1068 int nSel = FindString(rsStr);
0e320a79 1069
3c299c3a 1070 if (nSel > -1)
0e320a79 1071 {
3c299c3a 1072 SetSelection(nSel);
0e320a79
DW
1073 return TRUE;
1074 }
1075 else
1076 return FALSE;
3c299c3a 1077} // end of wxRadioBox::SetStringSelection
0e320a79 1078
3c299c3a
DW
1079bool wxRadioBox::Show(
1080 bool bShow
1081)
cdf1e714 1082{
3c299c3a
DW
1083 int nCmdShow = 0;
1084
1085 if (!wxControl::Show(bShow))
1086 return FALSE;
1087
1088 for (int i = 0; i < m_nNoItems; i++)
cdf1e714 1089 {
3c299c3a 1090 ::WinShowWindow((HWND)m_ahRadioButtons[i], (BOOL)bShow);
cdf1e714 1091 }
3c299c3a
DW
1092 return TRUE;
1093} // end of wxRadioBox::Show
cdf1e714 1094
3c299c3a
DW
1095// Show a specific button
1096void wxRadioBox::Show(
1097 int nItem
1098, bool bShow
1099)
0e320a79 1100{
3c299c3a
DW
1101 wxCHECK_RET( nItem >= 0 && nItem < m_nNoItems,
1102 wxT("invalid item in wxRadioBox::Show()") );
0e320a79 1103
3c299c3a
DW
1104 ::WinShowWindow((HWND)m_ahRadioButtons[nItem], bShow);
1105} // end of wxRadioBox::Show
cdf1e714 1106
3c299c3a
DW
1107void wxRadioBox::SubclassRadioButton(
1108 WXHWND hWndBtn
1109)
1110{
1111 HWND hwndBtn = (HWND)hWndBtn;
cdf1e714 1112
3c299c3a
DW
1113 fnWndProcRadioBtn = (WXFARPROC)::WinSubclassWindow(hWndBtn, (PFNWP)wxRadioBtnWndProc);
1114} // end of wxRadioBox::SubclassRadioButton
cdf1e714 1115
3c299c3a
DW
1116MRESULT wxRadioBox::WindowProc(
1117 WXUINT uMsg
1118, WXWPARAM wParam
1119, WXLPARAM lParam
1120)
cdf1e714 1121{
3c299c3a
DW
1122 return (wxControl::OS2WindowProc( uMsg
1123 ,wParam
1124 ,lParam
1125 ));
1126} // end of wxRadioBox::WindowProc
cdf1e714
DW
1127
1128// ---------------------------------------------------------------------------
1129// window proc for radio buttons
1130// ---------------------------------------------------------------------------
1131
3c299c3a
DW
1132MRESULT wxRadioBtnWndProc(
1133 HWND hWnd
1134, UINT uMessage
1135, MPARAM wParam
1136, MPARAM lParam
1137)
cdf1e714 1138{
3c299c3a 1139 switch (uMessage)
cdf1e714 1140 {
3c299c3a
DW
1141 case WM_CHAR:
1142 {
1143 USHORT uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
cdf1e714 1144
3c299c3a 1145 if (!(uKeyFlags & KC_KEYUP)) // Key Down event
cdf1e714 1146 {
3c299c3a
DW
1147 if (uKeyFlags & KC_VIRTUALKEY)
1148 {
1149 wxRadioBox* pRadiobox = (wxRadioBox *)::WinQueryWindowULong( hWnd
1150 ,QWL_USER
1151 );
1152 USHORT uVk = SHORT2FROMMP((MPARAM)lParam);
1153 bool bProcessed = TRUE;
1154 wxDirection eDir;
1155
1156 switch(uVk)
1157 {
1158 case VK_LEFT:
1159 eDir = wxDOWN;
1160 break;
1161
1162 case VK_RIGHT:
1163 eDir = wxDOWN;
1164 break;
1165
1166 case VK_DOWN:
1167 eDir = wxDOWN;
1168 break;
1169
1170 case VK_UP:
1171 eDir = wxUP;
1172 break;
1173
1174 default:
1175 bProcessed = FALSE;
1176
1177 //
1178 // Just to suppress the compiler warning
1179 //
1180 eDir = wxALL;
1181 }
1182
1183 if (bProcessed)
1184 {
1185 int nSelOld = pRadiobox->GetSelection();
1186 int nSelNew = pRadiobox->GetNextItem( nSelOld
1187 ,eDir
1188 ,pRadiobox->GetWindowStyleFlag()
1189 );
1190
1191 if (nSelNew != nSelOld)
1192 {
1193 pRadiobox->SetSelection(nSelNew);
1194
1195 //
1196 // Emulate the button click
1197 //
1198 pRadiobox->SendNotificationEvent();
1199 return 0;
1200 }
1201 }
1202 }
cdf1e714 1203 }
cdf1e714 1204 }
3c299c3a 1205 break;
cdf1e714
DW
1206 }
1207
3c299c3a
DW
1208 return fnWndProcRadioBtn( hWnd
1209 ,(ULONG)uMessage
1210 ,(MPARAM)wParam
1211 ,(MPARAM)lParam
1212 );
1213} // end of wxRadioBtnWndProc
0e320a79 1214
f289196b
DW
1215MRESULT EXPENTRY wxRadioBoxWndProc(
1216 HWND hWnd
1217, UINT uMessage
1218, MPARAM wParam
1219, MPARAM lParam
1220)
1221{
1222 return (fnWndProcRadioBox( hWnd
1223 ,(ULONG)uMessage
1224 ,(MPARAM)wParam
1225 ,(MPARAM)lParam
1226 )
1227 );
1228} // end of wxRadioBoxWndProc
1229