Refactor and simplify wxChoice::DoGetBestSize().
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
This commit is contained in:
@@ -58,6 +58,13 @@ public:
|
|||||||
// override wxItemContainer::IsSorted
|
// override wxItemContainer::IsSorted
|
||||||
virtual bool IsSorted() const { return HasFlag(wxCB_SORT); }
|
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:
|
private:
|
||||||
wxDECLARE_NO_COPY_CLASS(wxChoiceBase);
|
wxDECLARE_NO_COPY_CLASS(wxChoiceBase);
|
||||||
};
|
};
|
||||||
|
@@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
#include "wx/choice.h"
|
#include "wx/choice.h"
|
||||||
|
|
||||||
|
#include "wx/private/textmeasure.h"
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -103,6 +105,21 @@ wxChoiceBase::~wxChoiceBase()
|
|||||||
// this destructor is required for Darwin
|
// 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
|
// misc
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -343,35 +343,13 @@ GdkWindow *wxChoice::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
|
|||||||
return gtk_widget_get_window(m_widget);
|
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
|
wxSize wxChoice::DoGetBestSize() const
|
||||||
{
|
{
|
||||||
// strangely, this returns a width of 188 pixels from GTK+ (?)
|
// Get the height of the control from GTK+ itself, but use our own version
|
||||||
wxSize ret( wxControl::DoGetBestSize() );
|
// to compute the width large enough to show all our strings as GTK+
|
||||||
|
// doesn't seem to take the control contents into account.
|
||||||
// we know better our horizontal extent: it depends on the longest string
|
return wxSize(wxChoiceBase::DoGetBestSize().x + 40,
|
||||||
// in the combobox
|
wxControl::DoGetBestSize().y);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxChoice::DoApplyWidgetStyle(GtkRcStyle *style)
|
void wxChoice::DoApplyWidgetStyle(GtkRcStyle *style)
|
||||||
|
@@ -587,34 +587,18 @@ void wxChoice::DoSetSize(int x, int y,
|
|||||||
|
|
||||||
wxSize wxChoice::DoGetBestSize() const
|
wxSize wxChoice::DoGetBestSize() const
|
||||||
{
|
{
|
||||||
// find the widest string
|
// The base version returns the size of the largest string
|
||||||
int wChoice = 0;
|
wxSize best( wxChoiceBase::DoGetBestSize() );
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// give it some reasonable default value if there are no strings in the
|
// We just need to adjust it to account for the arrow width.
|
||||||
// list
|
best.x += 5*GetCharWidth();
|
||||||
if ( wChoice == 0 )
|
|
||||||
wChoice = 100;
|
|
||||||
|
|
||||||
// the combobox should be slightly larger than the widest string
|
// set height on our own
|
||||||
wChoice += 5*GetCharWidth();
|
|
||||||
if( HasFlag( wxCB_SIMPLE ) )
|
if( HasFlag( wxCB_SIMPLE ) )
|
||||||
{
|
best.y = SetHeightSimpleComboBox(GetCount());
|
||||||
hChoice = SetHeightSimpleComboBox( nItems );
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
hChoice = EDIT_HEIGHT_FROM_CHAR_HEIGHT(GetCharHeight());
|
best.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(GetCharHeight());
|
||||||
|
|
||||||
wxSize best(wChoice, hChoice);
|
|
||||||
CacheBestSize(best);
|
|
||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -259,37 +259,13 @@ bool wxChoice::OSXHandleClicked( double WXUNUSED(timestampsec) )
|
|||||||
|
|
||||||
wxSize wxChoice::DoGetBestSize() const
|
wxSize wxChoice::DoGetBestSize() const
|
||||||
{
|
{
|
||||||
int lbWidth = GetCount() > 0 ? 20 : 100; // some defaults
|
// We use the base window size for the height (which is wrong as it doesn't
|
||||||
wxSize baseSize = wxWindow::DoGetBestSize();
|
// take the font into account -- TODO) and add some margins to the width
|
||||||
int lbHeight = baseSize.y;
|
// computed by the base class method to account for the arrow.
|
||||||
int wLine;
|
const int lbHeight = wxWindow::DoGetBestSize().y;
|
||||||
|
|
||||||
{
|
return wxSize(wxChoiceBase::DoGetBestSize().x + 2*lbHeight + GetCharWidth(),
|
||||||
wxClientDC dc(const_cast<wxChoice*>(this));
|
lbHeight);
|
||||||
|
|
||||||
// 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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_CHOICE
|
#endif // wxUSE_CHOICE
|
||||||
|
Reference in New Issue
Block a user