diff --git a/samples/treectrl/treetest.cpp b/samples/treectrl/treetest.cpp index d75bc7dd2f..1adf9954c8 100644 --- a/samples/treectrl/treetest.cpp +++ b/samples/treectrl/treetest.cpp @@ -291,7 +291,7 @@ MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h) tree_menu->Append(TreeTest_DecSpacing, "Reduce spacing by 5 points\tCtrl-R"); item_menu->Append(TreeTest_Dump, "&Dump item children"); - item_menu->Append(TreeTest_Rename, "&Rename item..."); + item_menu->Append(TreeTest_Rename, "&Rename item...\tF2"); item_menu->AppendSeparator(); item_menu->Append(TreeTest_SetBold, "Make item &bold"); diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index da0e87c99f..67c53f0aa3 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -100,9 +100,10 @@ public: protected: void OnChar( wxKeyEvent &event ); - void OnKeyUp( wxKeyEvent &event ); void OnKillFocus( wxFocusEvent &event ); + void IncreaseSizeForText( const wxString& text ); + bool AcceptChanges(); void Finish( bool setfocus ); @@ -417,7 +418,6 @@ void wxTreeRenameTimer::Notify() wxBEGIN_EVENT_TABLE(wxTreeTextCtrl,wxTextCtrl) EVT_CHAR (wxTreeTextCtrl::OnChar) - EVT_KEY_UP (wxTreeTextCtrl::OnKeyUp) EVT_KILL_FOCUS (wxTreeTextCtrl::OnKillFocus) wxEND_EVENT_TABLE() @@ -428,6 +428,11 @@ wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner, m_owner = owner; m_aboutToFinish = false; + // Create the text hidden to show it with the correct size -- which we + // can't determine before creating it. + Hide(); + Create(m_owner, wxID_ANY, m_startValue); + wxRect rect; m_owner->GetBoundingRect(m_itemEdited, rect, true); @@ -438,15 +443,27 @@ wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner, rect.x -= 5; #endif // platforms - (void)Create(m_owner, wxID_ANY, m_startValue, - rect.GetPosition(), rect.GetSize()); + const wxSize textSize = rect.GetSize(); + wxSize fullSize = GetSizeFromTextSize(textSize); + if ( fullSize.y > textSize.y ) + { + // It's ok to extend the rect to the right horizontally, which happens + // when we just change its size without changing its position below, + // but when extending it vertically, we need to keep it centered. + rect.y -= (fullSize.y - textSize.y + 1) / 2; + } + + // Also check that the control fits into the parent window. + const int totalWidth = m_owner->GetClientSize().x; + if ( rect.x + fullSize.x > totalWidth ) + { + fullSize.x = totalWidth - rect.x; + } + + rect.SetSize(fullSize); - int w; - GetTextExtent(m_startValue, &w, nullptr); - const wxSize size(GetSizeFromTextSize(w)); - rect.y += (rect.height - size.y) / 2; - rect.SetSize(size); SetSize(rect); + Show(); SelectAll(); } @@ -536,28 +553,38 @@ void wxTreeTextCtrl::OnChar( wxKeyEvent &event ) break; default: + if ( !m_aboutToFinish ) + { + wxChar ch = event.GetUnicodeKey(); + if ( ch != WXK_NONE ) + { + wxString value = GetValue(); + + long from, to; + GetSelection( &from, &to ); + if ( from != to ) + { + value.Remove( from, to - from ); + } + + IncreaseSizeForText( value + ch ); + } + } event.Skip(); } } -void wxTreeTextCtrl::OnKeyUp( wxKeyEvent &event ) +void wxTreeTextCtrl::IncreaseSizeForText( const wxString& text ) { - if ( !m_aboutToFinish ) - { - // auto-grow the textctrl: - wxSize parentSize = m_owner->GetSize(); - wxPoint myPos = GetPosition(); - wxSize mySize = GetSize(); - int sx, sy; - GetTextExtent(GetValue() + wxT("M"), &sx, &sy); - if (myPos.x + sx > parentSize.x) - sx = parentSize.x - myPos.x; - if (mySize.x > sx) - sx = mySize.x; + // auto-grow the textctrl: + wxSize parentSize = m_owner->GetClientSize(); + wxPoint myPos = GetPosition(); + wxSize mySize = GetSize(); + int sx = GetSizeFromText(text).x; + if (myPos.x + sx > parentSize.x) + sx = parentSize.x - myPos.x; + if (sx > mySize.x) SetSize(sx, wxDefaultCoord); - } - - event.Skip(); } void wxTreeTextCtrl::OnKillFocus( wxFocusEvent &event ) diff --git a/src/gtk/control.cpp b/src/gtk/control.cpp index f0cb37aac2..0006ed0b66 100644 --- a/src/gtk/control.cpp +++ b/src/gtk/control.cpp @@ -373,6 +373,13 @@ wxSize wxControl::GTKGetEntryMargins(GtkEntry* entry) const GtkStyleContext* sc = gtk_widget_get_style_context(GTK_WIDGET(entry)); gtk_style_context_get_padding(sc, gtk_style_context_get_state(sc), &border); #else + if (gtk_entry_get_has_frame(entry)) + { + GtkStyle* style = GTK_WIDGET(entry)->style; + size.x += 2 * style->xthickness; + size.y += 2 * style->ythickness; + } + // Equivalent to the GTK2 private function _gtk_entry_effective_inner_border() GtkBorder border = { 2, 2, 2, 2 }; diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index ea97ffe52b..f65cfd6216 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -2133,14 +2133,13 @@ wxSize wxTextCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const { wxASSERT_MSG( m_widget, wxS("GetSizeFromTextSize called before creation") ); - wxSize tsize(xlen, 0); int cHeight = GetCharHeight(); + wxSize tsize(xlen, cHeight); if ( IsSingleLine() ) { if ( HasFlag(wxBORDER_NONE) ) { - tsize.y = cHeight; #ifdef __WXGTK3__ tsize.IncBy(9, 0); #else @@ -2151,10 +2150,16 @@ wxSize wxTextCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const { // 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); +#ifdef __WXGTK3__ + // Add the margins we have previously set. + tsize.IncBy( GTKGetEntryMargins(GetEntry()) ); +#else + // For GTK 2 these margins are too big, so hard code something more + // reasonable, this is not great but should be fine considering + // that it's very unlikely that GTK 2 is going to evolve, making + // this inappropriate. + tsize.IncBy(20, 0); +#endif } } @@ -2166,7 +2171,6 @@ wxSize wxTextCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const tsize.IncBy(GTKGetPreferredSize(GTK_WIDGET(m_scrollBar[1])).x + 3, 0); // height - tsize.y = cHeight; if ( ylen <= 0 ) { tsize.y = 1 + cHeight * wxMax(wxMin(GetNumberOfLines(), 10), 2); @@ -2182,10 +2186,9 @@ wxSize wxTextCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const } } - // Perhaps the user wants something different from CharHeight, or ylen - // is used as the height of a multiline text. - if ( ylen > 0 ) - tsize.IncBy(0, ylen - cHeight); + // We should always use at least the specified height if it's valid. + if ( ylen > tsize.y ) + tsize.y = ylen; return tsize; } diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 2adda7d929..6f15bb6284 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -2555,10 +2555,9 @@ wxSize wxTextCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const 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(); + // We should always use at least the specified height if it's valid. + if ( ylen > hText ) + hText = ylen; return wxSize(wText, hText); }