wxSize wxToggleButton::DoGetBestSize() const { wxString label = wxGetWindowText(GetHWND()); int wBtn; wxFont vFont = GetFont(); int wChar; int hChar; GetTextExtent(label, &wBtn, NULL); wxGetCharSize(GetHWND(), &wChar, &hChar, &vFont); // add a margin - the button is wider than just its label wBtn += 3*wChar; // the button height is proportional to the height of the font used int hBtn = BUTTON_HEIGHT_FROM_CHAR_HEIGHT(hChar); #if wxUSE_BUTTON wxSize sz = wxButton::GetDefaultSize(); if (wBtn > sz.x) sz.x = wBtn; if (hBtn > sz.y) sz.y = hBtn; #else wxSize sz(wBtn, hBtn); #endif return sz; }
wxSize wxStaticBox::DoGetBestSize() const { wxSize best; // Calculate the size needed by the label int cx, cy; wxGetCharSize(GetHWND(), &cx, &cy, GetFont()); int wBox; GetTextExtent(GetLabelText(wxGetWindowText(m_hWnd)), &wBox, &cy); wBox += 3*cx; int hBox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy); // If there is a sizer then the base best size is the sizer's minimum if (GetSizer() != NULL) { wxSize cm(GetSizer()->CalcMin()); best = ClientToWindowSize(cm); // adjust for a long label if needed best.x = wxMax(best.x, wBox); } // otherwise the best size falls back to the label size else { best = wxSize(wBox, hBox); } return best; }
int wxChoice::SetHeightSimpleComboBox(int nItems) const { int cx, cy; wxGetCharSize( GetHWND(), &cx, &cy, GetFont() ); int hItem = SendMessage(GetHwnd(), CB_GETITEMHEIGHT, (WPARAM)-1, 0); return EDIT_HEIGHT_FROM_CHAR_HEIGHT( cy ) * wxMin( wxMax( nItems, 3 ), 6 ) + hItem - 1; }
wxSize wxToggleButton::DoGetBestSize() const { wxString label = wxGetWindowText(GetHWND()); int wBtn; GetTextExtent(GetLabelText(label), &wBtn, NULL); int wChar, hChar; wxGetCharSize(GetHWND(), &wChar, &hChar, GetFont()); // add a margin - the button is wider than just its label wBtn += 3*wChar; // the button height is proportional to the height of the font used int hBtn = BUTTON_HEIGHT_FROM_CHAR_HEIGHT(hChar); #if wxUSE_BUTTON // make all buttons of at least standard size unless wxBU_EXACTFIT is given if ( !HasFlag(wxBU_EXACTFIT) ) { const wxSize szMin = wxButton::GetDefaultSize(); if ( wBtn < szMin.x ) wBtn = szMin.x; if ( hBtn < szMin.y ) hBtn = szMin.y; } #endif // wxUSE_BUTTON wxSize sz(wBtn, hBtn); CacheBestSize(sz); return sz; }
wxSize CFontNamesComboBox::DoGetBestSize() const { int hBitmap = 0; int wChoice = 0; int hChoice; const unsigned int nItems = GetCount(); for( unsigned int i = 0; i < nItems; i++ ) { int wLine; GetTextExtent( GetString( i ), &wLine, NULL ); if( wLine > wChoice ) wChoice = wLine; } if( wChoice == 0 ) wChoice = 100; wChoice += 5 * GetCharWidth(); if( m_bmp1 ) { wChoice += m_bmp1->GetWidth(); hBitmap = m_bmp1->GetHeight(); } int cx, cy; wxGetCharSize( GetHWND(), &cx, &cy, GetFont() ); if( hBitmap > cy ) cy = hBitmap; int hItem = SendMessage( GetHwnd(), CB_GETITEMHEIGHT, (WPARAM) -1, 0 ); if( hItem > cy ) hItem = cy; SendMessage( GetHwnd(), CB_SETITEMHEIGHT, (WPARAM) -1, hItem ); hChoice = ( EDIT_HEIGHT_FROM_CHAR_HEIGHT( cy ) * 6 ) + hItem - 6; wxSize best( wChoice, hChoice ); CacheBestSize( best ); return best; }
wxSize wxChoice::DoGetBestSize() const { // // Find the widest string // int nLineWidth; int nChoiceWidth = 0; int nItems = GetCount(); int nCx; int nCy; wxFont vFont = (wxFont)GetFont(); for (int i = 0; i < nItems; i++) { wxString sStr(GetString(i)); GetTextExtent( sStr ,&nLineWidth ,NULL ); if (nLineWidth > nChoiceWidth) nChoiceWidth = nLineWidth; } // // Give it some reasonable default value if there are no strings in the // list // if (nChoiceWidth == 0L) nChoiceWidth = 100L; // // The combobox should be larger than the widest string // wxGetCharSize( GetHWND() ,&nCx ,&nCy ,&vFont ); nChoiceWidth += 5 * nCx; // // Choice drop-down list depends on number of items (limited to 10) // size_t nStrings = nItems == 0 ? 10 : wxMin(10, nItems) + 1; int nChoiceHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * nStrings; return wxSize( nChoiceWidth ,nChoiceHeight ); } // end of wxChoice::DoGetBestSize
void CSizeComboBox::DoSetSize( int x, int y, int width, int height, int sizeFlags ) { int heightOrig = height; if( height != wxDefaultCoord ) { int cx, cy; wxGetCharSize( GetHWND(), &cx, &cy, GetFont() ); int hItem = SendMessage( GetHwnd(), CB_GETITEMHEIGHT, (WPARAM) -1, 0 ); height = ( EDIT_HEIGHT_FROM_CHAR_HEIGHT( cy ) * 6 ) + hItem; } wxControl::DoSetSize( x, y, width, height, sizeFlags ); if( m_pendingSize != wxDefaultSize ) m_pendingSize = wxSize( width, heightOrig ); }
wxSize wxStaticBox::DoGetBestSize() const { int cx, cy; wxGetCharSize(GetHWND(), &cx, &cy, GetFont()); int wBox; GetTextExtent(GetLabelText(wxGetWindowText(m_hWnd)), &wBox, &cy); wBox += 3*cx; int hBox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy); wxSize best(wBox, hBox); CacheBestSize(best); return best; }
wxSize wxButton::DoGetBestSize() const { wxString rsLabel = wxGetWindowText(GetHWND()); int nWidthButton; int nWidthChar; int nHeightChar; wxFont vFont = (wxFont)GetFont(); GetTextExtent( rsLabel ,&nWidthButton ,NULL ); wxGetCharSize( GetHWND() ,&nWidthChar ,&nHeightChar ,&vFont ); // // Add a margin - the button is wider than just its label // nWidthButton += 3 * nWidthChar; // // The button height is proportional to the height of the font used // int nHeightButton = BUTTON_HEIGHT_FROM_CHAR_HEIGHT(nHeightChar); // // Need a little extra to make it look right // nHeightButton += (int)(nHeightChar/1.5); if (!HasFlag(wxBU_EXACTFIT)) { wxSize vSize = GetDefaultSize(); if (nWidthButton > vSize.x) vSize.x = nWidthButton; if (nHeightButton > vSize.y) vSize.y = nHeightButton; return vSize; } return wxSize( nWidthButton ,nHeightButton ); } // end of wxButton::DoGetBestSize
wxSize wxListBox::DoGetBestSize() const { // // Find the widest string // int nLine; int nListbox = 0; int nCx; int nCy; wxFont vFont = (wxFont)GetFont(); for (int i = 0; i < m_nNumItems; i++) { wxString vStr(GetString(i)); GetTextExtent( vStr ,&nLine ,NULL ); if (nLine > nListbox) nListbox = nLine; } // // Give it some reasonable default value if there are no strings in the // list. // if (nListbox == 0) nListbox = 100; // // The listbox should be slightly larger than the widest string // wxGetCharSize( GetHWND() ,&nCx ,&nCy ,&vFont ); nListbox += 3 * nCx; int hListbox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * (wxMax(m_nNumItems, 7)); return wxSize( nListbox ,hListbox ); } // end of wxListBox::DoGetBestSize
wxSize wxTextCtrl::DoGetBestSize() const { int nCx; int nCy; wxFont vFont = (wxFont)GetFont(); wxGetCharSize(GetHWND(), &nCx, &nCy, &vFont); int wText = DEFAULT_ITEM_WIDTH; int hText = (int)(EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * .8); if (m_windowStyle & wxTE_MULTILINE) { hText *= wxMax(GetNumberOfLines(), 5); } //else: for single line control everything is ok return wxSize(wText, hText); } // end of wxTextCtrl::DoGetBestSize
wxSize wxSpinCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const { wxSize sizeBtn = wxSpinButton::DoGetBestSize(); int y; wxGetCharSize(GetHWND(), NULL, &y, GetFont()); // JACS: we should always use the height calculated // from above, because otherwise we'll get a spin control // that's too big. So never use the height calculated // from wxSpinButton::DoGetBestSize(). wxSize tsize(xlen + sizeBtn.x + MARGIN_BETWEEN + 3*y/10 + 10, EDIT_HEIGHT_FROM_CHAR_HEIGHT(y)); // Check if the user requested a non-standard height. if ( ylen > 0 ) tsize.IncBy(0, ylen - y); return tsize; }
wxSize wxTextCtrl::DoGetBestSize() const { int cx, cy; wxGetCharSize(GetBuddyHwnd(), &cx, &cy, GetFont()); int wText = DEFAULT_ITEM_WIDTH; int hText = cy; if ( m_windowStyle & wxTE_MULTILINE ) { hText *= wxMax(GetNumberOfLines(), 5); } //else: for single line control everything is ok // we have to add the adjustments for the control height only once, not // once per line, so do it after multiplication above hText += EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy) - cy; return wxSize(wText, hText); }
wxSize wxSpinCtrl::DoGetBestSize() const { wxSize sizeBtn = wxSpinButton::DoGetBestSize(); sizeBtn.x += DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN; int y; wxGetCharSize(GetHWND(), NULL, &y, GetFont()); y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(y); // JACS: we should always use the height calculated // from above, because otherwise we'll get a spin control // that's too big. So never use the height calculated // from wxSpinButton::DoGetBestSize(). // if ( sizeBtn.y < y ) { // make the text tall enough sizeBtn.y = y; } return sizeBtn; }
wxSize wxRadioBox::GetTotalButtonSize(const wxSize& sizeBtn) const { // the radiobox should be big enough for its buttons int cx1, cy1; wxGetCharSize(m_hWnd, &cx1, &cy1, GetFont()); int extraHeight = cy1; int height = GetRowCount() * sizeBtn.y + cy1/2 + extraHeight; int width = GetColumnCount() * (sizeBtn.x + cx1) + cx1; // Add extra space under the label, if it exists. if (!wxControl::GetLabel().empty()) height += cy1/2; // and also wide enough for its label int widthLabel; GetTextExtent(GetLabelText(), &widthLabel, NULL); widthLabel += RADIO_SIZE; // FIXME this is bogus too if ( widthLabel > width ) width = widthLabel; return wxSize(width, height); }
wxSize wxSpinCtrl::DoGetBestSize() const { wxSize vSizeBtn = wxSpinButton::DoGetBestSize(); int nHeight; wxFont vFont = (wxFont)GetFont(); vSizeBtn.x += DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN; wxGetCharSize( GetHWND() ,NULL ,&nHeight ,&vFont ); nHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nHeight)+4; if (vSizeBtn.y < nHeight) { // // Make the text tall enough // vSizeBtn.y = nHeight; } return vSizeBtn; } // end of wxSpinCtrl::DoGetBestSize
wxSize wxListBox::DoGetBestSize() const { // find the widest string int wLine; int wListbox = 0; for (unsigned int i = 0; i < m_noItems; i++) { wxString str(GetString(i)); GetTextExtent(str, &wLine, NULL); if ( wLine > wListbox ) wListbox = wLine; } // give it some reasonable default value if there are no strings in the // list if ( wListbox == 0 ) wListbox = 100; // the listbox should be slightly larger than the widest string int cx, cy; wxGetCharSize(GetHWND(), &cx, &cy, GetFont()); wListbox += 3*cx; // Add room for the scrollbar wListbox += wxSystemSettings::GetMetric(wxSYS_VSCROLL_X); // don't make the listbox too tall (limit height to 10 items) but don't // make it too small neither int hListbox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy)* wxMin(wxMax(m_noItems, 3), 10); wxSize best(wListbox, hListbox); CacheBestSize(best); return best; }
wxSize wxRadioBox::GetTotalButtonSize(const wxSize& sizeBtn) const { // the radiobox should be big enough for its buttons int cx1, cy1; wxGetCharSize(m_hWnd, &cx1, &cy1, GetFont()); int extraHeight = cy1; int height = GetRowCount() * sizeBtn.y + cy1/2 + extraHeight; int width = GetColumnCount() * (sizeBtn.x + cx1) + cx1; // Add extra space under the label, if it exists. if (!wxControl::GetLabel().empty()) height += wxRendererNative::Get().GetCheckBoxSize( reinterpret_cast<wxWindow*>(const_cast<wxRadioBox*>(this))).y / 2; // and also wide enough for its label int widthLabel; GetTextExtent(GetLabelText(), &widthLabel, NULL); if ( widthLabel > width ) width = widthLabel; return wxSize(width, height); }
void wxRadioBox::PositionAllButtons(int x, int y, int width, int WXUNUSED(height)) { wxSize maxSize = GetMaxButtonSize(); int maxWidth = maxSize.x, maxHeight = maxSize.y; // 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 GetMajorDim() is the number of columns while // wxRA_SPECIFY_ROWS means that the buttons are arranged top to bottom and // GetMajorDim() is the number of rows. int cx1, cy1; wxGetCharSize(m_hWnd, &cx1, &cy1, GetFont()); int x_offset = x + cx1; int y_offset = y + cy1; // Add extra space under the label, if it exists. if (!wxControl::GetLabel().empty()) y_offset += cy1/2; int startX = x_offset; int startY = y_offset; const unsigned int count = GetCount(); for (unsigned int i = 0; i < count; 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 isLastInTheRow; 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 unsigned int n = i + 1; isLastInTheRow = ((n % GetMajorDim()) == 0) || (n == count); } else // wxRA_SPECIFY_ROWS { // item is the last in the row if it is in the last columns isLastInTheRow = i >= (count/GetMajorDim())*GetMajorDim(); } // is this the start of new row/column? if ( i && (i % GetMajorDim() == 0) ) { if ( m_windowStyle & wxRA_SPECIFY_ROWS ) { // start of new column y_offset = startY; x_offset += maxWidth + cx1; } else // start of new row { x_offset = startX; y_offset += maxHeight; if (m_radioWidth[0]>0) y_offset += cy1/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 { // normal button, always of the same size widthBtn = maxWidth; } // 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) DoMoveSibling((*m_radioButtons)[i], x_offset, y_offset, widthBtn, maxHeight); // 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 { // to the right of this one x_offset += widthBtn + cx1; } } }
bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator, const wxString& name) { if ( (style & wxBORDER_MASK) == wxBORDER_DEFAULT ) style |= wxBORDER_SIMPLE; SetWindowStyle(style); WXDWORD exStyle = 0; WXDWORD msStyle = MSWGetStyle(GetWindowStyle(), & exStyle) ; wxSize sizeText(size), sizeBtn(size); sizeBtn.x = GetBestSpinnerSize(IsVertical(style)).x / 2; if ( sizeText.x == wxDefaultCoord ) { // DEFAULT_ITEM_WIDTH is the default width for the text control sizeText.x = DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN + sizeBtn.x; } sizeText.x -= sizeBtn.x + MARGIN_BETWEEN; if ( sizeText.x <= 0 ) { wxLogDebug(_T("not enough space for wxSpinCtrl!")); } wxPoint posBtn(pos); posBtn.x += sizeText.x + MARGIN_BETWEEN; // we need to turn '\n's into "\r\n"s for the multiline controls wxString valueWin; if ( m_windowStyle & wxTE_MULTILINE ) { valueWin = wxTextFile::Translate(value, wxTextFileType_Dos); } else // single line { valueWin = value; } // we must create the list control before the spin button for the purpose // of the dialog navigation: if there is a static text just before the spin // control, activating it by Alt-letter should give focus to the text // control, not the spin and the dialog navigation code will give focus to // the next control (at Windows level), not the one after it // create the text window m_hwndBuddy = (WXHWND)::CreateWindowEx ( exStyle, // sunken border _T("EDIT"), // window class valueWin, // no window title msStyle, // style (will be shown later) pos.x, pos.y, // position 0, 0, // size (will be set later) GetHwndOf(parent), // parent (HMENU)-1, // control id wxGetInstance(), // app instance NULL // unused client data ); if ( !m_hwndBuddy ) { wxLogLastError(wxT("CreateWindow(buddy text window)")); return false; } // initialize wxControl if ( !CreateControl(parent, id, posBtn, sizeBtn, style, validator, name) ) return false; // now create the real HWND WXDWORD spiner_style = WS_VISIBLE | UDS_ALIGNRIGHT | UDS_EXPANDABLE | UDS_NOSCROLL; if ( !IsVertical(style) ) spiner_style |= UDS_HORZ; if ( style & wxSP_WRAP ) spiner_style |= UDS_WRAP; if ( !MSWCreateControl(UPDOWN_CLASS, spiner_style, posBtn, sizeBtn, _T(""), 0) ) return false; // subclass the text ctrl to be able to intercept some events wxSetWindowUserData(GetBuddyHwnd(), this); m_wndProcBuddy = (WXFARPROC)wxSetWindowProc(GetBuddyHwnd(), wxBuddyTextCtrlWndProc); // set up fonts and colours (This is nomally done in MSWCreateControl) InheritAttributes(); if (!m_hasFont) SetFont(GetDefaultAttributes().font); // set the size of the text window - can do it only now, because we // couldn't call DoGetBestSize() before as font wasn't set if ( sizeText.y <= 0 ) { int cx, cy; wxGetCharSize(GetHWND(), &cx, &cy, GetFont()); sizeText.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy); } SetInitialSize(size); (void)::ShowWindow(GetBuddyHwnd(), SW_SHOW); // associate the list window with the spin button (void)::SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)GetBuddyHwnd(), 0); // do it after finishing with m_hwndBuddy creation to avoid generating // initial wxEVT_COMMAND_TEXT_UPDATED message ms_allTextSpins.Add(this); return true; }
// Restored old code. void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags) { int currentX, currentY; GetPosition(¤tX, ¤tY); int widthOld, heightOld; GetSize(&widthOld, &heightOld); int xx = x; int yy = y; if (x == wxDefaultCoord && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) xx = currentX; if (y == wxDefaultCoord && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) yy = currentY; int y_offset = 0; int x_offset = 0; 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. wxSize maxSize = GetMaxButtonSize(); int maxWidth = maxSize.x, maxHeight = maxSize.y; wxSize totSize = GetTotalButtonSize(maxSize); int totWidth = totSize.x, totHeight = totSize.y; // only change our width/height if asked for if ( width == wxDefaultCoord ) { if ( sizeFlags & wxSIZE_AUTO_WIDTH ) width = totWidth; else width = widthOld; } if ( height == wxDefaultCoord ) { if ( sizeFlags & wxSIZE_AUTO_HEIGHT ) height = totHeight; else height = heightOld; } DoMoveWindow(xx, yy, width, height); // 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; // Add extra space under the label, if it exists. if (!wxControl::GetLabel().empty()) y_offset += cy1/2; int startX = x_offset; int startY = y_offset; const int count = GetCount(); for ( int i = 0; i < count; 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 isLastInTheRow; 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; isLastInTheRow = ((n % m_majorDim) == 0) || (n == count); } else // wxRA_SPECIFY_ROWS { // item is the last in the row if it is in the last columns isLastInTheRow = i >= (count/m_majorDim)*m_majorDim; } // is this the start of new row/column? if ( i && (i % m_majorDim == 0) ) { if ( m_windowStyle & wxRA_SPECIFY_ROWS ) { // start of new column y_offset = startY; x_offset += maxWidth + cx1; } else // start of new row { x_offset = startX; y_offset += maxHeight; if (m_radioWidth[0]>0) y_offset += cy1/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 { // normal button, always of the same size widthBtn = maxWidth; } // 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) ::MoveWindow((*m_radioButtons)[i], x_offset, y_offset, widthBtn, maxHeight, TRUE); // 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 { // to the right of this one x_offset += widthBtn + cx1; } } }
bool wxSpinCtrl::Create(wxWindow *parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style, int min, int max, int initial, const wxString& name) { // this should be in ctor/init function but I don't want to add one to 2.8 // to avoid problems with default ctor which can be inlined in the user // code and so might not get this fix without recompilation m_oldValue = INT_MIN; // before using DoGetBestSize(), have to set style to let the base class // know whether this is a horizontal or vertical control (we're always // vertical) style |= wxSP_VERTICAL; if ( (style & wxBORDER_MASK) == wxBORDER_DEFAULT ) #ifdef __WXWINCE__ style |= wxBORDER_SIMPLE; #else style |= wxBORDER_SUNKEN; #endif SetWindowStyle(style); WXDWORD exStyle = 0; WXDWORD msStyle = MSWGetStyle(GetWindowStyle(), & exStyle) ; // calculate the sizes: the size given is the toal size for both controls // and we need to fit them both in the given width (height is the same) wxSize sizeText(size), sizeBtn(size); sizeBtn.x = wxSpinButton::DoGetBestSize().x; if ( sizeText.x <= 0 ) { // DEFAULT_ITEM_WIDTH is the default width for the text control sizeText.x = DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN + sizeBtn.x; } sizeText.x -= sizeBtn.x + MARGIN_BETWEEN; if ( sizeText.x <= 0 ) { wxLogDebug(_T("not enough space for wxSpinCtrl!")); } wxPoint posBtn(pos); posBtn.x += sizeText.x + MARGIN_BETWEEN; // we must create the text control before the spin button for the purpose // of the dialog navigation: if there is a static text just before the spin // control, activating it by Alt-letter should give focus to the text // control, not the spin and the dialog navigation code will give focus to // the next control (at Windows level), not the one after it // create the text window m_hwndBuddy = (WXHWND)::CreateWindowEx ( exStyle, // sunken border _T("EDIT"), // window class NULL, // no window title msStyle, // style (will be shown later) pos.x, pos.y, // position 0, 0, // size (will be set later) GetHwndOf(parent), // parent (HMENU)-1, // control id wxGetInstance(), // app instance NULL // unused client data ); if ( !m_hwndBuddy ) { wxLogLastError(wxT("CreateWindow(buddy text window)")); return false; } // create the spin button if ( !wxSpinButton::Create(parent, id, posBtn, sizeBtn, style, name) ) { return false; } wxSpinButtonBase::SetRange(min, max); // subclass the text ctrl to be able to intercept some events wxSetWindowUserData(GetBuddyHwnd(), this); m_wndProcBuddy = (WXFARPROC)wxSetWindowProc(GetBuddyHwnd(), wxBuddyTextWndProc); // set up fonts and colours (This is nomally done in MSWCreateControl) InheritAttributes(); if (!m_hasFont) SetFont(GetDefaultAttributes().font); // set the size of the text window - can do it only now, because we // couldn't call DoGetBestSize() before as font wasn't set if ( sizeText.y <= 0 ) { int cx, cy; wxGetCharSize(GetHWND(), &cx, &cy, GetFont()); sizeText.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy); } SetInitialSize(size); (void)::ShowWindow(GetBuddyHwnd(), SW_SHOW); // associate the text window with the spin button (void)::SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)m_hwndBuddy, 0); SetValue(initial); // Set the range in the native control SetRange(min, max); if ( !value.empty() ) { SetValue(value); m_oldValue = (int) wxAtol(value); } else { SetValue(wxString::Format(wxT("%d"), initial)); m_oldValue = initial; } // do it after finishing with m_hwndBuddy creation to avoid generating // initial wxEVT_COMMAND_TEXT_UPDATED message ms_allSpins.Add(this); return true; }
bool wxChoice::Create( wxWindow* pParent , wxWindowID vId , const wxPoint& rPos , const wxSize& rSize , int n , const wxString asChoices[] , long lStyle , const wxValidator& rValidator , const wxString& rsName ) { long lSstyle; if (!CreateControl( pParent ,vId ,rPos ,rSize ,lStyle ,rValidator ,rsName )) return false; lSstyle = CBS_DROPDOWNLIST | WS_TABSTOP | WS_VISIBLE; // clipping siblings does not yet work // if (lStyle & wxCLIP_SIBLINGS ) // lSstyle |= WS_CLIPSIBLINGS; wxASSERT_MSG( !(lStyle & wxCB_DROPDOWN) && !(lStyle & wxCB_READONLY) && !(lStyle & wxCB_SIMPLE), wxT("this style flag is ignored by wxChoice, you " "probably want to use a wxComboBox") ); if (!OS2CreateControl( wxT("COMBOBOX") ,lSstyle )) return false; // // A choice/combobox normally has a white background (or other, depending // on global settings) rather than inheriting the parent's background colour. // SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); // initialize the controls contents for (int i = 0; i < n; i++) { Append(asChoices[i]); } SetSize( rPos.x ,rPos.y ,rSize.x ,rSize.y ); // Set height to use with sizers i.e. without the dropdown listbox wxFont vFont = GetFont(); int nEditHeight; wxGetCharSize( GetHWND(), NULL, &nEditHeight, &vFont ); nEditHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nEditHeight); SetInitialSize(wxSize(-1,nEditHeight+4)); // +2x2 for the border return true; } // end of wxChoice::Create
bool wxSpinCtrl::Create(wxWindow *parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style, int min, int max, int initial, const wxString& name) { // before using DoGetBestSize(), have to set style to let the base class // know whether this is a horizontal or vertical control (we're always // vertical) style |= wxSP_VERTICAL; if ( (style & wxBORDER_MASK) == wxBORDER_DEFAULT ) #ifdef __WXWINCE__ style |= wxBORDER_SIMPLE; #else style |= wxBORDER_SUNKEN; #endif SetWindowStyle(style); WXDWORD exStyle = 0; WXDWORD msStyle = MSWGetStyle(GetWindowStyle(), & exStyle) ; // Scroll text automatically if there is not enough space to show all of // it, this is better than not allowing to enter more digits at all. msStyle |= ES_AUTOHSCROLL; // propagate text alignment style to text ctrl if ( style & wxALIGN_RIGHT ) msStyle |= ES_RIGHT; else if ( style & wxALIGN_CENTER ) msStyle |= ES_CENTER; // calculate the sizes: the size given is the total size for both controls // and we need to fit them both in the given width (height is the same) wxSize sizeText(size), sizeBtn(size); sizeBtn.x = wxSpinButton::DoGetBestSize().x; if ( sizeText.x <= 0 ) { // DEFAULT_ITEM_WIDTH is the default width for the text control sizeText.x = DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN + sizeBtn.x; } sizeText.x -= sizeBtn.x + MARGIN_BETWEEN; if ( sizeText.x <= 0 ) { wxLogDebug(wxT("not enough space for wxSpinCtrl!")); } wxPoint posBtn(pos); posBtn.x += sizeText.x + MARGIN_BETWEEN; // we must create the text control before the spin button for the purpose // of the dialog navigation: if there is a static text just before the spin // control, activating it by Alt-letter should give focus to the text // control, not the spin and the dialog navigation code will give focus to // the next control (at Windows level), not the one after it // create the text window m_hwndBuddy = (WXHWND)::CreateWindowEx ( exStyle, // sunken border wxT("EDIT"), // window class NULL, // no window title msStyle, // style (will be shown later) pos.x, pos.y, // position 0, 0, // size (will be set later) GetHwndOf(parent), // parent (HMENU)-1, // control id wxGetInstance(), // app instance NULL // unused client data ); if ( !m_hwndBuddy ) { wxLogLastError(wxT("CreateWindow(buddy text window)")); return false; } // create the spin button if ( !wxSpinButton::Create(parent, id, posBtn, sizeBtn, style, name) ) { return false; } wxSpinButtonBase::SetRange(min, max); // subclass the text ctrl to be able to intercept some events gs_spinForTextCtrl[GetBuddyHwnd()] = this; m_wndProcBuddy = (WXFARPROC)wxSetWindowProc(GetBuddyHwnd(), wxBuddyTextWndProc); // set up fonts and colours (This is nomally done in MSWCreateControl) InheritAttributes(); if (!m_hasFont) SetFont(GetDefaultAttributes().font); // set the size of the text window - can do it only now, because we // couldn't call DoGetBestSize() before as font wasn't set if ( sizeText.y <= 0 ) { int cx, cy; wxGetCharSize(GetHWND(), &cx, &cy, GetFont()); sizeText.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy); } SetInitialSize(size); (void)::ShowWindow(GetBuddyHwnd(), SW_SHOW); // associate the text window with the spin button (void)::SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)m_hwndBuddy, 0); // If the initial text value is actually a number, it overrides the // "initial" argument specified later. long initialFromText; if ( value.ToLong(&initialFromText) ) initial = initialFromText; SetValue(initial); m_oldValue = initial; // Set the range in the native control SetRange(min, max); // Also set the text part of the control if it was specified independently // but don't generate an event for this, it would be unexpected. m_blockEvent = true; if ( !value.empty() ) SetValue(value); m_blockEvent = false; return true; }
bool wxComboBox::Create( wxWindow* pParent , wxWindowID vId , const wxString& rsValue , const wxPoint& rPos , const wxSize& rSize , int n , const wxString asChoices[] , long lStyle , const wxValidator& rValidator , const wxString& rsName ) { m_isShown = false; if (!CreateControl( pParent ,vId ,rPos ,rSize ,lStyle ,rValidator ,rsName )) return false; // // Get the right style // long lSstyle = 0L; lSstyle = WS_TABSTOP | WS_VISIBLE; // clipping siblings does not yet work // if (lStyle & wxCLIP_SIBLINGS ) // lSstyle |= WS_CLIPSIBLINGS; if (lStyle & wxCB_READONLY) lSstyle |= CBS_DROPDOWNLIST; else if (lStyle & wxCB_SIMPLE) lSstyle |= CBS_SIMPLE; // A list (shown always) and edit control else lSstyle |= CBS_DROPDOWN; if (!OS2CreateControl( wxT("COMBOBOX") ,lSstyle )) return false; // // A choice/combobox normally has a white background (or other, depending // on global settings) rather than inheriting the parent's background colour. // SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); for (int i = 0; i < n; i++) { Append(asChoices[i]); } SetSize( rPos.x ,rPos.y ,rSize.x ,rSize.y ); // Set height to use with sizers i.e. without the dropdown listbox wxFont vFont = GetFont(); int nEditHeight; wxGetCharSize( GetHWND(), NULL, &nEditHeight, &vFont ); nEditHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nEditHeight); SetInitialSize(wxSize(-1,nEditHeight+4)); // +2x2 for the border if (!rsValue.empty()) { SetValue(rsValue); } gfnWndprocEdit = (WXFARPROC)::WinSubclassWindow( (HWND)GetHwnd() ,(PFNWP)wxComboEditWndProc ); ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this); Show(true); return true; } // end of wxComboBox::Create
void wxRadioBox::DoSetSize( int nX , int nY , int nWidth , int nHeight , int nSizeFlags ) { // // 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 (nHeight == -1) { if (nSizeFlags & wxSIZE_AUTO_HEIGHT) nHeight = nTotHeight; else nHeight = nHeightOld; } // // Now convert to OS/2 coordinate system // wxWindowOS2* pParent = (wxWindowOS2*)GetParent(); if (pParent) nYy = GetOS2ParentHeight(pParent) - nYy - nHeight; else { RECTL vRect; ::WinQueryWindowRect(HWND_DESKTOP, &vRect); nYy = vRect.yTop - nYy - nHeight; } 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++) { // // 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 % 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(); } // // 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; } } int nWidthBtn; if (bIsLastInTheRow) { // // Make the button go to the end of radio box // nWidthBtn = nStartX + nWidth - nXOffset - (2 * nCx1); if (nWidthBtn < nMaxWidth) nWidthBtn = nMaxWidth; } else { // // Normal button, always of the same size // nWidthBtn = nMaxWidth; } // // Make all buttons of the same, maximal size - like this they // cover the radiobox entirely and the radiobox tooltips are always // shown (otherwise they are not when the mouse pointer is in the // radiobox part not 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