Only allow specific client sizes

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
User avatar
Disch
Experienced Solver
Experienced Solver
Posts: 99
Joined: Wed Oct 17, 2007 2:01 am

Only allow specific client sizes

Post by Disch » Fri Nov 09, 2007 10:58 pm

I want to make it so that the user can resize my main window frame, but I want it to "snap" to specific sizes. For example, I would want the client area to be some multiple of 256. So 256x256, 512x512 would be acceptable, but anywhere in between wouldn't be.

I am handling the Size event for my main frame and I can fix it to a specific size by calling SetClientSize in my size handler. This almost works, except you can clearly see the frame being redrawn to the original size, before redrawing again to the size I set (very ugly).

Is there any way to accomplish this? Can I somehow prevent the original resize from redrawing?

Thanks in advance

User avatar
Disch
Experienced Solver
Experienced Solver
Posts: 99
Joined: Wed Oct 17, 2007 2:01 am

Post by Disch » Thu Nov 15, 2007 4:18 pm

I was tinkering around with this some more. I was looking at Freeze/Thaw pairs and thought I might be able to use them to prevent the size from redrawing the window. So I threw this test program together (which asserts that the client area is always perfectly square):

Code: Select all

#include <wx/wx.h>

class MyFrame : public wxFrame
{
public:
	MyFrame::MyFrame(wxWindow* parent,int id,const wxString& title) : wxFrame(parent,id,title)
	{
		frozen = 0;
	}

	void OnSize(wxSizeEvent& event)
	{
		if(!frozen)
		{
			Freeze();
			frozen = 1;
		}

		wxSize siz = GetClientSize();
		siz.SetHeight(siz.GetWidth());

		SetClientSize(siz);

		Thaw();
		Update();
		Freeze();
	}

	void OnIdle(wxIdleEvent& event)
	{
		event.Skip();
		if(frozen)
		{
			frozen = 0;
			Thaw();
		}
	}

	DECLARE_EVENT_TABLE()

	int frozen;
};

BEGIN_EVENT_TABLE(MyFrame,wxFrame)
	EVT_SIZE(MyFrame::OnSize)
	EVT_IDLE(MyFrame::OnIdle)
END_EVENT_TABLE()


class MyApp : public wxApp
{
public:
	bool		OnInit()
	{
		MyFrame* frm = new MyFrame(0,-1,wxT("Test"));
		frm->Show();
		SetTopWindow(frm);

		return true;
	}
};

IMPLEMENT_APP(MyApp);
This almost works perfectly... and in fact, it does work perfectly when the size of the frame is being increased. But when you shrink the frame, the window beneath my program does not get updated (as if it were frozen as well), so the program leaves a "trail" behind it that doesn't go away until you invalidate the area by some other means (see attached screenshot for what I mean).

So I guess my next questions are:

1) Is doing something like this a bad idea? I'm fuzzy on whether or not Freeze/Thaw should be used this way. Also documentation makes it sound like Freeze/Thaw are not supported on some platforms (but doesn't say which?)

2) Any way to force other windows outside my program to invalidate and redraw themselves to get rid of that trail?

Thanks
Attachments
funk.png
funk.png (1.61 KiB) Viewed 397 times

Post Reply