wxPanel draws over the scrollbar of wxScrolledWindow Topic is solved

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.
ongledda
In need of some credit
In need of some credit
Posts: 8
Joined: Thu Aug 10, 2017 2:16 am

wxPanel draws over the scrollbar of wxScrolledWindow

Post by ongledda »

I have a wxPanel that is being redrawn when mouse pointer has entered on it.
This panel is in a wxScrollWindow.

The problem is when the wxPanel is re-drawn, while the scrollbar of the wxScrollBarWindow is on top of it, the wxPanel will be drawn over the scrollbar.

This seems to happen only on MacOS.
My environment:
- MacOS X 10.12 Sierra
- wxcocoa (wxWidgets-3.1.1)

I have reproduced this behavior in "scroll" sample code.
I added a wxPanel inside the MyCanvas.

Created a wxPanel button:

Code: Select all

class MyButton : public wxWindow
{
    
public:
    MyButton(wxWindow *parent)
    : wxWindow(parent, wxID_ANY, wxDefaultPosition, wxSize(100, 50))
    {
        Connect(wxEVT_PAINT, wxPaintEventHandler(MyButton::OnPaint));
        Bind(wxEVT_ENTER_WINDOW, &MyButton::mouseEntered, this);
        Bind(wxEVT_LEAVE_WINDOW, &MyButton::mouseLeave, this);
    }
    
private:
    void OnPaint(wxPaintEvent& WXUNUSED(event))
    {
        render();
    }
    
    void mouseEntered(wxMouseEvent& WXUNUSED(evt))
    {
        render(*wxYELLOW);
    }
    
    void mouseLeave(wxMouseEvent& WXUNUSED(evt))
    {
        render();
    }
    
    void render(wxColor color = *wxRED)
    {
        wxClientDC dc(this);
        dc.SetBackground(wxBrush(color));
        
        dc.Clear();
    }
};
In MyCanvass class:

Code: Select all

    // you can use either a single SetScrollbars() call or these 2 functions,
    // usually using them is better because you normally won't need to change
    // the scroll rate in the future and the sizer can be used to update the
    // virtual size automatically
    SetScrollRate( 10, 10 );
    SetVirtualSize( 500, 1000 );

    (void) new wxButton( this, ID_ADDBUTTON,  "add button", wxPoint(10,10) );
    (void) new wxButton( this, ID_DELBUTTON,  "del button", wxPoint(10,40) );
    (void) new wxButton( this, ID_MOVEBUTTON, "move button", wxPoint(150,10) );
    (void) new wxButton( this, ID_SCROLLWIN,  "scroll win", wxPoint(250,10) );
    
    MyButton *btn = new MyButton(this);

    wxPanel *test = new wxPanel( this, wxID_ANY,
                                 wxPoint(10, 110), wxSize(130,50),
                                 wxSIMPLE_BORDER | wxTAB_TRAVERSAL );
    test->SetBackgroundColour( "WHEAT" );
Screenshots:

Scrollbar is over the panel:
scrollbar_over_panel.png
scrollbar_over_panel.png (18.72 KiB) Viewed 2671 times
..when mouse is hovered, the panel is redrawn over the scrollbar:
hovered.png
hovered.png (16.5 KiB) Viewed 2671 times

Thanks for the help!
Last edited by ongledda on Fri Sep 14, 2018 9:55 am, edited 1 time in total.
catalin
Moderator
Moderator
Posts: 1618
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Re: wxPanel draws over the scrollbar of wxScrolledWindow

Post by catalin »

Does it still happen if you move it around so that it will not overlap any of its siblings?
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxPanel draws over the scrollbar of wxScrolledWindow

Post by doublemax »

Code: Select all

 void render(wxColor color = *wxRED)
    {
        wxClientDC dc(this);
        dc.SetBackground(wxBrush(color));
       
        dc.Clear();
    }
Don't use wxClientDC in a paint event handler, use wxPaintDC.
Use the source, Luke!
ongledda
In need of some credit
In need of some credit
Posts: 8
Joined: Thu Aug 10, 2017 2:16 am

Re: wxPanel draws over the scrollbar of wxScrolledWindow

Post by ongledda »

Yes, it still happens.

I do not know if I'm missing something on wxPanel drawing or not.
This issue does not seem to happen on windows.

[img]
test_code.png
test_code.png (34.26 KiB) Viewed 2660 times
[/img]
ongledda
In need of some credit
In need of some credit
Posts: 8
Joined: Thu Aug 10, 2017 2:16 am

Re: wxPanel draws over the scrollbar of wxScrolledWindow

Post by ongledda »

Don't use wxClientDC in a paint event handler, use wxPaintDC.
I tried to use wxPaintDC in the paint event handler, but it still happens.

Code: Select all

class MyButton : public wxWindow
{
    
public:
    MyButton(wxWindow *parent, wxPoint pos)
    : wxWindow(parent, wxID_ANY, pos, wxSize(100, 50))
    {
        Connect(wxEVT_PAINT, wxPaintEventHandler(MyButton::OnPaint));
        Bind(wxEVT_ENTER_WINDOW, &MyButton::mouseEntered, this);
        Bind(wxEVT_LEAVE_WINDOW, &MyButton::mouseLeave, this);
    }
    
private:
    void OnPaint(wxPaintEvent& WXUNUSED(event))
    {
        wxPaintDC dc(this);
        render(dc);
    }
    
    void mouseEntered(wxMouseEvent& WXUNUSED(evt))
    {
        wxClientDC dc(this);
        render(dc, *wxYELLOW);
    }
    
    void mouseLeave(wxMouseEvent& WXUNUSED(evt))
    {
        wxClientDC dc(this);
        render(dc);
    }
    
    void render(wxDC& dc, wxColor color = *wxRED)
    {
        dc.SetBackground(wxBrush(color));
        dc.Clear();
    }
};
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxPanel draws over the scrollbar of wxScrolledWindow

Post by doublemax »

You're still using wxClientDC in the mouse enter/leave handlers. Try disabling these for a test.
Use the source, Luke!
ongledda
In need of some credit
In need of some credit
Posts: 8
Joined: Thu Aug 10, 2017 2:16 am

Re: wxPanel draws over the scrollbar of wxScrolledWindow

Post by ongledda »

Disabling the enter/leave handlers and drawing the panel in the paint event using wxPaintDC is working fine, it does not overlap the scrollbar.

But, I'd like to redraw the panel on mouse enter or leave, without overlapping the scrollbar.
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxPanel draws over the scrollbar of wxScrolledWindow

Post by doublemax »

Get rid of the render method, do your drawing in the paint event handler only. Use a flag that controls the color.

Code: Select all

bool m_mouse_inside;    // member of class

void OnPaint(wxPaintEvent& WXUNUSED(event))
{
    wxPaintDC dc(this);
    
    dc.SetBackground( m_mouse_inside ? *wxYELLOW : *wxRED );
    dc.Clear();
}

void mouseEntered(wxMouseEvent& WXUNUSED(evt))
{
  m_mouse_inside = true;
  Refresh();
}

void mouseLeave(wxMouseEvent& WXUNUSED(evt))
{
  m_mouse_inside = false;
  Refresh();
}
Use the source, Luke!
ongledda
In need of some credit
In need of some credit
Posts: 8
Joined: Thu Aug 10, 2017 2:16 am

Re: wxPanel draws over the scrollbar of wxScrolledWindow

Post by ongledda »

Your answer worked!

Thank you very much for the help. :D
ongledda
In need of some credit
In need of some credit
Posts: 8
Joined: Thu Aug 10, 2017 2:16 am

Re: wxPanel draws over the scrollbar of wxScrolledWindow

Post by ongledda »

Hello everyone,

I ran into a similar problem again, but this time it's the wxTextCtrl's highlight that is overlapping the scroll bars.

I also replicated the issue in the "scroll" sample code of wxWidgets 3.1.3.
I just added a wxTextCtrl in MyCanvas class.

Code: Select all

MyCanvas::MyCanvas(wxWindow *parent)
    : wxScrolled<wxPanel>(parent, wxID_ANY,
                          wxDefaultPosition, wxDefaultSize,
                          wxSUNKEN_BORDER | wxTAB_TRAVERSAL)
{
    // you can use either a single SetScrollbars() call or these 2 functions,
    // usually using them is better because you normally won't need to change
    // the scroll rate in the future and the sizer can be used to update the
    // virtual size automatically
    SetScrollRate( 10, 10 );
    SetVirtualSize( 500, 1000 );

    (void) new wxButton( this, ID_ADDBUTTON,  "add button", wxPoint(10,10) );
    (void) new wxButton( this, ID_DELBUTTON,  "del button", wxPoint(10,40) );
    (void) new wxButton( this, ID_MOVEBUTTON, "move button", wxPoint(150,10) );
    (void) new wxButton( this, ID_SCROLLWIN,  "scroll win", wxPoint(250,10) );

    wxPanel *test = new wxPanel( this, wxID_ANY,
                                 wxPoint(10, 110), wxSize(130,50),
                                 wxSIMPLE_BORDER | wxTAB_TRAVERSAL );
    test->SetBackgroundColour( "WHEAT" );

    wxTextCtrl *myText = new wxTextCtrl(this, wxID_ANY, "This is a text control", wxPoint(300,250), wxSize(150,24));

    SetBackgroundColour( "BLUE" );
}
Screenshot:
scroll.png
My questions are:
1. Do you have any suggestions on how to prevent this issue without modifying the wxWidgets code?
2. Is there a way to remove the blue highlight when the text control is on focus, again without modifying the wxWidgets code?

Thank you.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7459
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxPanel draws over the scrollbar of wxScrolledWindow

Post by ONEEYEMAN »

Hi,
Did you selected the code inside the wxTextCtrl?

Thank you.
ongledda
In need of some credit
In need of some credit
Posts: 8
Joined: Thu Aug 10, 2017 2:16 am

Re: wxPanel draws over the scrollbar of wxScrolledWindow

Post by ongledda »

Hello,
No, I did not make any changes on the library itself.
This is the version I used: https://github.com/wxWidgets/wxWidgets/ ... tag/v3.1.3

Did I answer your question correctly?

Thank you.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7459
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxPanel draws over the scrollbar of wxScrolledWindow

Post by ONEEYEMAN »

Hi,
You are setting the position and the size of the control which overrides the size of the canvas.
You should follow the idea of the button creation.

Thank you.
ongledda
In need of some credit
In need of some credit
Posts: 8
Joined: Thu Aug 10, 2017 2:16 am

Re: wxPanel draws over the scrollbar of wxScrolledWindow

Post by ongledda »

Hello,

I do not understand why it would override the size of the canvas.
As you have suggested, I tried to follow the syntax used to create the buttons.

Code: Select all

    //wxTextCtrl *myText = new wxTextCtrl(this, wxID_ANY, "This is a text control", wxPoint(300,250), wxSize(150,24));
    //(void) new wxTextCtrl(this, wxID_ANY, "This is a text control", wxPoint(300,250));
    (void) new wxTextCtrl(this, wxID_ANY, "This is a text control");
Even if I do not set the size and/or the position parameter, I can still reproduce the issue.

Thank you.
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxPanel draws over the scrollbar of wxScrolledWindow

Post by doublemax »

Looks like a bug to me. Try to open a ticket at http://trac.wxwidgets.org , ideally with a minimal patch to any of the samples that shows the issue.
Use the source, Luke!
Post Reply