From 23e30c7227474adf4efe5ee93f985e1140da9b6f Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Wed, 27 Nov 2024 14:54:55 +0800 Subject: [PATCH] FIX: transfer input events to children of PopupWindow Change-Id: I2ff9ba91a548402d77308aa88de34976a146a571 Jira: STUDIO-8942 --- src/slic3r/GUI/Plater.cpp | 22 ++++++------ src/slic3r/GUI/Widgets/PopupWindow.cpp | 49 ++++++++++++++++++++++++++ src/slic3r/GUI/Widgets/PopupWindow.hpp | 7 +++- 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index c29cbf45f..01c1bd76f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -725,17 +725,17 @@ public: wxSizer * sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(msg, 0, wxTOP | wxLEFT | wxRIGHT, FromDIP(10)); - wxSizer * sizer2 = new wxBoxSizer(wxHORIZONTAL); - wxSizer *sizer21 = new wxBoxSizer(wxVERTICAL); - sizer21->Add(img4, 0, wxALIGN_CENTRE_HORIZONTAL); - sizer21->Add(txt4, 0, wxTOP | wxALIGN_CENTRE_HORIZONTAL, FromDIP(10)); - sizer21->Add(val4, 0, wxTOP | wxALIGN_CENTRE_HORIZONTAL, FromDIP(10)); - sizer2->Add(sizer21, 1); - wxSizer *sizer22 = new wxBoxSizer(wxVERTICAL); - sizer22->Add(img1, 0, wxALIGN_CENTRE_HORIZONTAL); - sizer22->Add(txt1, 0, wxTOP | wxALIGN_CENTRE_HORIZONTAL, FromDIP(10)); - sizer22->Add(val1, 0, wxTOP | wxALIGN_CENTRE_HORIZONTAL, FromDIP(10)); - sizer2->Add(sizer22, 1); + wxSizer * sizer2 = new wxBoxSizer(wxHORIZONTAL); + wxSizer *sizer21 = new wxBoxSizer(wxVERTICAL); + sizer21->Add(img4, 0, wxALIGN_CENTRE); + sizer21->Add(txt4, 0, wxTOP | wxALIGN_CENTRE, FromDIP(10)); + sizer21->Add(val4, 0, wxTOP | wxALIGN_CENTRE, FromDIP(10)); + sizer2->Add(sizer21, 1); + wxSizer *sizer22 = new wxBoxSizer(wxVERTICAL); + sizer22->Add(img1, 0, wxALIGN_CENTRE); + sizer22->Add(txt1, 0, wxTOP | wxALIGN_CENTRE, FromDIP(10)); + sizer22->Add(val1, 0, wxTOP | wxALIGN_CENTRE, FromDIP(10)); + sizer2->Add(sizer22, 1); sizer->Add(sizer2, 0, wxTOP | wxBOTTOM | wxLEFT | wxRIGHT | wxEXPAND, FromDIP(10)); SetSizer(sizer); diff --git a/src/slic3r/GUI/Widgets/PopupWindow.cpp b/src/slic3r/GUI/Widgets/PopupWindow.cpp index 734963580..6cc91bb87 100644 --- a/src/slic3r/GUI/Widgets/PopupWindow.cpp +++ b/src/slic3r/GUI/Widgets/PopupWindow.cpp @@ -17,6 +17,11 @@ bool PopupWindow::Create(wxWindow *parent, int style) return false; #ifdef __WXGTK__ GetTopParent(parent)->Bind(wxEVT_ACTIVATE, &PopupWindow::topWindowActivate, this); +#endif +#ifdef __WXOSX__ + if (style & wxPU_CONTAINS_CONTROLS) + for (auto evt : {wxEVT_LEFT_DOWN, wxEVT_LEFT_UP, wxEVT_LEFT_DCLICK, wxEVT_MOTION, wxEVT_MOUSEWHEEL}) + Bind(evt, &PopupWindow::OnMouseEvent2, this); #endif return true; } @@ -28,6 +33,50 @@ PopupWindow::~PopupWindow() #endif } +#ifdef __WXOSX__ + +static wxEvtHandler * HitTest(wxWindow * parent, wxMouseEvent &evt) +{ + auto pt = evt.GetPosition(); + const wxWindowList &children = parent->GetChildren(); + for (auto w : children) { + wxRect rc { w->GetPosition(), w->GetSize() }; + if (rc.Contains(pt)) { + evt.SetPosition(pt - rc.GetTopLeft()); + if (auto child = HitTest(w, evt)) + return child; + return w; + } + } + return nullptr; +} + +void PopupWindow::OnMouseEvent2(wxMouseEvent &evt) +{ + auto child = ::HitTest(this, evt); + if (evt.GetEventType() == wxEVT_MOTION) { + auto h = child ? child : this; + if (hovered != h) { + wxMouseEvent leave(wxEVT_LEAVE_WINDOW); + leave.SetEventObject(hovered); + leave.SetId(static_cast(hovered)->GetId()); + hovered->ProcessEventLocally(leave); + hovered = h; + wxMouseEvent enter(wxEVT_ENTER_WINDOW); + enter.SetEventObject(hovered); + enter.SetId(static_cast(hovered)->GetId()); + hovered->ProcessEventLocally(enter); + } + } + if (child) { + child->ProcessEventLocally(evt); + } else { + evt.Skip(); + } +} + +#endif + #ifdef __WXGTK__ void PopupWindow::topWindowActivate(wxActivateEvent &event) { diff --git a/src/slic3r/GUI/Widgets/PopupWindow.hpp b/src/slic3r/GUI/Widgets/PopupWindow.hpp index f820be8c7..7b1c573b2 100644 --- a/src/slic3r/GUI/Widgets/PopupWindow.hpp +++ b/src/slic3r/GUI/Widgets/PopupWindow.hpp @@ -12,10 +12,15 @@ public: PopupWindow(wxWindow *parent, int style = wxBORDER_NONE) { Create(parent, style); } - + bool Create(wxWindow *parent, int flags = wxBORDER_NONE); private: +#ifdef __WXOSX__ + void OnMouseEvent2(wxMouseEvent &evt); + wxEvtHandler * hovered { this }; +#endif + #ifdef __WXGTK__ void topWindowActivate(wxActivateEvent &event); #endif