Reputation: 1
I'm trying to create a GUI with wxWidgets in C++, where the user can double click on the main panel to add and remove circles. When a user single clicks on one of these circles, I want it to toggle isSelected
and change its appearance, as well as de-selecting all the other circles and changing their appearance.
To do this, I've made a custom widget inheriting wxWindow to control the appearance. I can get it to work where clicking on a CustomWidgetCircle
element will make it selected, and clicking on the background panel WidgetPanel
will deselect all, but I am not able to figure out how to get the WidgetPanel
to respond and change its children's data by clicking on a CustomWidgetCircle
.
Code excerpts below. Right now, dynamic bindings are happening in the respective constructors.
// CustomWidgetCircle.h
class CustomWidgetCircle : public wxWindow {
public:
CustomWidgetCircle(wxPanel* parent, wxString label, wxPoint location);
bool isSelected = false;
private:
void OnMouseDown(wxMouseEvent& event);
void OnPaintEvent(wxPaintEvent& event);
void Render(wxDC& dc);
};
// CustomWidgetCircle.cpp
...
CustomWidgetCircle
CustomWidgetCircle::OnMouseDown(wxMouseEvent& event) {
this->isSelected = !this->isSelected;
Refresh();
}
...
// WidgetPanel.h
class WidgetPanel : public wxPanel {
public:
WidgetPanel(wxFrame* parent);
private:
void OnDoubleClick(wxMouseEvent& event);
void OnMouseDown
std::list<CustomWidgetCircle*> CustomWidgetCircleList;
};
// WidgetPanel.cpp
...
WidgetPanel::OnDoubleClick(wxMouseEvent& event) {
CustomWidgetCircle* newCircle = new CustomWidgetCircle(this, "lbl", event.GetPosition());
CustomWidgetCircleList.push_back(newCircle);
Refresh();
}
WidgetPanel::OnMouseDown(wxMouseEvent& event) {
for (auto circle_ptr : CustomWidgetCircleList) {
circle_ptr->isSelected = false;
}
Refresh();
}
...
What I've tried:
Skip()
in the call to OnMouseDown
on the child windows to pass the event up to the parent. Seems to do nothing.OnMouseDown
handler to the parent frame and calling GetEventObject()
on the event arg in order to modify the child window that's been clicked on, but that won't work because it returns a wxObject
so I can't access member methods / data for my custom class.OnMouseDown
handler on the parent from the child window, but I can't work out how to make parent methods accessible from the child.Fully admit I'm missing a fair amount on how event handling works, but I've been through the docs several times now and am no closer. If any of the above could work and I'm missing some details, please let me know. I can provide more code to make it reproducible but it's not a bug per se. Thanks in advance.
Upvotes: 0
Views: 67
Reputation: 22688
wxWidgets event handling system is very flexible (perhaps too much so), so there are many possible solutions, but I'd start with the simplest one:
child->Bind(wxEVT_LEFT_DOWN, &WidgetPanel::OnChildLeftDown, this)
for each child
.OnChildLeftDown()
handler deselect all the other children.event.Skip()
to let the child handle the event too.Upvotes: 0