From 13d6e033a3fd5c2a9334031b0e371916908e02b8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 5 Aug 2000 12:00:50 +0000 Subject: [PATCH] fixed 2d radiobox layout and kbd handling git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_2_BRANCH@7938 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/msw/radiobox.cpp | 160 ++++++++++++++++++++++++++++++++----------- 1 file changed, 121 insertions(+), 39 deletions(-) diff --git a/src/msw/radiobox.cpp b/src/msw/radiobox.cpp index 0d73aabe6a..529c46dbd3 100644 --- a/src/msw/radiobox.cpp +++ b/src/msw/radiobox.cpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: radiobox.cpp -// Purpose: wxRadioBox +// Name: msw/radiobox.cpp +// Purpose: wxRadioBox implementation // Author: Julian Smart // Modified by: // Created: 04/01/98 @@ -98,6 +98,7 @@ static WXFARPROC s_wndprocRadioBtn = (WXFARPROC)NULL; // wxRadioBox // --------------------------------------------------------------------------- +// returns the number of rows int wxRadioBox::GetNumVer() const { if ( m_windowStyle & wxRA_SPECIFY_ROWS ) @@ -110,6 +111,7 @@ int wxRadioBox::GetNumVer() const } } +// returns the number of columns int wxRadioBox::GetNumHor() const { if ( m_windowStyle & wxRA_SPECIFY_ROWS ) @@ -141,7 +143,14 @@ bool wxRadioBox::MSWCommand(WXUINT cmd, WXWORD id) } } - wxASSERT_MSG( selectedButton != -1, wxT("click from alien button?") ); + if ( selectedButton == -1 ) + { + // just ignore it - due to a hack with WM_NCHITTEST handling in our + // wnd proc, we can receive dummy click messages when we click near + // the radiobox edge (this is ugly but Julian wouldn't let me get + // rid of this...) + return FALSE; + } if ( selectedButton != m_selectedButton ) { @@ -459,9 +468,7 @@ void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags) int x_offset = xx; #endif - int current_width, cyf; - - int cx1,cy1; + int cx1, cy1; wxGetCharSize(m_hWnd, &cx1, &cy1, & GetFont()); // Attempt to have a look coherent with other platforms: We compute the @@ -493,6 +500,17 @@ void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags) ::MoveWindow(GetHwnd(), xx, yy, width, height, TRUE); + // 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. + x_offset += cx1; y_offset += cy1; @@ -500,30 +518,39 @@ void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags) y_offset += (int)(cy1/2); // Fudge factor since buttons overlapped label // JACS 2/12/93. CTL3D draws group label quite high. #endif + int startX = x_offset; int startY = y_offset; - for ( int i = 0 ; i < m_noItems; i++) + for ( int i = 0; i < m_noItems; 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 label is too long) - int extraWidth = 0; - if ( (i + 1) % m_majorDim == 0 ) + // happens, for example, when the radiobox label is very long) + bool isLastInTheRow; + if ( m_windowStyle & wxRA_SPECIFY_COLS ) { - // make the button go to the end of radio box - extraWidth = xx + width - x_offset; + // 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; + isLastInTheRow = ((n % m_majorDim) == 0) || (n == m_noItems); + } + else // wxRA_SPECIFY_ROWS + { + // item is the last in the row if it is in the last columns + isLastInTheRow = i >= (m_noItems/m_majorDim)*m_majorDim; } - // Bidimensional radio adjustment - if (i&&((i%m_majorDim)==0)) // Why is this omitted for i = 0? + // is this the start of new row/column? + if ( i && (i % m_majorDim == 0) ) { - if (m_windowStyle & wxRA_VERTICAL) + if ( m_windowStyle & wxRA_SPECIFY_ROWS ) { + // start of new column y_offset = startY; x_offset += maxWidth + cx1; } - else + else // start of new row { x_offset = startX; y_offset += maxHeight; @@ -531,23 +558,19 @@ void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags) y_offset += cy1/2; } } - int eachWidth; - int eachHeight; - if (m_radioWidth[i]<0) - { - // It's a labeled item - GetTextExtent(wxGetWindowText(m_radioButtons[i]), - ¤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); + int widthBtn; + if ( isLastInTheRow ) + { + // make the button go to the end of radio box + widthBtn = startX + width - x_offset - 2*cx1; + if ( widthBtn < maxWidth ) + widthBtn = maxWidth; } else { - eachWidth = m_radioWidth[i]; - eachHeight = m_radioHeight[i]; + // normal button, always of the same size + widthBtn = maxWidth; } // VZ: make all buttons of the same, maximal size - like this they @@ -555,17 +578,22 @@ void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags) // shown (otherwise they are not when the mouse pointer is in the // radiobox part not belonging to any radiobutton) ::MoveWindow((HWND)m_radioButtons[i], - x_offset, y_offset, maxWidth + extraWidth, maxHeight, + x_offset, y_offset, widthBtn, maxHeight, TRUE); - if (m_windowStyle & wxRA_SPECIFY_ROWS) + // where do we put the next button? + if ( m_windowStyle & wxRA_SPECIFY_ROWS ) { + // below this one y_offset += maxHeight; if (m_radioWidth[0]>0) y_offset += cy1/2; } else - x_offset += maxWidth + cx1; + { + // to the right of this one + x_offset += widthBtn + cx1; + } } } @@ -900,25 +928,60 @@ LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hwnd, bool processed = TRUE; + bool horz = (radiobox->GetWindowStyle() & wxRA_SPECIFY_COLS) != 0; + int num = radiobox->Number(), + rows = radiobox->GetNumVer(), + cols = radiobox->GetNumHor(); + int selOld = radiobox->GetSelection(); int selNew = selOld; + // wrapping will be handled below for the cases when we + // add/substract more than 1 but here otherwise as it's simpler switch ( wParam ) { case VK_UP: - selNew--; + if ( horz ) + selNew -= cols; + else + { + if ( selNew ) + selNew--; + else + selNew = num - 1; + } break; case VK_LEFT: - selNew -= radiobox->GetNumVer(); + if ( horz ) + { + if ( selNew ) + selNew--; + else + selNew = num - 1; + } + else + selNew -= rows; break; case VK_DOWN: - selNew++; + if ( horz ) + selNew += cols; + else + { + if ( ++selNew == num ) + selNew = 0; + } break; case VK_RIGHT: - selNew += radiobox->GetNumVer(); + if ( horz ) + { + if ( ++selNew == num ) + selNew = 0; + } + else + selNew += rows; break; default: @@ -928,9 +991,28 @@ LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hwnd, if ( processed ) { // ensure that selNew is in range [0..num) - int num = radiobox->Number(); - selNew += num; - selNew %= num; + if ( selNew >= num ) + { + selNew -= num; + + int dim = horz ? cols : rows; + selNew += dim - 1; + selNew %= dim; + } + else if ( selNew < 0 ) + { + selNew += num; + + int dim = horz ? cols : rows; + if ( selNew % dim == 0 ) + { + selNew -= dim - 1; + } + else + { + selNew++; + } + } if ( selNew != selOld ) {