Show full text in single line MSW wxTextCtrl if possible

A single line MSW wxTextCtrl created with a value too long to fit into
it continued showing the value only partially even if its size was
subsequently increased to allow the entire value to be shown.

This apparently happens because changing the native EDIT control size
doesn't affect its (horizontal) scroll offset. Moreover, there doesn't
seem to be any way to explicitly tell the control to update it neither,
except for changing its text.

So do change its text every time its width changes, as long as it is not
visible (because visible jumps in the visible text position could be an
even worse problem than the one we're trying to solve here). This fixes
the originally reported bug at the cost of a bunch of extra calls to
DoWriteText() which should hopefully be not too expensive for single
line controls that don't typically contain that much text.

Closes #18268.
This commit is contained in:
Vadim Zeitlin 2021-01-29 01:33:13 +01:00
parent 247bb98d07
commit 0d04792116
2 changed files with 26 additions and 0 deletions

View File

@ -241,6 +241,8 @@ protected:
virtual wxSize DoGetBestSize() const wxOVERRIDE;
virtual wxSize DoGetSizeFromTextSize(int xlen, int ylen = -1) const wxOVERRIDE;
virtual void DoMoveWindow(int x, int y, int width, int height) wxOVERRIDE;
#if wxUSE_RICHEDIT
virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI) wxOVERRIDE;

View File

@ -2639,6 +2639,30 @@ wxSize wxTextCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const
return wxSize(wText, hText);
}
void wxTextCtrl::DoMoveWindow(int x, int y, int width, int height)
{
// We reset the text of single line controls each time their width changes
// because they don't adjust their horizontal offset on their own and there
// doesn't seem to be any way to convince them to do it other than by just
// setting the text again, see #18268.
const bool resetText = IsSingleLine() && !IsShownOnScreen();
int oldWidth = -1;
if ( resetText )
{
oldWidth = GetSize().x;
}
wxTextCtrlBase::DoMoveWindow(x, y, width, height);
if ( resetText && GetSize().x != oldWidth )
{
// We need to use DoWriteText() to avoid our own optimization in
// ChangeValue() which does nothing when the text doesn't really
// change.
DoWriteText(DoGetValue(), 0 /* no flags for no events */);
}
}
// ----------------------------------------------------------------------------
// standard handlers for standard edit menu events
// ----------------------------------------------------------------------------