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