From aa24f946c6dcef84c4811deccd811781ec72e6db Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 14 Nov 2012 13:47:59 +0000 Subject: [PATCH] Implement DoGetSizeFromTextSize() for wxMSW wx{Choice,Combobox,TextCtrl}. Refactor and improve the existing DoGetBestSize() implementations to use DoGetBestSize(). Closes #14816. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72954 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/choice.h | 1 + include/wx/msw/combobox.h | 2 ++ include/wx/msw/textctrl.h | 1 + interface/wx/control.h | 2 +- src/msw/choice.cpp | 45 +++++++++++++++++++++++++++++++++------------ src/msw/combobox.cpp | 16 ++++++++++++++++ src/msw/textctrl.cpp | 37 ++++++++++++++++++++++++++++++++++--- 7 files changed, 88 insertions(+), 16 deletions(-) diff --git a/include/wx/msw/choice.h b/include/wx/msw/choice.h index c124543..496c20f 100644 --- a/include/wx/msw/choice.h +++ b/include/wx/msw/choice.h @@ -127,6 +127,7 @@ protected: virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO); + virtual wxSize DoGetSizeFromTextSize(int xlen, int ylen = -1) const; // Show or hide the popup part of the control. void MSWDoPopupOrDismiss(bool show); diff --git a/include/wx/msw/combobox.h b/include/wx/msw/combobox.h index aa10c8d..ac803c1 100644 --- a/include/wx/msw/combobox.h +++ b/include/wx/msw/combobox.h @@ -132,6 +132,8 @@ protected: virtual void DoSetToolTip(wxToolTip *tip); #endif + virtual wxSize DoGetSizeFromTextSize(int xlen, int ylen = -1) const; + // this is the implementation of GetEditHWND() which can also be used when // we don't have the edit control, it simply returns NULL then // diff --git a/include/wx/msw/textctrl.h b/include/wx/msw/textctrl.h index f8fdf1f..c56bcae 100644 --- a/include/wx/msw/textctrl.h +++ b/include/wx/msw/textctrl.h @@ -236,6 +236,7 @@ protected: bool SendUpdateEvent(); virtual wxSize DoGetBestSize() const; + virtual wxSize DoGetSizeFromTextSize(int xlen, int ylen = -1) const; #if wxUSE_RICHEDIT // Apply the character-related parts of wxTextAttr to the given selection diff --git a/interface/wx/control.h b/interface/wx/control.h index 88d1780..2fd28f3 100644 --- a/interface/wx/control.h +++ b/interface/wx/control.h @@ -172,7 +172,7 @@ public: @endcode Currently this method is only implemented for wxTextCtrl, wxComboBox - and wxChoice in wxGTK. + and wxChoice in wxMSW and wxGTK. @param xlen The horizontal extent of the area to leave for text, in pixels. diff --git a/src/msw/choice.cpp b/src/msw/choice.cpp index e408eb8..1cb3bd9 100644 --- a/src/msw/choice.cpp +++ b/src/msw/choice.cpp @@ -612,18 +612,7 @@ void wxChoice::DoSetSize(int x, int y, wxSize wxChoice::DoGetBestSize() const { // The base version returns the size of the largest string - wxSize best( wxChoiceBase::DoGetBestSize() ); - - // We just need to adjust it to account for the arrow width. - best.x += 5*GetCharWidth(); - - // set height on our own - if( HasFlag( wxCB_SIMPLE ) ) - best.y = SetHeightSimpleComboBox(GetCount()); - else - best.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(GetCharHeight()); - - return best; + return GetSizeFromTextSize(wxChoiceBase::DoGetBestSize().x); } int wxChoice::SetHeightSimpleComboBox(int nItems) const @@ -634,6 +623,38 @@ int wxChoice::SetHeightSimpleComboBox(int nItems) const return EDIT_HEIGHT_FROM_CHAR_HEIGHT( cy ) * wxMin( wxMax( nItems, 3 ), 6 ) + hItem - 1; } +wxSize wxChoice::DoGetSizeFromTextSize(int xlen, int ylen) const +{ + int cHeight = GetCharHeight(); + + // We are interested in the difference of sizes between the whole control + // and its child part. I.e. arrow, separators, etc. + wxSize tsize(xlen, 0); + + WinStruct info; + if ( MSWGetComboBoxInfo(&info) ) + { + tsize.x += info.rcItem.left + info.rcButton.right - info.rcItem.right + + info.rcItem.left + 3; // right and extra margins + } + else // Just use some rough approximation. + { + tsize.x += 4*cHeight; + } + + // set height on our own + if( HasFlag( wxCB_SIMPLE ) ) + tsize.y = SetHeightSimpleComboBox(GetCount()); + else + tsize.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cHeight); + + // Perhaps the user wants something different from CharHeight + if ( ylen > 0 ) + tsize.IncBy(0, ylen - cHeight); + + return tsize; +} + // ---------------------------------------------------------------------------- // Popup operations // ---------------------------------------------------------------------------- diff --git a/src/msw/combobox.cpp b/src/msw/combobox.cpp index 076f368..578e110 100644 --- a/src/msw/combobox.cpp +++ b/src/msw/combobox.cpp @@ -661,4 +661,20 @@ bool wxComboBox::SetHint(const wxString& hintOrig) #endif // wxUSE_UXTHEME +wxSize wxComboBox::DoGetSizeFromTextSize(int xlen, int ylen) const +{ + wxSize tsize( wxChoice::DoGetSizeFromTextSize(xlen, ylen) ); + + if ( !HasFlag(wxCB_READONLY) ) + { + // Add the margins we have previously set + wxPoint marg( GetMargins() ); + marg.x = wxMax(0, marg.x); + marg.y = wxMax(0, marg.y); + tsize.IncBy( marg ); + } + + return tsize; +} + #endif // wxUSE_COMBOBOX diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index b4f5be5..4dbf35d 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -2107,17 +2107,41 @@ bool wxTextCtrl::AcceptsFocusFromKeyboard() const wxSize wxTextCtrl::DoGetBestSize() const { + return DoGetSizeFromTextSize( DEFAULT_ITEM_WIDTH ); +} + +wxSize wxTextCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const +{ int cx, cy; wxGetCharSize(GetHWND(), &cx, &cy, GetFont()); - int wText = DEFAULT_ITEM_WIDTH; + DWORD wText = 1; + ::SystemParametersInfo(SPI_GETCARETWIDTH, 0, &wText, 0); + wText += xlen; int hText = cy; if ( m_windowStyle & wxTE_MULTILINE ) { - hText *= wxMax(wxMin(GetNumberOfLines(), 10), 2); + // add space for vertical scrollbar + if ( !(m_windowStyle & wxTE_NO_VSCROLL) ) + wText += ::GetSystemMetrics(SM_CXVSCROLL); + + if ( ylen <= 0 ) + { + hText *= wxMax(wxMin(GetNumberOfLines(), 10), 2); + // add space for horizontal scrollbar + if ( m_windowStyle & wxHSCROLL ) + hText += ::GetSystemMetrics(SM_CYHSCROLL); + } + } + // for single line control cy (height + external leading) is ok + else + { + // Add the margins we have previously set + wxPoint marg( GetMargins() ); + wText += wxMax(0, marg.x); + hText += wxMax(0, marg.y); } - //else: for single line control everything is ok // Text controls without border are special and have the same height as // static labels (they also have the same appearance when they're disable @@ -2126,11 +2150,18 @@ wxSize wxTextCtrl::DoGetBestSize() const // stand out). if ( !HasFlag(wxBORDER_NONE) ) { + wText += 9; // borders and inner margins + // 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; } + // Perhaps the user wants something different from CharHeight, or ylen + // is used as the height of a multiline text. + if ( ylen > 0 ) + hText += ylen - GetCharHeight(); + return wxSize(wText, hText); } -- 2.7.4