wxTE_MULTILINE flag breaks wxTextCtrl font scaling

102 Views Asked by At

I'm building an app using wxWidgets. I have a wxTextCtrl created like so:

Expression = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 
    wxTE_READONLY | wxNO_BORDER | wxTE_RIGHT );
Expression->SetForegroundColour(wxColour(55, 55, 55));
Expression->Bind(wxEVT_TEXT, [this](wxCommandEvent& evt) { Expression_Update(); evt.Skip(); });
Expression->Bind(wxEVT_SIZE, [this](wxSizeEvent& evt) { Expression_Update(); evt.Skip(); });
sizer->Add(Expression, 10, wxEXPAND);

It is bind to an Expression_Update() function which is supposed to scale its font correctly.

void Main::Expression_Update()
{
    wxString text = Expression->GetValue();
    const int MaxWidth = GetSize().GetWidth();

    int X, Y = Expression->GetSize().GetHeight();

    wxFont* font = new wxFont(
        wxSize(wxSize(0, Y / 1.3)),
        wxFONTFAMILY_SWISS,
        wxFONTSTYLE_NORMAL,
        wxFONTWEIGHT_BOLD,
        false,
        "Calibri"
    );

    Expression->GetTextExtent(text, &X, nullptr, NULL, NULL, font);

    if ((X + EXP_ANTI_CLIPPING_COEF) > MaxWidth)
    {
        do
        {
            int const fontHeight = font->GetPixelSize().GetHeight();
            font->SetPixelSize(wxSize(0, fontHeight - 2));
            Expression->GetTextExtent(text, &X, nullptr, NULL, NULL, font);
        } while ((X + EXP_ANTI_CLIPPING_COEF) > MaxWidth);
    }

    Expression->SetFont(*font);
    delete font;
}

This code works perfectly fine. However, if I add the wxTE_MULTILINE flag to the constructor:

Expression = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 
    wxTE_READONLY | wxNO_BORDER | wxTE_RIGHT | wxTE_MULTILINE );

...when I resize the window, the wxTextCtrl grows larger and larger until it fills up the entire frame. I did some debugging myself, and I figured out the problem:

int X, Y = Expression->GetSize().GetHeight();

Without the wxTE_MULTILINE flag, Y has a starting value of 88 and changes correctly based on the control's height when I resize. But with the multiline flag set, Y starts with 88, and when I resize the window, regardless if the window height increased or not, the value changes to 164, and when I resize again, to 308, and so on.

TLDR: The GetSize().GetHeight() method returns an incorrect height value that causes the font to grow larger and larger until the text control fills up the entire window.

0

There are 0 best solutions below