/////////////////////////////////////////////////////////////////////////////
// Name: radiobox.cpp
// Purpose: wxRadioBox
-// Author: AUTHOR
+// Author: David Webster
// Modified by:
-// Created: ??/??/98
+// Created: 10/12/99
// RCS-ID: $Id$
-// Copyright: (c) AUTHOR
-// Licence: wxWindows licence
+// Copyright: (c) David Webster
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#ifdef __GNUG__
-#pragma implementation "radiobox.h"
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifndef WX_PRECOMP
+ #include <stdio.h>
+ #include "wx/setup.h"
+ #include "wx/wxchar.h"
+ #include "wx/string.h"
+ #include "wx/bitmap.h"
+ #include "wx/brush.h"
+ #include "wx/radiobox.h"
#endif
-#include "wx/radiobox.h"
+#include "wx/os2/private.h"
-#if !USE_SHARED_LIBRARY
IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
-#endif
+
+// ---------------------------------------------------------------------------
+// private functions
+// ---------------------------------------------------------------------------
+
+// wnd proc for radio buttons
+MRESULT EXPENTRY wxRadioBtnWndProc( HWND hWnd
+ ,UINT uMessage
+ ,MPARAM wParam
+ ,MPARAM lParam
+ );
+
+// ---------------------------------------------------------------------------
+// global vars
+// ---------------------------------------------------------------------------
+
+// the pointer to standard radio button wnd proc
+static WXFARPROC fnWndProcRadioBtn = NULL;
+
+// ===========================================================================
+// implementation
+// ===========================================================================
+
+// ---------------------------------------------------------------------------
+// wxRadioBox
+// ---------------------------------------------------------------------------
// Radio box item
wxRadioBox::wxRadioBox()
{
- m_selectedButton = -1;
- m_noItems = 0;
- m_noRowsOrCols = 0;
- m_majorDim = 0 ;
-}
+ m_nSelectedButton = -1;
+ m_nNoItems = 0;
+ m_nNoRowsOrCols = 0;
+ m_ahRadioButtons = NULL;
+ m_nMajorDim = 0;
+ m_pnRadioWidth = NULL;
+ m_pnRadioHeight = NULL;
+} // end of wxRadioBox::wxRadioBox
-bool wxRadioBox::Create(wxWindow *parent, wxWindowID id, const wxString& title,
- const wxPoint& pos, const wxSize& size,
- int n, const wxString choices[],
- int majorDim, long style,
- const wxValidator& val, const wxString& name)
+wxRadioBox::~wxRadioBox()
{
- m_selectedButton = -1;
- m_noItems = n;
+ m_isBeingDeleted = TRUE;
- SetName(name);
- SetValidator(val);
+ if (m_ahRadioButtons)
+ {
+ int i;
+ for (i = 0; i < m_nNoItems; i++)
+ ::WinDestroyWindow((HWND)m_ahRadioButtons[i]);
+ delete[] m_ahRadioButtons;
+ }
+ if (m_pnRadioWidth)
+ delete[] m_pnRadioWidth;
+ if (m_pnRadioHeight)
+ delete[] m_pnRadioHeight;
+} // end of wxRadioBox::~wxRadioBox
- parent->AddChild(this);
+void wxRadioBox::AdjustButtons(
+ int nX
+, int nY
+, int nWidth
+, int nHeight
+, int nSizeFlags
+)
+{
+ wxSize vMaxSize;
+ int nXOffset = nX;
+ int nYOffset = nY + nHeight;
+ int nCx1;
+ int nCy1;
+ int nStartX;
+ int nStartY;
+ int nMaxWidth;
+ int nMaxHeight;
+ int nTotWidth;
+ int nTotHeight;
- m_windowStyle = (long&)style;
+ wxGetCharSize( m_hWnd
+ ,&nCx1
+ ,&nCy1
+ ,&GetFont()
+ );
+ vMaxSize = GetMaxButtonSize();
+ nMaxWidth = vMaxSize.x;
+ nMaxHeight = vMaxSize.y;
- if (id == -1)
- m_windowId = NewControlId();
- else
- m_windowId = id;
+ nXOffset += nCx1;
+ nYOffset -= (nMaxHeight + ((3*nCy1)/2));
- m_noRowsOrCols = majorDim;
+ nStartX = nXOffset;
+ nStartY = nYOffset;
- if (majorDim==0)
- m_majorDim = n ;
- else
- m_majorDim = majorDim ;
+ for (int i = 0; i < m_nNoItems; i++)
+ {
+ //
+ // The last button in the row may be wider than the other ones as the
+ // radiobox may be wider than the sum of the button widths (as it
+ // happens, for example, when the radiobox label is very long)
+ //
+ bool bIsLastInTheRow;
+
+ if (m_windowStyle & wxRA_SPECIFY_COLS)
+ {
+ //
+ // Item is the last in its row if it is a multiple of the number of
+ // columns or if it is just the last item
+ //
+ int n = i + 1;
+
+ bIsLastInTheRow = ((n % m_nMajorDim) == 0) || (n == m_nNoItems);
+ }
+ else // winRA_SPECIFY_ROWS
+ {
+ //
+ // Item is the last in the row if it is in the last columns
+ //
+ bIsLastInTheRow = i >= (m_nNoItems/m_nMajorDim) * m_nMajorDim;
+ }
+
+ //
+ // Is this the start of new row/column?
+ //
+ if (i && (i % m_nMajorDim == 0))
+ {
+ if (m_windowStyle & wxRA_SPECIFY_ROWS)
+ {
+
+ //
+ // Start of new column
+ //
+ nYOffset = nStartY;
+ nXOffset += nMaxWidth + nCx1;
+ }
+ else // start of new row
+ {
+ nXOffset = nStartX;
+ nYOffset -= nMaxHeight;
+ if (m_pnRadioWidth[0] > 0L)
+ nYOffset -= nCy1/2;
+ }
+ }
+
+ int nWidthBtn;
+ if (bIsLastInTheRow)
+ {
+ //
+ // Make the button go to the end of radio box
+ //
+ nWidthBtn = nStartX + nWidth - nXOffset - (2 * nCx1);
+ if (nWidthBtn < nMaxWidth)
+ nWidthBtn = nMaxWidth;
+ }
+ else
+ {
+ //
+ // Normal button, always of the same size
+ //
+ nWidthBtn = nMaxWidth;
+ }
+
+ //
+ // Make all buttons of the same, maximal size - like this they
+ // cover the radiobox entirely and the radiobox tooltips are always
+ // shown (otherwise they are not when the mouse pointer is in the
+ // radiobox part not beYInt32ing to any radiobutton)
+ //
+ ::WinSetWindowPos( (HWND)m_ahRadioButtons[i]
+ ,HWND_TOP
+ ,(LONG)nXOffset
+ ,(LONG)nYOffset
+ ,(LONG)nWidthBtn
+ ,(LONG)nMaxHeight
+ ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+ );
+ //
+ // Where do we put the next button?
+ //
+ if (m_windowStyle & wxRA_SPECIFY_ROWS)
+ {
+ //
+ // Below this one
+ //
+ nYOffset -= nMaxHeight;
+ if (m_pnRadioWidth[0] > 0)
+ nYOffset -= nCy1/2;
+ }
+ else
+ {
+ //
+ // To the right of this one
+ //
+ nXOffset += nWidthBtn + nCx1;
+ }
+ }
+} // end of wxRadioBox::AdjustButtons
+
+void wxRadioBox::Command (
+ wxCommandEvent& rEvent
+)
+{
+ SetSelection (rEvent.GetInt());
+ ProcessCommand(rEvent);
+} // end of wxRadioBox::Command
+
+bool wxRadioBox::ContainsHWND(
+ WXHWND hWnd
+) const
+{
+ size_t nCount = GetCount();
+ size_t i;
- // TODO create radiobox
+ for (i = 0; i < nCount; i++)
+ {
+ if (GetRadioButtons()[i] == hWnd)
+ return TRUE;
+ }
return FALSE;
-}
+} // end of wxRadioBox::ContainsHWND
+bool wxRadioBox::Create(
+ wxWindow* pParent
+, wxWindowID vId
+, const wxString& rsTitle
+, const wxPoint& rPos
+, const wxSize& rSize
+, int nNum
+, const wxString asChoices[]
+, int nMajorDim
+, long lStyle
+#if wxUSE_VALIDATORS
+, const wxValidator& rVal
+#endif
+, const wxString& rsName
+)
+{
+ //
+ // System fonts are too big in OS/2 and they are blue
+ // We want smaller fonts and black by default.
+ //
+ wxFont& rFont = *wxSMALL_FONT;
+ wxColour vColour;
+ LONG lColor;
-wxRadioBox::~wxRadioBox()
+ vColour.Set(wxString("BLACK"));
+ lColor = (LONG)vColour.GetPixel();
+ m_nSelectedButton = -1;
+ m_nNoItems = nNum;
+
+ m_nMajorDim = nMajorDim == 0 ? nNum : nMajorDim;
+ m_nNoRowsOrCols = nMajorDim;
+
+ //
+ // Common initialization
+ //
+ if (!OS2CreateControl( pParent
+ ,vId
+ ,rPos
+ ,rSize
+ ,lStyle
+#if wxUSE_VALIDATORS
+ ,rVal
+#endif
+ ,rsName
+ ))
+
+
+
+
+ if (!OS2CreateControl( "STATIC"
+#if RADIOBTN_PARENT_IS_RADIOBOX
+ ,SS_GROUPBOX | WS_GROUP | WS_CLIPCHILDREN
+#else
+ ,SS_GROUPBOX | WS_GROUP | WS_CLIPSIBLINGS
+#endif
+ ,rPos
+ ,rSize
+ ,rsTitle
+ ))
+
+#if RADIOBTN_PARENT_IS_RADIOBOX
+ HWND hWndParent = GetHwnd();
+#else
+ HWND hWndParent = GetHwndOf(pParent);
+#endif
+ HFONT hFont;
+
+ //
+ // Some radio boxes test consecutive id.
+ //
+ (void)NewControlId();
+ m_ahRadioButtons = new WXHWND[nNum];
+ m_pnRadioWidth = new int[nNum];
+ m_pnRadioHeight = new int[nNum];
+
+ if (rFont.Ok())
+ {
+ hFont = rFont.GetResourceHandle();
+ }
+
+ for (int i = 0; i < nNum; i++)
+ {
+ m_pnRadioWidth[i] = m_pnRadioHeight[i] = -1;
+
+ long lStyleBtn = BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE;
+ int nNewId = NewControlId();
+
+ if (i == 0 && lStyle == 0)
+ lStyleBtn |= WS_GROUP;
+
+ HWND hWndBtn = (WXHWND)::WinCreateWindow ( GetHwndOf(pParent)
+ ,WC_BUTTON
+ ,asChoices[i]
+ ,lStyleBtn
+ ,0, 0, 0, 0
+ ,GetWinHwnd(pParent)
+ ,HWND_TOP
+ ,(HMENU)nNewId
+ ,NULL
+ ,NULL
+ );
+ lColor = (LONG)vColour.GetPixel();
+ ::WinSetPresParam( hWndBtn
+ ,PP_FOREGROUNDCOLOR
+ ,sizeof(LONG)
+ ,(PVOID)&lColor
+ );
+ lColor = (LONG)m_backgroundColour.GetPixel();
+
+ ::WinSetPresParam( hWndBtn
+ ,PP_BACKGROUNDCOLOR
+ ,sizeof(LONG)
+ ,(PVOID)&lColor
+ );
+ if (!hWndBtn)
+ {
+ return FALSE;
+ }
+ m_ahRadioButtons[i] = (WXHWND)hWndBtn;
+ SubclassRadioButton((WXHWND)hWndBtn);
+ wxOS2SetFont( hWndBtn
+ ,rFont
+ );
+ ::WinSetWindowULong(hWndBtn, QWL_USER, (ULONG)this);
+ m_aSubControls.Add(nNewId);
+ }
+
+ //
+ // Create a dummy radio control to end the group.
+ //
+ (void)::WinCreateWindow ( GetHwndOf(pParent)
+ ,WC_BUTTON
+ ,""
+ ,WS_GROUP | BS_AUTORADIOBUTTON
+ ,0, 0, 0, 0
+ ,GetWinHwnd(pParent)
+ ,HWND_TOP
+ ,(HMENU)NewControlId()
+ ,NULL
+ ,NULL
+ );
+ SetFont(*wxSMALL_FONT);
+ lColor = (LONG)vColour.GetPixel();
+ ::WinSetPresParam( m_hWnd
+ ,PP_FOREGROUNDCOLOR
+ ,sizeof(LONG)
+ ,(PVOID)&lColor
+ );
+ lColor = (LONG)m_backgroundColour.GetPixel();
+
+ ::WinSetPresParam( m_hWnd
+ ,PP_BACKGROUNDCOLOR
+ ,sizeof(LONG)
+ ,(PVOID)&lColor
+ );
+ SetSelection(0);
+ SetSize( rPos.x
+ ,rPos.y
+ ,rSize.x
+ ,rSize.y
+ );
+ return TRUE;
+} // end of wxRadioBox::Create
+
+wxSize wxRadioBox::DoGetBestSize() const
{
- // TODO
-}
+ return (GetTotalButtonSize(GetMaxButtonSize()));
+} // end of WinGuiBase_CRadioBox::DoGetBestSize
-wxString wxRadioBox::GetLabel(int item) const
+void wxRadioBox::DoSetSize(
+ int nX
+, int nY
+, int nWidth
+, int nHeight
+, int nSizeFlags
+)
{
- // TODO
- return wxString("");
-}
+ int nCurrentX;
+ int nCurrentY;
+ int nWidthOld;
+ int nHeightOld;
+ int nXx = nX;
+ int nYy = nY;
+#if RADIOBTN_PARENT_IS_RADIOBOX
+ int nXOffset = 0;
+ int nYOffset = 0;
+#else
+ int nXOffset = nXx;
+ int nYOffset = nYy;
+#endif
+ int nCx1;
+ int nCy1;
+ wxSize vMaxSize = GetMaxButtonSize();
+ int nMaxWidth;
+ int nMaxHeight;
+ wxSize vTotSize;
+ int nTotWidth;
+ int nTotHeight;
+ int nStartX;
+ int nStartY;
+
+ m_nSizeFlags = nSizeFlags;
+ GetPosition( &nCurrentX
+ ,&nCurrentY
+ );
+ GetSize( &nWidthOld
+ ,&nHeightOld
+ );
+
+ if (nX == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+ nXx = nCurrentX;
+ if (nY == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+ nYy = nCurrentY;
+
+
+ wxGetCharSize( m_hWnd
+ ,&nCx1
+ ,&nCy1
+ ,&GetFont()
+ );
+
+ //
+ // Attempt to have a look coherent with other platforms: We compute the
+ // biggest toggle dim, then we align all items according this value.
+ //
+ vMaxSize = GetMaxButtonSize();
+ nMaxWidth = vMaxSize.x;
+ nMaxHeight = vMaxSize.y;
+
+ vTotSize = GetTotalButtonSize(vMaxSize);
+ nTotWidth = vTotSize.x;
+ nTotHeight = vTotSize.y;
+
+ //
+ // Only change our width/height if asked for
+ //
+ if (nWidth == -1)
+ {
+ if (nSizeFlags & wxSIZE_AUTO_WIDTH )
+ nWidth = nTotWidth;
+ else
+ nWidth = nWidthOld;
+ }
+
+ if (nHeight == -1)
+ {
+ if (nSizeFlags & wxSIZE_AUTO_HEIGHT)
+ nHeight = nTotHeight;
+ else
+ nHeight = nHeightOld;
+ }
+
+ wxWindowOS2* pParent = (wxWindowOS2*)GetParent();
+
+ if (pParent)
+ {
+ int nOS2Height = GetOS2ParentHeight(pParent);
+
+ nYy = nOS2Height - (nYy + nHeight);
+ nYOffset = nYy + nHeight;
+ }
+ else
+ {
+ RECTL vRect;
+
+ ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
+ nYy = vRect.yTop - (nYy + nHeight);
+ }
+ ::WinSetWindowPos( GetHwnd()
+ ,HWND_TOP
+ ,(LONG)nXx
+ ,(LONG)nYy
+ ,(LONG)nWidth
+ ,(LONG)nHeight
+ ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+ );
+
+ //
+ // Now position all the buttons: the current button will be put at
+ // wxPoint(x_offset, y_offset) and the new row/column will start at
+ // startX/startY. The size of all buttons will be the same wxSize(maxWidth,
+ // maxHeight) except for the buttons in the last column which should extend
+ // to the right border of radiobox and thus can be wider than this.
+ //
+ // Also, remember that wxRA_SPECIFY_COLS means that we arrange buttons in
+ // left to right order and m_majorDim is the number of columns while
+ // wxRA_SPECIFY_ROWS means that the buttons are arranged top to bottom and
+ // m_majorDim is the number of rows.
+ //
+ nXOffset += nCx1;
+ nYOffset -= (nMaxHeight + ((3*nCy1)/2));
-void wxRadioBox::SetLabel(int item, const wxString& label)
+ nStartX = nXOffset;
+ nStartY = nYOffset;
+
+ for (int i = 0; i < m_nNoItems; i++)
+ {
+ //
+ // The last button in the row may be wider than the other ones as the
+ // radiobox may be wider than the sum of the button widths (as it
+ // happens, for example, when the radiobox label is very long)
+ //
+ bool bIsLastInTheRow;
+
+ if (m_windowStyle & wxRA_SPECIFY_COLS)
+ {
+ //
+ // Item is the last in its row if it is a multiple of the number of
+ // columns or if it is just the last item
+ //
+ int n = i + 1;
+
+ bIsLastInTheRow = ((n % m_nMajorDim) == 0) || (n == m_nNoItems);
+ }
+ else // winRA_SPECIFY_ROWS
+ {
+ //
+ // Item is the last in the row if it is in the last columns
+ //
+ bIsLastInTheRow = i >= (m_nNoItems/m_nMajorDim) * m_nMajorDim;
+ }
+
+ //
+ // Is this the start of new row/column?
+ //
+ if (i && (i % m_nMajorDim == 0))
+ {
+ if (m_windowStyle & wxRA_SPECIFY_ROWS)
+ {
+
+ //
+ // Start of new column
+ //
+ nYOffset = nStartY;
+ nXOffset += nMaxWidth + nCx1;
+ }
+ else // start of new row
+ {
+ nXOffset = nStartX;
+ nYOffset -= nMaxHeight;
+ if (m_pnRadioWidth[0] > 0L)
+ nYOffset -= nCy1/2;
+ }
+ }
+
+ int nWidthBtn;
+
+ if (bIsLastInTheRow)
+ {
+ //
+ // Make the button go to the end of radio box
+ //
+ nWidthBtn = nStartX + nWidth - nXOffset - (2 * nCx1);
+ if (nWidthBtn < nMaxWidth)
+ nWidthBtn = nMaxWidth;
+ }
+ else
+ {
+ //
+ // Normal button, always of the same size
+ //
+ nWidthBtn = nMaxWidth;
+ }
+
+ //
+ // Make all buttons of the same, maximal size - like this they
+ // cover the radiobox entirely and the radiobox tooltips are always
+ // shown (otherwise they are not when the mouse pointer is in the
+ // radiobox part not beinting to any radiobutton)
+ //
+ ::WinSetWindowPos( (HWND)m_ahRadioButtons[i]
+ ,HWND_TOP
+ ,(LONG)nXOffset
+ ,(LONG)nYOffset
+ ,(LONG)nWidthBtn
+ ,(LONG)nMaxHeight
+ ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+ );
+ //
+ // Where do we put the next button?
+ //
+ if (m_windowStyle & wxRA_SPECIFY_ROWS)
+ {
+ //
+ // Below this one
+ //
+ nYOffset -= nMaxHeight;
+ if (m_pnRadioWidth[0] > 0)
+ nYOffset -= nCy1/2;
+ }
+ else
+ {
+ //
+ // To the right of this one
+ //
+ nXOffset += nWidthBtn + nCx1;
+ }
+ }
+} // end of wxRadioBox::DoSetSize
+
+void wxRadioBox::Enable(
+ int nItem
+, bool bEnable
+)
{
- // TODO
-}
+ wxCHECK_RET( nItem >= 0 && nItem < m_nNoItems,
+ wxT("invalid item in wxRadioBox::Enable()") );
+
+ ::WinEnableWindow((HWND) m_ahRadioButtons[nItem], bEnable);
+} // end of wxRadioBox::Enable
-int wxRadioBox::FindString(const wxString& s) const
+bool wxRadioBox::Enable(
+ bool bEnable
+)
{
- // TODO
- return -1;
-}
+ if ( !wxControl::Enable(bEnable) )
+ return FALSE;
+ for (int i = 0; i < m_nNoItems; i++)
+ ::WinEnableWindow((HWND)m_ahRadioButtons[i], bEnable);
+ return TRUE;
+} // end of wxRadioBox::Enable
-void wxRadioBox::SetSelection(int n)
+int wxRadioBox::FindString(
+ const wxString& rsStr
+) const
{
- if ((n < 0) || (n >= m_noItems))
- return;
- // TODO
+ for (int i = 0; i < m_nNoItems; i++)
+ {
+ if (rsStr == wxGetWindowText(m_ahRadioButtons[i]) )
+ return i;
+ }
+ return wxNOT_FOUND;
+} // end of wxRadioBox::FindString
+
+int wxRadioBox::GetColumnCount() const
+{
+ return GetNumHor();
+} // end of wxRadioBox::GetColumnCount
+
+int wxRadioBox::GetCount() const
+{
+ return m_nNoItems;
+} // end of wxRadioBox::GetCount
- m_selectedButton = n;
-}
+wxString wxRadioBox::GetLabel(
+ int nItem
+) const
+{
+ wxCHECK_MSG(nItem >= 0 && nItem < m_nNoItems, wxT(""), wxT("invalid radiobox index") );
+
+ return wxGetWindowText(m_ahRadioButtons[nItem]);
+} // end of wxRadioBox::GetLabel
+
+wxSize wxRadioBox::GetMaxButtonSize() const
+{
+ int nWidthMax = 0;
+ int nHeightMax = 0;
+
+ for (int i = 0 ; i < m_nNoItems; i++)
+ {
+ int nWidth;
+ int nHeight;
+
+ if (m_pnRadioWidth[i] < 0L)
+ {
+ GetTextExtent( wxGetWindowText(m_ahRadioButtons[i])
+ ,&nWidth
+ ,&nHeight
+ );
+
+ //
+ // Adjust the size to take into account the radio box itself
+ // FIXME this is totally bogus!
+ //
+ nWidth += RADIO_SIZE;
+ nHeight *= 3;
+ nHeight /= 2;
+ }
+ else
+ {
+ nWidth = m_pnRadioWidth[i];
+ nHeight = m_pnRadioHeight[i];
+ }
+ if (nWidthMax < nWidth )
+ nWidthMax = nWidth;
+ if (nHeightMax < nHeight )
+ nHeightMax = nHeight;
+ }
+ return(wxSize( nWidthMax
+ ,nHeightMax
+ )
+ );
+} // end of wxRadioBox::GetMaxButtonSize
+
+int wxRadioBox::GetNumHor() const
+{
+ if ( m_windowStyle & wxRA_SPECIFY_ROWS )
+ {
+ return (m_nNoItems + m_nMajorDim - 1)/m_nMajorDim;
+ }
+ else
+ {
+ return m_nMajorDim;
+ }
+} // end of wxRadioBox::GetNumHor
+
+int wxRadioBox::GetNumVer() const
+{
+ if ( m_windowStyle & wxRA_SPECIFY_ROWS )
+ {
+ return m_nMajorDim;
+ }
+ else
+ {
+ return (m_nNoItems + m_nMajorDim - 1)/m_nMajorDim;
+ }
+} // end of wxRadioBox::GetNumVer
+
+void wxRadioBox::GetPosition(
+ int* pnX
+, int* pnY
+) const
+{
+ wxWindowOS2* pParent = GetParent();
+ RECT vRect = { -1, -1, -1, -1 };;
+ POINTL vPoint;
+ int i;
+
+ for (i = 0; i < m_nNoItems; i++)
+ wxFindMaxSize( m_ahRadioButtons[i]
+ ,&vRect
+ );
+ if (m_hWnd)
+ wxFindMaxSize( m_hWnd
+ ,&vRect
+ );
+
+ //
+ // Since we now have the absolute screen coords, if there's a parent we
+ // must subtract its top left corner
+ //
+ vPoint.x = vRect.xLeft;
+ vPoint.y = vRect.yTop;
+ if (pParent)
+ {
+ SWP vSwp;
+
+ ::WinQueryWindowPos((HWND)pParent->GetHWND(), &vSwp);
+ vPoint.x = vSwp.x;
+ vPoint.y = vSwp.y;
+ }
+
+ //
+ // We may be faking the client origin. So a window that's really at (0, 30)
+ // may appear (to wxWin apps) to be at (0, 0).
+ //
+ if (GetParent())
+ {
+ wxPoint vPt(GetParent()->GetClientAreaOrigin());
+
+ vPoint.x = vPt.x;
+ vPoint.y = vPt.y;
+ }
+ *pnX = vPoint.x;
+ *pnX = vPoint.y;
+} // end of wxRadioBox::GetPosition
+
+int wxRadioBox::GetRowCount() const
+{
+ return GetNumVer();
+} // end of wxRadioBox::GetRowCount
// Get single selection, for single choice list items
int wxRadioBox::GetSelection() const
{
- return m_selectedButton;
-}
+ return m_nSelectedButton;
+} // end of wxRadioBox::GetSelection
+
+void wxRadioBox::GetSize(
+ int* pnWidth
+, int* pnHeight
+) const
+{
+ RECT vRect;
+ int i;
+
+ vRect.xLeft = -1;
+ vRect.xRight = -1;
+ vRect.yTop = -1;
+ vRect.yBottom = -1;
+
+ if (m_hWnd)
+ wxFindMaxSize( m_hWnd
+ ,&vRect
+ );
+
+ for (i = 0; i < m_nNoItems; i++)
+ wxFindMaxSize( m_ahRadioButtons[i]
+ ,&vRect
+ );
+
+ *pnWidth = vRect.xRight - vRect.xLeft;
+ *pnHeight = vRect.yBottom - vRect.yTop;
+} // end of wxRadioBox::GetSize
// Find string for position
-wxString wxRadioBox::GetString(int n) const
+wxString wxRadioBox::GetString(
+ int nNum
+) const
{
- // TODO
- return wxString("");
-}
+ return wxGetWindowText(m_ahRadioButtons[nNum]);
+} // end of wxRadioBox::GetString
-void wxRadioBox::SetSize(int x, int y, int width, int height, int sizeFlags)
+// For single selection items only
+wxString wxRadioBox::GetStringSelection() const
{
- // TODO
-}
+ wxString sResult;
+ int nSel = GetSelection();
+
+ if (nSel > -1)
+ sResult = GetString(nSel);
+ return sResult;
+} // end of wxRadioBox::GetStringSelection
-void wxRadioBox::GetSize(int *width, int *height) const
+wxSize wxRadioBox::GetTotalButtonSize(
+ const wxSize& rSizeBtn
+) const
{
- // TODO
-}
+ int nCx1;
+ int nCy1;
+ int nExtraHeight;
+ int nHeight;
+ int nWidth;
+ int nWidthLabel;
+
+ wxGetCharSize( m_hWnd
+ ,&nCx1
+ ,&nCy1
+ ,(wxFont*)&GetFont()
+ );
+ nExtraHeight = nCy1;
-void wxRadioBox::GetPosition(int *x, int *y) const
+ nHeight = GetNumVer() * rSizeBtn.y + (2 * nCy1);
+ nWidth = GetNumHor() * (rSizeBtn.x + nCx1) + nCx1;
+
+ //
+ // And also wide enough for its label
+ //
+ GetTextExtent( GetTitle()
+ ,&nWidthLabel
+ ,NULL
+ );
+ nWidthLabel += RADIO_SIZE;
+ if (nWidthLabel > nWidth)
+ nWidth = nWidthLabel;
+
+ return(wxSize( nWidth
+ ,nHeight
+ )
+ );
+} // end of wxRadioBox::GetTotalButtonSize
+
+WXHBRUSH wxRadioBox::OnCtlColor(
+ WXHDC hwinDC
+, WXHWND hWnd
+, WXUINT uCtlColor
+, WXUINT uMessage
+, WXWPARAM wParam
+, WXLPARAM lParam
+)
{
- // TODO
-}
+ HPS hPS = (HPS)hwinDC; // pass in a PS handle in OS/2
+
+ if (GetParent()->GetTransparentBackground())
+ ::GpiSetBackMix(hPS, BM_LEAVEALONE);
+ else
+ ::GpiSetBackMix(hPS, BM_OVERPAINT);
+
+ wxColour vColBack = GetBackgroundColour();
-wxString wxRadioBox::GetLabel() const
+ ::GpiSetBackColor(hPS, vColBack.GetPixel());
+ ::GpiSetColor(hPS, vColBack.GetPixel());
+
+
+ wxBrush* pBrush = wxTheBrushList->FindOrCreateBrush( vColBack
+ ,wxSOLID
+ );
+ return ((WXHBRUSH)pBrush->GetResourceHandle());
+} // end of wxRadioBox::OnCtlColor
+
+bool wxRadioBox::OS2Command(
+ WXUINT uCmd
+, WXWORD wId
+)
{
- // TODO
- return wxString("");
-}
+ int nSelectedButton = -1;
+
+ if (uCmd == BN_CLICKED)
+ {
+ if (wId == GetId())
+ return TRUE;
+
-void wxRadioBox::SetLabel(const wxString& label)
+ for (int i = 0; i < m_nNoItems; i++)
+ {
+ if (wId == wxGetWindowId(m_ahRadioButtons[i]))
+ {
+ nSelectedButton = i;
+ break;
+ }
+ }
+ if (nSelectedButton == -1)
+ {
+ //
+ // Just ignore it - due to a hack with WM_NCHITTEST handling in our
+ // wnd proc, we can receive dummy click messages when we click near
+ // the radiobox edge (this is ugly but Julian wouldn't let me get
+ // rid of this...)
+ return FALSE;
+ }
+ if (nSelectedButton != m_nSelectedButton)
+ {
+ m_nSelectedButton = nSelectedButton;
+ SendNotificationEvent();
+ }
+ return TRUE;
+ }
+ else
+ return FALSE;
+} // end of wxRadioBox::OS2Command
+
+void wxRadioBox::SendNotificationEvent()
{
- // TODO
-}
+ wxCommandEvent vEvent( wxEVT_COMMAND_RADIOBOX_SELECTED
+ ,m_windowId
+ );
+
+ vEvent.SetInt( m_nSelectedButton );
+ vEvent.SetString( GetString(m_nSelectedButton) );
+ vEvent.SetEventObject(this);
+ ProcessCommand(vEvent);
+} // end of wxRadioBox::SendNotificationEvent
void wxRadioBox::SetFocus()
{
- // TODO
-}
+ if (m_nNoItems > 0)
+ {
+ if (m_nSelectedButton == -1)
+ ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[0]);
+ else
+ ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[m_nSelectedButton]);
+ }
+} // end of wxRadioBox::SetFocus
-bool wxRadioBox::Show(bool show)
+bool wxRadioBox::SetFont(
+ const wxFont& rFont
+)
{
- // TODO
- return FALSE;
-}
+ if (!wxControl::SetFont(rFont))
+ {
+ //
+ // Nothing to do
+ //
+ return FALSE;
+ }
+ //
+ // Also set the font of our radio buttons
+ //
+ WXHFONT hFont = wxFont(rFont).GetResourceHandle();
-// Enable a specific button
-void wxRadioBox::Enable(int item, bool enable)
-{
- // TODO
-}
+ for (int n = 0; n < (int)m_nNoItems; n++)
+ {
+ HWND hWndBtn = (HWND)m_ahRadioButtons[n];
+
+ wxOS2SetFont( hWndBtn
+ ,rFont
+ );
+ ::WinInvalidateRect(hWndBtn, NULL, FALSE);
+ }
+ return TRUE;
+} // end of wxRadioBox::SetFont
-// Enable all controls
-void wxRadioBox::Enable(bool enable)
+void wxRadioBox::SetSelection(
+ int nNum
+)
{
- wxControl::Enable(enable);
+ wxCHECK_RET( (nNum >= 0) && (nNum < m_nNoItems), wxT("invalid radiobox index") );
- // TODO
-}
+ if (m_nSelectedButton >= 0 && m_nSelectedButton < m_nNoItems)
+ ::WinSendMsg((HWND)m_ahRadioButtons[m_nSelectedButton], BM_SETCHECK, (MPARAM)0, (MPARAM)0);
-// Show a specific button
-void wxRadioBox::Show(int item, bool show)
-{
- // TODO
-}
+ ::WinSendMsg((HWND)m_ahRadioButtons[nNum], BM_SETCHECK, (MPARAM)1, (MPARAM)0);
+ ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[nNum]);
+ m_nSelectedButton = nNum;
+} // end of wxRadioBox::SetSelection
-// For single selection items only
-wxString wxRadioBox::GetStringSelection () const
+void wxRadioBox::SetString(
+ int nItem
+, const wxString& rsLabel
+)
{
- int sel = GetSelection ();
- if (sel > -1)
- return this->GetString (sel);
- else
- return wxString("");
-}
+ wxCHECK_RET( nItem >= 0 && nItem < m_nNoItems, wxT("invalid radiobox index") );
-bool wxRadioBox::SetStringSelection (const wxString& s)
+ m_pnRadioWidth[nItem] = m_pnRadioHeight[nItem] = -1;
+ ::WinSetWindowText((HWND)m_ahRadioButtons[nItem], rsLabel.c_str());
+} // end of wxRadioBox::SetString
+
+bool wxRadioBox::SetStringSelection(
+ const wxString& rsStr
+)
{
- int sel = FindString (s);
- if (sel > -1)
+ int nSel = FindString(rsStr);
+
+ if (nSel > -1)
{
- SetSelection (sel);
+ SetSelection(nSel);
return TRUE;
}
else
return FALSE;
-}
+} // end of wxRadioBox::SetStringSelection
-void wxRadioBox::Command (wxCommandEvent & event)
+bool wxRadioBox::Show(
+ bool bShow
+)
{
- SetSelection (event.m_commandInt);
- ProcessCommand (event);
-}
+ int nCmdShow = 0;
+
+ if (!wxControl::Show(bShow))
+ return FALSE;
+
+ for (int i = 0; i < m_nNoItems; i++)
+ {
+ ::WinShowWindow((HWND)m_ahRadioButtons[i], (BOOL)bShow);
+ }
+ return TRUE;
+} // end of wxRadioBox::Show
+
+// Show a specific button
+void wxRadioBox::Show(
+ int nItem
+, bool bShow
+)
+{
+ wxCHECK_RET( nItem >= 0 && nItem < m_nNoItems,
+ wxT("invalid item in wxRadioBox::Show()") );
+
+ ::WinShowWindow((HWND)m_ahRadioButtons[nItem], bShow);
+} // end of wxRadioBox::Show
+
+void wxRadioBox::SubclassRadioButton(
+ WXHWND hWndBtn
+)
+{
+ HWND hwndBtn = (HWND)hWndBtn;
+
+ fnWndProcRadioBtn = (WXFARPROC)::WinSubclassWindow(hWndBtn, (PFNWP)wxRadioBtnWndProc);
+} // end of wxRadioBox::SubclassRadioButton
+
+MRESULT wxRadioBox::WindowProc(
+ WXUINT uMsg
+, WXWPARAM wParam
+, WXLPARAM lParam
+)
+{
+ return (wxControl::OS2WindowProc( uMsg
+ ,wParam
+ ,lParam
+ ));
+} // end of wxRadioBox::WindowProc
+
+// ---------------------------------------------------------------------------
+// window proc for radio buttons
+// ---------------------------------------------------------------------------
+
+MRESULT wxRadioBtnWndProc(
+ HWND hWnd
+, UINT uMessage
+, MPARAM wParam
+, MPARAM lParam
+)
+{
+ switch (uMessage)
+ {
+ case WM_CHAR:
+ {
+ USHORT uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
+
+ if (!(uKeyFlags & KC_KEYUP)) // Key Down event
+ {
+ if (uKeyFlags & KC_VIRTUALKEY)
+ {
+ wxRadioBox* pRadiobox = (wxRadioBox *)::WinQueryWindowULong( hWnd
+ ,QWL_USER
+ );
+ USHORT uVk = SHORT2FROMMP((MPARAM)lParam);
+ bool bProcessed = TRUE;
+ wxDirection eDir;
+
+ switch(uVk)
+ {
+ case VK_LEFT:
+ eDir = wxDOWN;
+ break;
+
+ case VK_RIGHT:
+ eDir = wxDOWN;
+ break;
+
+ case VK_DOWN:
+ eDir = wxDOWN;
+ break;
+
+ case VK_UP:
+ eDir = wxUP;
+ break;
+
+ default:
+ bProcessed = FALSE;
+
+ //
+ // Just to suppress the compiler warning
+ //
+ eDir = wxALL;
+ }
+
+ if (bProcessed)
+ {
+ int nSelOld = pRadiobox->GetSelection();
+ int nSelNew = pRadiobox->GetNextItem( nSelOld
+ ,eDir
+ ,pRadiobox->GetWindowStyleFlag()
+ );
+
+ if (nSelNew != nSelOld)
+ {
+ pRadiobox->SetSelection(nSelNew);
+
+ //
+ // Emulate the button click
+ //
+ pRadiobox->SendNotificationEvent();
+ return 0;
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ return fnWndProcRadioBtn( hWnd
+ ,(ULONG)uMessage
+ ,(MPARAM)wParam
+ ,(MPARAM)lParam
+ );
+} // end of wxRadioBtnWndProc