problem resizing wxStaticBitmap inside wxBoxSizer 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.
Post Reply
Lightman
Earned a small fee
Earned a small fee
Posts: 11
Joined: Sun Aug 14, 2011 11:24 am

problem resizing wxStaticBitmap inside wxBoxSizer

Post by Lightman »

Strange things happen when I'm trying to resize wxStaticBitmap...
Example 1 (real situation).
I have a complicated frame (built using wxSizers in wxSmith) containing wxStaticBitmap with some initial size (see screenshot here: http://s58.radikal.ru/i159/1109/fa/07ad11a9486a.jpg ). Everything is all right until I change its size - either by SetBitmap() (giving bitmap of another size) or manually using SetSize() function. After such operation, my frame looks like this: http://s46.radikal.ru/i113/1109/af/a540369c449c.jpg .
Documentation tells me I need to call Layout() on sizer to resize properly. This doesn't helps at all.
Proportion properties in the last sizer's children are all set to 0.

Example 2 (simplified case): to find out how I can solve this, I've made a new simple application with the next structure:
-> BoxSizer1 (horizontal):
-> wxStaticBitmap (initial size 90x90, proportion 0)
-> BoxSizer2 (vertical, proportion 0):
-> (two buttons)
Here is its source code (TestMain.cpp):

Code: Select all

TestDialog::TestDialog(wxWindow* parent,wxWindowID id)
{
    //(*Initialize(TestDialog)
    Create(parent, id, _("wxWidgets app"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE, _T("id"));
    BoxSizer1 = new wxBoxSizer(wxHORIZONTAL);
    sb = new wxStaticBitmap(this, ID_STATICBITMAP1, wxNullBitmap, wxDefaultPosition, wxSize(90,90), 0, _T("ID_STATICBITMAP1"));
    BoxSizer1->Add(sb, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer2 = new wxBoxSizer(wxVERTICAL);
    Button1 = new wxButton(this, ID_BUTTON1, _("About"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON1"));
    BoxSizer2->Add(Button1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 4);
    StaticLine1 = new wxStaticLine(this, ID_STATICLINE1, wxDefaultPosition, wxSize(10,-1), wxLI_HORIZONTAL, _T("ID_STATICLINE1"));
    BoxSizer2->Add(StaticLine1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 4);
    Button2 = new wxButton(this, ID_BUTTON2, _("Quit"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON2"));
    BoxSizer2->Add(Button2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 4);
    BoxSizer1->Add(BoxSizer2, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 4);
    SetSizer(BoxSizer1);
    BoxSizer1->Fit(this);
    BoxSizer1->SetSizeHints(this);

    Connect(ID_BUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&TestDialog::OnAbout);
    Connect(ID_BUTTON2,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&TestDialog::OnQuit);
    //*)
}

void TestDialog::OnAbout(wxCommandEvent& event)
{
    wxBitmap b(128,128);
    sb->SetBitmap(b);// this really changes sb's size, but does not changes its appearance
    sb->SetSize(i.sx,i.sy);// whatever I use previous line or this one - they both changes sb's size
    //sb->InvalidateBestSize();// I had tries this too - with no result
    sb->SetSize(-1,-1,128,128);// force set size - no result too

    BoxSizer1->Layout();// this does NOT helps, too !
}
This code really changes size of sb (wxStaticBitmap) and its' bitmap's size too (checked using GetSize()), but the frame still looks like there were no resizes at all...
Just created frame screenshot: http://s004.radikal.ru/i205/1109/30/b600ee64f0f0.jpg
After pressing the button: http://s45.radikal.ru/i109/1109/92/0f6bd12a28df.jpg
(There is a garbage inside wxBitmap b after creation; I don't care about it now)
All proportion properties are set to 0.

The questions are:
1) Why BoxSizer does not resizes ? What can I do to make it resize properly ?
2) In example 1 my wxStaticBitmap expanded to bitmap size and shown that bitmap, but in example 2 its visual size was not changed. Why ? (sorry, example 1 code is too large to post it here, but I had checked everything out and found no difference in creation method and properties (such as proportion)).

P.S: wxWidgets version: 2.8.12
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Re: problem resizing wxStaticBitmap inside wxBoxSizer

Post by Auria »

Hi,

your frame is just not big enough to contain a 128x128 bitmap. Keep in mind that wxSizer classes place widgets inside the currently allocated size. If you want to enlarge the frame to fit the contents, call Fit() (and maybe wxSizer::SetSizeHints before)
"Keyboard not detected. Press F1 to continue"
-- Windows
Lightman
Earned a small fee
Earned a small fee
Posts: 11
Joined: Sun Aug 14, 2011 11:24 am

Re: problem resizing wxStaticBitmap inside wxBoxSizer

Post by Lightman »

What I did:

1) added wxRESIZE_BORDER to TestDialog's Style (my fault I didn't done it earlier),

2) replaced Layout() call with Fit() or SetSizeHint() call - the only difference is: when I do call Layout(), the bitmap is displayed inside original 90x90 size, and if I do not call Layout(), wxStatibBitmap is displayed like this:
Image
There are no changes to controls' positions or dialog's size any way.

3) tried all combinations of SetSizeHint() and Fit() calls :) and found that the only working combination is:
  • BoxSizer1->SetSizeHints(sb);
    BoxSizer1->Fit(this);
Yes, I know the first line is really stupid, and the documentation says: "This only makes sense when window is actually a wxTopLevelWindow such as a wxFrame or a wxDialog, since SetSizeHints only has any effect in these classes. It does nothing in normal windows or controls." But if I comment it, nothing is changed after call to Fit().
Here is the result:
Image
Window is resized, but somehow in wrong way - whatever bitmap size I use, it's ALWAYS resized as shown above.

I still have no idea of how to fix that. Looks like everything must be simple - sizers are designed to make programmers' life easier, but... see screenshots :)
Any ideas ? I feel it MUST be simple...
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Re: problem resizing wxStaticBitmap inside wxBoxSizer

Post by Auria »

I am not sure why it doesn't work automatically, but you could just call ->SetMinSize( wxSize(128,128) ) and ->SetMaxSize( wxSize(128,128) ) on the static bitmap, then Layout and Fit. I'm pretty sure this will work
"Keyboard not detected. Press F1 to continue"
-- Windows
Lightman
Earned a small fee
Earned a small fee
Posts: 11
Joined: Sun Aug 14, 2011 11:24 am

Re: problem resizing wxStaticBitmap inside wxBoxSizer

Post by Lightman »

Thanks a lot, now it works !
The problem was because of default min/max size of wxStaticBitmap.
Solution:
1. Put your image to wxStaticBitmap (or just change its size)
2. call wxStaticBitmap->SetMinSize() and wxStaticBitmap->SetMaxSize() with current bitmap size values,
3. possibly call sizer->Layout() (I didn't mentioned any difference, but left this line commented :) )
4. call sizer->Fit(this) (it was the main dialog's sizer).
Post Reply