Page 1 of 1

wxFRAME_SHAPED and sizers broken on mac

Posted: Tue Feb 13, 2007 7:47 pm
by tommckenna
I have a problem that occurs on Mac but not windows. Basically, If I add items to a sizer in a frame, the sizer ends up making itself twice the size of the frame if the wxFRAME_SHAPED option is used in creating the frame. The code below is what I am using to simulate this problem: If wxFRAME_SHAPED is enabled on mac (cocoa), then the resulting "bad.png" that I have attached is what it looks like. "good.png" is what it looks like (as expected) when wxFRAME_SHAPED is not used.
I get the "good" result on windows no matter whether I use wxFRAME_SHAPED or not.

Code: Select all

#ifndef __COMMON_H
#define __COMMON_H

#include "wx/wx.h"
#include "wx/taskbar.h"
#include "wx/sizer.h"


#endif


//------- WIDGETSTESTAPP.H
#pragma once
#include "Common.h"

class WidgetsTestApp : public wxApp
{
public:
	WidgetsTestApp(void);
	virtual ~WidgetsTestApp(void);

	virtual bool OnInit();
};

IMPLEMENT_APP(WidgetsTestApp)


//------- WIDGETSTESTAPP.CPP
#include "WidgetsTestApp.h"
#include "WidgetsTestFrame.h"

WidgetsTestApp::WidgetsTestApp(void)
{
}

WidgetsTestApp::~WidgetsTestApp(void)
{
}

bool WidgetsTestApp::OnInit()
{

    WidgetsTestFrame *frame = new WidgetsTestFrame( wxT("") );
	
	frame->Show( true );
	SetTopWindow( frame );
	return true;
}

#ifndef __WIDGETSTESTFRAME_H
#define __WIDGETSTESTFRAME_H
#include "Common.h"


class WidgetsTestFrame: public wxFrame
{
public:
	WidgetsTestFrame(const wxString& title);
	virtual ~WidgetsTestFrame(void);


private:
    DECLARE_EVENT_TABLE()

};
#endif


//---------- WIDGETSTESTFRAME.CPP

#include "WidgetsTestFrame.h"
#include "WidgetsCustom.h"

#define ID_MAINFRAME 1000

WidgetsTestFrame::~WidgetsTestFrame(void)
{
}


WidgetsTestFrame::WidgetsTestFrame(const wxString& title)

	   : wxFrame((wxFrame *)NULL,ID_MAINFRAME, title, wxDefaultPosition, wxSize(250,500),wxDEFAULT_FRAME_STYLE|wxFRAME_SHAPED  )
{


	SetBackgroundColour(wxColour(65,130,195));
	wxFlexGridSizer *mysizer = new wxFlexGridSizer(3,3,0,0);
	
	WidgetsCustom* custom1 = new WidgetsCustom(this,this);
	WidgetsCustom* custom2 = new WidgetsCustom(this,this);
	WidgetsCustom* custom3 = new WidgetsCustom(this,this);
	WidgetsCustom* custom4 = new WidgetsCustom(this,this);
	WidgetsCustom* custom5 = new WidgetsCustom(this,this);
	WidgetsCustom* custom6 = new WidgetsCustom(this,this);
	WidgetsCustom* custom7 = new WidgetsCustom(this,this);
	WidgetsCustom* custom8 = new WidgetsCustom(this,this);
	WidgetsCustom* custom9 = new WidgetsCustom(this,this);
	mysizer->Add(custom1,0,wxEXPAND);
	mysizer->Add(custom2,0,wxEXPAND);
	mysizer->Add(custom3,0,wxEXPAND);
	mysizer->Add(custom4,0,wxEXPAND);
	mysizer->Add(custom5,0,wxEXPAND);
	mysizer->Add(custom6,0,wxEXPAND);
	mysizer->Add(custom7,0,wxEXPAND);
	mysizer->Add(custom8,0,wxEXPAND);
	mysizer->Add(custom9,0,wxEXPAND);


	mysizer->AddGrowableRow(0);
	mysizer->AddGrowableRow(1);
	mysizer->AddGrowableRow(2);
	mysizer->AddGrowableCol(0);
	mysizer->AddGrowableCol(1);
	mysizer->AddGrowableCol(2);


	this->SetSizer(mysizer);


	//this->SetShape(wxRegion(0,-20,250,520));
	Centre();

}

BEGIN_EVENT_TABLE(WidgetsTestFrame, wxFrame)
END_EVENT_TABLE()



#ifndef __WIDGETSCUSTOM_H
#define __WIDGETSCUSTOM_H
#include "Common.h"

class WidgetsCustom : public wxWindow
{
	DECLARE_CLASS(WidgetsCustom)

public:
	WidgetsCustom(wxWindow *parent, wxFrame* parent_frame);
	virtual ~WidgetsCustom(void);
	void OnPaint(wxPaintEvent& WXUNUSED(event));
	void OnEraseBackground(wxEraseEvent& WXUNUSED(event));
private:
	DECLARE_EVENT_TABLE()
	
	wxFrame* m_parent_frame;
};

#endif

// -------------- WIDGETSCUSTOM.CPP
#include "WidgetsCustom.h"
#include "WidgetsTestFrame.h"


BEGIN_EVENT_TABLE(WidgetsCustom, wxWindow)
    EVT_PAINT(WidgetsCustom::OnPaint)
	EVT_ERASE_BACKGROUND(WidgetsCustom::OnEraseBackground)
END_EVENT_TABLE()


IMPLEMENT_CLASS(WidgetsCustom, wxWindow)


WidgetsCustom::WidgetsCustom(wxWindow *parent,wxFrame *parent_frame) : wxWindow(parent, -1, wxDefaultPosition,wxSize(20,20),wxNO_BORDER|wxFULL_REPAINT_ON_RESIZE)
{
	m_parent_frame = parent_frame;
//	SetSizeHints(20, -1, 20,-1, -1, -1);
}
WidgetsCustom::~WidgetsCustom(void)
{
}

void WidgetsCustom::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
{
}
void WidgetsCustom::OnPaint(wxPaintEvent& WXUNUSED(event))
{
    wxPaintDC dc(this);
	wxRect r = this->GetRect();

	wxBitmap memBitmap(r.width,r.height);
  	wxMemoryDC memDC;
	memDC.SelectObject(memBitmap);



	wxPen pen(wxColor(255,255,255));
	wxBrush brush(wxColor(255,255,255));

	memDC.SetPen(pen);
	memDC.SetBrush(brush);
	
	memDC.DrawRectangle(0,0,r.width,r.height);

	wxPen pen2(wxColor(0,0,0));
	memDC.SetPen(pen2);
	memDC.DrawRectangle(0,0,r.width,r.height);
	memDC.DrawLine(0,0,r.width,r.height);



	dc.Blit(0, 0, r.width, r.height, &memDC, 0, 0);
}






Posted: Tue Feb 13, 2007 11:56 pm
by Auria
Did you say Cocoa? wxCocoa is not anywhere as stable as wxMac, you should not use it for making apps

But also maybe you just didn't use the right word - in this case providing a sample that compiles would be interesting

Posted: Wed Feb 14, 2007 4:39 pm
by tommckenna
I used the default compilation options on 2.8.0, which I believe is mac (not cocoa) - If I mentioned cocoa it was a mistake :)

I have attached my project directory for you to check out.

Posted: Thu Feb 15, 2007 12:52 am
by Auria
Hmm just a question... why are you building apps for classic only? That's long deprecated

Anyway it seems like a bug - it might be interesting to also test it on wxGTK see how it behaves there, but otherwise i haven't been able to find a solution to this (but... what are you trying to do anyway? to me it does not make much sense to use sizers in a non-rectangular frame)

Posted: Thu Feb 15, 2007 2:45 am
by tommckenna
What do you mean by "Classic Only"?

I'll give it a try on GTK and let you know how it works.

Posted: Thu Feb 15, 2007 9:09 pm
by Auria
tommckenna wrote:What do you mean by "Classic Only"?
Ok you're not used to mac OS X are you? ;)

The latest version of mac OS is Mac OS X. Before that there used to be Mac OS 9, etc. Mac OS X is now the standard on mac for years - however your makefile built a mac OS 9 app. Not even a 'carbon' self-contained app that runs on both OS X and Classic, which is what is usually used when backward compatibility is wanted. Also apps built like this will not run on the most recent macs

However i built it for mac OS X and the bug was still there