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