]> git.saurik.com Git - wxWidgets.git/blame - src/os2/radiobox.cpp
implementing pure carbon event behaviour, getting rid of doubly executed events
[wxWidgets.git] / src / os2 / radiobox.cpp
CommitLineData
0e320a79 1/////////////////////////////////////////////////////////////////////////////
11e62fe6 2// Name: src/os2/radiobox.cpp
0e320a79 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
f289196b
DW
49extern void wxAssociateWinWithHandle( HWND hWnd
50 ,wxWindowOS2* pWin
51 );
a4ebf7ba
SN
52extern void wxRemoveHandleAssociation( wxWindowOS2 *pWin );
53// the pointer to standard radio button & box wnd procs
3c299c3a 54static WXFARPROC fnWndProcRadioBtn = NULL;
f289196b 55static WXFARPROC fnWndProcRadioBox = NULL;
cdf1e714
DW
56
57// ===========================================================================
58// implementation
59// ===========================================================================
60
61// ---------------------------------------------------------------------------
62// wxRadioBox
63// ---------------------------------------------------------------------------
64
3c299c3a
DW
65// Radio box item
66wxRadioBox::wxRadioBox()
0367c1c0 67{
3c299c3a
DW
68 m_nSelectedButton = -1;
69 m_nNoItems = 0;
3c299c3a 70 m_ahRadioButtons = NULL;
3c299c3a
DW
71 m_pnRadioWidth = NULL;
72 m_pnRadioHeight = NULL;
73} // end of wxRadioBox::wxRadioBox
0367c1c0 74
3c299c3a 75wxRadioBox::~wxRadioBox()
0367c1c0 76{
1a87edf2 77 m_isBeingDeleted = true;
0367c1c0 78
a4ebf7ba
SN
79 if (m_hWnd)
80 wxRemoveHandleAssociation(this);
3c299c3a 81 if (m_ahRadioButtons)
cdf1e714 82 {
a4ebf7ba
SN
83 for (int i = 0; i < m_nNoItems; i++)
84 {
85 wxWindow* pWin = wxFindWinFromHandle((WXHWND)m_ahRadioButtons[i]);
86 wxRemoveHandleAssociation(pWin);
87
3c299c3a 88 ::WinDestroyWindow((HWND)m_ahRadioButtons[i]);
a4ebf7ba 89 }
3c299c3a 90 delete[] m_ahRadioButtons;
cdf1e714 91 }
3c299c3a
DW
92 if (m_pnRadioWidth)
93 delete[] m_pnRadioWidth;
94 if (m_pnRadioHeight)
95 delete[] m_pnRadioHeight;
96} // end of wxRadioBox::~wxRadioBox
97
3c299c3a
DW
98void wxRadioBox::Command (
99 wxCommandEvent& rEvent
100)
101{
102 SetSelection (rEvent.GetInt());
103 ProcessCommand(rEvent);
104} // end of wxRadioBox::Command
cdf1e714 105
3c299c3a
DW
106bool wxRadioBox::ContainsHWND(
107 WXHWND hWnd
108) const
0e320a79 109{
3c299c3a
DW
110 size_t nCount = GetCount();
111 size_t i;
112
113 for (i = 0; i < nCount; i++)
114 {
115 if (GetRadioButtons()[i] == hWnd)
1a87edf2 116 return true;
3c299c3a 117 }
1a87edf2 118 return false;
3c299c3a
DW
119} // end of wxRadioBox::ContainsHWND
120
584ad2a3
MB
121bool wxRadioBox::Create(
122 wxWindow* pParent
123, wxWindowID vId
124, const wxString& rsTitle
125, const wxPoint& rPos
126, const wxSize& rSize
127, const wxArrayString& asChoices
128, int nMajorDim
129, long lStyle
130, const wxValidator& rVal
131, const wxString& rsName
132)
133{
41c54fac 134 wxCArrayString chs(asChoices);
584ad2a3
MB
135
136 return Create(pParent, vId, rsTitle, rPos, rSize, chs.GetCount(),
137 chs.GetStrings(), nMajorDim, lStyle, rVal, rsName);
138}
139
3c299c3a
DW
140bool wxRadioBox::Create(
141 wxWindow* pParent
142, wxWindowID vId
143, const wxString& rsTitle
144, const wxPoint& rPos
145, const wxSize& rSize
146, int nNum
147, const wxString asChoices[]
148, int nMajorDim
149, long lStyle
3c299c3a 150, const wxValidator& rVal
3c299c3a
DW
151, const wxString& rsName
152)
0e320a79 153{
3c299c3a
DW
154 wxColour vColour;
155 LONG lColor;
a4ebf7ba 156 HWND hWndParent = GetHwndOf(pParent);
3c299c3a 157
0fba44b4 158 vColour.Set(wxString(wxT("BLACK")));
b389a12d 159 m_backgroundColour = pParent->GetBackgroundColour();
3c299c3a 160 m_nSelectedButton = -1;
b389a12d 161 m_nNoItems = 0;
3c299c3a 162
3c299c3a
DW
163 //
164 // Common initialization
165 //
b9b1d6c8
DW
166 if (!CreateControl( pParent
167 ,vId
168 ,rPos
169 ,rSize
170 ,lStyle
b9b1d6c8 171 ,rVal
b9b1d6c8
DW
172 ,rsName
173 ))
1a87edf2 174 return false;
0fba44b4 175 if (!OS2CreateControl( wxT("STATIC")
f289196b 176 ,SS_GROUPBOX
3c299c3a
DW
177 ,rPos
178 ,rSize
179 ,rsTitle
180 ))
1a87edf2 181 return false;
cdf1e714 182
f289196b 183 wxAssociateWinWithHandle(m_hWnd, this);
cdf1e714 184
3c299c3a 185 //
4b2bdce6 186 // Now we can set m_nNoItems and let SetMajorDim set m_numCols/m_numRows
3c299c3a 187 //
b389a12d 188 m_nNoItems = nNum;
4b2bdce6 189 SetMajorDim(nMajorDim == 0 ? nNum : nMajorDim, lStyle);
4b2bdce6 190
3c299c3a
DW
191 m_ahRadioButtons = new WXHWND[nNum];
192 m_pnRadioWidth = new int[nNum];
193 m_pnRadioHeight = new int[nNum];
194
3c299c3a 195 for (int i = 0; i < nNum; i++)
cdf1e714 196 {
3c299c3a 197 m_pnRadioWidth[i] = m_pnRadioHeight[i] = -1;
a4ebf7ba 198 long lStyleBtn = BS_AUTORADIOBUTTON | WS_VISIBLE;
3c299c3a
DW
199 int nNewId = NewControlId();
200
be9d9869 201 if (i == 0)
a4ebf7ba
SN
202 lStyleBtn |= WS_GROUP | WS_TABSTOP;
203
204 wxString sLabel = ::wxPMTextToLabel(asChoices[i]);
205
206 HWND hWndBtn = (WXHWND)::WinCreateWindow ( hWndParent,
207 WC_BUTTON,
208 sLabel.c_str(),
209 lStyleBtn,
210 0, 0, 0, 0,
211 hWndParent,
212 HWND_BOTTOM,
213 (HMENU)nNewId,
214 NULL,
215 NULL
3c299c3a 216 );
a4ebf7ba
SN
217 if (!hWndBtn)
218 {
219 return false;
220 }
5d44b24e 221 lColor = (LONG)vColour.GetPixel();
3c299c3a
DW
222 ::WinSetPresParam( hWndBtn
223 ,PP_FOREGROUNDCOLOR
224 ,sizeof(LONG)
225 ,(PVOID)&lColor
226 );
5d44b24e 227
a4ebf7ba 228 lColor = (LONG)m_backgroundColour.GetPixel();
5d44b24e
DW
229 ::WinSetPresParam( hWndBtn
230 ,PP_BACKGROUNDCOLOR
231 ,sizeof(LONG)
232 ,(PVOID)&lColor
233 );
3c299c3a
DW
234 m_ahRadioButtons[i] = (WXHWND)hWndBtn;
235 SubclassRadioButton((WXHWND)hWndBtn);
f289196b 236 wxAssociateWinWithHandle(hWndBtn, this);
3c299c3a 237 wxOS2SetFont( hWndBtn
f289196b 238 ,*wxSMALL_FONT
3c299c3a
DW
239 );
240 ::WinSetWindowULong(hWndBtn, QWL_USER, (ULONG)this);
241 m_aSubControls.Add(nNewId);
cdf1e714 242 }
0e320a79 243
3c299c3a 244 //
be9d9869 245 // Create a dummy control to end the group.
3c299c3a 246 //
a4ebf7ba 247 (void)::WinCreateWindow ( hWndParent,
743e24aa
WS
248 WC_BUTTON,
249 "",
be9d9869 250 WS_GROUP,
743e24aa 251 0, 0, 0, 0,
a4ebf7ba 252 hWndParent,
743e24aa
WS
253 HWND_TOP,
254 (HMENU)NewControlId(),
255 NULL,
256 NULL
3c299c3a 257 );
f289196b
DW
258 fnWndProcRadioBox = (WXFARPROC)::WinSubclassWindow( GetHwnd()
259 ,(PFNWP)wxRadioBoxWndProc
260 );
261 ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
5d44b24e 262 lColor = (LONG)vColour.GetPixel();
3c299c3a
DW
263 ::WinSetPresParam( m_hWnd
264 ,PP_FOREGROUNDCOLOR
265 ,sizeof(LONG)
266 ,(PVOID)&lColor
267 );
5d44b24e 268
be9d9869 269 lColor = (LONG)m_backgroundColour.GetPixel();
5d44b24e
DW
270 ::WinSetPresParam( m_hWnd
271 ,PP_BACKGROUNDCOLOR
272 ,sizeof(LONG)
273 ,(PVOID)&lColor
274 );
b389a12d
DW
275 SetXComp(0);
276 SetYComp(0);
cdf1e714 277 SetSelection(0);
3c299c3a
DW
278 SetSize( rPos.x
279 ,rPos.y
280 ,rSize.x
281 ,rSize.y
282 );
1a87edf2 283 return true;
3c299c3a 284} // end of wxRadioBox::Create
0e320a79 285
3c299c3a 286wxSize wxRadioBox::DoGetBestSize() const
0e320a79 287{
3c299c3a 288 return (GetTotalButtonSize(GetMaxButtonSize()));
a4ebf7ba 289} // end of wxRadioBox::DoGetBestSize
3c299c3a
DW
290
291void wxRadioBox::DoSetSize(
292 int nX
293, int nY
294, int nWidth
295, int nHeight
296, int nSizeFlags
297)
298{
a4ebf7ba
SN
299 //
300 // Input parameters assume wxWidgets coordinate system
301 //
3c299c3a
DW
302 int nCurrentX;
303 int nCurrentY;
304 int nWidthOld;
305 int nHeightOld;
306 int nXx = nX;
307 int nYy = nY;
3c299c3a
DW
308 int nXOffset = nXx;
309 int nYOffset = nYy;
3c299c3a
DW
310 int nCx1;
311 int nCy1;
312 wxSize vMaxSize = GetMaxButtonSize();
313 int nMaxWidth;
314 int nMaxHeight;
315 wxSize vTotSize;
316 int nTotWidth;
317 int nTotHeight;
318 int nStartX;
319 int nStartY;
7804d121 320 wxFont vFont = GetFont();
3c299c3a
DW
321
322 m_nSizeFlags = nSizeFlags;
323 GetPosition( &nCurrentX
324 ,&nCurrentY
325 );
326 GetSize( &nWidthOld
327 ,&nHeightOld
328 );
329
fa50c0e3 330 if (nX == wxDefaultCoord && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
3c299c3a 331 nXx = nCurrentX;
fa50c0e3 332 if (nY == wxDefaultCoord && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
3c299c3a 333 nYy = nCurrentY;
b389a12d
DW
334 if (nYy < 0)
335 nYy = 0;
336 if (nXx < 0)
337 nXx = 0;
3c299c3a
DW
338
339 wxGetCharSize( m_hWnd
340 ,&nCx1
341 ,&nCy1
7804d121 342 ,&vFont
3c299c3a
DW
343 );
344
345 //
346 // Attempt to have a look coherent with other platforms: We compute the
347 // biggest toggle dim, then we align all items according this value.
348 //
349 vMaxSize = GetMaxButtonSize();
350 nMaxWidth = vMaxSize.x;
351 nMaxHeight = vMaxSize.y;
352
353 vTotSize = GetTotalButtonSize(vMaxSize);
354 nTotWidth = vTotSize.x;
355 nTotHeight = vTotSize.y;
356
357 //
358 // Only change our width/height if asked for
359 //
360 if (nWidth == -1)
361 {
362 if (nSizeFlags & wxSIZE_AUTO_WIDTH )
363 nWidth = nTotWidth;
364 else
365 nWidth = nWidthOld;
366 }
cdf1e714 367
3c299c3a 368 if (nHeight == -1)
cdf1e714 369 {
3c299c3a
DW
370 if (nSizeFlags & wxSIZE_AUTO_HEIGHT)
371 nHeight = nTotHeight;
372 else
373 nHeight = nHeightOld;
cdf1e714
DW
374 }
375
a4ebf7ba
SN
376 //
377 // Now convert to OS/2 coordinate system
378 //
3c299c3a 379 wxWindowOS2* pParent = (wxWindowOS2*)GetParent();
3c299c3a 380 if (pParent)
a4ebf7ba 381 nYy = GetOS2ParentHeight(pParent) - nYy - nHeight;
3c299c3a
DW
382 else
383 {
384 RECTL vRect;
3c299c3a 385 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
a4ebf7ba 386 nYy = vRect.yTop - nYy - nHeight;
3c299c3a 387 }
a4ebf7ba 388 nYOffset = nYy + nHeight;
3c299c3a
DW
389 ::WinSetWindowPos( GetHwnd()
390 ,HWND_TOP
391 ,(LONG)nXx
392 ,(LONG)nYy
393 ,(LONG)nWidth
394 ,(LONG)nHeight
395 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
396 );
397
398 //
399 // Now position all the buttons: the current button will be put at
400 // wxPoint(x_offset, y_offset) and the new row/column will start at
401 // startX/startY. The size of all buttons will be the same wxSize(maxWidth,
402 // maxHeight) except for the buttons in the last column which should extend
403 // to the right border of radiobox and thus can be wider than this.
404 //
405 // Also, remember that wxRA_SPECIFY_COLS means that we arrange buttons in
406 // left to right order and m_majorDim is the number of columns while
407 // wxRA_SPECIFY_ROWS means that the buttons are arranged top to bottom and
408 // m_majorDim is the number of rows.
409 //
410 nXOffset += nCx1;
411 nYOffset -= (nMaxHeight + ((3*nCy1)/2));
412
413 nStartX = nXOffset;
414 nStartY = nYOffset;
415
416 for (int i = 0; i < m_nNoItems; i++)
417 {
418 //
419 // The last button in the row may be wider than the other ones as the
420 // radiobox may be wider than the sum of the button widths (as it
421 // happens, for example, when the radiobox label is very long)
422 //
423 bool bIsLastInTheRow;
424
425 if (m_windowStyle & wxRA_SPECIFY_COLS)
426 {
427 //
428 // Item is the last in its row if it is a multiple of the number of
429 // columns or if it is just the last item
430 //
431 int n = i + 1;
0367c1c0 432
21e0a4d5 433 bIsLastInTheRow = ((n % GetMajorDim()) == 0) || (n == m_nNoItems);
3c299c3a
DW
434 }
435 else // winRA_SPECIFY_ROWS
436 {
437 //
438 // Item is the last in the row if it is in the last columns
439 //
21e0a4d5 440 bIsLastInTheRow = i >= (m_nNoItems/GetMajorDim()) * GetMajorDim();
3c299c3a 441 }
0367c1c0 442
3c299c3a
DW
443 //
444 // Is this the start of new row/column?
445 //
21e0a4d5 446 if (i && (i % GetMajorDim() == 0))
3c299c3a
DW
447 {
448 if (m_windowStyle & wxRA_SPECIFY_ROWS)
449 {
3c299c3a
DW
450 //
451 // Start of new column
452 //
453 nYOffset = nStartY;
454 nXOffset += nMaxWidth + nCx1;
455 }
456 else // start of new row
457 {
458 nXOffset = nStartX;
459 nYOffset -= nMaxHeight;
460 if (m_pnRadioWidth[0] > 0L)
461 nYOffset -= nCy1/2;
462 }
463 }
464
465 int nWidthBtn;
466
467 if (bIsLastInTheRow)
468 {
469 //
470 // Make the button go to the end of radio box
471 //
472 nWidthBtn = nStartX + nWidth - nXOffset - (2 * nCx1);
473 if (nWidthBtn < nMaxWidth)
474 nWidthBtn = nMaxWidth;
475 }
476 else
477 {
478 //
479 // Normal button, always of the same size
480 //
481 nWidthBtn = nMaxWidth;
482 }
cdf1e714 483
3c299c3a
DW
484 //
485 // Make all buttons of the same, maximal size - like this they
486 // cover the radiobox entirely and the radiobox tooltips are always
487 // shown (otherwise they are not when the mouse pointer is in the
4b2bdce6 488 // radiobox part not belonging to any radiobutton)
3c299c3a
DW
489 //
490 ::WinSetWindowPos( (HWND)m_ahRadioButtons[i]
be9d9869 491 ,HWND_BOTTOM
3c299c3a
DW
492 ,(LONG)nXOffset
493 ,(LONG)nYOffset
494 ,(LONG)nWidthBtn
495 ,(LONG)nMaxHeight
496 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
497 );
498 //
499 // Where do we put the next button?
500 //
501 if (m_windowStyle & wxRA_SPECIFY_ROWS)
502 {
503 //
504 // Below this one
505 //
506 nYOffset -= nMaxHeight;
507 if (m_pnRadioWidth[0] > 0)
508 nYOffset -= nCy1/2;
509 }
510 else
511 {
512 //
513 // To the right of this one
514 //
515 nXOffset += nWidthBtn + nCx1;
516 }
517 }
518} // end of wxRadioBox::DoSetSize
0e320a79 519
1a87edf2 520bool wxRadioBox::Enable(int nItem, bool bEnable)
0e320a79 521{
fa50c0e3 522 wxCHECK_MSG( IsValid(nItem), false,
3c299c3a 523 wxT("invalid item in wxRadioBox::Enable()") );
cdf1e714 524
3c299c3a 525 ::WinEnableWindow((HWND) m_ahRadioButtons[nItem], bEnable);
1a87edf2 526 return true;
3c299c3a 527} // end of wxRadioBox::Enable
0e320a79 528
3c299c3a
DW
529bool wxRadioBox::Enable(
530 bool bEnable
531)
0e320a79 532{
3c299c3a 533 if ( !wxControl::Enable(bEnable) )
1a87edf2 534 return false;
3c299c3a
DW
535 for (int i = 0; i < m_nNoItems; i++)
536 ::WinEnableWindow((HWND)m_ahRadioButtons[i], bEnable);
1a87edf2 537 return true;
3c299c3a 538} // end of wxRadioBox::Enable
0e320a79 539
3c299c3a 540int wxRadioBox::GetCount() const
0e320a79 541{
3c299c3a
DW
542 return m_nNoItems;
543} // end of wxRadioBox::GetCount
0e320a79 544
11e62fe6 545wxString wxRadioBox::GetLabel(int nItem) const
0e320a79 546{
fa50c0e3 547 wxCHECK_MSG( IsValid(nItem), wxEmptyString, wxT("invalid radiobox index") );
cdf1e714 548
3c299c3a
DW
549 return wxGetWindowText(m_ahRadioButtons[nItem]);
550} // end of wxRadioBox::GetLabel
cdf1e714 551
3c299c3a
DW
552wxSize wxRadioBox::GetMaxButtonSize() const
553{
554 int nWidthMax = 0;
555 int nHeightMax = 0;
cdf1e714 556
3c299c3a 557 for (int i = 0 ; i < m_nNoItems; i++)
cdf1e714 558 {
3c299c3a
DW
559 int nWidth;
560 int nHeight;
561
562 if (m_pnRadioWidth[i] < 0L)
cdf1e714 563 {
3c299c3a
DW
564 GetTextExtent( wxGetWindowText(m_ahRadioButtons[i])
565 ,&nWidth
566 ,&nHeight
567 );
568
569 //
570 // Adjust the size to take into account the radio box itself
571 // FIXME this is totally bogus!
572 //
573 nWidth += RADIO_SIZE;
574 nHeight *= 3;
575 nHeight /= 2;
cdf1e714
DW
576 }
577 else
578 {
3c299c3a
DW
579 nWidth = m_pnRadioWidth[i];
580 nHeight = m_pnRadioHeight[i];
cdf1e714 581 }
3c299c3a
DW
582 if (nWidthMax < nWidth )
583 nWidthMax = nWidth;
584 if (nHeightMax < nHeight )
585 nHeightMax = nHeight;
586 }
6670f564
WS
587 wxSize maxsize( nWidthMax, nHeightMax);
588 return maxsize;
3c299c3a 589} // end of wxRadioBox::GetMaxButtonSize
cdf1e714 590
3c299c3a
DW
591// Get single selection, for single choice list items
592int wxRadioBox::GetSelection() const
593{
594 return m_nSelectedButton;
595} // end of wxRadioBox::GetSelection
cdf1e714 596
743e24aa 597void wxRadioBox::GetSize( int* pnWidth, int* pnHeight ) const
3c299c3a
DW
598{
599 RECT vRect;
cdf1e714 600
3c299c3a
DW
601 vRect.xLeft = -1;
602 vRect.xRight = -1;
603 vRect.yTop = -1;
604 vRect.yBottom = -1;
605
606 if (m_hWnd)
607 wxFindMaxSize( m_hWnd
608 ,&vRect
609 );
610
a4ebf7ba 611 for (int i = 0; i < m_nNoItems; i++)
3c299c3a
DW
612 wxFindMaxSize( m_ahRadioButtons[i]
613 ,&vRect
614 );
615
a00ffdf1
SN
616 if (pnWidth)
617 *pnWidth = vRect.xRight - vRect.xLeft;
618 if (pnHeight)
619 *pnHeight = vRect.yTop - vRect.yBottom;
3c299c3a 620} // end of wxRadioBox::GetSize
cdf1e714 621
3c299c3a
DW
622// Find string for position
623wxString wxRadioBox::GetString(
624 int nNum
625) const
626{
a4ebf7ba 627 wxCHECK_MSG( IsValid(nNum), wxString(""), wxT("invalid radiobox index") );
3c299c3a
DW
628 return wxGetWindowText(m_ahRadioButtons[nNum]);
629} // end of wxRadioBox::GetString
630
631// For single selection items only
632wxString wxRadioBox::GetStringSelection() const
633{
634 wxString sResult;
635 int nSel = GetSelection();
636
637 if (nSel > -1)
638 sResult = GetString(nSel);
639 return sResult;
640} // end of wxRadioBox::GetStringSelection
641
6670f564 642wxSize wxRadioBox::GetTotalButtonSize( const wxSize& rSizeBtn ) const
3c299c3a 643{
6670f564
WS
644 int nCx1;
645 int nCy1;
6670f564
WS
646 int nHeight;
647 int nWidth;
c5f975dd 648 int nWidthLabel = 0;
3c299c3a 649
c5f975dd
SN
650 nCx1 = GetCharWidth();
651 nCy1 = GetCharHeight();
21e0a4d5
VZ
652 nHeight = GetRowCount() * rSizeBtn.y + (2 * nCy1);
653 nWidth = GetColumnCount() * (rSizeBtn.x + nCx1) + nCx1;
3c299c3a
DW
654
655 //
656 // And also wide enough for its label
657 //
c5f975dd
SN
658 wxString sStr = wxGetWindowText(GetHwnd());
659 if (!sStr.IsEmpty())
660 {
661 GetTextExtent( sStr
662 ,&nWidthLabel
663 ,NULL
664 );
665 nWidthLabel += 2*nCx1;
666 }
3c299c3a
DW
667 if (nWidthLabel > nWidth)
668 nWidth = nWidthLabel;
669
6670f564
WS
670 wxSize total( nWidth, nHeight );
671 return total;
3c299c3a
DW
672} // end of wxRadioBox::GetTotalButtonSize
673
6670f564
WS
674WXHBRUSH wxRadioBox::OnCtlColor( WXHDC hwinDC,
675 WXHWND WXUNUSED(hWnd),
676 WXUINT WXUNUSED(uCtlColor),
677 WXUINT WXUNUSED(uMessage),
678 WXWPARAM WXUNUSED(wParam),
679 WXLPARAM WXUNUSED(lParam) )
3c299c3a 680{
6670f564 681 HPS hPS = (HPS)hwinDC; // pass in a PS handle in OS/2
3c299c3a
DW
682
683 if (GetParent()->GetTransparentBackground())
684 ::GpiSetBackMix(hPS, BM_LEAVEALONE);
685 else
686 ::GpiSetBackMix(hPS, BM_OVERPAINT);
687
6670f564 688 wxColour vColBack = GetBackgroundColour();
cdf1e714 689
3c299c3a
DW
690 ::GpiSetBackColor(hPS, vColBack.GetPixel());
691 ::GpiSetColor(hPS, vColBack.GetPixel());
692
6670f564 693 wxBrush* pBrush = wxTheBrushList->FindOrCreateBrush( vColBack, wxSOLID );
3c299c3a
DW
694 return ((WXHBRUSH)pBrush->GetResourceHandle());
695} // end of wxRadioBox::OnCtlColor
696
6670f564
WS
697bool wxRadioBox::OS2Command( WXUINT uCmd,
698 WXWORD wId)
3c299c3a 699{
6670f564 700 int nSelectedButton = -1;
3c299c3a
DW
701
702 if (uCmd == BN_CLICKED)
cdf1e714 703 {
3c299c3a 704 if (wId == GetId())
1a87edf2 705 return true;
3c299c3a 706
3c299c3a 707 for (int i = 0; i < m_nNoItems; i++)
cdf1e714 708 {
3c299c3a 709 if (wId == wxGetWindowId(m_ahRadioButtons[i]))
cdf1e714 710 {
3c299c3a
DW
711 nSelectedButton = i;
712 break;
cdf1e714
DW
713 }
714 }
3c299c3a 715 if (nSelectedButton == -1)
cdf1e714 716 {
3c299c3a 717 //
f289196b
DW
718 // Just ignore it
719 //
1a87edf2 720 return false;
cdf1e714 721 }
3c299c3a 722 if (nSelectedButton != m_nSelectedButton)
cdf1e714 723 {
3c299c3a
DW
724 m_nSelectedButton = nSelectedButton;
725 SendNotificationEvent();
cdf1e714 726 }
1a87edf2 727 return true;
cdf1e714 728 }
3c299c3a 729 else
1a87edf2 730 return false;
3c299c3a 731} // end of wxRadioBox::OS2Command
0e320a79 732
3c299c3a 733void wxRadioBox::SendNotificationEvent()
0e320a79 734{
3c299c3a
DW
735 wxCommandEvent vEvent( wxEVT_COMMAND_RADIOBOX_SELECTED
736 ,m_windowId
737 );
cdf1e714 738
3c299c3a
DW
739 vEvent.SetInt( m_nSelectedButton );
740 vEvent.SetString( GetString(m_nSelectedButton) );
741 vEvent.SetEventObject(this);
742 ProcessCommand(vEvent);
743} // end of wxRadioBox::SendNotificationEvent
0e320a79
DW
744
745void wxRadioBox::SetFocus()
746{
3c299c3a 747 if (m_nNoItems > 0)
cdf1e714 748 {
3c299c3a
DW
749 if (m_nSelectedButton == -1)
750 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[0]);
cdf1e714 751 else
3c299c3a 752 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[m_nSelectedButton]);
cdf1e714 753 }
3c299c3a 754} // end of wxRadioBox::SetFocus
0e320a79 755
3c299c3a
DW
756bool wxRadioBox::SetFont(
757 const wxFont& rFont
758)
0e320a79 759{
3c299c3a
DW
760 if (!wxControl::SetFont(rFont))
761 {
762 //
763 // Nothing to do
764 //
1a87edf2 765 return false;
3c299c3a
DW
766 }
767 //
768 // Also set the font of our radio buttons
769 //
3c299c3a 770 for (int n = 0; n < (int)m_nNoItems; n++)
cdf1e714 771 {
3c299c3a 772 HWND hWndBtn = (HWND)m_ahRadioButtons[n];
cdf1e714 773
3c299c3a
DW
774 wxOS2SetFont( hWndBtn
775 ,rFont
776 );
777 ::WinInvalidateRect(hWndBtn, NULL, FALSE);
778 }
1a87edf2 779 return true;
3c299c3a 780} // end of wxRadioBox::SetFont
0e320a79 781
3c299c3a
DW
782void wxRadioBox::SetSelection(
783 int nNum
784)
0e320a79 785{
fa50c0e3 786 wxCHECK_RET( IsValid(nNum), wxT("invalid radiobox index") );
cdf1e714 787
fa50c0e3 788 if ( IsValid(m_nSelectedButton) )
3c299c3a 789 ::WinSendMsg((HWND)m_ahRadioButtons[m_nSelectedButton], BM_SETCHECK, (MPARAM)0, (MPARAM)0);
0e320a79 790
3c299c3a
DW
791 ::WinSendMsg((HWND)m_ahRadioButtons[nNum], BM_SETCHECK, (MPARAM)1, (MPARAM)0);
792 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[nNum]);
793 m_nSelectedButton = nNum;
794} // end of wxRadioBox::SetSelection
0e320a79 795
3c299c3a
DW
796void wxRadioBox::SetString(
797 int nItem
798, const wxString& rsLabel
799)
0e320a79 800{
fa50c0e3 801 wxCHECK_RET( IsValid(nItem), wxT("invalid radiobox index") );
cdf1e714 802
3c299c3a 803 m_pnRadioWidth[nItem] = m_pnRadioHeight[nItem] = -1;
0fba44b4 804 ::WinSetWindowText((HWND)m_ahRadioButtons[nItem], (PSZ)rsLabel.c_str());
3c299c3a 805} // end of wxRadioBox::SetString
cdf1e714 806
11e62fe6 807bool wxRadioBox::SetStringSelection(const wxString& rsStr)
cdf1e714 808{
11e62fe6 809 int nSel = FindString(rsStr);
0e320a79 810
3c299c3a 811 if (nSel > -1)
0e320a79 812 {
3c299c3a 813 SetSelection(nSel);
1a87edf2 814 return true;
0e320a79
DW
815 }
816 else
1a87edf2 817 return false;
3c299c3a 818} // end of wxRadioBox::SetStringSelection
0e320a79 819
3c299c3a
DW
820bool wxRadioBox::Show(
821 bool bShow
822)
cdf1e714 823{
3c299c3a 824 if (!wxControl::Show(bShow))
1a87edf2 825 return false;
3c299c3a
DW
826
827 for (int i = 0; i < m_nNoItems; i++)
cdf1e714 828 {
3c299c3a 829 ::WinShowWindow((HWND)m_ahRadioButtons[i], (BOOL)bShow);
cdf1e714 830 }
1a87edf2 831 return true;
3c299c3a 832} // end of wxRadioBox::Show
cdf1e714 833
3c299c3a 834// Show a specific button
fa50c0e3 835bool wxRadioBox::Show(
3c299c3a
DW
836 int nItem
837, bool bShow
838)
0e320a79 839{
fa50c0e3 840 wxCHECK_MSG( IsValid(nItem), false,
3c299c3a 841 wxT("invalid item in wxRadioBox::Show()") );
0e320a79 842
3c299c3a 843 ::WinShowWindow((HWND)m_ahRadioButtons[nItem], bShow);
fa50c0e3
WS
844
845 return true;
3c299c3a 846} // end of wxRadioBox::Show
cdf1e714 847
3c299c3a
DW
848void wxRadioBox::SubclassRadioButton(
849 WXHWND hWndBtn
850)
851{
3c299c3a
DW
852 fnWndProcRadioBtn = (WXFARPROC)::WinSubclassWindow(hWndBtn, (PFNWP)wxRadioBtnWndProc);
853} // end of wxRadioBox::SubclassRadioButton
cdf1e714 854
3c299c3a
DW
855MRESULT wxRadioBox::WindowProc(
856 WXUINT uMsg
857, WXWPARAM wParam
858, WXLPARAM lParam
859)
cdf1e714 860{
3c299c3a
DW
861 return (wxControl::OS2WindowProc( uMsg
862 ,wParam
863 ,lParam
864 ));
865} // end of wxRadioBox::WindowProc
cdf1e714
DW
866
867// ---------------------------------------------------------------------------
868// window proc for radio buttons
869// ---------------------------------------------------------------------------
870
3c299c3a
DW
871MRESULT wxRadioBtnWndProc(
872 HWND hWnd
873, UINT uMessage
874, MPARAM wParam
875, MPARAM lParam
876)
cdf1e714 877{
3c299c3a 878 switch (uMessage)
cdf1e714 879 {
3c299c3a
DW
880 case WM_CHAR:
881 {
882 USHORT uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
cdf1e714 883
3c299c3a 884 if (!(uKeyFlags & KC_KEYUP)) // Key Down event
cdf1e714 885 {
3c299c3a
DW
886 if (uKeyFlags & KC_VIRTUALKEY)
887 {
888 wxRadioBox* pRadiobox = (wxRadioBox *)::WinQueryWindowULong( hWnd
889 ,QWL_USER
890 );
891 USHORT uVk = SHORT2FROMMP((MPARAM)lParam);
1a87edf2 892 bool bProcessed = true;
3c299c3a
DW
893 wxDirection eDir;
894
895 switch(uVk)
896 {
897 case VK_LEFT:
be9d9869 898 eDir = wxLEFT;
3c299c3a
DW
899 break;
900
901 case VK_RIGHT:
be9d9869 902 eDir = wxRIGHT;
3c299c3a
DW
903 break;
904
905 case VK_DOWN:
906 eDir = wxDOWN;
907 break;
908
909 case VK_UP:
910 eDir = wxUP;
911 break;
912
913 default:
1a87edf2 914 bProcessed = false;
3c299c3a
DW
915
916 //
917 // Just to suppress the compiler warning
918 //
919 eDir = wxALL;
920 }
921
922 if (bProcessed)
923 {
924 int nSelOld = pRadiobox->GetSelection();
925 int nSelNew = pRadiobox->GetNextItem( nSelOld
926 ,eDir
927 ,pRadiobox->GetWindowStyleFlag()
928 );
929
930 if (nSelNew != nSelOld)
931 {
932 pRadiobox->SetSelection(nSelNew);
933
934 //
935 // Emulate the button click
936 //
937 pRadiobox->SendNotificationEvent();
938 return 0;
939 }
940 }
941 }
cdf1e714 942 }
cdf1e714 943 }
3c299c3a 944 break;
cdf1e714
DW
945 }
946
3c299c3a
DW
947 return fnWndProcRadioBtn( hWnd
948 ,(ULONG)uMessage
949 ,(MPARAM)wParam
950 ,(MPARAM)lParam
951 );
952} // end of wxRadioBtnWndProc
0e320a79 953
743e24aa
WS
954MRESULT EXPENTRY wxRadioBoxWndProc( HWND hWnd,
955 UINT uMessage,
956 MPARAM wParam,
957 MPARAM lParam )
f289196b 958{
743e24aa
WS
959 return (fnWndProcRadioBox( hWnd,
960 (ULONG)uMessage,
961 (MPARAM)wParam,
962 (MPARAM)lParam )
f289196b
DW
963 );
964} // end of wxRadioBoxWndProc