Add wxControl::GetSizeFromTextSize() to size the control to its text.

This function can be used to size a, say, wxTextCtrl to be exactly of the size
needed to enter the given amount of text in it.

This patch adds wxGTK implementation for wxTextCtrl, wxChoice and wxCombobox;
changes to the samples and the documentation.

Closes #14812.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72935 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2012-11-09 21:11:37 +00:00
parent c017416682
commit 7a78a93782
15 changed files with 269 additions and 62 deletions

View File

@ -582,6 +582,7 @@ All (GUI):
- Implement clipping for wxSVGFileDC (Steve Benbow).
- Added wxDirCtrl::GetPath() (troelsk).
- Added wxEVT_COMMAND_DIRCTRL_CHANGED event (troelsk).
- Added wxControl::GetSizeFromTextSize() (Manuel Martin).
wxGTK:

View File

@ -134,6 +134,10 @@ public:
// wxControl-specific processing after processing the update event
virtual void DoUpdateWindowUI(wxUpdateUIEvent& event);
wxSize GetSizeFromTextSize(int xlen, int ylen = -1) const
{ return DoGetSizeFromTextSize(xlen, ylen); }
wxSize GetSizeFromTextSize(const wxSize& tsize) const
{ return DoGetSizeFromTextSize(tsize.x, tsize.y); }
// static utilities for mnemonics char (&) handling
@ -192,6 +196,8 @@ protected:
virtual bool DoSetLabelMarkup(const wxString& markup);
#endif // wxUSE_MARKUP
// override this to return the total control's size from a string size
virtual wxSize DoGetSizeFromTextSize(int xlen, int ylen = -1) const;
// initialize the common fields of wxCommandEvent
void InitCommandEvent(wxCommandEvent& event) const;

View File

@ -95,6 +95,7 @@ protected:
int m_stringCellIndex;
virtual wxSize DoGetBestSize() const;
virtual wxSize DoGetSizeFromTextSize(int xlen, int ylen = -1) const;
virtual int DoInsertItems(const wxArrayStringsAdapter& items,
unsigned int pos,
void **clientData, wxClientDataType type);

View File

@ -145,6 +145,8 @@ protected:
// custom list stores.
virtual void GTKCreateComboBoxWidget();
virtual wxSize DoGetSizeFromTextSize(int xlen, int ylen = -1) const;
virtual GtkEntry *GetEntry() const
{ return m_entry; }

View File

@ -12,6 +12,7 @@
typedef struct _GtkLabel GtkLabel;
typedef struct _GtkFrame GtkFrame;
typedef struct _GtkEntry GtkEntry;
//-----------------------------------------------------------------------------
// wxControl
@ -100,6 +101,12 @@ protected:
// Fix sensitivity due to bug in GTK+ < 2.14
void GTKFixSensitivity(bool onlyIfUnderMouse = true);
// Ask GTK+ for preferred size. Use it after setting the font.
wxSize GTKGetPreferredSize(GtkWidget* widget) const;
// Inner margins in a GtkEntry
wxPoint GTKGetEntryMargins(GtkEntry* entry) const;
private:
DECLARE_DYNAMIC_CLASS(wxControl)
};

View File

@ -155,6 +155,8 @@ protected:
virtual void DoApplyWidgetStyle(GtkRcStyle *style);
virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
virtual wxSize DoGetSizeFromTextSize(int xlen, int ylen = -1) const;
virtual void DoFreeze();
virtual void DoThaw();

View File

@ -152,6 +152,47 @@ public:
*/
wxString GetLabelText() const;
/**
Determine the size needed by the control to leave the given area for
its text.
This function is mostly useful with control displaying short amounts of
text that can be edited by the user, e.g. wxTextCtrl, wxComboBox,
wxSearchCtrl etc. Typically it is used to size these controls for the
maximal amount of input they are supposed to contain, for example:
@code
// Create a control for post code entry.
wxTextCtrl* postcode = new wxTextCtrl(this, ...);
// And set its initial and minimal size to be big enough for
// entering 5 digits.
postcode->SetInitialSize(
postcode->GetSizeFromTextSize(
postcode->GetTextExtent("99999")));
@endcode
Currently this method is only implemented for wxTextCtrl, wxComboBox
and wxChoice in wxGTK.
@param xlen The horizontal extent of the area to leave for text, in
pixels.
@param ylen The vertical extent of the area to leave for text, in
pixels. By default -1 meaning that the vertical component of the
returned size should be the default height of this control.
@return The size that the control should have to leave the area of the
specified size for its text. May return wxDefaultSize if this
method is not implemented for this particular control under the
current platform.
@since 2.9.5
*/
wxSize GetSizeFromTextSize(int xlen, int ylen = -1) const;
/**
@overload
*/
wxSize GetSizeFromTextSize(const wxSize& tsize) const;
/**
Sets the control's label.

View File

@ -981,7 +981,8 @@ void MyFrame::OnShowComparison( wxCommandEvent& WXUNUSED(event) )
groupSizer = new wxStaticBoxSizer(new wxStaticBox(dlg,wxID_ANY,wxT(" wxOwnerDrawnComboBox ")),
wxVERTICAL);
groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Writable, sorted:")), 0,
groupSizer->Add( new wxStaticText(dlg, wxID_ANY,
wxT("Writable, with margins, sorted:")), 0,
wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, border );
odc = new wxOwnerDrawnComboBox(dlg,wxID_ANY,wxEmptyString,
@ -993,12 +994,14 @@ void MyFrame::OnShowComparison( wxCommandEvent& WXUNUSED(event) )
odc->Append(wxT("H - Appended Item")); // test sorting in append
odc->SetValue(wxT("Dot Dash"));
groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
odc->SetMargins(15, 10);
groupSizer->Add( odc, 0, wxALIGN_CENTER_VERTICAL|wxALL, border );
groupSizer->AddStretchSpacer();
//
// Readonly ODComboBox
groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Read-only:")), 0,
groupSizer->Add( new wxStaticText(dlg, wxID_ANY,
wxT("Read-only, big font:")), 0,
wxALIGN_CENTER_VERTICAL|wxRIGHT, border );
odc = new wxOwnerDrawnComboBox(dlg,wxID_ANY,wxEmptyString,
@ -1007,10 +1010,12 @@ void MyFrame::OnShowComparison( wxCommandEvent& WXUNUSED(event) )
wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY
);
odc->SetFont(odc->GetFont().Scale(1.5));
odc->SetValue(wxT("Dot Dash"));
odc->SetText(wxT("Dot Dash (Testing SetText)"));
groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
groupSizer->Add( odc, 0, wxALL, border );
groupSizer->AddStretchSpacer();
//
// Disabled ODComboBox
@ -1026,7 +1031,7 @@ void MyFrame::OnShowComparison( wxCommandEvent& WXUNUSED(event) )
odc->SetValue(wxT("Dot Dash"));
odc->Enable(false);
groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
groupSizer->Add( odc, 3, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
rowSizer->Add( groupSizer, 1, wxEXPAND|wxALL, border );
@ -1037,7 +1042,8 @@ void MyFrame::OnShowComparison( wxCommandEvent& WXUNUSED(event) )
//
// wxComboBox
//
groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Writable, sorted:")), 0,
groupSizer->Add( new wxStaticText(dlg,wxID_ANY,
wxT("Writable, with margins, sorted:")), 0,
wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, border );
cb = new wxComboBox(dlg,wxID_ANY,wxEmptyString,
@ -1049,12 +1055,14 @@ void MyFrame::OnShowComparison( wxCommandEvent& WXUNUSED(event) )
cb->Append(wxT("H - Appended Item")); // test sorting in append
cb->SetValue(wxT("Dot Dash"));
groupSizer->Add( cb, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
cb->SetMargins(15, 10);
groupSizer->Add( cb, 0, wxALIGN_CENTER_VERTICAL|wxALL, border );
groupSizer->AddStretchSpacer();
//
// Readonly wxComboBox
groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Read-only:")), 0,
groupSizer->Add( new wxStaticText(dlg, wxID_ANY,
wxT("Read-only, big font:")), 0,
wxALIGN_CENTER_VERTICAL|wxRIGHT, border );
cb = new wxComboBox(dlg,wxID_ANY,wxEmptyString,
@ -1063,9 +1071,11 @@ void MyFrame::OnShowComparison( wxCommandEvent& WXUNUSED(event) )
wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY
);
cb->SetFont(cb->GetFont().Scale(1.5));
cb->SetValue(wxT("Dot Dash"));
groupSizer->Add( cb, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
groupSizer->Add( cb, 0, wxALL, border );
groupSizer->AddStretchSpacer();
//
// Disabled wxComboBox
@ -1081,11 +1091,11 @@ void MyFrame::OnShowComparison( wxCommandEvent& WXUNUSED(event) )
cb->SetValue(wxT("Dot Dash"));
cb->Enable(false);
groupSizer->Add( cb, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
groupSizer->Add( cb, 3, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
rowSizer->Add( groupSizer, 1, wxEXPAND|wxALL, border );
colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, border );
colSizer->Add( rowSizer, 1, wxEXPAND|wxALL, border );
dlg->SetSizer( colSizer );
colSizer->SetSizeHints( dlg );

View File

@ -770,7 +770,7 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
// ------------------------------------------------------------------------
#if wxUSE_CHOICE
panel = new wxPanel(m_book);
m_choice = new MyChoice( panel, ID_CHOICE, wxPoint(10,10), wxSize(120,wxDefaultCoord), 5, choices );
m_choice = new MyChoice( panel, ID_CHOICE, wxPoint(10,10), wxDefaultSize, 5, choices );
m_choiceSorted = new MyChoice( panel, ID_CHOICE_SORTED, wxPoint(10,70), wxSize(120,wxDefaultCoord),
5, choices, wxCB_SORT );
@ -778,12 +778,12 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
SetChoiceClientData(wxT("choice"), m_choiceSorted);
m_choice->SetSelection(2);
(void)new wxButton( panel, ID_CHOICE_SEL_NUM, wxT("Select #&2"), wxPoint(180,30), wxSize(140,30) );
(void)new wxButton( panel, ID_CHOICE_SEL_STR, wxT("&Select 'This'"), wxPoint(340,30), wxSize(140,30) );
(void)new wxButton( panel, ID_CHOICE_CLEAR, wxT("&Clear"), wxPoint(180,80), wxSize(140,30) );
(void)new wxButton( panel, ID_CHOICE_APPEND, wxT("&Append 'Hi!'"), wxPoint(340,80), wxSize(140,30) );
(void)new wxButton( panel, ID_CHOICE_DELETE, wxT("D&elete selected item"), wxPoint(180,130), wxSize(140,30) );
(void)new wxButton( panel, ID_CHOICE_FONT, wxT("Set &Italic font"), wxPoint(340,130), wxSize(140,30) );
(void)new wxButton( panel, ID_CHOICE_SEL_NUM, wxT("Select #&2"), wxPoint(220,30), wxSize(140,30) );
(void)new wxButton( panel, ID_CHOICE_SEL_STR, wxT("&Select 'This'"), wxPoint(380,30), wxSize(140,30) );
(void)new wxButton( panel, ID_CHOICE_CLEAR, wxT("&Clear"), wxPoint(220,80), wxSize(140,30) );
(void)new wxButton( panel, ID_CHOICE_APPEND, wxT("&Append 'Hi!'"), wxPoint(380,80), wxSize(140,30) );
(void)new wxButton( panel, ID_CHOICE_DELETE, wxT("D&elete selected item"), wxPoint(220,130), wxSize(140,30) );
(void)new wxButton( panel, ID_CHOICE_FONT, wxT("Set &Italic font"), wxPoint(380,130), wxSize(140,30) );
(void)new wxCheckBox( panel, ID_CHOICE_ENABLE, wxT("&Disable"), wxPoint(20,130), wxSize(140,30) );
m_book->AddPage(panel, wxT("wxChoice"), false, Image_Choice);
@ -793,20 +793,21 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
// combo page
// ------------------------------------------------------------------------
panel = new wxPanel(m_book);
(void)new wxStaticBox( panel, wxID_ANY, wxT("&Box around combobox"),
wxPoint(5, 5), wxSize(150, 100));
m_combo = new MyComboBox( panel, ID_COMBO, wxT("This"),
wxPoint(20,25), wxSize(120, wxDefaultCoord),
wxPoint(15,25), wxDefaultSize,
5, choices,
wxTE_PROCESS_ENTER);
wxSize combosize(m_combo->GetBestSize().x + 20, 100);
(void)new wxStaticBox( panel, wxID_ANY, wxT("&Box around combobox"),
wxPoint(5, 5), combosize);
(void)new wxButton( panel, ID_COMBO_SEL_NUM, wxT("Select #&2"), wxPoint(180,30), wxSize(140,30) );
(void)new wxButton( panel, ID_COMBO_SEL_STR, wxT("&Select 'This'"), wxPoint(340,30), wxSize(140,30) );
(void)new wxButton( panel, ID_COMBO_CLEAR, wxT("&Clear"), wxPoint(180,80), wxSize(140,30) );
(void)new wxButton( panel, ID_COMBO_APPEND, wxT("&Append 'Hi!'"), wxPoint(340,80), wxSize(140,30) );
(void)new wxButton( panel, ID_COMBO_DELETE, wxT("D&elete selected item"), wxPoint(180,130), wxSize(140,30) );
(void)new wxButton( panel, ID_COMBO_FONT, wxT("Set &Italic font"), wxPoint(340,130), wxSize(140,30) );
(void)new wxButton( panel, ID_COMBO_SET_TEXT, wxT("Set 'Hi!' at #2"), wxPoint(340,180), wxSize(140,30) );
(void)new wxButton( panel, ID_COMBO_SEL_NUM, wxT("Select #&2"), wxPoint(220,30), wxSize(140,30) );
(void)new wxButton( panel, ID_COMBO_SEL_STR, wxT("&Select 'This'"), wxPoint(380,30), wxSize(140,30) );
(void)new wxButton( panel, ID_COMBO_CLEAR, wxT("&Clear"), wxPoint(220,80), wxSize(140,30) );
(void)new wxButton( panel, ID_COMBO_APPEND, wxT("&Append 'Hi!'"), wxPoint(380,80), wxSize(140,30) );
(void)new wxButton( panel, ID_COMBO_DELETE, wxT("D&elete selected item"), wxPoint(220,130), wxSize(140,30) );
(void)new wxButton( panel, ID_COMBO_FONT, wxT("Set &Italic font"), wxPoint(380,130), wxSize(140,30) );
(void)new wxButton( panel, ID_COMBO_SET_TEXT, wxT("Set 'Hi!' at #2"), wxPoint(380,180), wxSize(140,30) );
(void)new wxCheckBox( panel, ID_COMBO_ENABLE, wxT("&Disable"), wxPoint(20,130), wxSize(140,30) );
m_book->AddPage(panel, wxT("wxComboBox"), false, Image_Combo);

View File

@ -1074,16 +1074,22 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
m_password = new MyTextCtrl( this, wxID_ANY, wxT(""),
wxPoint(10,50), wxSize(140,wxDefaultCoord), wxTE_PASSWORD );
m_readonly = new MyTextCtrl( this, wxID_ANY, wxT("Read only"),
wxPoint(10,90), wxSize(140,wxDefaultCoord), wxTE_READONLY );
m_limited = new MyTextCtrl(this, wxID_ANY, "",
wxPoint(10, 130), wxSize(140, wxDefaultCoord));
wxPoint(10, 90), wxDefaultSize);
m_limited->SetHint("Max 8 ch");
m_limited->SetMaxLength(8);
wxSize size2 = m_limited->GetSizeFromTextSize(m_limited->GetTextExtent("WWWWWWWW"));
m_limited->SetSizeHints(size2, size2);
// multi line text controls
wxString string3L("Read only\nMultiline\nFitted size");
m_readonly = new MyTextCtrl( this, wxID_ANY, string3L,
wxPoint(10, 120), wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY );
wxWindowDC dc(m_readonly);
size2 = m_readonly->GetSizeFromTextSize(dc.GetMultiLineTextExtent(string3L));
m_readonly->SetMinSize(size2);
m_horizontal = new MyTextCtrl( this, wxID_ANY, wxT("Multiline text control with a horizontal scrollbar.\n"),
wxPoint(10,170), wxSize(140,70), wxTE_MULTILINE | wxHSCROLL);
@ -1137,7 +1143,7 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
#endif
m_tab = new MyTextCtrl( this, 100, wxT("Multiline, allow <TAB> processing."),
wxPoint(180,90), wxSize(200,70), wxTE_MULTILINE | wxTE_PROCESS_TAB );
wxPoint(180,90), wxDefaultSize, wxTE_MULTILINE | wxTE_PROCESS_TAB );
m_tab->SetClientData((void *)wxT("tab"));
m_enter = new MyTextCtrl( this, 100, wxT("Multiline, allow <ENTER> processing."),
@ -1173,13 +1179,13 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
wxBoxSizer *column1 = new wxBoxSizer(wxVERTICAL);
column1->Add( m_text, 0, wxALL | wxEXPAND, 10 );
column1->Add( m_password, 0, wxALL | wxEXPAND, 10 );
column1->Add( m_readonly, 0, wxALL | wxEXPAND, 10 );
column1->Add( m_limited, 0, wxALL | wxEXPAND, 10 );
column1->Add( m_readonly, 0, wxALL, 10 );
column1->Add( m_limited, 0, wxALL, 10 );
column1->Add( m_horizontal, 1, wxALL | wxEXPAND, 10 );
wxBoxSizer *column2 = new wxBoxSizer(wxVERTICAL);
column2->Add( m_multitext, 1, wxALL | wxEXPAND, 10 );
column2->Add( m_tab, 1, wxALL | wxEXPAND, 10 );
column2->Add( m_tab, 0, wxALL | wxEXPAND, 10 );
column2->Add( m_enter, 1, wxALL | wxEXPAND, 10 );
wxBoxSizer *row1 = new wxBoxSizer(wxHORIZONTAL);

View File

@ -149,6 +149,12 @@ void wxControlBase::DoUpdateWindowUI(wxUpdateUIEvent& event)
#endif // wxUSE_RADIOBTN
}
wxSize wxControlBase::DoGetSizeFromTextSize(int WXUNUSED(xlen),
int WXUNUSED(ylen)) const
{
return wxSize(-1, -1);
}
/* static */
wxString wxControlBase::GetLabelText(const wxString& label)
{

View File

@ -348,8 +348,38 @@ wxSize wxChoice::DoGetBestSize() const
// 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);
return GetSizeFromTextSize(wxChoiceBase::DoGetBestSize().x);
}
wxSize wxChoice::DoGetSizeFromTextSize(int xlen, int ylen) const
{
wxASSERT_MSG( m_widget, wxS("GetSizeFromTextSize called before creation") );
// a GtkEntry for wxComboBox and a GtkCellView for wxChoice
GtkWidget* childPart = gtk_bin_get_child(GTK_BIN(m_widget));
// Set a as small as possible size for the control, so preferred sizes
// return "natural" sizes, not taking into account the previous ones (which
// seems to be GTK+3 behaviour)
gtk_widget_set_size_request(m_widget, 0, 0);
// We are interested in the difference of sizes between the whole contol
// and its child part. I.e. arrow, separators, etc.
GtkRequisition req;
gtk_widget_size_request(childPart, &req);
wxSize totalS = GTKGetPreferredSize(m_widget);
wxSize tsize(xlen + totalS.x - req.width, totalS.y);
// For a wxChoice, not for wxComboBox, add some margins
if ( !GTK_IS_ENTRY(childPart) )
tsize.IncBy(5, 0);
// Perhaps the user wants something different from CharHeight
if ( ylen > 0 )
tsize.IncBy(0, ylen - GetCharHeight());
return tsize;
}
void wxChoice::DoApplyWidgetStyle(GtkRcStyle *style)

View File

@ -404,4 +404,17 @@ void wxComboBox::Dismiss()
{
gtk_combo_box_popdown( GTK_COMBO_BOX(m_widget) );
}
wxSize wxComboBox::DoGetSizeFromTextSize(int xlen, int ylen) const
{
wxSize tsize( wxChoice::DoGetSizeFromTextSize(xlen, ylen) );
// Add the margins we have previously set, but only the horizontal border
// as vertical one has been taken account in the prevoius call.
// Also get other GTK+ margins.
tsize.IncBy( GTKGetEntryMargins(GetEntry()).x, 0);
return tsize;
}
#endif // wxUSE_COMBOBOX

View File

@ -86,24 +86,9 @@ wxSize wxControl::DoGetBestSize() const
}
else
{
GtkRequisition req;
#ifdef __WXGTK3__
if (gtk_widget_get_request_mode(m_widget) != GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
{
gtk_widget_get_preferred_height(m_widget, NULL, &req.height);
gtk_widget_get_preferred_width_for_height(m_widget, req.height, NULL, &req.width);
}
else
{
gtk_widget_get_preferred_width(m_widget, NULL, &req.width);
gtk_widget_get_preferred_height_for_width(m_widget, req.width, NULL, &req.height);
}
#else
GTK_WIDGET_GET_CLASS(m_widget)->size_request(m_widget, &req);
#endif
best.Set(req.width, req.height);
best = GTKGetPreferredSize(m_widget);
}
CacheBestSize(best);
return best;
}
@ -364,4 +349,58 @@ wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromAdj_t widget_new,
return attr;
}
// This is not the same as GetBestSize() because that size may have
// been recalculated and cached by us. We want GTK+ information.
wxSize wxControl::GTKGetPreferredSize(GtkWidget* widget) const
{
GtkRequisition req;
#ifdef __WXGTK3__
if (gtk_widget_get_request_mode(widget) != GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
{
gtk_widget_get_preferred_height(widget, NULL, &req.height);
gtk_widget_get_preferred_width_for_height(widget, req.height, NULL, &req.width);
}
else
{
gtk_widget_get_preferred_width(widget, NULL, &req.width);
gtk_widget_get_preferred_height_for_width(widget, req.width, NULL, &req.height);
}
#else
GTK_WIDGET_GET_CLASS(widget)->size_request(widget, &req);
#endif
return wxSize(req.width, req.height);
}
wxPoint wxControl::GTKGetEntryMargins(GtkEntry* entry) const
{
wxPoint marg(0, 0);
#ifndef __WXGTK3__
#if GTK_CHECK_VERSION(2,10,0)
// The margins we have previously set
const GtkBorder* border = gtk_entry_get_inner_border(entry);
if ( border )
{
marg.x = border->left + border->right;
marg.y = border->top + border->bottom;
}
#endif // GTK+ 2.10+
#else // GTK+ 3
// Gtk3 does not use inner border, but StyleContext and CSS
// TODO: implement it, starting with wxTextEntry::DoSetMargins()
#endif // GTK+ 2/3
int x, y;
gtk_entry_get_layout_offsets(entry, &x, &y);
// inner borders are included. Substract them so we can get other margins
x -= marg.x;
y -= marg.y;
marg.x += 2 * x + 2;
marg.y += 2 * y + 2;
return marg;
}
#endif // wxUSE_CONTROLS

View File

@ -1820,13 +1820,55 @@ void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
wxSize wxTextCtrl::DoGetBestSize() const
{
// FIXME should be different for multi-line controls...
wxSize ret( wxControl::DoGetBestSize() );
wxSize best(80, ret.y);
CacheBestSize(best);
return best;
return DoGetSizeFromTextSize(80);
}
wxSize wxTextCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const
{
wxASSERT_MSG( m_widget, wxS("GetSizeFromTextSize called before creation") );
wxSize tsize(xlen, 0);
int cHeight = GetCharHeight();
if ( IsSingleLine() )
{
// default height
tsize.y = GTKGetPreferredSize(m_widget).y;
// Add the margins we have previously set, but only the horizontal border
// as vertical one has been taken account at GTKGetPreferredSize().
// Also get other GTK+ margins.
tsize.IncBy( GTKGetEntryMargins(GetEntry()).x, 0);
}
//multiline
else
{
// add space for vertical scrollbar
if ( m_scrollBar[1] && !(m_windowStyle & wxTE_NO_VSCROLL) )
tsize.IncBy(GTKGetPreferredSize(GTK_WIDGET(m_scrollBar[1])).x + 3, 0);
// height
tsize.y = cHeight;
if ( ylen <= 0 )
{
tsize.y = cHeight * wxMax(wxMin(GetNumberOfLines(), 10), 2);
// add space for horizontal scrollbar
if ( m_scrollBar[0] && (m_windowStyle & wxHSCROLL) )
tsize.IncBy(0, GTKGetPreferredSize(GTK_WIDGET(m_scrollBar[0])).y + 3);
}
// hardcode borders, margins, etc
tsize.IncBy(5, 5);
}
// Perhaps the user wants something different from CharHeight
if ( ylen > 0 )
tsize.IncBy(0, ylen - cHeight);
return tsize;
}
// ----------------------------------------------------------------------------
// freeze/thaw
// ----------------------------------------------------------------------------