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