Search code examples
c++windowsuser-interfacewxwidgets

elements on the panel are displayed incorrectly When changing panels


I am using WxWidgets 3.2 for my C++ Windows application. In my application I need to change the interface for the user when he clicks the buttons.

To change the interface, I use this idea: I show the desired panel using the Show() function and hide the rest of the panels using the Hide() function. Of course, I create the necessary panels in advance.

For example, here is the code for the main window of my application:

MainFrame.h
class MainFrame : public wxFrame {
public:
    MainFrame(const wxString& title);
    ~MainFrame();

private:
    LoginPanel * loginPanel;  // panel pointer 
    TablePanel * tablePanel;  // panel pointer

public:
    void ShowLoginPanel(); // function that displays the loginPanel
    void ShowTablePanel(); // function that displays the tablePanel
    void OnLoginEntered(wxCommandEvent& event); // to check the login
};

class implementation

MainFrame.cpp
MainFrameFrame::MainFrameFrame(const wxString& title)
    : wxFrame(nullptr, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE & ~wxRESIZE_BORDER) {
    wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);

    loginPanel = new LoginPanel(this, wxID_ANY);
    tablePanel = new TablePanel(this, wxID_ANY);
    mainSizer->Add(loginPanel, 1, wxEXPAND);
    mainSizer->Add(tablePanel, 1, wxEXPAND);
    SetSizer(mainSizer);

    ShowLoginPanel();
}

void MainFrame::OnLoginEntered(wxCommandEvent& event) {
    auto login = event.GetString();
    if (login == CORRECT)
       ShowTablePanel();
}
void MainFrame::ShowTablePanel() {
    if (loginPanel != nullptr)
        loginPanel->Hide();
    if (tablePanel != nullptr) {
        tablePanel->Show();
    }
}
void MainFrame::ShowLoginPanel() {
    if (tablePanel != nullptr) {
        tablePanel->Hide();
    }
    if (loginPanel != nullptr)
        loginPanel->Show();
}

In this code, if the user entered the correct login, then I show the tablePanel and hide the loginPanel.

Here is the LoginPanel class code :

LoginPanel.h
class LoginPanel : public wxPanel {
public:
    LoginPanel(wxWindow* parent, wxWindowID id = wxID_ANY);

private:
    wxTextCtrl* usernameInput;
};

LoginPanel.cpp
LoginPanel::LoginPanel(wxWindow* parent, wxWindowID id)
    : wxPanel(parent, id) {
    wxButton* connectButton = new wxButton(loginTab, wxID_ANY, "Connect");
    connectButton->Bind(wxEVT_BUTTON, &LoginPanel::OnConnectButton, this);
}

Here is the TablePanel class code :

TablePanel.h
class TablePanel : public wxPanel {
public:
    TablePanel(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
                     const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL, const wxString& name = wxPanelNameStr);

private:
    wxButton* backButton;
    wxGridSizer* tableGrid;

    wxPanel* CreateTableItemPanel(int tableNumber);
};

TablePanel.cpp
TablePanel::TablePanel(wxWindow* parent, wxWindowID id, const wxPoint& pos,
                     const wxSize& size, long style, const wxString& name)
        : wxPanel(parent, id, pos, size, style, name)
    {
        // Creating a back button
        backButton = new wxButton(this, wxID_ANY, "Back");

        // Create a grid of gaming tables
        tableGrid = new wxGridSizer(5, 4, 5, 5);

        // Adding multiple grid elements
        for (int i = 1; i <= 20; ++i) {
            wxPanel* tableItemPanel = CreateTableItemPanel(i);
            tableGrid->Add(tableItemPanel, 0, wxEXPAND | wxALL, 5);
        }

        // Placing elements on the gaming table selection panel
        wxBoxSizer* tableSelectSizer = new wxBoxSizer(wxVERTICAL);
        tableSelectSizer->Add(backButton, 0, wxALIGN_LEFT | wxALL, 5);
        tableSelectSizer->Add(tableGrid, 1, wxEXPAND | wxALL, 5);

        this->SetSizer(tableSelectSizer);
}


wxPanel* TableSelectPanel::CreateTableItemPanel(int tableNumber){
        wxPanel* itemPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE);

        wxBoxSizer* itemSizer = new wxBoxSizer(wxVERTICAL);

        // Create an image and add it to the grid
        wxBitmap bitmap; // Replace with real image
        wxStaticBitmap* bmpCtrl = new wxStaticBitmap(itemPanel, wxID_ANY, bitmap);
        itemSizer->Add(bmpCtrl, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);

        // Creating text with information about the table
        wxString tableInfo = wxString::Format("Стол %d", tableNumber);
        wxStaticText* infoText = new wxStaticText(itemPanel, wxID_ANY, tableInfo);
        itemSizer->Add(infoText, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);

        // Create a "Play" button and add it to the grid
        wxButton* playButton = new wxButton(itemPanel, wxID_ANY, "Play");
        itemSizer->Add(playButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);

        itemPanel->SetSizer(itemSizer);
        return itemPanel;
}

The problem is that when changing panels, all elements in the displayed panel are shifted to the upper left corner.

enter image description here

If you stretch the panel to full screen, then all the elements are displayed correctly again. Why do items in the rendered panel display incorrectly when changing panels? And how can I fix it?


Solution

  • You can, of course, implement this yourself, but what you describe seems an awful lot like wxSimplebook, so perhaps you could just use this class instead?