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