Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TextCtrl changes size in Design window when a border or alignment is set. #536

Open
reticulatus opened this issue Dec 5, 2023 · 17 comments
Assignees
Labels
bug Something isn't working wxWidgets upstream change required
Milestone

Comments

@reticulatus
Copy link

reticulatus commented Dec 5, 2023

OS: Linux Mint 21.2
wxPython: wxPython 4.2.1 gtk3 (phoenix) wxWidgets 3.2.2.1
Python: 3.10.12
wxGlade: 1.0.5 and 1.1.0a2

If I add a TextCtrl to a BoxSizer or a FlexGridSizer and then check one of the Border options or one of the Alignment options (excluding wxEXPAND) in the TextCtrl's Layout tab, the TextCtrl increases in size in the Design window. If I save the .wxg file and then re-open it, the size of the TextCtrl reverts to its original default size.

Simple example:

  • Start wxGlade.
  • Add a Frame.
  • Add a TextCtrl to the BoxSizer's SLOT 0.
  • In the TextCtrl's Common tab, its Size is showing as 89,28 (on my system).
  • In the TextCtrl's Layout tab, do not change the Proportion setting or check the wxEXPAND option, but check one of the Border options.
  • The size of the TextCtrl in the Design window increases.
  • In the TextCtrl's Common tab, its Size is now showing as 93,40.
  • If I keep clicking the Border SpinCtrl's '+' button, the height of the TextCtrl keeps increasing until the setting reaches 5, after which it doesn't increase any further.
  • Do not check the Size option, but save the project to a .wxg file.
  • Re-open the .wxg file.
  • The TextCtrl has reverted to its original default size in the Design window and in the Size setting in its Common tab.

If I repeat the above steps but check wxALIGN_RIGHT instead of checking one of the Border options, then the TextCtrl's size gets set to 93,49.

Unchecking the Border or Alignment option can cause the TextCtrl's height increase further.

I have also noticed that if I check the Size option of a TextCtrl and explicitly set it to a value such as 100,-1 then the size displayed in the Design window still increases, although it is still showing as 100,-1 in the Common tab.

Other composite controls that contain a TextCtrl, such as ComboBox, SpinCtrl and DatePickerCtrl do not display the same issue.

I first noticed this issue when I was placing TextCtrls in a FlexGridSizer and was trying to set all the controls in a row to wxALIGN_CENTER_VERTICAL to line them up in particular way. Because the TextCtrls kept changing size, I had to keep saving and loading the project to see if the controls were lined up correctly.

@DietmarSchwertberger
Copy link
Collaborator

On Windows I can see only a small increase in size.
Is the increase the same in the design and preview windows?

@reticulatus
Copy link
Author

The size in the preview window never changes, only the design window. That is one workaround that I have used, i.e. keep pressing F5 to refresh the preview window to see how the layout really looks. However, when working on a large design it becomes a bit clumsy when the design and preview windows keep obstructing each other.

@reticulatus
Copy link
Author

Screenshot at 2023-12-05 16-58-34

@DietmarSchwertberger
Copy link
Collaborator

OK, thanks, I will check in my Linux VM.

@DietmarSchwertberger DietmarSchwertberger self-assigned this Dec 5, 2023
@DietmarSchwertberger DietmarSchwertberger added the bug Something isn't working label Dec 5, 2023
@DietmarSchwertberger DietmarSchwertberger added this to the 1.1.0 milestone Dec 5, 2023
@DietmarSchwertberger
Copy link
Collaborator

I can see it on Linux with 4.2.1. It was OK with 4.1.x.
On Windows both versions are OK (only a small increase in width). I will try to find the cause.

@DietmarSchwertberger
Copy link
Collaborator

Between these releases there were some changes in the TextCtrl code for gtk. That makes it harder for me to debug. I prefer Windows problems...

@DietmarSchwertberger
Copy link
Collaborator

DietmarSchwertberger commented Dec 18, 2023

Building wxPython on Linux is still a nightmare.
Anyway, I could build it on one of my Ubuntu installations.
This should be fixed in the next wxPython release.

The root cause is this line in wxWidgets 3.2.1 [src/gtk/textctrl.cpp]:
tsize.IncBy( GTKGetEntryMargins(GetEntry()) );

The relevant code in the wxWidgets versions:

wxWidgets 3.1.0

 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() )
    {
        if ( HasFlag(wxBORDER_NONE) ) {
            tsize.y = cHeight;
            tsize.IncBy(9, 0);
        } else {
            // 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 {  }

    // 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);

    return tsize;
}

wxWidgets 3.2.1:

 wxSize wxTextCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const
{
    wxASSERT_MSG( m_widget, wxS("GetSizeFromTextSize called before creation") );

    int cHeight = GetCharHeight();
    wxSize tsize(xlen, cHeight);

    if ( IsSingleLine() ) {
        if ( HasFlag(wxBORDER_NONE) ) {
            tsize.IncBy(9, 0);
        } else {
            // default height
            tsize.y = GTKGetPreferredSize(m_widget).y;
            // Add the margins we have previously set.
            tsize.IncBy( GTKGetEntryMargins(GetEntry()) );
        }
    }
    //multiline
    else {  }

    // We should always use at least the specified height if it's valid.
    if ( ylen > tsize.y )  tsize.y = ylen;

    return tsize;
}

current

wxSize wxTextCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const
{
    wxASSERT_MSG( m_widget, wxS("GetSizeFromTextSize called before creation") );

    int cHeight = GetCharHeight();
    wxSize tsize(xlen, cHeight);

    if ( IsSingleLine() )
    {
        // Default height
        tsize.y = GTKGetPreferredSize(m_widget).y;
        // Add padding + border size
        tsize.x += GTKGetEntryMargins(GetEntry()).x;
    }
    //multiline
    else {  }

    // We should always use at least the specified height if it's valid.
    if ( ylen > tsize.y )  tsize.y = ylen;

    return tsize;
}

@DietmarSchwertberger
Copy link
Collaborator

DietmarSchwertberger commented Dec 18, 2023

I don't see how to call GTKGetEntryMargins or GTKGetPreferredSize from Python. So I can't replace this code with some Python code as workaround.

The only (untested) workaround I'm seeing is this one in edit_sizers/edit_sizers.py:

grafik

The comment is out of date, as wxGlade does now re-create TextCtrl on style change. Still, I would like to leave the SetSize() call there.

@DietmarSchwertberger DietmarSchwertberger added the wxWidgets upstream change required label Dec 18, 2023
@DietmarSchwertberger
Copy link
Collaborator

Could you please test this workaround whether it's working for you?
Then I would include it into rev. 1.1.

@reticulatus
Copy link
Author

reticulatus commented Dec 20, 2023

I edited edit_sizers.py as shown in the png of the diff you posted.

I then tested the following cases starting from a fresh design in each case:

  1. If I check the TextCtrl's wxRIGHT option, the TextCtrl no longer immediately changes size.
    However, if I then click the '+' button on the Border SpinCtrl, the TextCtrl's height does increase in the Design window.

  2. If I check the TextCtrl's wxALIGN_CENTER_HORIZONTAL it moves to the correct position and doesn't change size.
    However, if I then uncheck that option, the TextCtrl moves back to the left of the Frame and does increase in size.

  3. If I check the TextCtrl's Size option on its Common tab and set the size to 100,-1 then the TextCtrl's height jumps to a larger value, although the size setting still shows 100,-1.

It looks like the code change only prevents the resizing for the first action in setting a border or alignment. However, the resizing is still happening for the other changes.

@DietmarSchwertberger
Copy link
Collaborator

OK, next try. I have created a separate branch ISSUE_536 for this.
Please test. For me it seems to work.

@reticulatus
Copy link
Author

I have tested the code from the ISSUE_536 branch and the workaround is working for me also.

Thank you for investigating this problem and devising the workaround.

@DietmarSchwertberger
Copy link
Collaborator

When you open this .wxg file, can you navigate in the Design window using the arrow keys?
On my Linux installations I can navigate in the Tree window, but not in the Design window when something was opened or pasted.
The workaround is to call SetFocus on one of the widgets. I need to figure out the best way of doing this. After that I will prepare 1.1.0a3.

@reticulatus
Copy link
Author

When you open this .wxg file, can you navigate in the Design window using the arrow keys? On my Linux installations I can navigate in the Tree window, but not in the Design window when something was opened or pasted. The workaround is to call SetFocus on one of the widgets. I need to figure out the best way of doing this. After that I will prepare 1.1.0a3.

Which .wxg file do you mean?

@DietmarSchwertberger
Copy link
Collaborator

The one from your screenshot above. Frame -> Panel -> Sizer -> TextCtrl

@reticulatus
Copy link
Author

I get the same. The arrow keys navigate in the Tree window, but not in the Design window.

@DietmarSchwertberger
Copy link
Collaborator

OK. This is not critical, but anyway I will look for a solution.
One other thing I'm seeing sometimes is that wxGlade does not react to mouse clicks any more. Setting focus or resizing windows is still working and when I want to close the window I get the dialog about unsaved changes, but other than that I can't do anything. That's weird and it's difficult to debug...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working wxWidgets upstream change required
Projects
None yet
Development

No branches or pull requests

2 participants