Help passing custom data to event 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
georgeplusplus
Knows some wx things
Knows some wx things
Posts: 25
Joined: Tue May 11, 2021 1:49 pm

Help passing custom data to event

Post by georgeplusplus »

I have a tree control with a right click event that populates different menu commands based on what item is selected in the tree.

I want to pass the wxTreeItemData through the event handler so whatever the user decides the treedata is readily accessible to handle. I have been able to accomplish this using a custom Userdata through Menu.Connect and having a dispatcher function call a map of functions but it seemed rather hacky and would prefer to use Bind.

Currently my setup is something like this. Looking for recommendations as I am rather stumped :S

Code: Select all

void MainWindow::OnTreeItemRightClick(wxTreeEvent& event)
{
	auto temp_selected = m_tree_view->GetItemData(event.GetItem());

	BaseData* tree_data = static_cast<BaseData*>(temp_selected);
	
	wxMenu menu;
	tree_data->AppendPopUpMenu(menu);

	PopupMenu(&menu);

	event.Skip();
	
}

Code: Select all

void MainWindow::OnUpdateDialog(wxCommandEvent& event)
{
        auto tree_data = (BaseData*)tree_panel_->GetItemData(event.GetItem());

	if(tree_data ->OpenDialog())
	{
		wxLogDebug("Opened the Dialog");
		//tree_panel_->SetItemText(tree_data ->GetId(), selected_data->get_property());
	}

}
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Help passing custom data to event

Post by doublemax »

Use GetPopupMenuSelectionFromUser(). It's a blocking call and returns with the ID of the selected menu entry. So you don't have to send around any data.
https://docs.wxwidgets.org/trunk/classw ... 682a61a93e
Use the source, Luke!
georgeplusplus
Knows some wx things
Knows some wx things
Posts: 25
Joined: Tue May 11, 2021 1:49 pm

Re: Help passing custom data to event

Post by georgeplusplus »

Doublemax this doesnt help since I am not having an issue getting the ID of the popup menu selection.

The provided code should explain what I am trying to do. Essentially, I am trying to open a dialog that is attached to a specific treedata member node since that dialog is a member and has properties the user may want to edit.

Any further suggestions?

Edit:

I think I see what you are getting at. In place of PopupMenu(&menu), use whatever value GetPopupMenuSelectionFromUser() returns to handle which ID the user selected and dispatch from the original function, this might work great!
georgeplusplus
Knows some wx things
Knows some wx things
Posts: 25
Joined: Tue May 11, 2021 1:49 pm

Re: Help passing custom data to event

Post by georgeplusplus »

I still need help. While I get the ID after calling GetPopupMenuSelectionFromUser, I still need to make some sort of dictionary that maps the wxID to the function I want to execute with the proper TreeItemData.

Ultimately what I trying to do is signal when the TreeItemData's PropertyDialog has been updated, I need a way to signal back to update the corresponding treectrl or other wxwidgets that rely on the elements in that dialog. Right now the treedata members dont have access to the mainwindow to push an event to it.
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Help passing custom data to event

Post by doublemax »

Sorry, i don't understand the problem. Inside OnTreeItemRightClick() you have all the information you need. Where on the "execution path" does it get lost?
Use the source, Luke!
georgeplusplus
Knows some wx things
Knows some wx things
Posts: 25
Joined: Tue May 11, 2021 1:49 pm

Re: Help passing custom data to event

Post by georgeplusplus »

It gets lost in OnUpdateDialog,

From OnTreeItemRightClick() , It populates menu selections based on the type of treeitem right clicked.

>> Rename
>> Change Date
>> Update Image
>> Save

Rename Item and Change date opens the treeitems property dialog which has the properties associated with it (Name, Date, Image)

Selecting one of these popupmenu options calls the function OnUpdateDialog(wxCommandEvent& event)

I want to create a way to signal back which dialog properties were changed to update them appropriately. Because different treeitems have different methods and my treeitemdata. Right now my treeitemdata has no reference back to ::MainWindow to post an event. I suppose I can add that reference when generating the treedata but it seems hacky.

Looking for suggestions or samples that deal with storing data inside a tree member and updating other class widgets when changed.
georgeplusplus
Knows some wx things
Knows some wx things
Posts: 25
Joined: Tue May 11, 2021 1:49 pm

Re: Help passing custom data to event

Post by georgeplusplus »

Had an idea to post the event from the dialog since it inherits from the mainwindow as a parent, however the event is not being generated.

Code: Select all

TreeItemDialog::TreeItemDialog(const bool image_field, wxWindow* parent, wxWindowID id,
	const wxString& title, const wxPoint& pos, const wxSize& size,
	long style,const wxString& name ) :
	wxDialog(parent, id, title, pos, size, style, name)
{

Code: Select all

bool TreeItemDialog::TransferDataFromWindow()
{
	
	// Called when we close

	if (name_ != nameText->GetValue())
	{
		wxLogDebug("Changing value");
		wxCommandEvent event(EVT_UPDATE_NAME);
		event.SetString(nameText->GetValue());
		wxPostEvent(this->GetParent(), event);
	}
	name_ = nameText->GetValue();
}
This is put inside the constructor of Mainwindow

Code: Select all

Bind(EVT_UPDATE_NAME, &MainWindow::OnUpdateName, this, window::id::PROPERTY_DIALOG);

Code: Select all

void MainWindow::OnUpdateName(wxCommandEvent& event)
{
	wxLogDebug("Signaled to change the name.");
}
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Help passing custom data to event

Post by doublemax »

How is EVT_UPDATE_NAME defined?

I suspect there is a mixup of eventtypes and/or ids. E.g. when you create the wxCommandEvent, you don't set the id, which should be window::id::PROPERTY_DIALOG to match your Bind() call.

In principle the code should work.
Use the source, Luke!
georgeplusplus
Knows some wx things
Knows some wx things
Posts: 25
Joined: Tue May 11, 2021 1:49 pm

Re: Help passing custom data to event

Post by georgeplusplus »

Updated to add the ID to the event constructor and confirmed the correct ID is being passed.
I create the define event in the cpp file of TreeItemDialog and bind to it in the constructor. I am wondering if because the Dialog Model is blocking it gets lost in some event queue or something.

Code: Select all

#include "include/TreeItemDialog.h"
#include "include/MainWindow.h"
#include <wx/artprov.h>

wxDEFINE_EVENT(EVT_UPDATE_NAME, wxCommandEvent);

TreeItemDialog::TreeItemDialog(const bool image_field, wxWindow* parent, wxWindowID id,
	const wxString& title, const wxPoint& pos, const wxSize& size,
	long style,const wxString& name ) :
	wxDialog(parent, id, title, pos, size, style, name)
{
	name_ = "Default Entry";
	filepath_ = "Enter the path here...";
	// Populate elements
	wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);

	// Elements associated with the name field
	wxBoxSizer* nameSizer = new wxBoxSizer(wxHORIZONTAL);

	wxStaticText* nameLabel = new wxStaticText(this, wxID_ANY, _("Name"));
	nameLabel->SetMinSize(wxSize(nameLabel->GetMinSize().x, nameLabel->GetMinSize().y));
	nameSizer->Add(nameLabel, 0, wxALL, 5);

	nameText = new wxTextCtrl(this, wxID_ANY);
	nameSizer->Add(nameText, 1);

	Bind(EVT_UPDATE_NAME, &MainWindow::OnUpdateName, (MainWindow*)parent, id);  //<<<<<<<<<<<

.....

Code: Select all

bool TreeItemDialog::TransferDataFromWindow()
{
	
	// Called when we close

	if (name_ != nameText->GetValue())
	{
		wxLogDebug(wxT("Posting to event ID n=%d"), this->GetId());
		wxCommandEvent event(EVT_UPDATE_NAME, this->GetId());
		event.SetString(nameText->GetValue());
		wxPostEvent((MainWindow*)this->GetParent(), event);
	}

	name_ = nameText->GetValue();
}
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Help passing custom data to event

Post by doublemax »

The Bind call should be in MainWindow, or you need to call parent->Bind() (ugly).
Use the source, Luke!
georgeplusplus
Knows some wx things
Knows some wx things
Posts: 25
Joined: Tue May 11, 2021 1:49 pm

Re: Help passing custom data to event

Post by georgeplusplus »

Bingo that was it.
Post Reply