wxTreeCtrl changes size during Layout() after wxDragImage was created 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.
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 542
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

wxTreeCtrl changes size during Layout() after wxDragImage was created

Post by mael15 »

hi everyone,
i have a strange phenomenon when using a wxDragImage in a wxTreeCtrl. what happens is that Layout() causes a size change in the wxTreeCtrl only after a wxDragImage was created.
it is hard to describe, so i made a minimal example (win 10 pro, wxWidgets 3.1.0):

app.h

Code: Select all

#pragma once

class wxTreeCtrl;

class MyFrame1 : public wxFrame 
{
public:
	MyFrame1( wxWindow* parent = NULL, 
		wxWindowID id = wxID_ANY, 
		const wxString& title = wxEmptyString, 
		const wxPoint& pos = wxDefaultPosition, 
		const wxSize& size = wxSize( 500,300 ), 
		long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
	~MyFrame1();

private:
	void onAddItemClicked(wxCommandEvent &evt);
	void onRemoveItemClicked(wxCommandEvent &evt);
	void onLayoutClicked(wxCommandEvent &evt);
	void onDragImageClicked(wxCommandEvent &evt);

	wxTreeCtrl *tree = nullptr;
};

class App : public wxApp {
	virtual bool OnInit();
	virtual int OnExit();
};
app.cpp

Code: Select all

#include "app.h"
#include "wx/treectrl.h"
#include <wx/dragimag.h>

bool App::OnInit() {
	MyFrame1 *mainFrame = new MyFrame1();
	mainFrame->Show();
	SetTopWindow(mainFrame);

	return TRUE;
}

int App::OnExit() {
	return 0;
}

IMPLEMENT_APP(App)

MyFrame1::MyFrame1( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : 
	wxFrame( parent, id, title, pos, size, style )
{
	SetSizer(new wxBoxSizer(wxHORIZONTAL));

	wxBoxSizer *vertSiz = new wxBoxSizer(wxVERTICAL);
	tree = new wxTreeCtrl(this);
	tree->AddRoot(wxT("root"));
	tree->AppendItem(tree->GetRootItem(), wxT("whatever"));
	tree->ExpandAll();
	vertSiz->Add(tree, 1, wxEXPAND);

	wxPanel *pan = new wxPanel(this);
	vertSiz->Add(pan, 2, wxEXPAND);

	GetSizer()->Add(vertSiz);

	wxBoxSizer *butSiz = new wxBoxSizer(wxVERTICAL);

	wxButton *addItemBut = new wxButton(this, wxID_ANY, wxT("addItem"));
	Connect(addItemBut->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MyFrame1::onAddItemClicked));
	butSiz->Add(addItemBut);

	wxButton *removeItemBut = new wxButton(this, wxID_ANY, wxT("delete last Item"));
	Connect(removeItemBut->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MyFrame1::onRemoveItemClicked));
	butSiz->Add(removeItemBut);

	wxButton *layoutBut = new wxButton(this, wxID_ANY, wxT("layout"));
	Connect(layoutBut->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MyFrame1::onLayoutClicked));
	butSiz->Add(layoutBut);

	wxButton *dragImageBut = new wxButton(this, wxID_ANY, wxT("wxDragImage"));
	Connect(dragImageBut->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MyFrame1::onDragImageClicked));
	butSiz->Add(dragImageBut);

	wxStaticText *text = new wxStaticText(this, wxID_ANY, wxT("a) add items -> layout -> remove items -> layout => wxTreeCtrl stays the same\n"));
	text->SetLabel(text->GetLabel().Append(wxT("b) add items -> wxDragImage -> layout => wxTreeCtrl grows WHY?!\n")));
	text->SetLabel(text->GetLabel().Append(wxT("wxTreeCtrl onyl changes size after wxDragImage was created (and destroyed immediately)")));
	butSiz->Add(text);

	GetSizer()->Add(butSiz);

	this->SetSizeHints( wxDefaultSize, wxDefaultSize );
	this->Centre( wxBOTH );
}

MyFrame1::~MyFrame1()
{
}

void MyFrame1::onAddItemClicked(wxCommandEvent &evt)
{
	tree->AppendItem(tree->GetRootItem(), wxT("whatever"));
}

void MyFrame1::onRemoveItemClicked(wxCommandEvent &evt)
{
	tree->Delete(tree->GetLastChild(tree->GetRootItem()));
}

void MyFrame1::onLayoutClicked(wxCommandEvent &evt)
{
	Layout();
}

void MyFrame1::onDragImageClicked(wxCommandEvent &evt)
{
	wxDragImage *dragImg = new wxDragImage(tree, tree->GetRootItem());
	delete dragImg;
}
instructions how to see the effect are added in the example.
any idea anyone?
thank you!
User avatar
doublemax
Moderator
Moderator
Posts: 19163
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxTreeCtrl changes size during Layout() after wxDragImage was created

Post by doublemax »

Change:

Code: Select all

wxDragImage *dragImg = new wxDragImage(tree, tree->GetRootItem());
to:

Code: Select all

wxDragImage *dragImg = new wxDragImage(*tree, tree->GetRootItem());
                                       ^
I highly recommend the use of a debugger. If you had traced into the wxDragImage ctor, you would have noticed right away what went wrong.
Use the source, Luke!
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 542
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: wxTreeCtrl changes size during Layout() after wxDragImage was created

Post by mael15 »

THANK YOU!
i would have never found this. =D> =D> =D>