Search code examples
c++scrollwxwidgetsonpaint

CustomButton displayed out of Boundary While Using wxScrollWindow


I am doing some scrolling using wxScrolledWindow class. The scrolling is working fine. I am also using wxNotebook to switch between tabs. I have 2 tabs for this example. The first tab contains a header and then a ScrolledWidgetsPane class which is derived from wxScrolledWindow. The 2nd tab contains a blank page.
Now when I am at tab1 everything works fine and the custombuttons are hidden behind the header(shown in red in the screenshot). But when I switch to tab2 and then back to tab1 the custombutton is displayed outside its boundary that is on top of the header. I have attached the three screenshots which highlight the situation. Note that inside tab1 i have a vertical sizer. That vertical sizer contains first a header of height 40 and then below it, it contains a ScrolledWidgetsPane.
Moreover I noticed that this happens only when I use the CustomButton::onPaint(wxPaintEvent&) method. If I comment the code inside the onPaint method of CustomButton then there is no overlapping of custombuttons onto the header part of the tab1. The code inside CustomButton::onPaint is as follows:

void CustomButton::onPaint(wxPaintEvent &event)
{
        *If i comment the next three statements then code works fine but if i use them in the program then the above
        problem happens*/
        wxClientDC dc(this);
        dc.SetBrush(wxBrush(wxColour(100, 123,32), wxBRUSHSTYLE_SOLID));
        dc.DrawRectangle(0, 0, 100, 40);
}

The code inside FirstPage class(that corresponds to tab1's content) is as follows:

First_Page::First_Page(wxNotebook *parent): wxPanel(parent, wxID_ANY)
{
        
        wxBoxSizer *verticalSizer = new wxBoxSizer(wxVERTICAL);
        wxPanel *headerPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 40));
        headerPanel->SetBackgroundColour("red");

        verticalSizer->Add(headerPanel, 0, wxEXPAND, 0);
        
        
        wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
        SetBackgroundColour(wxColour(233,233,233));
        ScrolledWidgetsPane* my_image = new ScrolledWidgetsPane(this, wxID_ANY);
        sizer->Add(my_image, 1, wxEXPAND);

        verticalSizer->Add(sizer, 1, wxEXPAND, 0);
       

        
        SetSizer(verticalSizer);
}


And the code inside ScrolledWidgetsPane is as follows:

ScrolledWidgetsPane::ScrolledWidgetsPane(wxWindow* parent, wxWindowID id) : wxScrolledWindow(parent, id)
{
      
       wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
       SetBackgroundColour("blue"); 
        // add a series of widgets
        for (int w=1; w<=120; w++)
        {
            
            CustomButton *b = new CustomButton(this, wxID_ANY);
            sizer->Add(b, 0, wxALL, 3);
        } 
        this->SetSizer(sizer);
        this->FitInside();
        this->SetScrollRate(5, 5);

}

How can I resolve this issue and what is the cause of this? Note that this only happens when I use the onPaint method of CustomButton.

Additional Question: Is there a way to not display the scroll thumb that is visible at the right side of the window? That is to hide(or not show) the thumb but still have the scrolling functionality.

Below i have attached the 3 screenshots.

tab1 tab2 tab3


Solution

  • How can I resolve this issue and what is the cause of this? Note that this only happens when I use the onPaint method of CustomButton.

    In the paint handler, you need to use a wxPaintDC instead of wxClientDC:

    void CustomButton::onPaint(wxPaintEvent &event)
    {
            wxPaintDC dc(this);
    ...
    }
    

    Additional Question: Is there a way to not display the scroll thumb that is visible at the right side of the window? That is to hide(or not show) the thumb but still have the scrolling functionality.

    In ScrolledWidgetsPane::ScrolledWidgetsPane, you should be able to add

    this->ShowScrollbars(wxSHOW_SB_NEVER,wxSHOW_SB_NEVER);
    

    to disable showing the scrollbars.