Draw over widgets (after widgets are shown)

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
akamed
In need of some credit
In need of some credit
Posts: 6
Joined: Wed Jan 13, 2021 5:59 pm

Draw over widgets (after widgets are shown)

Post by akamed » Wed Jan 13, 2021 6:05 pm

Hello

I want to have borders with rounded corners in my sizer (wxBoxSizer), so I capture the OnPaint event and I draw these borders in the panel that I am working on (wxScrolledWindow).
That works fine, but when I put widgets on the sizer that goes inside that panel, the widgets are drawn over the border, and I need the to be inside, so it looks under the border and not over it.

Any ideas to draw after the sizer has been drawn?

Thanks

My code is:

Code: Select all

void ScrolledPanel::OnPaint(wxPaintEvent& event)
{
    wxPaintDC dc(this);
    wxSize size = GetSize();
    int width = size.GetWidth();
    int height = size.GetHeight();
    dc.SetPen(wxPen(this->GetForegroundColour(), 8));
    dc.SetBrush(this->GetBackgroundColour());
    dc.DrawRoundedRectangle(0,0,width, height, 20);
}
Image

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

Re: Draw over widgets (after widgets are shown)

Post by doublemax » Wed Jan 13, 2021 6:15 pm

That's not going to work.

I'd try a different approach: Use sizers to place 4 (or 8 ) separate panels for the 4 edges (+ 4 corners) around the window. In these panels you can draw the custom border. You could write a helper class that accepts any window and it will wrap it with the custom border.
Use the source, Luke!

akamed
In need of some credit
In need of some credit
Posts: 6
Joined: Wed Jan 13, 2021 5:59 pm

Re: Draw over widgets (after widgets are shown)

Post by akamed » Wed Jan 13, 2021 6:56 pm

doublemax wrote:
Wed Jan 13, 2021 6:15 pm
That's not going to work.

I'd try a different approach: Use sizers to place 4 (or 8 ) separate panels for the 4 edges (+ 4 corners) around the window. In these panels you can draw the custom border. You could write a helper class that accepts any window and it will wrap it with the custom border.
I seems a bit dificult, but I will try to wrap everything on a class as you say.

Do you have any suggestions about the base class to begin with? would it be better to be a window or maybe a panel?

Thanks doublemax!

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

Re: Draw over widgets (after widgets are shown)

Post by doublemax » Wed Jan 13, 2021 7:04 pm

akamed wrote:
Wed Jan 13, 2021 6:56 pm
Do you have any suggestions about the base class to begin with? would it be better to be a window or maybe a panel?
Use wxPanel, otherwise tab-navigation between controls might not work properly.
Use the source, Luke!

akamed
In need of some credit
In need of some credit
Posts: 6
Joined: Wed Jan 13, 2021 5:59 pm

Re: Draw over widgets (after widgets are shown)

Post by akamed » Wed Jan 13, 2021 7:08 pm

OK, I will use a wxpanel as the wrapper class as you suggest.
So then...may I use one sizer and 8 panels? or 8 sizers, each one containing one panel?
Thanks for your help...sometimes I get lost with wx :)

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

Re: Draw over widgets (after widgets are shown)

Post by doublemax » Wed Jan 13, 2021 7:19 pm

I was overthinking this, it's actually much simpler.

Paste this into the "minimal" sample at the end of the MyFrame contructor.

Code: Select all

#define BORDER_SIZE 16
wxPanel *panel = new wxPanel(this, wxID_ANY);
 wxBoxSizer *mainsizer = new wxBoxSizer(wxVERTICAL);

    // now the element you want to wrap
    wxPanel *contentpanel = new wxPanel(panel, wxID_ANY);
    contentpanel->SetBackgroundColour(*wxRED);    // just to see where the panel is

 mainsizer->Add(contentpanel, 1, wxALL|wxEXPAND, BORDER_SIZE);

 panel->SetSizer(mainsizer);
You will see the red panel pinned to the middle, with the border around it. You just have to add the paint event handler to draw the border into the "empty" areas.
Use the source, Luke!

akamed
In need of some credit
In need of some credit
Posts: 6
Joined: Wed Jan 13, 2021 5:59 pm

Re: Draw over widgets (after widgets are shown)

Post by akamed » Wed Jan 13, 2021 9:04 pm

mmmm it does not work when I put it on my design, it makes a border, yes, but it is still "behind"...
:(

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

Re: Draw over widgets (after widgets are shown)

Post by doublemax » Wed Jan 13, 2021 9:56 pm

Can you post another screenshot with the new version?
Use the source, Luke!

akamed
In need of some credit
In need of some credit
Posts: 6
Joined: Wed Jan 13, 2021 5:59 pm

Re: Draw over widgets (after widgets are shown)

Post by akamed » Thu Jan 14, 2021 8:26 pm

doublemax wrote:
Wed Jan 13, 2021 9:56 pm
Can you post another screenshot with the new version?
Yes, of course!

Here it is:

Image

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

Re: Draw over widgets (after widgets are shown)

Post by doublemax » Thu Jan 14, 2021 10:25 pm

That looks like the minimum size of the inner controls is just too big. You either need to set a smaller minimum size, or make the frame bigger.
Use the source, Luke!

akamed
In need of some credit
In need of some credit
Posts: 6
Joined: Wed Jan 13, 2021 5:59 pm

Re: Draw over widgets (after widgets are shown)

Post by akamed » Sun Jan 17, 2021 10:51 am

doublemax wrote:
Thu Jan 14, 2021 10:25 pm
That looks like the minimum size of the inner controls is just too big. You either need to set a smaller minimum size, or make the frame bigger.
Yes!
thank you. It worked setting a smaller minimum size.
Anyway, my actual project has a much more complex distribution, and I solved it by placing a panel inside a sizer (with a wxBorder) that is inside a sizer that has another panel (where all the widgets are shown) and applying a wxBorder that inside sizer, more or less what you said at first.
And the I draw by hand the rounded custom border in the outter panel and everything seems ok.

Thank you very much Doublemax!

Best regards

Post Reply