]> git.saurik.com Git - wxWidgets.git/commitdiff
Refactor and simplify wxChoice::DoGetBestSize().
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 1 Nov 2012 17:15:28 +0000 (17:15 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 1 Nov 2012 17:15:28 +0000 (17:15 +0000)
Use wxTextMeasure instead of duplicating its code and also reuse the code
between different ports.

Closes #14706.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72848 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/choice.h
src/common/choiccmn.cpp
src/gtk/choice.cpp
src/msw/choice.cpp
src/osx/choice_osx.cpp

index 46f27b9d8a838997cece1f223d551fac8f47fd4c..369dbb517a0d55ba7f1b5508b12202ee117b9f4c 100644 (file)
@@ -58,6 +58,13 @@ public:
     // override wxItemContainer::IsSorted
     virtual bool IsSorted() const { return HasFlag(wxCB_SORT); }
 
+protected:
+    // The generic implementation doesn't determine the height correctly and
+    // doesn't account for the width of the arrow but does take into account
+    // the string widths, so the derived classes should override it and set the
+    // height and add the arrow width to the size returned by this version.
+    virtual wxSize DoGetBestSize() const;
+
 private:
     wxDECLARE_NO_COPY_CLASS(wxChoiceBase);
 };
index dc925335a268a8e1c4fafc11e8bbe466b19c0679..31b0a2df064cec038032bcae7160e6ff477ae004 100644 (file)
@@ -28,6 +28,8 @@
 
 #include "wx/choice.h"
 
+#include "wx/private/textmeasure.h"
+
 #ifndef WX_PRECOMP
 #endif
 
@@ -103,6 +105,21 @@ wxChoiceBase::~wxChoiceBase()
     // this destructor is required for Darwin
 }
 
+wxSize wxChoiceBase::DoGetBestSize() const
+{
+    // a reasonable width for an empty choice list
+    wxSize best(80, -1);
+
+    const unsigned int nItems = GetCount();
+    if ( nItems > 0 )
+    {
+        wxTextMeasure txm(this);
+        best.x = txm.GetLargestStringExtent(GetStrings()).x;
+    }
+
+    return best;
+}
+
 // ----------------------------------------------------------------------------
 // misc
 // ----------------------------------------------------------------------------
index dbc8579872dfd0ebc38d1ff42ca712d51f78f842..28832ef3e4f0d4d34c4b7fc2f4cf5cdd6cb18da2 100644 (file)
@@ -343,35 +343,13 @@ GdkWindow *wxChoice::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
     return gtk_widget_get_window(m_widget);
 }
 
-// Notice that this method shouldn't be necessary, because GTK calculates
-// properly size of the combobox but for unknown reasons it doesn't work
-// correctly in wx without this.
 wxSize wxChoice::DoGetBestSize() const
 {
-    // strangely, this returns a width of 188 pixels from GTK+ (?)
-    wxSize ret( wxControl::DoGetBestSize() );
-
-    // we know better our horizontal extent: it depends on the longest string
-    // in the combobox
-    if ( m_widget )
-    {
-        ret.x = GetCount() > 0 ? 0 : 60;  // start with something "sensible"
-        int width;
-        unsigned int count = GetCount();
-        for ( unsigned int n = 0; n < count; n++ )
-        {
-            GetTextExtent(GetString(n), &width, NULL, NULL, NULL );
-            if ( width + 40 > ret.x ) // 40 for drop down arrow and space around text
-                ret.x = width + 40;
-        }
-    }
-
-    // empty combobox should have some reasonable default size too
-    if ((GetCount() == 0) && (ret.x < 80))
-        ret.x = 80;
-
-    CacheBestSize(ret);
-    return ret;
+    // Get the height of the control from GTK+ itself, but use our own version
+    // to compute the width large enough to show all our strings as GTK+
+    // doesn't seem to take the control contents into account.
+    return wxSize(wxChoiceBase::DoGetBestSize().x + 40,
+                  wxControl::DoGetBestSize().y);
 }
 
 void wxChoice::DoApplyWidgetStyle(GtkRcStyle *style)
index ea922c9e411fc1ae0462bb498755d0be80378d25..5ad9416212632d93fd85cfd7aae748cdb61783a5 100644 (file)
@@ -587,34 +587,18 @@ void wxChoice::DoSetSize(int x, int y,
 
 wxSize wxChoice::DoGetBestSize() const
 {
-    // find the widest string
-    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;
-    }
+    // The base version returns the size of the largest string
+    wxSize best( wxChoiceBase::DoGetBestSize() );
 
-    // give it some reasonable default value if there are no strings in the
-    // list
-    if ( wChoice == 0 )
-        wChoice = 100;
+    // We just need to adjust it to account for the arrow width.
+    best.x += 5*GetCharWidth();
 
-    // the combobox should be slightly larger than the widest string
-    wChoice += 5*GetCharWidth();
+    // set height on our own
     if( HasFlag( wxCB_SIMPLE ) )
-    {
-        hChoice = SetHeightSimpleComboBox( nItems );
-    }
+        best.y = SetHeightSimpleComboBox(GetCount());
     else
-        hChoice = EDIT_HEIGHT_FROM_CHAR_HEIGHT(GetCharHeight());
+        best.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(GetCharHeight());
 
-    wxSize best(wChoice, hChoice);
-    CacheBestSize(best);
     return best;
 }
 
index d26812a571b6efe11f320d7ea6209915f16396bd..2bf2c102535b66afc4f913b092bd00ab78717d9d 100644 (file)
@@ -259,37 +259,13 @@ bool wxChoice::OSXHandleClicked( double WXUNUSED(timestampsec) )
 
 wxSize wxChoice::DoGetBestSize() const
 {
-    int lbWidth = GetCount() > 0 ? 20 : 100;  // some defaults
-    wxSize baseSize = wxWindow::DoGetBestSize();
-    int lbHeight = baseSize.y;
-    int wLine;
+    // We use the base window size for the height (which is wrong as it doesn't
+    // take the font into account -- TODO) and add some margins to the width
+    // computed by the base class method to account for the arrow.
+    const int lbHeight = wxWindow::DoGetBestSize().y;
 
-    {
-        wxClientDC dc(const_cast<wxChoice*>(this));
-
-        // Find the widest line
-        for(unsigned int i = 0; i < GetCount(); i++)
-        {
-            wxString str(GetString(i));
-
-            wxCoord width, height ;
-            dc.GetTextExtent( str , &width, &height);
-            wLine = width ;
-
-            lbWidth = wxMax( lbWidth, wLine ) ;
-        }
-
-        // Add room for the popup arrow
-        lbWidth += 2 * lbHeight ;
-
-        wxCoord width, height ;
-        dc.GetTextExtent( wxT("X"), &width, &height);
-        int cx = width ;
-
-        lbWidth += cx ;
-    }
-
-    return wxSize( lbWidth, lbHeight );
+    return wxSize(wxChoiceBase::DoGetBestSize().x + 2*lbHeight + GetCharWidth(),
+                  lbHeight);
 }
 
 #endif // wxUSE_CHOICE