X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/cdf1e7142564c55f5299f1f2d0909090534eb97c..04fa04d8067d235ab45b5bc05b65f0679634b541:/src/os2/radiobox.cpp diff --git a/src/os2/radiobox.cpp b/src/os2/radiobox.cpp index 9e48ac41d8..19ff8a2bac 100644 --- a/src/os2/radiobox.cpp +++ b/src/os2/radiobox.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: radiobox.cpp +// Name: src/os2/radiobox.cpp // Purpose: wxRadioBox // Author: David Webster // Modified by: @@ -12,36 +12,49 @@ // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" +#if wxUSE_RADIOBOX + +#include "wx/radiobox.h" + #ifndef WX_PRECOMP #include - #include "wx/setup.h" + #include "wx/crt.h" + #include "wx/string.h" #include "wx/bitmap.h" #include "wx/brush.h" - #include "wx/radiobox.h" #endif #include "wx/os2/private.h" -#if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl) -#endif // --------------------------------------------------------------------------- // private functions // --------------------------------------------------------------------------- // wnd proc for radio buttons -MRESULT _EXPORT 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 @@ -51,723 +64,878 @@ static s_wndprocRadioBtn = NULL; // 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 ) + SendDestroyEvent(); + + 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, - const wxValidator& val, const wxString& name) + 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); - SetValidator(val); - - 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 = 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 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()); - 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.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1; - - if (m_hWnd) - wxFindMaxSize(m_hWnd, &rect); - - int i; - for (i = 0; i < m_noItems; i++) - wxFindMaxSize(m_radioButtons[i], &rect); - - *width = rect.right - rect.left; - *height = rect.bottom - rect.top; -} + else + return false; +} // end of wxRadioBox::OS2Command -void wxRadioBox::GetPosition(int *x, int *y) const +void wxRadioBox::SendNotificationEvent() { - wxWindow *parent = GetParent(); - RECT rect; - rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -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 - POINT point; - point.x = rect.left; - point.y = rect.top; -// 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 = 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 APIENTRY _EXPORT 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 = (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