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