X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/cdf1e7142564c55f5299f1f2d0909090534eb97c..f90566f5c386e6e5d80deecad9052ec53a0394ba:/src/os2/radiobox.cpp diff --git a/src/os2/radiobox.cpp b/src/os2/radiobox.cpp index 9e48ac41d8..4e97989340 100644 --- a/src/os2/radiobox.cpp +++ b/src/os2/radiobox.cpp @@ -15,6 +15,8 @@ #ifndef WX_PRECOMP #include #include "wx/setup.h" + #include "wx/wxchar.h" + #include "wx/string.h" #include "wx/bitmap.h" #include "wx/brush.h" #include "wx/radiobox.h" @@ -22,26 +24,25 @@ #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 + ); // --------------------------------------------------------------------------- // global vars // --------------------------------------------------------------------------- // the pointer to standard radio button wnd proc -static s_wndprocRadioBtn = NULL; +static WXFARPROC fnWndProcRadioBtn = NULL; // =========================================================================== // implementation @@ -51,723 +52,1158 @@ 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_nNoRowsOrCols = 0; + m_ahRadioButtons = NULL; + m_nMajorDim = 0; + m_pnRadioWidth = NULL; + m_pnRadioHeight = NULL; +} // end of wxRadioBox::wxRadioBox -int wxRadioBox::GetNumHor() const +wxRadioBox::~wxRadioBox() { - if ( m_windowStyle & wxRA_SPECIFY_ROWS ) - { - return (m_noItems + m_majorDim - 1)/m_majorDim; - } - else + m_isBeingDeleted = TRUE; + + if (m_ahRadioButtons) { - return m_majorDim; + int i; + for (i = 0; i < m_nNoItems; i++) + ::WinDestroyWindow((HWND)m_ahRadioButtons[i]); + delete[] m_ahRadioButtons; } -} - -bool wxRadioBox::OS2Command(WXUINT cmd, WXWORD id) + if (m_pnRadioWidth) + delete[] m_pnRadioWidth; + if (m_pnRadioHeight) + delete[] m_pnRadioHeight; +} // end of wxRadioBox::~wxRadioBox + +void wxRadioBox::AdjustButtons( + int nX +, int nY +, int nWidth +, int nHeight +, int nSizeFlags +) { -// TODO: -/* - if ( cmd == BN_CLICKED ) + 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; + + wxGetCharSize( m_hWnd + ,&nCx1 + ,&nCy1 + ,&GetFont() + ); + vMaxSize = GetMaxButtonSize(); + nMaxWidth = vMaxSize.x; + nMaxHeight = vMaxSize.y; + + nXOffset += nCx1; + nYOffset -= (nMaxHeight + ((3*nCy1)/2)); + + nStartX = nXOffset; + nStartY = nYOffset; + + for (int i = 0; i < m_nNoItems; i++) { - int selectedButton = -1; + // + // 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; - for ( int i = 0; i < m_noItems; i++ ) + bIsLastInTheRow = ((n % m_nMajorDim) == 0) || (n == m_nNoItems); + } + else // winRA_SPECIFY_ROWS { - if ( id == wxGetWindowId(m_radioButtons[i]) ) + // + // 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) { - selectedButton = i; - break; + // + // 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; } } - wxASSERT_MSG( selectedButton != -1, wxT("click from alien button?") ); + int nWidthBtn; - if ( selectedButton != m_selectedButton ) + if (bIsLastInTheRow) { - m_selectedButton = selectedButton; - - SendNotificationEvent(); + // + // 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; } - //else: don't generate events when the selection doesn't change - return TRUE; + // + // 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; + } } - 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; -} +} // end of wxRadioBox::AdjustButtons -#endif +void wxRadioBox::Command ( + wxCommandEvent& rEvent +) +{ + SetSelection (rEvent.GetInt()); + ProcessCommand(rEvent); +} // end of wxRadioBox::Command -// Radio box item -wxRadioBox::wxRadioBox() +bool wxRadioBox::ContainsHWND( + WXHWND hWnd +) const { - m_selectedButton = -1; - m_noItems = 0; - m_noRowsOrCols = 0; - m_radioButtons = NULL; - m_majorDim = 0; - m_radioWidth = NULL; - m_radioHeight = NULL; -} + size_t nCount = GetCount(); + size_t i; -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) + 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 +) { - m_selectedButton = -1; - m_noItems = n; + // + // System fonts are too big in OS/2 and they are blue + // We want smaller fonts and black by default. + // + wxFont* pTextFont = new wxFont( 10 + ,wxMODERN + ,wxNORMAL + ,wxNORMAL + ); + wxColour vColour; + LONG lColor; + + 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 (!CreateControl( pParent + ,vId + ,rPos + ,rSize + ,lStyle +#if wxUSE_VALIDATORS + ,rVal +#endif + ,rsName + )) - 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; + 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; - if (id == -1) - m_windowId = NewControlId(); - else - m_windowId = id; + // + // Some radio boxes test consecutive id. + // + (void)NewControlId(); + m_ahRadioButtons = new WXHWND[nNum]; + m_pnRadioWidth = new int[nNum]; + m_pnRadioHeight = new int[nNum]; - if ( majorDim == 0 ) - m_majorDim = n; - 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) + if (pTextFont->Ok()) { - Ctl3dSubclassCtl((HWND)m_hWnd); - m_useCtl3D = TRUE; + hFont = pTextFont->GetResourceHandle(); } -#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++) + for (int i = 0; i < nNum; 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() ) + 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) { - SendMessage(hwndBtn, WM_SETFONT, - (WPARAM)font.GetResourceHandle(), 0L); + return FALSE; } - - m_subControls.Append((wxObject *)(WXDWORD)(WXWORD)newId); -*/ + m_ahRadioButtons[i] = (WXHWND)hWndBtn; + SubclassRadioButton((WXHWND)hWndBtn); + wxOS2SetFont( hWndBtn + ,*pTextFont + ); + ::WinSetWindowULong(hWndBtn, QWL_USER, (ULONG)this); + m_aSubControls.Add(nNewId); } + // // 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); - + // + (void)::WinCreateWindow ( GetHwndOf(pParent) + ,WC_BUTTON + ,"" + ,WS_GROUP | BS_AUTORADIOBUTTON + ,0, 0, 0, 0 + ,GetWinHwnd(pParent) + ,HWND_TOP + ,(HMENU)NewControlId() + ,NULL + ,NULL + ); + SetFont(*pTextFont); + 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(x, y, width, height); - + SetSize( rPos.x + ,rPos.y + ,rSize.x + ,rSize.y + ); + delete pTextFont; return TRUE; -} +} // end of wxRadioBox::Create -wxRadioBox::~wxRadioBox() +wxSize wxRadioBox::DoGetBestSize() const { - m_isBeingDeleted = TRUE; + return (GetTotalButtonSize(GetMaxButtonSize())); +} // end of WinGuiBase_CRadioBox::DoGetBestSize + +void wxRadioBox::DoSetSize( + int nX +, int nY +, int nWidth +, int nHeight +, int nSizeFlags +) +{ + 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 (m_radioButtons) + if (nHeight == -1) { - int i; -// TODO: -/* - for (i = 0; i < m_noItems; i++) - ::DestroyWindow((HWND)m_radioButtons[i]); - delete[] m_radioButtons; -*/ + if (nSizeFlags & wxSIZE_AUTO_HEIGHT) + nHeight = nTotHeight; + else + nHeight = nHeightOld; } - if (m_radioWidth) - delete[] m_radioWidth; - if (m_radioHeight) - delete[] m_radioHeight; + wxWindowOS2* pParent = (wxWindowOS2*)GetParent(); -} + if (pParent) + { + int nOS2Height = GetOS2ParentHeight(pParent); -wxString wxRadioBox::GetLabel(int item) const -{ - wxCHECK_MSG( item >= 0 && item < m_noItems, wxT(""), wxT("invalid radiobox index") ); + 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)); + + 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; + } - return wxGetWindowText(m_radioButtons[item]); -} + // + // 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::SetLabel(int item, const wxString& label) +void wxRadioBox::Enable( + int nItem +, bool bEnable +) { - wxCHECK_RET( item >= 0 && item < m_noItems, wxT("invalid radiobox index") ); + wxCHECK_RET( nItem >= 0 && nItem < m_nNoItems, + wxT("invalid item in wxRadioBox::Enable()") ); - m_radioWidth[item] = m_radioHeight[item] = -1; -// TODO: SetWindowText((HWND)m_radioButtons[item], label.c_str()); -} + ::WinEnableWindow((HWND) m_ahRadioButtons[nItem], bEnable); +} // end of wxRadioBox::Enable -void wxRadioBox::SetLabel(int item, wxBitmap *bitmap) +bool wxRadioBox::Enable( + bool bEnable +) { - /* - m_radioWidth[item] = bitmap->GetWidth() + FB_MARGIN; - m_radioHeight[item] = bitmap->GetHeight() + FB_MARGIN; - */ - wxFAIL_MSG(wxT("not implemented")); -} + 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 -int wxRadioBox::FindString(const wxString& s) const +int wxRadioBox::FindString( + const wxString& rsStr +) const { - for (int i = 0; i < m_noItems; i++) + for (int i = 0; i < m_nNoItems; i++) { - if ( s == wxGetWindowText(m_radioButtons[i]) ) + if (rsStr == wxGetWindowText(m_ahRadioButtons[i]) ) return i; } - return wxNOT_FOUND; -} - -void wxRadioBox::SetSelection(int N) -{ - wxCHECK_RET( (N >= 0) && (N < m_noItems), wxT("invalid radiobox index") ); - - // 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); - - ::SendMessage((HWND)m_radioButtons[N], BM_SETCHECK, 1, 0L); - ::SetFocus((HWND)m_radioButtons[N]); -*/ - m_selectedButton = N; -} +} // end of wxRadioBox::FindString -// Get single selection, for single choice list items -int wxRadioBox::GetSelection() const +int wxRadioBox::GetColumnCount() const { - return m_selectedButton; -} + return GetNumHor(); +} // end of wxRadioBox::GetColumnCount -// Find string for position -wxString wxRadioBox::GetString(int N) const +int wxRadioBox::GetCount() const { - return wxGetWindowText(m_radioButtons[N]); -} + return m_nNoItems; +} // end of wxRadioBox::GetCount -// Restored old code. -void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags) +wxString wxRadioBox::GetLabel( + int nItem +) const { - int currentX, currentY; - GetPosition(¤tX, ¤tY); - int widthOld, heightOld; - GetSize(&widthOld, &heightOld); - - int xx = x; - int yy = y; - - if (x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) - xx = currentX; - if (y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) - yy = currentY; + wxCHECK_MSG(nItem >= 0 && nItem < m_nNoItems, wxT(""), wxT("invalid radiobox index") ); - wxString buf; + return wxGetWindowText(m_ahRadioButtons[nItem]); +} // end of wxRadioBox::GetLabel - int y_offset = yy; - int x_offset = xx; - int current_width, cyf; - - int cx1,cy1; - wxGetCharSize(m_hWnd, &cx1, &cy1, & GetFont()); - - // 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; +wxSize wxRadioBox::GetMaxButtonSize() const +{ + int nWidthMax = 0; + int nHeightMax = 0; - int i; - for (i = 0 ; i < m_noItems; i++) + for (int i = 0 ; i < m_nNoItems; i++) { - int eachWidth; - int eachHeight; - if (m_radioWidth[i]<0) + int nWidth; + int nHeight; + + if (m_pnRadioWidth[i] < 0L) { - // 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); + 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 { - eachWidth = m_radioWidth[i]; - eachHeight = m_radioHeight[i]; + 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 - if (maxWidthGetHWND(), &vSwp); + vPoint.x = vSwp.x; + vPoint.y = vSwp.y; + } - int nbHor = GetNumHor(), - nbVer = GetNumVer(); + // + // 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()); - // 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); + vPoint.x = vPt.x; + vPoint.y = vPt.y; + } + *pnX = vPoint.x; + *pnX = vPoint.y; +} // end of wxRadioBox::GetPosition - int extraHeight = cy1; +int wxRadioBox::GetRowCount() const +{ + return GetNumVer(); +} // end of wxRadioBox::GetRowCount - // only change our width/height if asked for - if ( width == -1 ) - { - if ( sizeFlags & wxSIZE_AUTO_WIDTH ) - width = totWidth + cx1; - else - width = widthOld; - } +// Get single selection, for single choice list items +int wxRadioBox::GetSelection() const +{ + return m_nSelectedButton; +} // end of wxRadioBox::GetSelection - if ( height == -1 ) - { - if ( sizeFlags & wxSIZE_AUTO_HEIGHT ) - height = totHeight + extraHeight; - else - height = heightOld; - } +void wxRadioBox::GetSize( + int* pnWidth +, int* pnHeight +) const +{ + RECT vRect; + int i; - MoveWindow(GetHwnd(), x_offset, y_offset, width, height, TRUE); + vRect.xLeft = -1; + vRect.xRight = -1; + vRect.yTop = -1; + vRect.yBottom = -1; - x_offset += cx1; - y_offset += cy1; - } + 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 nNum +) const +{ + return wxGetWindowText(m_ahRadioButtons[nNum]); +} // end of wxRadioBox::GetString - int startX = x_offset; - int startY = y_offset; +// For single selection items only +wxString wxRadioBox::GetStringSelection() const +{ + wxString sResult; + int nSel = GetSelection(); - for ( i = 0 ; i < m_noItems; i++) + if (nSel > -1) + sResult = GetString(nSel); + return sResult; +} // end of wxRadioBox::GetStringSelection + +wxSize wxRadioBox::GetTotalButtonSize( + const wxSize& rSizeBtn +) const +{ + int nCx1; + int nCy1; + int nExtraHeight; + int nHeight; + int nWidth; + int nWidthLabel; + + wxGetCharSize( m_hWnd + ,&nCx1 + ,&nCy1 + ,(wxFont*)&GetFont() + ); + nExtraHeight = nCy1; + + 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 +) +{ + 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(); + + ::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 +) +{ + int nSelectedButton = -1; + + 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 (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 - 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; } - else + if (nSelectedButton != m_nSelectedButton) { - 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) - { - 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; + wxCommandEvent vEvent( wxEVT_COMMAND_RADIOBOX_SELECTED + ,m_windowId + ); - 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; - } - - *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) ) + if (!wxControl::SetFont(rFont)) + { + // + // Nothing to do + // return FALSE; + } + // + // Also set the font of our radio buttons + // + WXHFONT hFont = wxFont(rFont).GetResourceHandle(); - int nCmdShow = show ? SW_SHOW : SW_HIDE; - for ( int i = 0; i < m_noItems; i++ ) + for (int n = 0; n < (int)m_nNoItems; n++) { -// TODO: ::ShowWindow((HWND)m_radioButtons[i], nCmdShow); - } + HWND hWndBtn = (HWND)m_ahRadioButtons[n]; + wxOS2SetFont( hWndBtn + ,rFont + ); + ::WinInvalidateRect(hWndBtn, NULL, FALSE); + } return TRUE; -} +} // end of wxRadioBox::SetFont -// Enable a specific button -void wxRadioBox::Enable(int item, bool enable) +void wxRadioBox::SetSelection( + int nNum +) { - wxCHECK_RET( item >= 0 && item < m_noItems, - wxT("invalid item in wxRadioBox::Enable()") ); + wxCHECK_RET( (nNum >= 0) && (nNum < m_nNoItems), wxT("invalid radiobox index") ); -// TODO: ::EnableWindow((HWND) m_radioButtons[item], enable); -} + if (m_nSelectedButton >= 0 && m_nSelectedButton < m_nNoItems) + ::WinSendMsg((HWND)m_ahRadioButtons[m_nSelectedButton], BM_SETCHECK, (MPARAM)0, (MPARAM)0); -// Enable all controls -bool wxRadioBox::Enable(bool enable) -{ - if ( !wxControl::Enable(enable) ) - return FALSE; - -// TODO: -/* - for (int i = 0; i < m_noItems; i++) - ::EnableWindow((HWND) m_radioButtons[i], enable); -*/ - return TRUE; -} + ::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 -// Show a specific button -void wxRadioBox::Show(int item, bool show) +void wxRadioBox::SetString( + int nItem +, const wxString& rsLabel +) { - wxCHECK_RET( item >= 0 && item < m_noItems, - wxT("invalid item in wxRadioBox::Show()") ); + wxCHECK_RET( nItem >= 0 && nItem < m_nNoItems, wxT("invalid radiobox index") ); -// TODO: ::ShowWindow((HWND)m_radioButtons[item], show ? SW_SHOW : SW_HIDE); -} + m_pnRadioWidth[nItem] = m_pnRadioHeight[nItem] = -1; + ::WinSetWindowText((HWND)m_ahRadioButtons[nItem], rsLabel.c_str()); +} // end of wxRadioBox::SetString -WXHBRUSH wxRadioBox::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor, - WXUINT message, WXWPARAM wParam, WXLPARAM lParam) +bool wxRadioBox::SetStringSelection( + const wxString& rsStr +) { -// TODO: -/* - if (GetParent()->GetTransparentBackground()) - SetBkMode((HDC) pDC, TRANSPARENT); - else - SetBkMode((HDC) pDC, OPAQUE); + int nSel = FindString(rsStr); - ::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); - - return (WXHBRUSH) backgroundBrush->GetResourceHandle(); -} - -// For single selection items only -wxString wxRadioBox::GetStringSelection() const -{ - wxString result; - int sel = GetSelection(); - if (sel > -1) - result = GetString(sel); - - return result; -} - -bool wxRadioBox::SetStringSelection(const wxString& s) -{ - int sel = FindString (s); - if (sel > -1) + if (nSel > -1) { - SetSelection (sel); + SetSelection(nSel); return TRUE; } else 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++) + int nCmdShow = 0; + + if (!wxControl::Show(bShow)) + return FALSE; + + for (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) +// Show a specific button +void wxRadioBox::Show( + int nItem +, bool bShow +) { - SetSelection (event.m_commandInt); - ProcessCommand (event); -} + wxCHECK_RET( nItem >= 0 && nItem < m_nNoItems, + wxT("invalid item in wxRadioBox::Show()") ); -void wxRadioBox::SubclassRadioButton(WXHWND hWndBtn) -{ - HWND hwndBtn = (HWND)hWndBtn; + ::WinShowWindow((HWND)m_ahRadioButtons[nItem], bShow); +} // end of wxRadioBox::Show -// TODO: -/* - if ( !s_wndprocRadioBtn ) - s_wndprocRadioBtn = (WXFARPROC)::GetWindowLong(hwndBtn, GWL_WNDPROC); +void wxRadioBox::SubclassRadioButton( + WXHWND hWndBtn +) +{ + HWND hwndBtn = (HWND)hWndBtn; - // No GWL_USERDATA in Win16, so omit this subclassing. - ::SetWindowLong(hwndBtn, GWL_WNDPROC, (long)wxRadioBtnWndProc); - ::SetWindowLong(hwndBtn, GWL_USERDATA, (long)this); -*/ -} + fnWndProcRadioBtn = (WXFARPROC)::WinSubclassWindow(hWndBtn, (PFNWP)wxRadioBtnWndProc); +} // end of wxRadioBox::SubclassRadioButton -void wxRadioBox::SendNotificationEvent() +MRESULT wxRadioBox::WindowProc( + WXUINT uMsg +, WXWPARAM wParam +, WXLPARAM lParam +) { - wxCommandEvent event(wxEVT_COMMAND_RADIOBOX_SELECTED, m_windowId); - event.SetInt( m_selectedButton ); - event.SetString( GetString(m_selectedButton) ); - event.SetEventObject( this ); - ProcessCommand(event); -} + 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 = 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; + } + } + } } - // 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