Improve size and handling of in-place editor in wxGenericTreeCtrl
Squash merge the changes from master with some additional tweaks to preserve ABI-compatibility and allow building with wxUSE_UNICODE==0 in this branch. See #23001, #23205. (cherry picked from commit 3e571ef2535ebaf3fe4ebb5f04fd05708be0458a)
This commit is contained in:
parent
94997a44d6
commit
087f0c7742
@ -272,6 +272,7 @@ wxGTK:
|
||||
- Fix display artefacts when using AUI without compositor under X11 (#23135).
|
||||
- Allow selecting and copying text in wxMessageDialog (Ian McInerney, #23039).
|
||||
- Fix initial size of top-level window on Wayland (#23041).
|
||||
- Improve size and behaviour of in-place editor in wxTreeCtrl (taler21, #23001).
|
||||
|
||||
wxMSW:
|
||||
|
||||
|
@ -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");
|
||||
|
@ -103,6 +103,8 @@ protected:
|
||||
void OnKeyUp( wxKeyEvent &event );
|
||||
void OnKillFocus( wxFocusEvent &event );
|
||||
|
||||
void IncreaseSizeForText( const wxString& text );
|
||||
|
||||
bool AcceptChanges();
|
||||
void Finish( bool setfocus );
|
||||
|
||||
@ -428,6 +430,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);
|
||||
|
||||
@ -442,8 +449,27 @@ wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner,
|
||||
rect.height += 4;
|
||||
#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);
|
||||
|
||||
SetSize(rect);
|
||||
Show();
|
||||
|
||||
SelectAll();
|
||||
}
|
||||
@ -533,30 +559,57 @@ void wxTreeTextCtrl::OnChar( wxKeyEvent &event )
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( !m_aboutToFinish )
|
||||
{
|
||||
#if wxUSE_UNICODE
|
||||
wxChar ch = event.GetUnicodeKey();
|
||||
#else
|
||||
wxChar ch = event.m_keyCode < 256 &&
|
||||
event.m_keyCode >= 0 &&
|
||||
wxIsprint(event.m_keyCode)
|
||||
? (wxChar)event.m_keyCode
|
||||
: WXK_NONE;
|
||||
#endif
|
||||
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 )
|
||||
{
|
||||
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;
|
||||
SetSize(sx, wxDefaultCoord);
|
||||
}
|
||||
|
||||
// This function is only preserved in 3.2 branch to avoid warnings from the
|
||||
// ABI compatibility checked, as this class (wrongly) uses public visibility
|
||||
// there, even though it's not public at all -- and so we can't remove any
|
||||
// of its functions, even if they're not needed any longer.
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void wxTreeTextCtrl::IncreaseSizeForText( const wxString& text )
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
void wxTreeTextCtrl::OnKillFocus( wxFocusEvent &event )
|
||||
{
|
||||
if ( !m_aboutToFinish )
|
||||
|
@ -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 };
|
||||
|
@ -2156,14 +2156,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
|
||||
@ -2174,10 +2173,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
|
||||
}
|
||||
}
|
||||
|
||||
@ -2189,7 +2194,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);
|
||||
@ -2205,10 +2209,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;
|
||||
}
|
||||
|
@ -2801,10 +2801,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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user