]> git.saurik.com Git - wxWidgets.git/blame - src/os2/radiobox.cpp
destroying native and wx controls
[wxWidgets.git] / src / os2 / radiobox.cpp
CommitLineData
0e320a79
DW
1/////////////////////////////////////////////////////////////////////////////
2// Name: radiobox.cpp
3// Purpose: wxRadioBox
cdf1e714 4// Author: David Webster
0e320a79 5// Modified by:
cdf1e714 6// Created: 10/12/99
0e320a79 7// RCS-ID: $Id$
cdf1e714 8// Copyright: (c) David Webster
65571936 9// Licence: wxWindows licence
0e320a79
DW
10/////////////////////////////////////////////////////////////////////////////
11
cdf1e714
DW
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifndef WX_PRECOMP
16 #include <stdio.h>
17 #include "wx/setup.h"
b59c98dd
SN
18 #include "wx/wxchar.h"
19 #include "wx/string.h"
cdf1e714
DW
20 #include "wx/bitmap.h"
21 #include "wx/brush.h"
22 #include "wx/radiobox.h"
0e320a79
DW
23#endif
24
cdf1e714 25#include "wx/os2/private.h"
0e320a79 26
0e320a79 27IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
0e320a79 28
cdf1e714
DW
29// ---------------------------------------------------------------------------
30// private functions
31// ---------------------------------------------------------------------------
32
33// wnd proc for radio buttons
3c299c3a
DW
34MRESULT EXPENTRY wxRadioBtnWndProc( HWND hWnd
35 ,UINT uMessage
36 ,MPARAM wParam
37 ,MPARAM lParam
38 );
f289196b
DW
39MRESULT EXPENTRY wxRadioBoxWndProc( HWND hWnd
40 ,UINT uMessage
41 ,MPARAM wParam
42 ,MPARAM lParam
43 );
cdf1e714
DW
44
45// ---------------------------------------------------------------------------
46// global vars
47// ---------------------------------------------------------------------------
48
49// the pointer to standard radio button wnd proc
f289196b
DW
50extern void wxAssociateWinWithHandle( HWND hWnd
51 ,wxWindowOS2* pWin
52 );
3c299c3a 53static WXFARPROC fnWndProcRadioBtn = NULL;
f289196b 54static WXFARPROC fnWndProcRadioBox = NULL;
cdf1e714
DW
55
56// ===========================================================================
57// implementation
58// ===========================================================================
59
60// ---------------------------------------------------------------------------
61// wxRadioBox
62// ---------------------------------------------------------------------------
63
3c299c3a
DW
64// Radio box item
65wxRadioBox::wxRadioBox()
0367c1c0 66{
3c299c3a
DW
67 m_nSelectedButton = -1;
68 m_nNoItems = 0;
69 m_nNoRowsOrCols = 0;
70 m_ahRadioButtons = NULL;
71 m_nMajorDim = 0;
72 m_pnRadioWidth = NULL;
73 m_pnRadioHeight = NULL;
74} // end of wxRadioBox::wxRadioBox
0367c1c0 75
3c299c3a 76wxRadioBox::~wxRadioBox()
0367c1c0 77{
1a87edf2 78 m_isBeingDeleted = true;
0367c1c0 79
3c299c3a 80 if (m_ahRadioButtons)
cdf1e714 81 {
3c299c3a
DW
82 int i;
83 for (i = 0; i < m_nNoItems; i++)
84 ::WinDestroyWindow((HWND)m_ahRadioButtons[i]);
85 delete[] m_ahRadioButtons;
cdf1e714 86 }
3c299c3a
DW
87 if (m_pnRadioWidth)
88 delete[] m_pnRadioWidth;
89 if (m_pnRadioHeight)
90 delete[] m_pnRadioHeight;
91} // end of wxRadioBox::~wxRadioBox
92
93void wxRadioBox::AdjustButtons(
94 int nX
95, int nY
96, int nWidth
97, int nHeight
d8a3f66c 98, int nSizeFlags
3c299c3a 99)
cdf1e714 100{
3c299c3a
DW
101 wxSize vMaxSize;
102 int nXOffset = nX;
103 int nYOffset = nY + nHeight;
104 int nCx1;
105 int nCy1;
106 int nStartX;
107 int nStartY;
108 int nMaxWidth;
109 int nMaxHeight;
7804d121 110 wxFont vFont = GetFont();
3c299c3a
DW
111
112 wxGetCharSize( m_hWnd
113 ,&nCx1
114 ,&nCy1
7804d121 115 ,&vFont
3c299c3a
DW
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++)
cdf1e714 128 {
3c299c3a
DW
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;
cdf1e714 143
3c299c3a
DW
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 }
cdf1e714 153
3c299c3a
DW
154 //
155 // Is this the start of new row/column?
156 //
157 if (i && (i % m_nMajorDim == 0))
cdf1e714 158 {
3c299c3a 159 if (m_windowStyle & wxRA_SPECIFY_ROWS)
cdf1e714 160 {
cdf1e714 161
3c299c3a
DW
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;
cdf1e714
DW
174 }
175 }
176
3c299c3a 177 int nWidthBtn;
cdf1e714 178
3c299c3a 179 if (bIsLastInTheRow)
cdf1e714 180 {
3c299c3a
DW
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;
cdf1e714 194 }
cdf1e714 195
3c299c3a
DW
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 }
cdf1e714 229 }
3c299c3a 230} // end of wxRadioBox::AdjustButtons
cdf1e714 231
3c299c3a
DW
232void wxRadioBox::Command (
233 wxCommandEvent& rEvent
234)
235{
236 SetSelection (rEvent.GetInt());
237 ProcessCommand(rEvent);
238} // end of wxRadioBox::Command
cdf1e714 239
3c299c3a
DW
240bool wxRadioBox::ContainsHWND(
241 WXHWND hWnd
242) const
0e320a79 243{
3c299c3a
DW
244 size_t nCount = GetCount();
245 size_t i;
246
247 for (i = 0; i < nCount; i++)
248 {
249 if (GetRadioButtons()[i] == hWnd)
1a87edf2 250 return true;
3c299c3a 251 }
1a87edf2 252 return false;
3c299c3a
DW
253} // end of wxRadioBox::ContainsHWND
254
584ad2a3
MB
255bool 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{
41c54fac 268 wxCArrayString chs(asChoices);
584ad2a3
MB
269
270 return Create(pParent, vId, rsTitle, rPos, rSize, chs.GetCount(),
271 chs.GetStrings(), nMajorDim, lStyle, rVal, rsName);
272}
273
3c299c3a
DW
274bool 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
3c299c3a 284, const wxValidator& rVal
3c299c3a
DW
285, const wxString& rsName
286)
0e320a79 287{
3c299c3a
DW
288 wxColour vColour;
289 LONG lColor;
290
291 vColour.Set(wxString("BLACK"));
b389a12d 292 m_backgroundColour = pParent->GetBackgroundColour();
3c299c3a 293 m_nSelectedButton = -1;
b389a12d 294 m_nNoItems = 0;
3c299c3a
DW
295
296 m_nMajorDim = nMajorDim == 0 ? nNum : nMajorDim;
297 m_nNoRowsOrCols = nMajorDim;
298
299 //
300 // Common initialization
301 //
b9b1d6c8
DW
302 if (!CreateControl( pParent
303 ,vId
304 ,rPos
305 ,rSize
306 ,lStyle
b9b1d6c8 307 ,rVal
b9b1d6c8
DW
308 ,rsName
309 ))
1a87edf2 310 return false;
3c299c3a 311 if (!OS2CreateControl( "STATIC"
f289196b 312 ,SS_GROUPBOX
3c299c3a
DW
313 ,rPos
314 ,rSize
315 ,rsTitle
316 ))
1a87edf2 317 return false;
cdf1e714 318
f289196b 319 wxAssociateWinWithHandle(m_hWnd, this);
cdf1e714 320
3c299c3a 321 //
cdf1e714 322 // Some radio boxes test consecutive id.
3c299c3a 323 //
b389a12d 324 m_nNoItems = nNum;
cdf1e714 325 (void)NewControlId();
3c299c3a
DW
326 m_ahRadioButtons = new WXHWND[nNum];
327 m_pnRadioWidth = new int[nNum];
328 m_pnRadioHeight = new int[nNum];
329
3c299c3a 330 for (int i = 0; i < nNum; i++)
cdf1e714 331 {
3c299c3a
DW
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 );
5d44b24e 351 lColor = (LONG)vColour.GetPixel();
3c299c3a
DW
352 ::WinSetPresParam( hWndBtn
353 ,PP_FOREGROUNDCOLOR
354 ,sizeof(LONG)
355 ,(PVOID)&lColor
356 );
5d44b24e
DW
357 lColor = (LONG)m_backgroundColour.GetPixel();
358
359 ::WinSetPresParam( hWndBtn
360 ,PP_BACKGROUNDCOLOR
361 ,sizeof(LONG)
362 ,(PVOID)&lColor
363 );
3c299c3a 364 if (!hWndBtn)
cdf1e714 365 {
1a87edf2 366 return false;
cdf1e714 367 }
3c299c3a
DW
368 m_ahRadioButtons[i] = (WXHWND)hWndBtn;
369 SubclassRadioButton((WXHWND)hWndBtn);
f289196b 370 wxAssociateWinWithHandle(hWndBtn, this);
3c299c3a 371 wxOS2SetFont( hWndBtn
f289196b 372 ,*wxSMALL_FONT
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 );
f289196b
DW
392 SetFont(*wxSMALL_FONT);
393 fnWndProcRadioBox = (WXFARPROC)::WinSubclassWindow( GetHwnd()
394 ,(PFNWP)wxRadioBoxWndProc
395 );
396 ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
5d44b24e 397 lColor = (LONG)vColour.GetPixel();
3c299c3a
DW
398 ::WinSetPresParam( m_hWnd
399 ,PP_FOREGROUNDCOLOR
400 ,sizeof(LONG)
401 ,(PVOID)&lColor
402 );
f289196b
DW
403 ::WinSetPresParam( m_hWnd
404 ,PP_BORDERDARKCOLOR
405 ,sizeof(LONG)
406 ,(PVOID)&lColor
407 );
5d44b24e
DW
408 lColor = (LONG)m_backgroundColour.GetPixel();
409
410 ::WinSetPresParam( m_hWnd
411 ,PP_BACKGROUNDCOLOR
412 ,sizeof(LONG)
413 ,(PVOID)&lColor
414 );
f289196b
DW
415 ::WinSetPresParam( m_hWnd
416 ,PP_BORDERLIGHTCOLOR
417 ,sizeof(LONG)
418 ,(PVOID)&lColor
419 );
b389a12d
DW
420 SetXComp(0);
421 SetYComp(0);
cdf1e714 422 SetSelection(0);
3c299c3a
DW
423 SetSize( rPos.x
424 ,rPos.y
425 ,rSize.x
426 ,rSize.y
427 );
1a87edf2 428 return true;
3c299c3a 429} // end of wxRadioBox::Create
0e320a79 430
3c299c3a 431wxSize wxRadioBox::DoGetBestSize() const
0e320a79 432{
3c299c3a
DW
433 return (GetTotalButtonSize(GetMaxButtonSize()));
434} // end of WinGuiBase_CRadioBox::DoGetBestSize
435
436void 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;
7804d121 467 wxFont vFont = GetFont();
3c299c3a
DW
468
469 m_nSizeFlags = nSizeFlags;
470 GetPosition( &nCurrentX
471 ,&nCurrentY
472 );
473 GetSize( &nWidthOld
474 ,&nHeightOld
475 );
476
fa50c0e3 477 if (nX == wxDefaultCoord && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
3c299c3a 478 nXx = nCurrentX;
fa50c0e3 479 if (nY == wxDefaultCoord && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
3c299c3a 480 nYy = nCurrentY;
b389a12d
DW
481 if (nYy < 0)
482 nYy = 0;
483 if (nXx < 0)
484 nXx = 0;
3c299c3a
DW
485
486 wxGetCharSize( m_hWnd
487 ,&nCx1
488 ,&nCy1
7804d121 489 ,&vFont
3c299c3a
DW
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 }
cdf1e714 514
3c299c3a 515 if (nHeight == -1)
cdf1e714 516 {
3c299c3a
DW
517 if (nSizeFlags & wxSIZE_AUTO_HEIGHT)
518 nHeight = nTotHeight;
519 else
520 nHeight = nHeightOld;
cdf1e714
DW
521 }
522
3c299c3a 523 wxWindowOS2* pParent = (wxWindowOS2*)GetParent();
cdf1e714 524
3c299c3a
DW
525 if (pParent)
526 {
d8a3f66c
DW
527 int nOS2Height = GetOS2ParentHeight(pParent);
528
529 nYy = nOS2Height - (nYy + nHeight);
3c299c3a
DW
530 nYOffset = nYy + nHeight;
531 }
532 else
533 {
534 RECTL vRect;
0e320a79 535
3c299c3a
DW
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;
0367c1c0 582
3c299c3a
DW
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 }
0367c1c0 592
3c299c3a
DW
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 }
cdf1e714 634
3c299c3a
DW
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 );
b389a12d 649 GetParent()->Refresh();
3c299c3a
DW
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
0e320a79 671
1a87edf2 672bool wxRadioBox::Enable(int nItem, bool bEnable)
0e320a79 673{
fa50c0e3 674 wxCHECK_MSG( IsValid(nItem), false,
3c299c3a 675 wxT("invalid item in wxRadioBox::Enable()") );
cdf1e714 676
3c299c3a 677 ::WinEnableWindow((HWND) m_ahRadioButtons[nItem], bEnable);
1a87edf2 678 return true;
3c299c3a 679} // end of wxRadioBox::Enable
0e320a79 680
3c299c3a
DW
681bool wxRadioBox::Enable(
682 bool bEnable
683)
0e320a79 684{
3c299c3a 685 if ( !wxControl::Enable(bEnable) )
1a87edf2 686 return false;
3c299c3a
DW
687 for (int i = 0; i < m_nNoItems; i++)
688 ::WinEnableWindow((HWND)m_ahRadioButtons[i], bEnable);
1a87edf2 689 return true;
3c299c3a 690} // end of wxRadioBox::Enable
0e320a79 691
3c299c3a
DW
692int wxRadioBox::FindString(
693 const wxString& rsStr
694) const
0e320a79 695{
3c299c3a 696 for (int i = 0; i < m_nNoItems; i++)
cdf1e714 697 {
3c299c3a 698 if (rsStr == wxGetWindowText(m_ahRadioButtons[i]) )
cdf1e714
DW
699 return i;
700 }
cdf1e714 701 return wxNOT_FOUND;
3c299c3a 702} // end of wxRadioBox::FindString
cdf1e714 703
3c299c3a 704int wxRadioBox::GetColumnCount() const
0e320a79 705{
3c299c3a
DW
706 return GetNumHor();
707} // end of wxRadioBox::GetColumnCount
0e320a79 708
3c299c3a 709int wxRadioBox::GetCount() const
0e320a79 710{
3c299c3a
DW
711 return m_nNoItems;
712} // end of wxRadioBox::GetCount
0e320a79 713
3c299c3a
DW
714wxString wxRadioBox::GetLabel(
715 int nItem
716) const
0e320a79 717{
fa50c0e3 718 wxCHECK_MSG( IsValid(nItem), wxEmptyString, wxT("invalid radiobox index") );
cdf1e714 719
3c299c3a
DW
720 return wxGetWindowText(m_ahRadioButtons[nItem]);
721} // end of wxRadioBox::GetLabel
cdf1e714 722
3c299c3a
DW
723wxSize wxRadioBox::GetMaxButtonSize() const
724{
725 int nWidthMax = 0;
726 int nHeightMax = 0;
cdf1e714 727
3c299c3a 728 for (int i = 0 ; i < m_nNoItems; i++)
cdf1e714 729 {
3c299c3a
DW
730 int nWidth;
731 int nHeight;
732
733 if (m_pnRadioWidth[i] < 0L)
cdf1e714 734 {
3c299c3a
DW
735 GetTextExtent( wxGetWindowText(m_ahRadioButtons[i])
736 ,&nWidth
737 ,&nHeight
738 );
739
740 //
741 // Adjust the size to take into account the radio box itself
742 // FIXME this is totally bogus!
743 //
744 nWidth += RADIO_SIZE;
745 nHeight *= 3;
746 nHeight /= 2;
cdf1e714
DW
747 }
748 else
749 {
3c299c3a
DW
750 nWidth = m_pnRadioWidth[i];
751 nHeight = m_pnRadioHeight[i];
cdf1e714 752 }
3c299c3a
DW
753 if (nWidthMax < nWidth )
754 nWidthMax = nWidth;
755 if (nHeightMax < nHeight )
756 nHeightMax = nHeight;
757 }
758 return(wxSize( nWidthMax
759 ,nHeightMax
760 )
761 );
762} // end of wxRadioBox::GetMaxButtonSize
cdf1e714 763
3c299c3a
DW
764int wxRadioBox::GetNumHor() const
765{
766 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
767 {
768 return (m_nNoItems + m_nMajorDim - 1)/m_nMajorDim;
769 }
770 else
771 {
772 return m_nMajorDim;
773 }
774} // end of wxRadioBox::GetNumHor
775
776int wxRadioBox::GetNumVer() const
777{
778 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
779 {
780 return m_nMajorDim;
cdf1e714 781 }
3c299c3a
DW
782 else
783 {
784 return (m_nNoItems + m_nMajorDim - 1)/m_nMajorDim;
785 }
786} // end of wxRadioBox::GetNumVer
cdf1e714 787
3c299c3a
DW
788void wxRadioBox::GetPosition(
789 int* pnX
790, int* pnY
791) const
792{
793 wxWindowOS2* pParent = GetParent();
794 RECT vRect = { -1, -1, -1, -1 };;
795 POINTL vPoint;
796 int i;
797
798 for (i = 0; i < m_nNoItems; i++)
799 wxFindMaxSize( m_ahRadioButtons[i]
800 ,&vRect
801 );
cdf1e714 802 if (m_hWnd)
3c299c3a
DW
803 wxFindMaxSize( m_hWnd
804 ,&vRect
805 );
806
807 //
808 // Since we now have the absolute screen coords, if there's a parent we
809 // must subtract its top left corner
810 //
811 vPoint.x = vRect.xLeft;
812 vPoint.y = vRect.yTop;
813 if (pParent)
cdf1e714 814 {
3c299c3a 815 SWP vSwp;
cdf1e714 816
3c299c3a
DW
817 ::WinQueryWindowPos((HWND)pParent->GetHWND(), &vSwp);
818 vPoint.x = vSwp.x;
819 vPoint.y = vSwp.y;
820 }
cdf1e714 821
3c299c3a
DW
822 //
823 // We may be faking the client origin. So a window that's really at (0, 30)
824 // may appear (to wxWin apps) to be at (0, 0).
825 //
826 if (GetParent())
827 {
828 wxPoint vPt(GetParent()->GetClientAreaOrigin());
cdf1e714 829
3c299c3a
DW
830 vPoint.x = vPt.x;
831 vPoint.y = vPt.y;
832 }
833 *pnX = vPoint.x;
834 *pnX = vPoint.y;
835} // end of wxRadioBox::GetPosition
cdf1e714 836
3c299c3a
DW
837int wxRadioBox::GetRowCount() const
838{
839 return GetNumVer();
840} // end of wxRadioBox::GetRowCount
cdf1e714 841
3c299c3a
DW
842// Get single selection, for single choice list items
843int wxRadioBox::GetSelection() const
844{
845 return m_nSelectedButton;
846} // end of wxRadioBox::GetSelection
cdf1e714 847
3c299c3a
DW
848void wxRadioBox::GetSize(
849 int* pnWidth
850, int* pnHeight
851) const
852{
853 RECT vRect;
854 int i;
cdf1e714 855
3c299c3a
DW
856 vRect.xLeft = -1;
857 vRect.xRight = -1;
858 vRect.yTop = -1;
859 vRect.yBottom = -1;
860
861 if (m_hWnd)
862 wxFindMaxSize( m_hWnd
863 ,&vRect
864 );
865
866 for (i = 0; i < m_nNoItems; i++)
867 wxFindMaxSize( m_ahRadioButtons[i]
868 ,&vRect
869 );
870
a00ffdf1
SN
871 if (pnWidth)
872 *pnWidth = vRect.xRight - vRect.xLeft;
873 if (pnHeight)
874 *pnHeight = vRect.yTop - vRect.yBottom;
3c299c3a 875} // end of wxRadioBox::GetSize
cdf1e714 876
3c299c3a
DW
877// Find string for position
878wxString wxRadioBox::GetString(
879 int nNum
880) const
881{
882 return wxGetWindowText(m_ahRadioButtons[nNum]);
883} // end of wxRadioBox::GetString
884
885// For single selection items only
886wxString wxRadioBox::GetStringSelection() const
887{
888 wxString sResult;
889 int nSel = GetSelection();
890
891 if (nSel > -1)
892 sResult = GetString(nSel);
893 return sResult;
894} // end of wxRadioBox::GetStringSelection
895
896wxSize wxRadioBox::GetTotalButtonSize(
897 const wxSize& rSizeBtn
898) const
899{
900 int nCx1;
901 int nCy1;
902 int nExtraHeight;
903 int nHeight;
904 int nWidth;
905 int nWidthLabel;
7804d121 906 wxFont vFont = GetFont();
3c299c3a
DW
907
908 wxGetCharSize( m_hWnd
909 ,&nCx1
910 ,&nCy1
7804d121 911 ,&vFont
3c299c3a
DW
912 );
913 nExtraHeight = nCy1;
914
915 nHeight = GetNumVer() * rSizeBtn.y + (2 * nCy1);
916 nWidth = GetNumHor() * (rSizeBtn.x + nCx1) + nCx1;
917
918 //
919 // And also wide enough for its label
920 //
921 GetTextExtent( GetTitle()
922 ,&nWidthLabel
923 ,NULL
924 );
925 nWidthLabel += RADIO_SIZE;
926 if (nWidthLabel > nWidth)
927 nWidth = nWidthLabel;
928
929 return(wxSize( nWidth
930 ,nHeight
931 )
932 );
933} // end of wxRadioBox::GetTotalButtonSize
934
935WXHBRUSH wxRadioBox::OnCtlColor(
936 WXHDC hwinDC
937, WXHWND hWnd
938, WXUINT uCtlColor
939, WXUINT uMessage
940, WXWPARAM wParam
941, WXLPARAM lParam
942)
943{
944 HPS hPS = (HPS)hwinDC; // pass in a PS handle in OS/2
945
946 if (GetParent()->GetTransparentBackground())
947 ::GpiSetBackMix(hPS, BM_LEAVEALONE);
948 else
949 ::GpiSetBackMix(hPS, BM_OVERPAINT);
950
951 wxColour vColBack = GetBackgroundColour();
cdf1e714 952
3c299c3a
DW
953 ::GpiSetBackColor(hPS, vColBack.GetPixel());
954 ::GpiSetColor(hPS, vColBack.GetPixel());
955
956
957 wxBrush* pBrush = wxTheBrushList->FindOrCreateBrush( vColBack
958 ,wxSOLID
959 );
960 return ((WXHBRUSH)pBrush->GetResourceHandle());
961} // end of wxRadioBox::OnCtlColor
962
963bool wxRadioBox::OS2Command(
964 WXUINT uCmd
965, WXWORD wId
966)
967{
968 int nSelectedButton = -1;
969
970 if (uCmd == BN_CLICKED)
cdf1e714 971 {
3c299c3a 972 if (wId == GetId())
1a87edf2 973 return true;
3c299c3a
DW
974
975
976 for (int i = 0; i < m_nNoItems; i++)
cdf1e714 977 {
3c299c3a 978 if (wId == wxGetWindowId(m_ahRadioButtons[i]))
cdf1e714 979 {
3c299c3a
DW
980 nSelectedButton = i;
981 break;
cdf1e714
DW
982 }
983 }
3c299c3a 984 if (nSelectedButton == -1)
cdf1e714 985 {
3c299c3a 986 //
f289196b
DW
987 // Just ignore it
988 //
1a87edf2 989 return false;
cdf1e714 990 }
3c299c3a 991 if (nSelectedButton != m_nSelectedButton)
cdf1e714 992 {
3c299c3a
DW
993 m_nSelectedButton = nSelectedButton;
994 SendNotificationEvent();
cdf1e714 995 }
1a87edf2 996 return true;
cdf1e714 997 }
3c299c3a 998 else
1a87edf2 999 return false;
3c299c3a 1000} // end of wxRadioBox::OS2Command
0e320a79 1001
3c299c3a 1002void wxRadioBox::SendNotificationEvent()
0e320a79 1003{
3c299c3a
DW
1004 wxCommandEvent vEvent( wxEVT_COMMAND_RADIOBOX_SELECTED
1005 ,m_windowId
1006 );
cdf1e714 1007
3c299c3a
DW
1008 vEvent.SetInt( m_nSelectedButton );
1009 vEvent.SetString( GetString(m_nSelectedButton) );
1010 vEvent.SetEventObject(this);
1011 ProcessCommand(vEvent);
1012} // end of wxRadioBox::SendNotificationEvent
0e320a79
DW
1013
1014void wxRadioBox::SetFocus()
1015{
3c299c3a 1016 if (m_nNoItems > 0)
cdf1e714 1017 {
3c299c3a
DW
1018 if (m_nSelectedButton == -1)
1019 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[0]);
cdf1e714 1020 else
3c299c3a 1021 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[m_nSelectedButton]);
cdf1e714 1022 }
3c299c3a 1023} // end of wxRadioBox::SetFocus
0e320a79 1024
3c299c3a
DW
1025bool wxRadioBox::SetFont(
1026 const wxFont& rFont
1027)
0e320a79 1028{
3c299c3a
DW
1029 if (!wxControl::SetFont(rFont))
1030 {
1031 //
1032 // Nothing to do
1033 //
1a87edf2 1034 return false;
3c299c3a
DW
1035 }
1036 //
1037 // Also set the font of our radio buttons
1038 //
3c299c3a 1039 for (int n = 0; n < (int)m_nNoItems; n++)
cdf1e714 1040 {
3c299c3a 1041 HWND hWndBtn = (HWND)m_ahRadioButtons[n];
cdf1e714 1042
3c299c3a
DW
1043 wxOS2SetFont( hWndBtn
1044 ,rFont
1045 );
1046 ::WinInvalidateRect(hWndBtn, NULL, FALSE);
1047 }
1a87edf2 1048 return true;
3c299c3a 1049} // end of wxRadioBox::SetFont
0e320a79 1050
3c299c3a
DW
1051void wxRadioBox::SetSelection(
1052 int nNum
1053)
0e320a79 1054{
fa50c0e3 1055 wxCHECK_RET( IsValid(nNum), wxT("invalid radiobox index") );
cdf1e714 1056
fa50c0e3 1057 if ( IsValid(m_nSelectedButton) )
3c299c3a 1058 ::WinSendMsg((HWND)m_ahRadioButtons[m_nSelectedButton], BM_SETCHECK, (MPARAM)0, (MPARAM)0);
0e320a79 1059
3c299c3a
DW
1060 ::WinSendMsg((HWND)m_ahRadioButtons[nNum], BM_SETCHECK, (MPARAM)1, (MPARAM)0);
1061 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[nNum]);
1062 m_nSelectedButton = nNum;
1063} // end of wxRadioBox::SetSelection
0e320a79 1064
3c299c3a
DW
1065void wxRadioBox::SetString(
1066 int nItem
1067, const wxString& rsLabel
1068)
0e320a79 1069{
fa50c0e3 1070 wxCHECK_RET( IsValid(nItem), wxT("invalid radiobox index") );
cdf1e714 1071
3c299c3a
DW
1072 m_pnRadioWidth[nItem] = m_pnRadioHeight[nItem] = -1;
1073 ::WinSetWindowText((HWND)m_ahRadioButtons[nItem], rsLabel.c_str());
1074} // end of wxRadioBox::SetString
cdf1e714 1075
3c299c3a
DW
1076bool wxRadioBox::SetStringSelection(
1077 const wxString& rsStr
1078)
cdf1e714 1079{
3c299c3a 1080 int nSel = FindString(rsStr);
0e320a79 1081
3c299c3a 1082 if (nSel > -1)
0e320a79 1083 {
3c299c3a 1084 SetSelection(nSel);
1a87edf2 1085 return true;
0e320a79
DW
1086 }
1087 else
1a87edf2 1088 return false;
3c299c3a 1089} // end of wxRadioBox::SetStringSelection
0e320a79 1090
3c299c3a
DW
1091bool wxRadioBox::Show(
1092 bool bShow
1093)
cdf1e714 1094{
3c299c3a 1095 if (!wxControl::Show(bShow))
1a87edf2 1096 return false;
3c299c3a
DW
1097
1098 for (int i = 0; i < m_nNoItems; i++)
cdf1e714 1099 {
3c299c3a 1100 ::WinShowWindow((HWND)m_ahRadioButtons[i], (BOOL)bShow);
cdf1e714 1101 }
1a87edf2 1102 return true;
3c299c3a 1103} // end of wxRadioBox::Show
cdf1e714 1104
3c299c3a 1105// Show a specific button
fa50c0e3 1106bool wxRadioBox::Show(
3c299c3a
DW
1107 int nItem
1108, bool bShow
1109)
0e320a79 1110{
fa50c0e3 1111 wxCHECK_MSG( IsValid(nItem), false,
3c299c3a 1112 wxT("invalid item in wxRadioBox::Show()") );
0e320a79 1113
3c299c3a 1114 ::WinShowWindow((HWND)m_ahRadioButtons[nItem], bShow);
fa50c0e3
WS
1115
1116 return true;
3c299c3a 1117} // end of wxRadioBox::Show
cdf1e714 1118
3c299c3a
DW
1119void wxRadioBox::SubclassRadioButton(
1120 WXHWND hWndBtn
1121)
1122{
3c299c3a
DW
1123 fnWndProcRadioBtn = (WXFARPROC)::WinSubclassWindow(hWndBtn, (PFNWP)wxRadioBtnWndProc);
1124} // end of wxRadioBox::SubclassRadioButton
cdf1e714 1125
3c299c3a
DW
1126MRESULT wxRadioBox::WindowProc(
1127 WXUINT uMsg
1128, WXWPARAM wParam
1129, WXLPARAM lParam
1130)
cdf1e714 1131{
3c299c3a
DW
1132 return (wxControl::OS2WindowProc( uMsg
1133 ,wParam
1134 ,lParam
1135 ));
1136} // end of wxRadioBox::WindowProc
cdf1e714
DW
1137
1138// ---------------------------------------------------------------------------
1139// window proc for radio buttons
1140// ---------------------------------------------------------------------------
1141
3c299c3a
DW
1142MRESULT wxRadioBtnWndProc(
1143 HWND hWnd
1144, UINT uMessage
1145, MPARAM wParam
1146, MPARAM lParam
1147)
cdf1e714 1148{
3c299c3a 1149 switch (uMessage)
cdf1e714 1150 {
3c299c3a
DW
1151 case WM_CHAR:
1152 {
1153 USHORT uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
cdf1e714 1154
3c299c3a 1155 if (!(uKeyFlags & KC_KEYUP)) // Key Down event
cdf1e714 1156 {
3c299c3a
DW
1157 if (uKeyFlags & KC_VIRTUALKEY)
1158 {
1159 wxRadioBox* pRadiobox = (wxRadioBox *)::WinQueryWindowULong( hWnd
1160 ,QWL_USER
1161 );
1162 USHORT uVk = SHORT2FROMMP((MPARAM)lParam);
1a87edf2 1163 bool bProcessed = true;
3c299c3a
DW
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:
1a87edf2 1185 bProcessed = false;
3c299c3a
DW
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 }
cdf1e714 1213 }
cdf1e714 1214 }
3c299c3a 1215 break;
cdf1e714
DW
1216 }
1217
3c299c3a
DW
1218 return fnWndProcRadioBtn( hWnd
1219 ,(ULONG)uMessage
1220 ,(MPARAM)wParam
1221 ,(MPARAM)lParam
1222 );
1223} // end of wxRadioBtnWndProc
0e320a79 1224
f289196b
DW
1225MRESULT 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