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