From 6f792b7ffbc90ef535ba7ced09cf77a8110e87c0 Mon Sep 17 00:00:00 2001 From: Lukas Matena <lukasmatena@seznam.cz> Date: Thu, 17 May 2018 10:23:02 +0200 Subject: [PATCH] Horrible workaround to make the gcode preview dropdown (show feature types) work on all platforms --- xs/src/slic3r/GUI/wxExtensions.cpp | 31 +++++++++++++++++++++++------- xs/src/slic3r/GUI/wxExtensions.hpp | 15 +++++++++++++++ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 8bc282474..5949efb37 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -82,15 +82,27 @@ void wxCheckListBoxComboPopup::OnCheckListBox(wxCommandEvent& evt) { // forwards the checklistbox event to the owner wxComboCtrl - wxComboCtrl* cmb = GetComboCtrl(); - if (cmb != nullptr) + if (m_check_box_events_status == OnCheckListBoxFunction::FreeToProceed ) { - wxCommandEvent event(wxEVT_CHECKLISTBOX, cmb->GetId()); - event.SetEventObject(cmb); - cmb->ProcessWindowEvent(event); + wxComboCtrl* cmb = GetComboCtrl(); + if (cmb != nullptr) { + wxCommandEvent event(wxEVT_CHECKLISTBOX, cmb->GetId()); + event.SetEventObject(cmb); + cmb->ProcessWindowEvent(event); + } } evt.Skip(); + + #ifndef _WIN32 // events are sent differently on OSX+Linux vs Win (more description in header file) + if ( m_check_box_events_status == OnCheckListBoxFunction::RefuseToProceed ) + // this happens if the event was resent by OnListBoxSelection - next call to OnListBoxSelection is due to user clicking the text, so the function should + // explicitly change the state on the checkbox + m_check_box_events_status = OnCheckListBoxFunction::WasRefusedLastTime; + else + // if the user clicked the checkbox square, this event was sent before OnListBoxSelection was called, so we don't want it to resend it + m_check_box_events_status = OnCheckListBoxFunction::RefuseToProceed; + #endif } void wxCheckListBoxComboPopup::OnListBoxSelection(wxCommandEvent& evt) @@ -100,9 +112,14 @@ void wxCheckListBoxComboPopup::OnListBoxSelection(wxCommandEvent& evt) int selId = GetSelection(); if (selId != wxNOT_FOUND) { - Check((unsigned int)selId, !IsChecked((unsigned int)selId)); - SetSelection(wxNOT_FOUND); + #ifndef _WIN32 + if (m_check_box_events_status == OnCheckListBoxFunction::RefuseToProceed) + #endif + Check((unsigned int)selId, !IsChecked((unsigned int)selId)); + m_check_box_events_status = OnCheckListBoxFunction::FreeToProceed; // so the checkbox reacts to square-click the next time + + SetSelection(wxNOT_FOUND); wxCommandEvent event(wxEVT_CHECKLISTBOX, GetId()); event.SetInt(selId); event.SetEventObject(this); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index ed8bb9276..3667c7905 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -13,6 +13,21 @@ class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup wxString m_text; + // Events sent on mouseclick are quite complex. Function OnListBoxSelection is supposed to pass the event to the checkbox, which works fine on + // Win. On OSX and Linux the events are generated differently - clicking on the checkbox square generates the event twice (and the square + // therefore seems not to respond). + // This enum is meant to save current state of affairs, i.e., if the event forwarding is ok to do or not. It is only used on Linux + // and OSX by some #ifdefs. It also stores information whether OnListBoxSelection is supposed to change the checkbox status, + // or if it changed status on its own already (which happens when the square is clicked). More comments in OnCheckListBox(...) + // There indeed is a better solution, maybe making a custom event used for the event passing to distinguish the original and passed message + // and blocking one of them on OSX and Linux. Feel free to refactor, but carefully test on all platforms. + enum class OnCheckListBoxFunction{ + FreeToProceed, + RefuseToProceed, + WasRefusedLastTime + } m_check_box_events_status = OnCheckListBoxFunction::FreeToProceed; + + public: virtual bool Create(wxWindow* parent); virtual wxWindow* GetControl();