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).
|
- Fix display artefacts when using AUI without compositor under X11 (#23135).
|
||||||
- Allow selecting and copying text in wxMessageDialog (Ian McInerney, #23039).
|
- Allow selecting and copying text in wxMessageDialog (Ian McInerney, #23039).
|
||||||
- Fix initial size of top-level window on Wayland (#23041).
|
- Fix initial size of top-level window on Wayland (#23041).
|
||||||
|
- Improve size and behaviour of in-place editor in wxTreeCtrl (taler21, #23001).
|
||||||
|
|
||||||
wxMSW:
|
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");
|
tree_menu->Append(TreeTest_DecSpacing, "Reduce spacing by 5 points\tCtrl-R");
|
||||||
|
|
||||||
item_menu->Append(TreeTest_Dump, "&Dump item children");
|
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->AppendSeparator();
|
||||||
item_menu->Append(TreeTest_SetBold, "Make item &bold");
|
item_menu->Append(TreeTest_SetBold, "Make item &bold");
|
||||||
|
@ -103,6 +103,8 @@ protected:
|
|||||||
void OnKeyUp( wxKeyEvent &event );
|
void OnKeyUp( wxKeyEvent &event );
|
||||||
void OnKillFocus( wxFocusEvent &event );
|
void OnKillFocus( wxFocusEvent &event );
|
||||||
|
|
||||||
|
void IncreaseSizeForText( const wxString& text );
|
||||||
|
|
||||||
bool AcceptChanges();
|
bool AcceptChanges();
|
||||||
void Finish( bool setfocus );
|
void Finish( bool setfocus );
|
||||||
|
|
||||||
@ -428,6 +430,11 @@ wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner,
|
|||||||
m_owner = owner;
|
m_owner = owner;
|
||||||
m_aboutToFinish = false;
|
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;
|
wxRect rect;
|
||||||
m_owner->GetBoundingRect(m_itemEdited, rect, true);
|
m_owner->GetBoundingRect(m_itemEdited, rect, true);
|
||||||
|
|
||||||
@ -442,8 +449,27 @@ wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner,
|
|||||||
rect.height += 4;
|
rect.height += 4;
|
||||||
#endif // platforms
|
#endif // platforms
|
||||||
|
|
||||||
(void)Create(m_owner, wxID_ANY, m_startValue,
|
const wxSize textSize = rect.GetSize();
|
||||||
rect.GetPosition(), 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();
|
SelectAll();
|
||||||
}
|
}
|
||||||
@ -533,30 +559,57 @@ void wxTreeTextCtrl::OnChar( wxKeyEvent &event )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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();
|
event.Skip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxTreeTextCtrl::OnKeyUp( wxKeyEvent &event )
|
void wxTreeTextCtrl::OnKeyUp( wxKeyEvent &event )
|
||||||
{
|
{
|
||||||
if ( !m_aboutToFinish )
|
// This function is only preserved in 3.2 branch to avoid warnings from the
|
||||||
{
|
// ABI compatibility checked, as this class (wrongly) uses public visibility
|
||||||
// auto-grow the textctrl:
|
// there, even though it's not public at all -- and so we can't remove any
|
||||||
wxSize parentSize = m_owner->GetSize();
|
// of its functions, even if they're not needed any longer.
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
event.Skip();
|
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 )
|
void wxTreeTextCtrl::OnKillFocus( wxFocusEvent &event )
|
||||||
{
|
{
|
||||||
if ( !m_aboutToFinish )
|
if ( !m_aboutToFinish )
|
||||||
|
@ -373,6 +373,13 @@ wxSize wxControl::GTKGetEntryMargins(GtkEntry* entry) const
|
|||||||
GtkStyleContext* sc = gtk_widget_get_style_context(GTK_WIDGET(entry));
|
GtkStyleContext* sc = gtk_widget_get_style_context(GTK_WIDGET(entry));
|
||||||
gtk_style_context_get_padding(sc, gtk_style_context_get_state(sc), &border);
|
gtk_style_context_get_padding(sc, gtk_style_context_get_state(sc), &border);
|
||||||
#else
|
#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()
|
// Equivalent to the GTK2 private function _gtk_entry_effective_inner_border()
|
||||||
|
|
||||||
GtkBorder border = { 2, 2, 2, 2 };
|
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") );
|
wxASSERT_MSG( m_widget, wxS("GetSizeFromTextSize called before creation") );
|
||||||
|
|
||||||
wxSize tsize(xlen, 0);
|
|
||||||
int cHeight = GetCharHeight();
|
int cHeight = GetCharHeight();
|
||||||
|
wxSize tsize(xlen, cHeight);
|
||||||
|
|
||||||
if ( IsSingleLine() )
|
if ( IsSingleLine() )
|
||||||
{
|
{
|
||||||
if ( HasFlag(wxBORDER_NONE) )
|
if ( HasFlag(wxBORDER_NONE) )
|
||||||
{
|
{
|
||||||
tsize.y = cHeight;
|
|
||||||
#ifdef __WXGTK3__
|
#ifdef __WXGTK3__
|
||||||
tsize.IncBy(9, 0);
|
tsize.IncBy(9, 0);
|
||||||
#else
|
#else
|
||||||
@ -2174,10 +2173,16 @@ wxSize wxTextCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const
|
|||||||
{
|
{
|
||||||
// default height
|
// default height
|
||||||
tsize.y = GTKGetPreferredSize(m_widget).y;
|
tsize.y = GTKGetPreferredSize(m_widget).y;
|
||||||
// Add the margins we have previously set, but only the horizontal border
|
#ifdef __WXGTK3__
|
||||||
// as vertical one has been taken account at GTKGetPreferredSize().
|
// Add the margins we have previously set.
|
||||||
// Also get other GTK+ margins.
|
tsize.IncBy( GTKGetEntryMargins(GetEntry()) );
|
||||||
tsize.IncBy( GTKGetEntryMargins(GetEntry()).x, 0);
|
#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);
|
tsize.IncBy(GTKGetPreferredSize(GTK_WIDGET(m_scrollBar[1])).x + 3, 0);
|
||||||
|
|
||||||
// height
|
// height
|
||||||
tsize.y = cHeight;
|
|
||||||
if ( ylen <= 0 )
|
if ( ylen <= 0 )
|
||||||
{
|
{
|
||||||
tsize.y = 1 + cHeight * wxMax(wxMin(GetNumberOfLines(), 10), 2);
|
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
|
// We should always use at least the specified height if it's valid.
|
||||||
// is used as the height of a multiline text.
|
if ( ylen > tsize.y )
|
||||||
if ( ylen > 0 )
|
tsize.y = ylen;
|
||||||
tsize.IncBy(0, ylen - cHeight);
|
|
||||||
|
|
||||||
return tsize;
|
return tsize;
|
||||||
}
|
}
|
||||||
|
@ -2801,10 +2801,9 @@ wxSize wxTextCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const
|
|||||||
hText += EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy) - cy;
|
hText += EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy) - cy;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perhaps the user wants something different from CharHeight, or ylen
|
// We should always use at least the specified height if it's valid.
|
||||||
// is used as the height of a multiline text.
|
if ( ylen > hText )
|
||||||
if ( ylen > 0 )
|
hText = ylen;
|
||||||
hText += ylen - GetCharHeight();
|
|
||||||
|
|
||||||
return wxSize(wText, hText);
|
return wxSize(wText, hText);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user