// 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);
};
#include "wx/choice.h"
+#include "wx/private/textmeasure.h"
+
#ifndef WX_PRECOMP
#endif
// 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
// ----------------------------------------------------------------------------
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)
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;
}
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