Question about SetClientSize()

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
mbeardsley
Experienced Solver
Experienced Solver
Posts: 74
Joined: Thu Sep 25, 2014 7:40 pm

Question about SetClientSize()

Post by mbeardsley »

I am running wxWidgets 3.0.2 on Win7, and am getting some unexpected behavior out of SetClientSize().

I have a wxPanel inside of a wxFrame. In the constructor of the frame, I do SetClientSize() for the frame to set it to the size that I want (this is not hard coded, as it needs to be configurable). I also set the client size of the panel (to the same size).

For most sizes this works correctly. However, if the height I specify is actually higher than my screen resolution, the value seems to get truncated to what is probably the maximum height after accounting for the frame borders.

This behavior might be understandable, except that when setting the client size of the interior wxPanel, it does NOT get truncated in a similar manner. So I end up with a panel that has a larger client size than the frame that surrounds it. This tends to confuse my re-sizing code.

I tried calling Fit() on the frame (after setting the client sizes on both the frame and the panel), but this resulted in very small sizes for both.

It's unclear to me what I should need to do to get a wxFrame and wxPanel to be of a desired client size where that client size might be larger than the screen resolution.

Furthermore, what should happen when I do panel->SetClientSize(512,512) if the panel is a child of a wxFrame that currently has a Client size of (256,256) ?
Should the frame be forced to grow? Should the size of the panel get truncated?
User avatar
doublemax
Moderator
Moderator
Posts: 19117
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Question about SetClientSize()

Post by doublemax »

I assume the wxPanel is the only child of the wxFrame? In this case the size of the panel becomes locked to the client size of the frame automatically. If you set the client size of the panel, it will probably snap back immediately when the frame gets resized.

Why would you want a frame that's bigger than the screen size? Wouldn't it become impossible to resize for the user?

Usually one would use a wxScrolledWindow if you want to display something bigger than the screen.
Use the source, Luke!
mbeardsley
Experienced Solver
Experienced Solver
Posts: 74
Joined: Thu Sep 25, 2014 7:40 pm

Re: Question about SetClientSize()

Post by mbeardsley »

Why would you want a frame that's bigger than the screen size? Wouldn't it become impossible to resize for the user?
Yes, this is probably an unusual situation. In my case, I am doing OpenGL rendering into the panel, and the results of this rendering are then being read back and post-processed. This processing may require high-resolution images in some cases. As for resizing by the user, I prevent this, as resizing the rendering output during the run would cause problems for the post-processor. The user can configure the output size at startup (which is when I do the SetClientSize() on both the panel and the frame), but not after rendering has started.
I assume the wxPanel is the only child of the wxFrame?
Yes, this is correct.
In this case the size of the panel becomes locked to the client size of the frame automatically. If you set the client size of the panel, it will probably snap back immediately when the frame gets resized.
This is not the behavior that I see. In my case, when I set the client size of the wxFrame and the wxPanel to 1920x1080 (the size of my screen), the Frame actually gets set to 1920x1064, but the wxPanel gets the correct size of 1920x1080. So I end up with a wxPanel with a client size that is larger than the client size of the wxFrame to which it belongs.

Similarly, if I try to set the size of them to 4096x4096, the wxFrame gets set to 4096x1064 and the wxPanel gets set to 4096x4096.

I have found a workaround, in that in my case I can just ignore the reported size of the Frame and use the size of the Panel in all cases, and so far this seems to work ok.

It seems odd though, that if I do:

Code: Select all

    frame->SetClientSize( 4096, 4096 );
    panel->SetClientSize( 4096, 4096 );
    wxSize framesize = frame->GetClientSize();
    wxSize panelsize = panel->GetClientSize();
then (on a 1920x1080 screen):
framesize is set to 4096x1064 and panelsize is set to 4096x4096
User avatar
doublemax
Moderator
Moderator
Posts: 19117
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Question about SetClientSize()

Post by doublemax »

Yes, this is probably an unusual situation. In my case, I am doing OpenGL rendering into the panel, and the results of this rendering are then being read back and post-processed. This processing may require high-resolution images in some cases.
Maybe it would be easier to render into a texture to avoid dirty workarounds.

I would try to calculate the difference between outer frame size and client size once and then use wxFrame::SetSize() to set a size so that the client area becomes 4096x4096.
Use the source, Luke!
Manolo
Can't get richer than this
Can't get richer than this
Posts: 827
Joined: Mon Apr 30, 2012 11:07 pm

Re: Question about SetClientSize()

Post by Manolo »

What I would use for that kind of OGL rendering is a FBO (Frame Buffer Object) with its proper glViewport. Or at least, as doublemax pointed to, a texture.
After the rendering, you can use glReadBuffer and glReadPixels to access that render result.

A wxFrame handles its only-child wxPane size. Even you can cheat wxFrame and set a larger wxPanel size, this is not a good thing.

OGL will render to the glViewport you set, being it the same or not as the size of the panel. If you want to match both sizes, I advice to use a wxScrolledWindow instead of a wxPanel.
mbeardsley
Experienced Solver
Experienced Solver
Posts: 74
Joined: Thu Sep 25, 2014 7:40 pm

Re: Question about SetClientSize()

Post by mbeardsley »

Well, the problem is really not the rendering (that all works fine).

My concern is that SetClientSize() seems to be misbehaving, regardless of what is eventually going to be put on the panel.

It seems like a bug that I can request a client size for a frame and (without it generating an error), give me a different (smaller) size.
Furthermore, if I request that same size for a panel (a child of that frame), it will give me the correct size.

This results in a panel with a larger client size than the client size of the frame to which it belongs. This seems wrong also.

None of this really has anything to do with OpenGL rendering methods. I only mentioned the rendering as an explanation of why I want a large client size in some cases.
This "bug/behavior" was confusing my rendering at one point, as I was assuming that the client size for the panel could not be larger than the one for the frame. Once I stopped making that assumption, my rendering was fine again.

I don't really know if this is a "bug" or is expected behavior. Hence my question about what "should" happen if I request a larger client size than the screen resolution, or if I request a client size for a child that is bigger than the client size of its parent.

Note also, that I may have a multiple-monitor setup where my useable screen space is larger than my current screen's resolution.
Post Reply