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