How to clear client area or replace sizers and controls on a panel

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
PaulUK
Earned a small fee
Earned a small fee
Posts: 22
Joined: Wed Nov 18, 2020 12:55 pm

How to clear client area or replace sizers and controls on a panel

Post by PaulUK » Thu Dec 24, 2020 9:30 am

I've been making some progress with my wxWidgets project and decided to go with a ribbon menu to choose from a number of independent calculator and simulation programs that would be shown in the main window frame. I have successfully been able to connect ribbon icons to event functions. It could equally be a toolbar by the way.

The problem I have now is how do I reset and place controls and sizers on the window when switching between programs in my app. Do I need a new panel for each independent calculator app, or does the panel need to be cleared and reset in some way.

I tried simply to create a new panel and sizers in an event function, but they get added to the original one created in the main frame definition. Any advice would be appreciated. Thank you.

User avatar
doublemax
Moderator
Moderator
Posts: 16208
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: How to clear client area or replace sizers and controls on a panel

Post by doublemax » Thu Dec 24, 2020 10:16 am

The easiest way would be to have a separate panel for each calculator/simulation, create them all at once when the program starts, and put them into a wxSimpleBook, so that only one is visible at a time.
I tried simply to create a new panel and sizers in an event function, but they get added to the original one created in the main frame definition.
That should also work, but without seeing code, it's hard to tell what you did wrong.
Use the source, Luke!

PaulUK
Earned a small fee
Earned a small fee
Posts: 22
Joined: Wed Nov 18, 2020 12:55 pm

Re: How to clear client area or replace sizers and controls on a panel

Post by PaulUK » Thu Apr 29, 2021 12:28 pm

Since the last posts I have been trying to get panels to be shown or to hidden whenever an icon/button is clicked on. These buttons are on a ribbon and I tested them to work fine so far with a message that pops up to confirm that I clicked on an icon. I can create a panel, give it a colour and add it to a sizer. From with the MainWindow I can hide or show the panel, this works fine. However, my problem now is that when I try to hide or show a panel from within a function that is activated by a ribbon button click, nothing seems to happen.

Is this problem because I am trying to show or hide the panel from outside the MainWindow function? If so is there a way to achieve what I want whenever an icon is clicked and a OnXXXButton event is called?

Here is the MainWindow.cpp file. The function "void MainWindow::OnMicrostripButton(wxRibbonButtonBarEvent& evt)" is where I'd like to hide the default panel and show a new one with its own controls. Near the bottom of MainWindow is where I was trying to show and hide the default panel by commenting out and uncommenting various lines. I hope that someone can help with this issue. Thank you.

The function "void MainWindow::OnCPWButton(wxRibbonButtonBarEvent& evt)" is a mess and doesn't do what I want either.

Code: Select all

#include "MainWindow.h"
#include <cmath>
#include "dish32.xpm"

// Static Event Table
wxBEGIN_EVENT_TABLE(MainWindow, wxFrame)
    EVT_TEXT_ENTER(wxID_ANY, MainWindow::OnRadiusEntered)
    // Ribbon menu buttons
    EVT_RIBBONBUTTONBAR_CLICKED(ID_MICROSTRIP, MainWindow::OnMicrostripButton)
    EVT_RIBBONBUTTONBAR_CLICKED(ID_CPW, MainWindow::OnCPWButton)
    EVT_RIBBONBUTTONBAR_CLICKED(ID_CPW_G, MainWindow::OnCPW_GButton)
    EVT_RIBBONBUTTONBAR_CLICKED(ID_STRIPLINE, MainWindow::OnStriplineButton)
    EVT_RIBBONBUTTONBAR_CLICKED(ID_COUPLED_STRIPLINE, MainWindow::OnCoupled_StriplineButton)



wxEND_EVENT_TABLE()

wxStaticText *EnterRadius;
wxTextCtrl *RadiusEntered;
wxStaticText *RadiusIs;
wxTextCtrl *AreaResult;
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
wxSizer* panelSizer = new wxBoxSizer(wxVERTICAL);

MainWindow::MainWindow(wxWindow *parent,
		wxWindowID id,
		const wxString& title,
		const wxPoint& pos,
		const wxSize& size,
		long style,
		const wxString& name)
	:wxFrame(parent, id, title, pos, wxSize(1024, 768), style, name)
{
    wxPanel *panel = new wxPanel(this, -1);
    panel->SetBackgroundColour(wxColor(000, 000, 000));



    // Set frame icon
    wxIcon frameicon(dish32_xpm);
    SetIcon(frameicon);

    // Ribbon
    ribbonBar = new wxRibbonBar(this, -1, wxDefaultPosition, wxDefaultSize, wxRIBBON_BAR_FLOW_HORIZONTAL
                                | wxRIBBON_BAR_SHOW_PAGE_LABELS
                                | wxRIBBON_BAR_SHOW_PANEL_EXT_BUTTONS
                                | wxRIBBON_BAR_SHOW_TOGGLE_BUTTON
                                );

    tlinesRibbonPage = new wxRibbonPage(ribbonBar, wxID_ANY, wxT("TLine Calculators"), wxNullBitmap);
    radomeRibbonPage = new wxRibbonPage(ribbonBar, wxID_ANY, wxT("Radome Analysis"), wxNullBitmap);
    hornsRibbonPage = new wxRibbonPage(ribbonBar, wxID_ANY, wxT("Horn Analysis"), wxNullBitmap);
    sinuousRibbonPage = new wxRibbonPage(ribbonBar, wxID_ANY, wxT("Sinuous & Spiral"), wxNullBitmap);
    reflectorsRibbonPage = new wxRibbonPage(ribbonBar, wxID_ANY, wxT("Reflector Analysis"), wxNullBitmap);


    planartlinesRibbonPanel = new wxRibbonPanel(tlinesRibbonPage, wxID_ANY, wxT("Planar TLines"), wxNullBitmap,
                                        wxDefaultPosition, wxDefaultSize,
                                        wxRIBBON_PANEL_NO_AUTO_MINIMISE);

    wgRibbonPanel = new wxRibbonPanel(tlinesRibbonPage, wxID_ANY, wxT("Waveguide"), wxNullBitmap,
                                        wxDefaultPosition, wxDefaultSize,
                                        wxRIBBON_PANEL_NO_AUTO_MINIMISE);

    coaxRibbonPanel = new wxRibbonPanel(tlinesRibbonPage, wxID_ANY, wxT("Coaxial"), wxNullBitmap,
                                        wxDefaultPosition, wxDefaultSize,
                                        wxRIBBON_PANEL_NO_AUTO_MINIMISE);

    radomeRibbonPanel = new wxRibbonPanel(radomeRibbonPage, wxID_ANY, wxT("Radome"), wxNullBitmap,
                                        wxDefaultPosition, wxDefaultSize,
                                        wxRIBBON_PANEL_NO_AUTO_MINIMISE);

    planartlinesRibbonButtonBar = new wxRibbonButtonBar(planartlinesRibbonPanel);
    wgRibbonButtonBar = new wxRibbonButtonBar(wgRibbonPanel);
    coaxRibbonButtonBar = new wxRibbonButtonBar(coaxRibbonPanel);
    radomeRibbonButtonBar = new wxRibbonButtonBar(radomeRibbonPanel);


    // Planar TLine Tools
    planartlinesRibbonButtonBar->AddButton(ID_MICROSTRIP, wxT("Microstrip"),
                                   wxArtProvider::GetBitmap(wxART_ADD_BOOKMARK, wxART_TOOLBAR, wxSize(32,32)));

    planartlinesRibbonButtonBar->AddButton(ID_CPW, wxT("CPW"),
                                   wxArtProvider::GetBitmap(wxART_ADD_BOOKMARK, wxART_TOOLBAR, wxSize(32,32)));

    planartlinesRibbonButtonBar->AddButton(ID_CPW_G, wxT("CPW-G"),
                                   wxArtProvider::GetBitmap(wxART_ADD_BOOKMARK, wxART_TOOLBAR, wxSize(32,32)));

    planartlinesRibbonButtonBar->AddButton(ID_STRIPLINE, wxT("Stripline"),
                                   wxArtProvider::GetBitmap(wxART_ADD_BOOKMARK, wxART_TOOLBAR, wxSize(32,32)));

    planartlinesRibbonButtonBar->AddButton(ID_COUPLED_STRIPLINE, wxT("Coupled Stripline"),
                                   wxArtProvider::GetBitmap(wxART_ADD_BOOKMARK, wxART_TOOLBAR, wxSize(32,32)));
    // Waveguide Tools
    wgRibbonButtonBar->AddButton(wxID_ANY, wxT("Rectangular Waveguide"),
                                   wxArtProvider::GetBitmap(wxART_QUESTION, wxART_TOOLBAR, wxSize(32,32)));

    wgRibbonButtonBar->AddButton(wxID_ANY, wxT("Circular Waveguide"),
                                   wxArtProvider::GetBitmap(wxART_QUESTION, wxART_TOOLBAR, wxSize(32,32)));

    wgRibbonButtonBar->AddButton(wxID_ANY, wxT("Double Ridge Waveguide"),
                                   wxArtProvider::GetBitmap(wxART_QUESTION, wxART_TOOLBAR, wxSize(32,32)));

    wgRibbonButtonBar->AddButton(wxID_ANY, wxT("Waveguide Modes"),
                                   wxArtProvider::GetBitmap(wxART_QUESTION, wxART_TOOLBAR, wxSize(32,32)));

    wgRibbonButtonBar->AddButton(wxID_ANY, wxT("Waveguide Dimensions"),
                                   wxArtProvider::GetBitmap(wxART_QUESTION, wxART_TOOLBAR, wxSize(32,32)));

    coaxRibbonButtonBar->AddButton(wxID_ANY, wxT("Coaxial Impedance"),
                                   wxArtProvider::GetBitmap(wxART_QUESTION, wxART_TOOLBAR, wxSize(32,32)));

    //Radome Tools
    radomeRibbonButtonBar->AddButton(wxID_ANY, wxT("Multi-Layer Radome Analysis"),
                                   wxArtProvider::GetBitmap(wxART_QUESTION, wxART_TOOLBAR, wxSize(32,32)));

    radomeRibbonButtonBar->AddButton(wxID_ANY, wxT("Dielectric Properties"),
                                   wxArtProvider::GetBitmap(wxART_QUESTION, wxART_TOOLBAR, wxSize(32,32)));



    ribbonBar->AddPageHighlight(ribbonBar->GetPageCount());
    ribbonBar->Realise();


    // Set layout with sizers
    wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
    sizer->Add(ribbonBar, 0, wxEXPAND);

    wxSizer* panelSizer = new wxBoxSizer(wxVERTICAL);
    panelSizer->Add(panel, 1, wxEXPAND);

   // panelSizer->Show(panel);

    sizer->Add(panelSizer, 1, wxEXPAND);
    panelSizer->Hide(panel);


  SetSizer(sizer);

 // panelSizer->Show(panel);

    Center();

    // Set status bar
    CreateStatusBar(2);
    SetStatusText(_T("Status Text 1"), 0);
    SetStatusText(_T("Status Text 2"), 1);

//panelSizer->Show(panel);  Testing Show(panel) within MainWindow setup and it works here.
//panel->Show();
}

// Functions Here

void MainWindow::OnMicrostripButton(wxRibbonButtonBarEvent& evt)
{
 MainWindow::panel->Show();
    //panelSizer->Show(panel);
    panel->Refresh();
}

void MainWindow::OnCPWButton(wxRibbonButtonBarEvent& evt)
{
  //wxMessageBox("MainWindow::OnCPWButton");

  wxPanel *panelCPW = new wxPanel(this, -1);
  panelCPW->SetBackgroundColour(wxColor(50, 200, 200));
//  sizer->Add(panelCPW, 1, wxEXPAND);
//  //SetSizer(sizer);
//  panelMicrostrip->Hide();
//  panelCPW->Show();
//  panelCPW->Refresh();
//  SetSizer(sizer);

}

void MainWindow::OnCPW_GButton(wxRibbonButtonBarEvent& evt)
{
  wxMessageBox("MainWindow::OnCPW_GButton");
}

void MainWindow::OnStriplineButton(wxRibbonButtonBarEvent& evt)
{
  wxMessageBox("MainWindow::OnStriplineButton");
}

void MainWindow::OnCoupled_StriplineButton(wxRibbonButtonBarEvent& evt)
{
  wxMessageBox("MainWindow::OnCoupled_StriplineButton");
}


PaulUK
Earned a small fee
Earned a small fee
Posts: 22
Joined: Wed Nov 18, 2020 12:55 pm

Re: How to clear client area or replace sizers and controls on a panel

Post by PaulUK » Tue Jun 15, 2021 1:52 pm

I hope it's ok to bump this thread.
I still haven't solved the problem of showing / hiding or setting up controls on a panel from a function outside of the "MainWindow" function. Just a reminder, I want to be able to click on icons of a ribbon icon bar, and for each one to show a panel in the frame with controls related to that icon. Each icon clicked should show only the controls related to that "sub program" chosen. Please can anyone more experience tell me if this can be done and how. When I try to just show or hide an empty panel, I can't seem to do it from a function which is activated with an event from a mouse click on the icon. However I can show and hide a panel with code in the "MainWindow" section of code.

The event table seems fine and I can display a popup message box on icon clicks. So at least that is working.
Thank you.

User avatar
doublemax
Moderator
Moderator
Posts: 16208
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: How to clear client area or replace sizers and controls on a panel

Post by doublemax » Tue Jun 15, 2021 2:24 pm

As the code doesn't compile as it is, i can't play around with it, which makes providing a solution mode difficult. And if it's much code, people might not be motivated to look into it at all.

If you don't want to use a wxSimpleBook (which you should), you have to:
- store the pointers of all panels you want to show / hide. Otherwise you won't be able to show / hide them
- if you create a new panel at runtime, you need to put it into the sizer, and then hide all other panels

Relevant code parts:

Code: Select all

wxStaticText *EnterRadius;
wxTextCtrl *RadiusEntered;
wxStaticText *RadiusIs;
wxTextCtrl *AreaResult;
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
wxSizer* panelSizer = new wxBoxSizer(wxVERTICAL);
Don't use globale variables, turn them into member variables.

Code: Select all

    wxPanel *panel = new wxPanel(this, -1);
    panel->SetBackgroundColour(wxColor(000, 000, 000));
You need to store the wxPanel pointer in a member variable

Code: Select all

    wxSizer* panelSizer = new wxBoxSizer(wxVERTICAL);
    panelSizer->Add(panel, 1, wxEXPAND);
You need to store the wxBoxSizer pointer in a member variable, because you'll need it in the button click handler

Code: Select all

  wxPanel *panelCPW = new wxPanel(this, -1);
  panelCPW->SetBackgroundColour(wxColor(50, 200, 200));
You need to store the wxPanel pointer in a member variable. And you should make sure that you don't create a new panel if another instance of the same panel already exists (unless you want that to be possible).
add panelCPW to the panelSizer
hide all other panels in the sizer
call Layout() on the sizer

I highly recommend to use wxSimpleBook which makes managing all this much easier.
Use the source, Luke!

PaulUK
Earned a small fee
Earned a small fee
Posts: 22
Joined: Wed Nov 18, 2020 12:55 pm

Re: How to clear client area or replace sizers and controls on a panel

Post by PaulUK » Wed Jun 16, 2021 12:34 pm

Thank you for the reply, If I attach the few files associated with this project would you mind having a quick look and showing how to do this? I'm struggling a bit with this coming from a C background and previously VB. I'm using Codeblocks. I'm open to using wxSimpleBook but haven't yet found any examples to use as a guide. Thank you.

Just to point out that the ribbon toolbar was based on the example in the samples with my own changes off course. I will check the samples about the wxSimplebook, and would I be right about assuming that a panel and controls can be assigned to various "pages" or screens of the wxSimplebook?

I'm trying to make an interface to my program simple to use for the user so that different sub programs can be easily selected from the ribbon icons.

User avatar
doublemax
Moderator
Moderator
Posts: 16208
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: How to clear client area or replace sizers and controls on a panel

Post by doublemax » Wed Jun 16, 2021 3:29 pm

If I attach the few files associated with this project would you mind having a quick look and showing how to do this?
Sure, if it's not too much hazzle to get it to compile :)
Use the source, Luke!

PaulUK
Earned a small fee
Earned a small fee
Posts: 22
Joined: Wed Nov 18, 2020 12:55 pm

Re: How to clear client area or replace sizers and controls on a panel

Post by PaulUK » Wed Jun 16, 2021 3:45 pm

It compiles fine on my machine with my wxWidgets setup, I would hope that it compiles fine on yours, I'll attach the files tomorrow. Thank you, I appreciate it. The GUI is the bottleneck for my project at the moment. Once I can start adding panels with controls I'll be able to make rapid progress.

PaulUK
Earned a small fee
Earned a small fee
Posts: 22
Joined: Wed Nov 18, 2020 12:55 pm

Re: How to clear client area or replace sizers and controls on a panel

Post by PaulUK » Thu Jun 17, 2021 8:52 am

I have attached the CodeBlocks project. There are two cpp and two header files with a number of image recourses. I deleted the Debug and Release folders to take less space. I hope that it compiles and if you could show what you meant in the previous messages. I'd really appreciate it.
ProjectTemplateRibbon.zip
CodeBlocks Project
(94.53 KiB) Downloaded 20 times

User avatar
doublemax
Moderator
Moderator
Posts: 16208
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: How to clear client area or replace sizers and controls on a panel

Post by doublemax » Thu Jun 17, 2021 9:29 am

Here you go. I just added 3 colored panel and put them in a wxSimplebook. You can switch between the panels with the first 3 buttons on the ribbonbar.
Attachments
MainWindow.h
(1.99 KiB) Downloaded 30 times
MainWindow.cpp
(8.26 KiB) Downloaded 26 times
Use the source, Luke!

PaulUK
Earned a small fee
Earned a small fee
Posts: 22
Joined: Wed Nov 18, 2020 12:55 pm

Re: How to clear client area or replace sizers and controls on a panel

Post by PaulUK » Thu Jun 17, 2021 11:03 am

Thank you very much, I will try it this evening and report back how I get on. It's very much appreciated. :D

Post Reply