BambuStudio/src/slic3r/GUI/Widgets/PopupWindow.cpp

86 lines
2.2 KiB
C++

#include "PopupWindow.hpp"
static wxWindow *GetTopParent(wxWindow *pWindow)
{
wxWindow *pWin = pWindow;
while (pWin->GetParent()) {
pWin = pWin->GetParent();
if (auto top = dynamic_cast<wxNonOwnedWindow*>(pWin))
return top;
}
return pWin;
}
bool PopupWindow::Create(wxWindow *parent, int style)
{
if (!wxPopupTransientWindow::Create(parent, 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;
}
PopupWindow::~PopupWindow()
{
#ifdef __WXGTK__
GetTopParent(this)->Unbind(wxEVT_ACTIVATE, &PopupWindow::topWindowActivate, this);
#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<wxWindow*>(hovered)->GetId());
hovered->ProcessEventLocally(leave);
hovered = h;
wxMouseEvent enter(wxEVT_ENTER_WINDOW);
enter.SetEventObject(hovered);
enter.SetId(static_cast<wxWindow*>(hovered)->GetId());
hovered->ProcessEventLocally(enter);
}
}
if (child) {
child->ProcessEventLocally(evt);
} else {
evt.Skip();
}
}
#endif
#ifdef __WXGTK__
void PopupWindow::topWindowActivate(wxActivateEvent &event)
{
event.Skip();
}
#endif