/////////////////////////////////////////////////////////////////////////////
-// Name: radiobox.cpp
+// Name: src/os2/radiobox.cpp
// Purpose: wxRadioBox
// Author: David Webster
// Modified by:
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
+#if wxUSE_RADIOBOX
+
+#include "wx/radiobox.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/os2/private.h"
// ---------------------------------------------------------------------------
// wnd proc for radio buttons
-MRESULT wxRadioBtnWndProc(HWND hWnd,
- UINT message,
- MPARAM wParam,
- MPARAM lParam);
+MRESULT EXPENTRY wxRadioBtnWndProc( HWND hWnd
+ ,UINT uMessage
+ ,MPARAM wParam
+ ,MPARAM lParam
+ );
+MRESULT EXPENTRY wxRadioBoxWndProc( HWND hWnd
+ ,UINT uMessage
+ ,MPARAM wParam
+ ,MPARAM lParam
+ );
// ---------------------------------------------------------------------------
// global vars
// ---------------------------------------------------------------------------
-// the pointer to standard radio button wnd proc
-static s_wndprocRadioBtn = NULL;
+extern void wxAssociateWinWithHandle( HWND hWnd
+ ,wxWindowOS2* pWin
+ );
+extern void wxRemoveHandleAssociation( wxWindowOS2 *pWin );
+// the pointer to standard radio button & box wnd procs
+static WXFARPROC fnWndProcRadioBtn = NULL;
+static WXFARPROC fnWndProcRadioBox = NULL;
// ===========================================================================
// implementation
// wxRadioBox
// ---------------------------------------------------------------------------
-int wxRadioBox::GetNumVer() const
+// Radio box item
+wxRadioBox::wxRadioBox()
{
- if ( m_windowStyle & wxRA_SPECIFY_ROWS )
- {
- return m_majorDim;
- }
- else
- {
- return (m_noItems + m_majorDim - 1)/m_majorDim;
- }
-}
+ m_nSelectedButton = -1;
+ m_nNoItems = 0;
+ m_ahRadioButtons = NULL;
+ m_pnRadioWidth = NULL;
+ m_pnRadioHeight = NULL;
+} // end of wxRadioBox::wxRadioBox
-int wxRadioBox::GetNumHor() const
+wxRadioBox::~wxRadioBox()
{
- if ( m_windowStyle & wxRA_SPECIFY_ROWS )
+ m_isBeingDeleted = true;
+
+ if (m_hWnd)
+ wxRemoveHandleAssociation(this);
+ if (m_ahRadioButtons)
{
- return (m_noItems + m_majorDim - 1)/m_majorDim;
+ for (unsigned int i = 0; i < m_nNoItems; i++)
+ {
+ wxWindow* pWin = wxFindWinFromHandle((WXHWND)m_ahRadioButtons[i]);
+ wxRemoveHandleAssociation(pWin);
+
+ ::WinDestroyWindow((HWND)m_ahRadioButtons[i]);
}
- else
- {
- return m_majorDim;
+ delete[] m_ahRadioButtons;
}
-}
+ if (m_pnRadioWidth)
+ delete[] m_pnRadioWidth;
+ if (m_pnRadioHeight)
+ delete[] m_pnRadioHeight;
+} // end of wxRadioBox::~wxRadioBox
-bool wxRadioBox::OS2Command(WXUINT cmd, WXWORD id)
+void wxRadioBox::Command ( wxCommandEvent& rEvent )
{
-// TODO:
-/*
- if ( cmd == BN_CLICKED )
- {
- int selectedButton = -1;
+ SetSelection (rEvent.GetInt());
+ ProcessCommand(rEvent);
+} // end of wxRadioBox::Command
- for ( int i = 0; i < m_noItems; i++ )
- {
- if ( id == wxGetWindowId(m_radioButtons[i]) )
- {
- selectedButton = i;
+bool wxRadioBox::ContainsHWND( WXHWND hWnd ) const
+{
+ unsigned int nCount = GetCount();
+ unsigned int i;
- break;
- }
- }
+ 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,
+ const wxArrayString& asChoices,
+ int nMajorDim,
+ long lStyle,
+ const wxValidator& rVal,
+ const wxString& rsName )
+{
+ wxCArrayString chs(asChoices);
- wxASSERT_MSG( selectedButton != -1, wxT("click from alien button?") );
+ return Create(pParent, vId, rsTitle, rPos, rSize, chs.GetCount(),
+ chs.GetStrings(), nMajorDim, lStyle, rVal, rsName);
+}
- if ( selectedButton != m_selectedButton )
+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,
+ const wxValidator& rVal,
+ const wxString& rsName )
+{
+ wxColour vColour(*wxBLACK);
+ LONG lColor;
+ HWND hWndParent = GetHwndOf(pParent);
+
+ m_backgroundColour = pParent->GetBackgroundColour();
+ m_nSelectedButton = -1;
+ m_nNoItems = 0;
+
+ //
+ // Common initialization
+ //
+ if (!CreateControl( pParent
+ ,vId
+ ,rPos
+ ,rSize
+ ,lStyle
+ ,rVal
+ ,rsName
+ ))
+ return false;
+ if (!OS2CreateControl( wxT("STATIC")
+ ,SS_GROUPBOX
+ ,rPos
+ ,rSize
+ ,rsTitle
+ ))
+ return false;
+
+ wxAssociateWinWithHandle(m_hWnd, this);
+
+ //
+ // Now we can set m_nNoItems and let SetMajorDim set m_numCols/m_numRows
+ //
+ m_nNoItems = (unsigned int)nNum;
+ SetMajorDim(nMajorDim == 0 ? nNum : nMajorDim, lStyle);
+
+ m_ahRadioButtons = new WXHWND[nNum];
+ m_pnRadioWidth = new int[nNum];
+ m_pnRadioHeight = new int[nNum];
+
+ for (int i = 0; i < nNum; i++)
+ {
+ m_pnRadioWidth[i] = m_pnRadioHeight[i] = -1;
+ long lStyleBtn = BS_AUTORADIOBUTTON | WS_VISIBLE;
+ int nNewId = NewControlId();
+
+ if (i == 0)
+ lStyleBtn |= WS_GROUP | WS_TABSTOP;
+
+ wxString sLabel = ::wxPMTextToLabel(asChoices[i]);
+
+ HWND hWndBtn = (WXHWND)::WinCreateWindow ( hWndParent,
+ WC_BUTTON,
+ sLabel.c_str(),
+ lStyleBtn,
+ 0, 0, 0, 0,
+ hWndParent,
+ HWND_BOTTOM,
+ (HMENU)nNewId,
+ NULL,
+ NULL
+ );
+ if (!hWndBtn)
{
- m_selectedButton = selectedButton;
-
- SendNotificationEvent();
+ return false;
}
- //else: don't generate events when the selection doesn't change
-
- return TRUE;
+ 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
+ );
+ m_ahRadioButtons[i] = (WXHWND)hWndBtn;
+ SubclassRadioButton((WXHWND)hWndBtn);
+ wxAssociateWinWithHandle(hWndBtn, this);
+ wxOS2SetFont( hWndBtn
+ ,*wxSMALL_FONT
+ );
+ ::WinSetWindowULong(hWndBtn, QWL_USER, (ULONG)this);
+ m_aSubControls.Add(nNewId);
}
- else
- return FALSE;
-*/
- return FALSE;
-}
-#if WXWIN_COMPATIBILITY
-wxRadioBox::wxRadioBox(wxWindow *parent, wxFunction func, const char *title,
- int x, int y, int width, int height,
- int n, char **choices,
- int majorDim, long style, const char *name)
-{
- wxString *choices2 = new wxString[n];
- for ( int i = 0; i < n; i ++) choices2[i] = choices[i];
- Create(parent, -1, title, wxPoint(x, y), wxSize(width, height), n, choices2, majorDim, style,
- wxDefaultValidator, name);
- Callback(func);
- delete choices2;
-}
-
-#endif
-
-// Radio box item
-wxRadioBox::wxRadioBox()
+ //
+ // Create a dummy control to end the group.
+ //
+ (void)::WinCreateWindow ( hWndParent,
+ WC_BUTTON,
+ "",
+ WS_GROUP,
+ 0, 0, 0, 0,
+ hWndParent,
+ HWND_TOP,
+ (HMENU)NewControlId(),
+ NULL,
+ NULL
+ );
+ fnWndProcRadioBox = (WXFARPROC)::WinSubclassWindow( GetHwnd()
+ ,(PFNWP)wxRadioBoxWndProc
+ );
+ ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
+ 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
+ );
+ SetXComp(0);
+ SetYComp(0);
+ SetSelection(0);
+ SetSize( rPos.x
+ ,rPos.y
+ ,rSize.x
+ ,rSize.y
+ );
+ return true;
+} // end of wxRadioBox::Create
+
+wxSize wxRadioBox::DoGetBestSize() const
{
- m_selectedButton = -1;
- m_noItems = 0;
- m_noRowsOrCols = 0;
- m_radioButtons = NULL;
- m_majorDim = 0;
- m_radioWidth = NULL;
- m_radioHeight = NULL;
-}
-
-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,
-#if wxUSE_VALIDATORS
- const wxValidator& val, const wxString& name)
-#endif
+ return (GetTotalButtonSize(GetMaxButtonSize()));
+} // end of wxRadioBox::DoGetBestSize
+
+void wxRadioBox::DoSetSize(
+ int nX
+, int nY
+, int nWidth
+, int nHeight
+, int nSizeFlags
+)
{
- m_selectedButton = -1;
- m_noItems = n;
-
- SetName(name);
-#if wxUSE_VALIDATORS
- SetValidator(val);
-#endif
- parent->AddChild(this);
- m_backgroundColour = parent->GetBackgroundColour();
- m_foregroundColour = parent->GetForegroundColour();
-
- m_windowStyle = (long&)style;
-
- int x = pos.x;
- int y = pos.y;
- int width = size.x;
- int height = size.y;
+ //
+ // Input parameters assume wxWidgets coordinate system
+ //
+ int nCurrentX;
+ int nCurrentY;
+ int nWidthOld;
+ int nHeightOld;
+ int nXx = nX;
+ int nYy = nY;
+ int nXOffset = nXx;
+ int nYOffset = nYy;
+ int nCx1;
+ int nCy1;
+ wxSize vMaxSize = GetMaxButtonSize();
+ int nMaxWidth;
+ int nMaxHeight;
+ wxSize vTotSize;
+ int nTotWidth;
+ int nTotHeight;
+ int nStartX;
+ int nStartY;
+ wxFont vFont = GetFont();
+
+ m_nSizeFlags = nSizeFlags;
+ GetPosition( &nCurrentX
+ ,&nCurrentY
+ );
+ GetSize( &nWidthOld
+ ,&nHeightOld
+ );
+
+ if (nX == wxDefaultCoord && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+ nXx = nCurrentX;
+ if (nY == wxDefaultCoord && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+ nYy = nCurrentY;
+ if (nYy < 0)
+ nYy = 0;
+ if (nXx < 0)
+ nXx = 0;
+
+ wxGetCharSize( m_hWnd
+ ,&nCx1
+ ,&nCy1
+ ,&vFont
+ );
+
+ //
+ // 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 (id == -1)
- m_windowId = NewControlId();
- else
- m_windowId = id;
+ if (nHeight == -1)
+ {
+ if (nSizeFlags & wxSIZE_AUTO_HEIGHT)
+ nHeight = nTotHeight;
+ else
+ nHeight = nHeightOld;
+ }
- if ( majorDim == 0 )
- m_majorDim = n;
+ //
+ // Now convert to OS/2 coordinate system
+ //
+ wxWindowOS2* pParent = (wxWindowOS2*)GetParent();
+ if (pParent)
+ nYy = GetOS2ParentHeight(pParent) - nYy - nHeight;
else
- m_majorDim = majorDim;
- m_noRowsOrCols = majorDim;
-
- long msStyle = 0; // TODO: GROUP_FLAGS;
-
- bool want3D;
- WXDWORD exStyle = Determine3DEffects(0, &want3D);
-
- HWND hwndParent = (HWND)parent->GetHWND();
-/*
- m_hWnd = (WXHWND)::CreateWindowEx
- (
- (DWORD)exStyle,
- GROUP_CLASS,
- title,
- msStyle,
- 0, 0, 0, 0,
- hwndParent,
- (HMENU)m_windowId,
- wxGetInstance(),
- NULL
- );
-
-#if wxUSE_CTL3D
- if (want3D)
{
- Ctl3dSubclassCtl((HWND)m_hWnd);
- m_useCtl3D = TRUE;
+ RECTL vRect;
+ ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
+ nYy = vRect.yTop - nYy - nHeight;
}
-#endif // wxUSE_CTL3D
-*/
- SetFont(parent->GetFont());
-
- SubclassWin(m_hWnd);
-
- // Some radio boxes test consecutive id.
- (void)NewControlId();
- m_radioButtons = new WXHWND[n];
- m_radioWidth = new int[n];
- m_radioHeight = new int[n];
- int i;
- for (i = 0; i < n; i++)
+ nYOffset = 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));
+
+ nStartX = nXOffset;
+ nStartY = nYOffset;
+
+ for (unsigned int i = 0; i < m_nNoItems; i++)
{
-// TODO:
-/*
- m_radioWidth[i] = m_radioHeight[i] = -1;
- long groupStyle = 0;
- if ( i == 0 && style == 0 )
- groupStyle = WS_GROUP;
- long newId = NewControlId();
- long msStyle = groupStyle | RADIO_FLAGS;
-
- HWND hwndBtn = CreateWindowEx(exStyle, RADIO_CLASS,
- choices[i], msStyle,
- 0,0,0,0,
- hwndParent,
- (HMENU)newId, wxGetInstance(),
- NULL);
-
- m_radioButtons[i] = (WXHWND)hwndBtn;
-
- SubclassRadioButton((WXHWND)hwndBtn);
-
- wxFont& font = GetFont();
- if ( font.Ok() )
+ //
+ // 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)
{
- SendMessage(hwndBtn, WM_SETFONT,
- (WPARAM)font.GetResourceHandle(), 0L);
- }
-
- m_subControls.Append((wxObject *)(WXDWORD)(WXWORD)newId);
-*/
- }
-
- // Create a dummy radio control to end the group.
-// (void)CreateWindowEx(0, RADIO_CLASS, wxT(""), WS_GROUP | RADIO_FLAGS,
-// 0, 0, 0, 0, hwndParent,
-// (HMENU)NewControlId(), wxGetInstance(), NULL);
+ //
+ // 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;
- SetSelection(0);
+ bIsLastInTheRow = ((n % GetMajorDim()) == 0) || (n == (int)m_nNoItems);
+ }
+ else // winRA_SPECIFY_ROWS
+ {
+ //
+ // Item is the last in the row if it is in the last columns
+ //
+ bIsLastInTheRow = i >= (m_nNoItems/GetMajorDim()) * GetMajorDim();
+ }
- SetSize(x, y, width, height);
+ //
+ // Is this the start of new row/column?
+ //
+ if (i && (i % GetMajorDim() == 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;
+ }
+ }
- return TRUE;
-}
+ int nWidthBtn;
-wxRadioBox::~wxRadioBox()
-{
- m_isBeingDeleted = TRUE;
+ 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;
+ }
- if (m_radioButtons)
- {
- int i;
-// TODO:
-/*
- for (i = 0; i < m_noItems; i++)
- ::DestroyWindow((HWND)m_radioButtons[i]);
- delete[] m_radioButtons;
-*/
+ //
+ // 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 belonging to any radiobutton)
+ //
+ ::WinSetWindowPos( (HWND)m_ahRadioButtons[i]
+ ,HWND_BOTTOM
+ ,(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
- if (m_radioWidth)
- delete[] m_radioWidth;
- if (m_radioHeight)
- delete[] m_radioHeight;
-
-}
-
-wxString wxRadioBox::GetLabel(int item) const
+bool wxRadioBox::Enable(unsigned int nItem, bool bEnable)
{
- wxCHECK_MSG( item >= 0 && item < m_noItems, wxT(""), wxT("invalid radiobox index") );
+ wxCHECK_MSG( IsValid(nItem), false,
+ wxT("invalid item in wxRadioBox::Enable()") );
- return wxGetWindowText(m_radioButtons[item]);
-}
+ ::WinEnableWindow((HWND) m_ahRadioButtons[nItem], bEnable);
+ return true;
+} // end of wxRadioBox::Enable
-void wxRadioBox::SetLabel(int item, const wxString& label)
+bool wxRadioBox::Enable(bool bEnable)
{
- wxCHECK_RET( item >= 0 && item < m_noItems, wxT("invalid radiobox index") );
-
- m_radioWidth[item] = m_radioHeight[item] = -1;
-// TODO: SetWindowText((HWND)m_radioButtons[item], label.c_str());
-}
-
-void wxRadioBox::SetLabel(int item, wxBitmap *bitmap)
+ if ( !wxControl::Enable(bEnable) )
+ return false;
+ for (unsigned int i = 0; i < m_nNoItems; i++)
+ ::WinEnableWindow((HWND)m_ahRadioButtons[i], bEnable);
+ return true;
+} // end of wxRadioBox::Enable
+
+unsigned int wxRadioBox::GetCount() const
{
- /*
- m_radioWidth[item] = bitmap->GetWidth() + FB_MARGIN;
- m_radioHeight[item] = bitmap->GetHeight() + FB_MARGIN;
- */
- wxFAIL_MSG(wxT("not implemented"));
-}
+ return m_nNoItems;
+} // end of wxRadioBox::GetCount
-int wxRadioBox::FindString(const wxString& s) const
+wxString wxRadioBox::GetLabel(int nItem) const
{
- for (int i = 0; i < m_noItems; i++)
- {
- if ( s == wxGetWindowText(m_radioButtons[i]) )
- return i;
- }
+ wxCHECK_MSG( IsValid(nItem), wxEmptyString, wxT("invalid radiobox index") );
- return wxNOT_FOUND;
-}
+ return wxGetWindowText(m_ahRadioButtons[nItem]);
+} // end of wxRadioBox::GetLabel
-void wxRadioBox::SetSelection(int N)
+wxSize wxRadioBox::GetMaxButtonSize() const
{
- wxCHECK_RET( (N >= 0) && (N < m_noItems), wxT("invalid radiobox index") );
+ int nWidthMax = 0;
+ int nHeightMax = 0;
- // Following necessary for Win32s, because Win32s translate BM_SETCHECK
-// TODO:
-/*
- if (m_selectedButton >= 0 && m_selectedButton < m_noItems)
- ::SendMessage((HWND) m_radioButtons[m_selectedButton], BM_SETCHECK, 0, 0L);
+ for (unsigned int i = 0 ; i < m_nNoItems; i++)
+ {
+ int nWidth;
+ int nHeight;
- ::SendMessage((HWND)m_radioButtons[N], BM_SETCHECK, 1, 0L);
- ::SetFocus((HWND)m_radioButtons[N]);
-*/
- m_selectedButton = N;
-}
+ 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;
+ }
+ wxSize maxsize( nWidthMax, nHeightMax);
+ return maxsize;
+} // end of wxRadioBox::GetMaxButtonSize
// Get single selection, for single choice list items
int wxRadioBox::GetSelection() const
{
- return m_selectedButton;
-}
-
-// Find string for position
-wxString wxRadioBox::GetString(int N) const
-{
- return wxGetWindowText(m_radioButtons[N]);
-}
+ return m_nSelectedButton;
+} // end of wxRadioBox::GetSelection
-// Restored old code.
-void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
+void wxRadioBox::GetSize( int* pnWidth, int* pnHeight ) const
{
- int currentX, currentY;
- GetPosition(¤tX, ¤tY);
- int widthOld, heightOld;
- GetSize(&widthOld, &heightOld);
+ RECT vRect;
- int xx = x;
- int yy = y;
+ vRect.xLeft = -1;
+ vRect.xRight = -1;
+ vRect.yTop = -1;
+ vRect.yBottom = -1;
- if (x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
- xx = currentX;
- if (y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
- yy = currentY;
+ if (m_hWnd)
+ wxFindMaxSize( m_hWnd, &vRect );
- wxString buf;
+ for (unsigned int i = 0; i < m_nNoItems; i++)
+ wxFindMaxSize( m_ahRadioButtons[i], &vRect );
- int y_offset = yy;
- int x_offset = xx;
- int current_width, cyf;
+ if (pnWidth)
+ *pnWidth = vRect.xRight - vRect.xLeft;
+ if (pnHeight)
+ *pnHeight = vRect.yTop - vRect.yBottom;
+} // end of wxRadioBox::GetSize
- int cx1,cy1;
- wxGetCharSize(m_hWnd, &cx1, &cy1, & GetFont());
+// Find string for position
+wxString wxRadioBox::GetString(unsigned int nNum) const
+{
+ wxCHECK_MSG( IsValid(nNum), wxEmptyString, wxT("invalid radiobox index") );
+ return wxGetWindowText(m_ahRadioButtons[nNum]);
+} // end of wxRadioBox::GetString
- // Attempt to have a look coherent with other platforms: We compute the
- // biggest toggle dim, then we align all items according this value.
- int maxWidth = -1;
- int maxHeight = -1;
+// For single selection items only
+wxString wxRadioBox::GetStringSelection() const
+{
+ wxString sResult;
+ int nSel = GetSelection();
- int i;
- for (i = 0 ; i < m_noItems; i++)
- {
- int eachWidth;
- int eachHeight;
- if (m_radioWidth[i]<0)
- {
- // It's a labelled toggle
- buf = wxGetWindowText(m_radioButtons[i]);
- GetTextExtent(buf, ¤t_width, &cyf);
- eachWidth = (int)(current_width + RADIO_SIZE);
- eachHeight = (int)((3*cyf)/2);
- }
- else
- {
- eachWidth = m_radioWidth[i];
- eachHeight = m_radioHeight[i];
- }
+ if (nSel != wxNOT_FOUND)
+ sResult = GetString(nSel);
- if (maxWidth<eachWidth)
- maxWidth = eachWidth;
- if (maxHeight<eachHeight)
- maxHeight = eachHeight;
- }
+ return sResult;
+} // end of wxRadioBox::GetStringSelection
- if (m_hWnd)
+wxSize wxRadioBox::GetTotalButtonSize( const wxSize& rSizeBtn ) const
+{
+ int nCx1;
+ int nCy1;
+ int nHeight;
+ int nWidth;
+ int nWidthLabel = 0;
+
+ nCx1 = GetCharWidth();
+ nCy1 = GetCharHeight();
+ nHeight = GetRowCount() * rSizeBtn.y + (2 * nCy1);
+ nWidth = GetColumnCount() * (rSizeBtn.x + nCx1) + nCx1;
+
+ //
+ // And also wide enough for its label
+ //
+ wxString sStr = wxGetWindowText(GetHwnd());
+ if (!sStr.empty())
{
- int totWidth;
- int totHeight;
-
- int nbHor = GetNumHor(),
- nbVer = GetNumVer();
-
- // this formula works, but I don't know why.
- // Please, be sure what you do if you modify it!!
- if (m_radioWidth[0]<0)
- totHeight = (nbVer * maxHeight) + cy1/2;
- else
- totHeight = nbVer * (maxHeight+cy1/2);
- totWidth = nbHor * (maxWidth+cx1);
+ GetTextExtent( sStr
+ ,&nWidthLabel
+ ,NULL
+ );
+ nWidthLabel += 2*nCx1;
+ }
+ if (nWidthLabel > nWidth)
+ nWidth = nWidthLabel;
+
+ wxSize total( nWidth, nHeight );
+ return total;
+} // end of wxRadioBox::GetTotalButtonSize
+
+WXHBRUSH wxRadioBox::OnCtlColor( WXHDC hwinDC,
+ WXHWND WXUNUSED(hWnd),
+ WXUINT WXUNUSED(uCtlColor),
+ WXUINT WXUNUSED(uMessage),
+ WXWPARAM WXUNUSED(wParam),
+ WXLPARAM WXUNUSED(lParam) )
+{
+ HPS hPS = (HPS)hwinDC; // pass in a PS handle in OS/2
- int extraHeight = cy1;
+ if (GetParent()->GetTransparentBackground())
+ ::GpiSetBackMix(hPS, BM_LEAVEALONE);
+ else
+ ::GpiSetBackMix(hPS, BM_OVERPAINT);
- // only change our width/height if asked for
- if ( width == -1 )
- {
- if ( sizeFlags & wxSIZE_AUTO_WIDTH )
- width = totWidth + cx1;
- else
- width = widthOld;
- }
+ wxColour vColBack = GetBackgroundColour();
- if ( height == -1 )
- {
- if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
- height = totHeight + extraHeight;
- else
- height = heightOld;
- }
+ ::GpiSetBackColor(hPS, vColBack.GetPixel());
+ ::GpiSetColor(hPS, vColBack.GetPixel());
-// TODO: MoveWindow(GetHwnd(), x_offset, y_offset, width, height, TRUE);
+ wxBrush* pBrush = wxTheBrushList->FindOrCreateBrush( vColBack, wxSOLID );
+ return ((WXHBRUSH)pBrush->GetResourceHandle());
+} // end of wxRadioBox::OnCtlColor
- x_offset += cx1;
- y_offset += cy1;
- }
-
- int startX = x_offset;
- int startY = y_offset;
+bool wxRadioBox::OS2Command( WXUINT uCmd,
+ WXWORD wId)
+{
+ int nSelectedButton = -1;
- for ( i = 0 ; i < m_noItems; i++)
+ if (uCmd == BN_CLICKED)
{
- // Bidimensional radio adjustment
- if (i&&((i%m_majorDim)==0)) // Why is this omitted for i = 0?
+ if (wId == GetId())
+ return true;
+
+ for (unsigned int i = 0; i < m_nNoItems; i++)
{
- if (m_windowStyle & wxRA_VERTICAL)
+ if (wId == wxGetWindowId(m_ahRadioButtons[i]))
{
- y_offset = startY;
- x_offset += maxWidth + cx1;
- }
- else
- {
- x_offset = startX;
- y_offset += maxHeight;
- if (m_radioWidth[0]>0)
- y_offset += cy1/2;
+ nSelectedButton = i;
+ break;
}
}
- int eachWidth;
- int eachHeight;
- if (m_radioWidth[i]<0)
+ if (nSelectedButton == -1)
{
- // It's a labeled item
- buf = wxGetWindowText(m_radioButtons[i]);
- GetTextExtent(buf, ¤t_width, &cyf);
-
- // How do we find out radio button bitmap size!!
- // By adjusting them carefully, manually :-)
- eachWidth = (int)(current_width + RADIO_SIZE);
- eachHeight = (int)((3*cyf)/2);
+ //
+ // Just ignore it
+ //
+ return false;
}
- else
- {
- eachWidth = m_radioWidth[i];
- eachHeight = m_radioHeight[i];
- }
-
-// TODO:
-/*
- MoveWindow((HWND)m_radioButtons[i], x_offset, y_offset,
- eachWidth, eachHeight,
- TRUE);
-*/
- if (m_windowStyle & wxRA_SPECIFY_ROWS)
+ if (nSelectedButton != m_nSelectedButton)
{
- y_offset += maxHeight;
- if (m_radioWidth[0]>0)
- y_offset += cy1/2;
+ m_nSelectedButton = nSelectedButton;
+ SendNotificationEvent();
}
- else
- x_offset += maxWidth + cx1;
+ return true;
}
-}
-
-void wxRadioBox::GetSize(int *width, int *height) const
-{
- RECT rect;
- rect.xLeft = -1; rect.xRight = -1; rect.yTop = -1; rect.yBottom = -1;
-
- if (m_hWnd)
- wxFindMaxSize(m_hWnd, &rect);
-
- int i;
- for (i = 0; i < m_noItems; i++)
- wxFindMaxSize(m_radioButtons[i], &rect);
-
- *width = rect.xRight - rect.xLeft;
- *height = rect.yBottom - rect.yTop;
-}
+ else
+ return false;
+} // end of wxRadioBox::OS2Command
-void wxRadioBox::GetPosition(int *x, int *y) const
+void wxRadioBox::SendNotificationEvent()
{
- wxWindow *parent = GetParent();
- RECT rect;
- rect.xLeft = -1; rect.xRight = -1; rect.yTop = -1; rect.yBottom = -1;
-
- int i;
- for (i = 0; i < m_noItems; i++)
- wxFindMaxSize(m_radioButtons[i], &rect);
-
- if (m_hWnd)
- wxFindMaxSize(m_hWnd, &rect);
-
- // Since we now have the absolute screen coords,
- // if there's a parent we must subtract its top left corner
- POINTL point;
- point.x = rect.xLeft;
- point.y = rect.yTop;
-// TODO:
-/*
- if (parent)
- {
- ::ScreenToClient((HWND) parent->GetHWND(), &point);
- }
-*/
- // 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 pt(GetParent()->GetClientAreaOrigin());
- point.x -= pt.x;
- point.y -= pt.y;
- }
+ wxCommandEvent vEvent(
+ wxEVT_COMMAND_RADIOBOX_SELECTED,
+ m_windowId
+ );
- *x = point.x;
- *y = point.y;
-}
+ vEvent.SetInt( m_nSelectedButton );
+ vEvent.SetString( GetString(m_nSelectedButton) );
+ vEvent.SetEventObject(this);
+ ProcessCommand(vEvent);
+} // end of wxRadioBox::SendNotificationEvent
void wxRadioBox::SetFocus()
{
-// TODO:
-/*
- if (m_noItems > 0)
+ if (m_nNoItems > 0)
{
- if (m_selectedButton == -1)
- ::SetFocus((HWND) m_radioButtons[0]);
+ if (m_nSelectedButton == -1)
+ ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[0]);
else
- ::SetFocus((HWND) m_radioButtons[m_selectedButton]);
+ ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[m_nSelectedButton]);
}
-*/
-}
+} // end of wxRadioBox::SetFocus
-bool wxRadioBox::Show(bool show)
+bool wxRadioBox::SetFont(const wxFont& rFont)
{
- if ( !wxControl::Show(show) )
- return FALSE;
-
- int nCmdShow = 0; // TODO: show ? SW_SHOW : SW_HIDE;
- for ( int i = 0; i < m_noItems; i++ )
+ if (!wxControl::SetFont(rFont))
{
-// TODO: ::ShowWindow((HWND)m_radioButtons[i], nCmdShow);
+ //
+ // Nothing to do
+ //
+ return false;
}
+ //
+ // Also set the font of our radio buttons
+ //
+ for (unsigned int n = 0; n < m_nNoItems; n++)
+ {
+ HWND hWndBtn = (HWND)m_ahRadioButtons[n];
- return TRUE;
-}
-
-// Enable a specific button
-void wxRadioBox::Enable(int item, bool enable)
-{
- wxCHECK_RET( item >= 0 && item < m_noItems,
- wxT("invalid item in wxRadioBox::Enable()") );
-
-// TODO: ::EnableWindow((HWND) m_radioButtons[item], enable);
-}
+ wxOS2SetFont( hWndBtn, rFont );
+ ::WinInvalidateRect(hWndBtn, NULL, FALSE);
+ }
+ return true;
+} // end of wxRadioBox::SetFont
-// Enable all controls
-bool wxRadioBox::Enable(bool enable)
+void wxRadioBox::SetSelection(
+ int nNum
+)
{
- if ( !wxControl::Enable(enable) )
- return FALSE;
+ wxCHECK_RET( IsValid(nNum), wxT("invalid radiobox index") );
-// TODO:
-/*
- for (int i = 0; i < m_noItems; i++)
- ::EnableWindow((HWND) m_radioButtons[i], enable);
-*/
- return TRUE;
-}
+ if ( IsValid(m_nSelectedButton) )
+ ::WinSendMsg((HWND)m_ahRadioButtons[m_nSelectedButton], BM_SETCHECK, (MPARAM)0, (MPARAM)0);
-// Show a specific button
-void wxRadioBox::Show(int item, bool show)
-{
- wxCHECK_RET( item >= 0 && item < m_noItems,
- wxT("invalid item in wxRadioBox::Show()") );
-
-// TODO: ::ShowWindow((HWND)m_radioButtons[item], show ? SW_SHOW : SW_HIDE);
-}
+ ::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
-WXHBRUSH wxRadioBox::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
- WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
+void wxRadioBox::SetString(unsigned int nItem, const wxString& rsLabel)
{
-// TODO:
-/*
- if (GetParent()->GetTransparentBackground())
- SetBkMode((HDC) pDC, TRANSPARENT);
- else
- SetBkMode((HDC) pDC, OPAQUE);
-
- ::SetBkColor((HDC) pDC, RGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue()));
- ::SetTextColor((HDC) pDC, RGB(GetForegroundColour().Red(), GetForegroundColour().Green(), GetForegroundColour().Blue()));
-*/
- wxBrush *backgroundBrush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID);
+ wxCHECK_RET( IsValid(nItem), wxT("invalid radiobox index") );
- return (WXHBRUSH) backgroundBrush->GetResourceHandle();
-}
+ m_pnRadioWidth[nItem] = m_pnRadioHeight[nItem] = -1;
+ ::WinSetWindowText((HWND)m_ahRadioButtons[nItem], rsLabel.c_str());
+} // end of wxRadioBox::SetString
-// For single selection items only
-wxString wxRadioBox::GetStringSelection() const
+bool wxRadioBox::SetStringSelection(const wxString& rsStr)
{
- wxString result;
- int sel = GetSelection();
- if (sel > -1)
- result = GetString(sel);
-
- return result;
-}
+ int nSel = FindString(rsStr);
-bool wxRadioBox::SetStringSelection(const wxString& s)
-{
- int sel = FindString (s);
- if (sel > -1)
+ if (nSel > -1)
{
- SetSelection (sel);
- return TRUE;
+ SetSelection(nSel);
+ return true;
}
else
- return FALSE;
-}
+ return false;
+} // end of wxRadioBox::SetStringSelection
-bool wxRadioBox::ContainsHWND(WXHWND hWnd) const
+bool wxRadioBox::Show(bool bShow)
{
- int i;
- for (i = 0; i < Number(); i++)
+ if (!wxControl::Show(bShow))
+ return false;
+
+ for (unsigned int i = 0; i < m_nNoItems; i++)
{
- if (GetRadioButtons()[i] == hWnd)
- return TRUE;
+ ::WinShowWindow((HWND)m_ahRadioButtons[i], (BOOL)bShow);
}
+ return true;
+} // end of wxRadioBox::Show
- return FALSE;
-}
-
-void wxRadioBox::Command (wxCommandEvent & event)
-{
- SetSelection (event.m_commandInt);
- ProcessCommand (event);
-}
-
-void wxRadioBox::SubclassRadioButton(WXHWND hWndBtn)
+// Show a specific button
+bool wxRadioBox::Show(unsigned int nItem, bool bShow)
{
- HWND hwndBtn = (HWND)hWndBtn;
+ wxCHECK_MSG( IsValid(nItem), false,
+ wxT("invalid item in wxRadioBox::Show()") );
-// TODO:
-/*
- if ( !s_wndprocRadioBtn )
- s_wndprocRadioBtn = (WXFARPROC)::GetWindowLong(hwndBtn, GWL_WNDPROC);
+ ::WinShowWindow((HWND)m_ahRadioButtons[nItem], bShow);
- // No GWL_USERDATA in Win16, so omit this subclassing.
- ::SetWindowLong(hwndBtn, GWL_WNDPROC, (long)wxRadioBtnWndProc);
- ::SetWindowLong(hwndBtn, GWL_USERDATA, (long)this);
-*/
-}
+ return true;
+} // end of wxRadioBox::Show
-void wxRadioBox::SendNotificationEvent()
+void wxRadioBox::SubclassRadioButton(
+ WXHWND hWndBtn
+)
{
- wxCommandEvent event(wxEVT_COMMAND_RADIOBOX_SELECTED, m_windowId);
- event.SetInt( m_selectedButton );
- event.SetString( GetString(m_selectedButton) );
- event.SetEventObject( this );
- ProcessCommand(event);
-}
+ 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 msg,
- MPARAM wParam,
- MPARAM lParam)
+MRESULT wxRadioBtnWndProc(
+ HWND hWnd
+, UINT uMessage
+, MPARAM wParam
+, MPARAM lParam
+)
{
- bool processed = TRUE;
-// if ( msg != WM_KEYDOWN )
-// processed = FALSE;
-
- if ( processed )
+ switch (uMessage)
{
- wxRadioBox *radiobox = NULL; // TODO: (wxRadioBox *)::GetWindowLong(hwnd, GWL_USERDATA);
-
- wxCHECK_MSG( radiobox, 0, wxT("radio button without radio box?") );
-
- int sel = radiobox->GetSelection();
-
-// TODO:
-/*
- switch ( wParam )
- {
- case VK_UP:
- sel--;
- break;
-
- case VK_LEFT:
- sel -= radiobox->GetNumVer();
- break;
-
- case VK_DOWN:
- sel++;
- break;
-
- case VK_RIGHT:
- sel += radiobox->GetNumVer();
- break;
+ case WM_CHAR:
+ {
+ USHORT uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
- case VK_TAB:
+ if (!(uKeyFlags & KC_KEYUP)) // Key Down event
{
- wxNavigationKeyEvent event;
- event.SetDirection(!(::GetKeyState(VK_SHIFT) & 0x100));
- event.SetWindowChange(FALSE);
- event.SetEventObject(radiobox);
-
- if ( radiobox->GetEventHandler()->ProcessEvent(event) )
- return 0;
+ 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 = wxLEFT;
+ break;
+
+ case VK_RIGHT:
+ eDir = wxRIGHT;
+ 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;
+ }
+ }
+ }
}
- // fall through
-
- default:
- processed = FALSE;
- }
-*/
- if ( processed )
- {
- if ( sel >= 0 && sel < radiobox->Number() )
- {
- radiobox->SetSelection(sel);
-
- // emulate the button click
- radiobox->SendNotificationEvent();
}
- }
+ break;
}
-// TODO:
-/*
- if ( !processed )
- return ::CallWindowProc(CASTWNDPROC s_wndprocRadioBtn, hwnd, msg, wParam, lParam);
- else
- return 0;
-*/
- return 0;
-}
-
+ return fnWndProcRadioBtn( hWnd
+ ,(ULONG)uMessage
+ ,(MPARAM)wParam
+ ,(MPARAM)lParam
+ );
+} // end of wxRadioBtnWndProc
+
+MRESULT EXPENTRY wxRadioBoxWndProc( HWND hWnd,
+ UINT uMessage,
+ MPARAM wParam,
+ MPARAM lParam )
+{
+ return (fnWndProcRadioBox( hWnd,
+ (ULONG)uMessage,
+ (MPARAM)wParam,
+ (MPARAM)lParam )
+ );
+} // end of wxRadioBoxWndProc
+
+#endif // wxUSE_RADIOBOX