mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-02 15:52:14 +00:00
fix: freezing caused by dynamically hidden printer edit button (#14010)
* fix: freezing caused by dynamically hidden printer edit button * track hover state of individual widgets
This commit is contained in:
@@ -1796,39 +1796,35 @@ Sidebar::Sidebar(Plater *parent)
|
|||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
// ORCA use Show/Hide to gain text area instead using blank icon. also manages hover effect for border
|
// ORCA use Show/Hide to gain text area instead using blank icon. also manages hover effect for border
|
||||||
|
auto printer_preset_hovered = std::make_shared<std::unordered_set<wxWindow*>>();
|
||||||
for (wxWindow *w : std::initializer_list<wxWindow *>{p->panel_printer_preset, p->btn_edit_printer, p->image_printer, p->combo_printer}) {
|
for (wxWindow *w : std::initializer_list<wxWindow *>{p->panel_printer_preset, p->btn_edit_printer, p->image_printer, p->combo_printer}) {
|
||||||
w->Bind(wxEVT_ENTER_WINDOW, [this, panel_color](wxMouseEvent &e) {
|
w->Bind(wxEVT_ENTER_WINDOW, [this, w, panel_color, printer_preset_hovered](wxMouseEvent &e) {
|
||||||
|
printer_preset_hovered->insert(w);
|
||||||
if(!p->combo_printer->HasFocus())
|
if(!p->combo_printer->HasFocus())
|
||||||
p->panel_printer_preset->SetBorderColor(panel_color.bd_hover);
|
p->panel_printer_preset->SetBorderColor(panel_color.bd_hover);
|
||||||
if(!p->btn_edit_printer->IsShown()){
|
|
||||||
p->btn_edit_printer->Show();
|
|
||||||
p->panel_printer_preset->Layout();
|
|
||||||
}
|
|
||||||
e.Skip();
|
e.Skip();
|
||||||
});
|
});
|
||||||
w->Bind(wxEVT_LEAVE_WINDOW, [this, panel_color](wxMouseEvent &e) {
|
w->Bind(wxEVT_LEAVE_WINDOW, [this, w, panel_color, printer_preset_hovered](wxMouseEvent &e) {
|
||||||
// Orca: if the edit button is already hidden the handler has no
|
printer_preset_hovered->erase(w);
|
||||||
// state to change, so skip the expensive wxFindWindowAtPoint tree
|
if (printer_preset_hovered->empty() && !p->combo_printer->HasFocus())
|
||||||
// walk. Without this guard, when the parent window is on an
|
p->panel_printer_preset->SetBorderColor(panel_color.bd_normal);
|
||||||
// inactive Hyprland/Wayland workspace, GTK keeps delivering
|
|
||||||
// synthetic leave events and the Hide()+Layout() below re-enters
|
|
||||||
// the same handler in a feedback loop that pegs a CPU core.
|
|
||||||
// (IsShownOnScreen() can't be used here — see Plater.cpp:9304.)
|
|
||||||
if (!p->btn_edit_printer->IsShown()) { e.Skip(); return; }
|
|
||||||
// Use event-relative coords instead of wxGetMousePosition() which
|
|
||||||
// returns (0,0) on Wayland for global screen coordinates.
|
|
||||||
wxWindow* evtObj = dynamic_cast<wxWindow*>(e.GetEventObject());
|
|
||||||
wxPoint screenPos = evtObj ? evtObj->ClientToScreen(e.GetPosition()) : wxGetMousePosition();
|
|
||||||
wxWindow* next_w = wxFindWindowAtPoint(screenPos);
|
|
||||||
if (!next_w || !p->panel_printer_preset->IsDescendant(next_w)){
|
|
||||||
if(!p->combo_printer->HasFocus())
|
|
||||||
p->panel_printer_preset->SetBorderColor(panel_color.bd_normal);
|
|
||||||
p->btn_edit_printer->Hide();
|
|
||||||
p->panel_printer_preset->Layout();
|
|
||||||
}
|
|
||||||
e.Skip();
|
e.Skip();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// Perform show/hide in wxEVT_IDLE after enter/leave events have settled.
|
||||||
|
// This prevents the extraneous enter/leave events generated by the
|
||||||
|
// layout change itself from causing a feedback loop.
|
||||||
|
Bind(wxEVT_IDLE, [this, printer_preset_hovered](wxIdleEvent &e) {
|
||||||
|
auto hovered = !printer_preset_hovered->empty();
|
||||||
|
if (p->btn_edit_printer->IsShown() != hovered) {
|
||||||
|
if (hovered) {
|
||||||
|
p->btn_edit_printer->Show();
|
||||||
|
} else {
|
||||||
|
p->btn_edit_printer->Hide();
|
||||||
|
}
|
||||||
|
p->panel_printer_preset->Layout();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// ORCA unified Nozzle diameter selection
|
// ORCA unified Nozzle diameter selection
|
||||||
p->panel_nozzle_dia = new StaticBox(p->m_panel_printer_content);
|
p->panel_nozzle_dia = new StaticBox(p->m_panel_printer_content);
|
||||||
@@ -1874,19 +1870,17 @@ Sidebar::Sidebar(Plater *parent)
|
|||||||
p->label_nozzle_type->SetMaxSize(FromDIP(wxSize(56, -1)));
|
p->label_nozzle_type->SetMaxSize(FromDIP(wxSize(56, -1)));
|
||||||
|
|
||||||
// highlight border on hover
|
// highlight border on hover
|
||||||
|
auto nozzle_dia_hovered = std::make_shared<std::unordered_set<wxWindow*>>();
|
||||||
for (wxWindow *w : std::initializer_list<wxWindow *>{p->panel_nozzle_dia, p->label_nozzle_title, p->label_nozzle_type, p->combo_nozzle_dia}) {
|
for (wxWindow *w : std::initializer_list<wxWindow *>{p->panel_nozzle_dia, p->label_nozzle_title, p->label_nozzle_type, p->combo_nozzle_dia}) {
|
||||||
w->Bind(wxEVT_ENTER_WINDOW, [this, panel_color](wxMouseEvent &e) {
|
w->Bind(wxEVT_ENTER_WINDOW, [this, w, panel_color, nozzle_dia_hovered](wxMouseEvent &e) {
|
||||||
|
nozzle_dia_hovered->insert(w);
|
||||||
if(!p->combo_nozzle_dia->HasFocus())
|
if(!p->combo_nozzle_dia->HasFocus())
|
||||||
p->panel_nozzle_dia->SetBorderColor(panel_color.bd_hover);
|
p->panel_nozzle_dia->SetBorderColor(panel_color.bd_hover);
|
||||||
e.Skip();
|
e.Skip();
|
||||||
});
|
});
|
||||||
w->Bind(wxEVT_LEAVE_WINDOW, [this, panel_color](wxMouseEvent &e) {
|
w->Bind(wxEVT_LEAVE_WINDOW, [this, w, panel_color, nozzle_dia_hovered](wxMouseEvent &e) {
|
||||||
// Use event-relative coords instead of wxGetMousePosition() which
|
nozzle_dia_hovered->erase(w);
|
||||||
// returns (0,0) on Wayland for global screen coordinates.
|
if (nozzle_dia_hovered->empty() && !p->combo_nozzle_dia->HasFocus())
|
||||||
wxWindow* evtObj = dynamic_cast<wxWindow*>(e.GetEventObject());
|
|
||||||
wxPoint screenPos = evtObj ? evtObj->ClientToScreen(e.GetPosition()) : wxGetMousePosition();
|
|
||||||
wxWindow* next_w = wxFindWindowAtPoint(screenPos);
|
|
||||||
if (!p->combo_nozzle_dia->HasFocus() && (!next_w || !p->panel_nozzle_dia->IsDescendant(next_w)))
|
|
||||||
p->panel_nozzle_dia->SetBorderColor(panel_color.bd_normal);
|
p->panel_nozzle_dia->SetBorderColor(panel_color.bd_normal);
|
||||||
e.Skip();
|
e.Skip();
|
||||||
});
|
});
|
||||||
@@ -1946,21 +1940,19 @@ Sidebar::Sidebar(Plater *parent)
|
|||||||
p->combo_printer_bed->Bind(wxEVT_KILL_FOCUS, [this, bed_focus_bg](auto& e) {bed_focus_bg(false); e.Skip();});
|
p->combo_printer_bed->Bind(wxEVT_KILL_FOCUS, [this, bed_focus_bg](auto& e) {bed_focus_bg(false); e.Skip();});
|
||||||
|
|
||||||
// highlight border on hover
|
// highlight border on hover
|
||||||
|
auto printer_bed_hovered = std::make_shared<std::unordered_set<wxWindow*>>();
|
||||||
for (wxWindow *w : std::initializer_list<wxWindow *>{p->panel_printer_bed, p->image_printer_bed, p->combo_printer_bed}) {
|
for (wxWindow *w : std::initializer_list<wxWindow *>{p->panel_printer_bed, p->image_printer_bed, p->combo_printer_bed}) {
|
||||||
w->Bind(wxEVT_ENTER_WINDOW, [this, w, panel_color](wxMouseEvent &e) {
|
w->Bind(wxEVT_ENTER_WINDOW, [this, w, panel_color, printer_bed_hovered](wxMouseEvent &e) {
|
||||||
|
printer_bed_hovered->insert(w);
|
||||||
if(!p->combo_printer_bed->HasFocus())
|
if(!p->combo_printer_bed->HasFocus())
|
||||||
p->panel_printer_bed->SetBorderColor(panel_color.bd_hover);
|
p->panel_printer_bed->SetBorderColor(panel_color.bd_hover);
|
||||||
if(w == p->image_printer_bed && !p->combo_printer_bed->is_drop_down()) // dont trigger while combo open
|
if(w == p->image_printer_bed && !p->combo_printer_bed->is_drop_down()) // dont trigger while combo open
|
||||||
on_enter_image_printer_bed(e);
|
on_enter_image_printer_bed(e);
|
||||||
e.Skip();
|
e.Skip();
|
||||||
});
|
});
|
||||||
w->Bind(wxEVT_LEAVE_WINDOW, [this, w, panel_color](wxMouseEvent &e) {
|
w->Bind(wxEVT_LEAVE_WINDOW, [this, w, panel_color, printer_bed_hovered](wxMouseEvent &e) {
|
||||||
// Use event-relative coords instead of wxGetMousePosition() which
|
printer_bed_hovered->erase(w);
|
||||||
// returns (0,0) on Wayland for global screen coordinates.
|
if (printer_bed_hovered->empty() && !p->combo_printer_bed->HasFocus())
|
||||||
wxWindow* evtObj = dynamic_cast<wxWindow*>(e.GetEventObject());
|
|
||||||
wxPoint screenPos = evtObj ? evtObj->ClientToScreen(e.GetPosition()) : wxGetMousePosition();
|
|
||||||
wxWindow* next_w = wxFindWindowAtPoint(screenPos);
|
|
||||||
if (!p->combo_printer_bed->HasFocus() && (!next_w || !p->panel_printer_bed->IsDescendant(next_w)))
|
|
||||||
p->panel_printer_bed->SetBorderColor(panel_color.bd_normal);
|
p->panel_printer_bed->SetBorderColor(panel_color.bd_normal);
|
||||||
if(w == p->image_printer_bed)
|
if(w == p->image_printer_bed)
|
||||||
on_leave_image_printer_bed(e);
|
on_leave_image_printer_bed(e);
|
||||||
|
|||||||
Reference in New Issue
Block a user