diff --git a/src/slic3r/GUI/StatusPanel.cpp b/src/slic3r/GUI/StatusPanel.cpp index 9d41b7c84f..c8fe0fddcc 100644 --- a/src/slic3r/GUI/StatusPanel.cpp +++ b/src/slic3r/GUI/StatusPanel.cpp @@ -3488,15 +3488,12 @@ void StatusPanel::update_ams_insert_material(MachineObject* obj) { void StatusPanel::update_ams_control_state(std::string ams_id, std::string slot_id) { - // set default value to true - bool enable[ACTION_BTN_COUNT]; - enable[ACTION_BTN_LOAD] = true; - enable[ACTION_BTN_UNLOAD] = true; + wxString load_error_info, unload_error_info; if (obj->is_in_printing() && !obj->can_resume()) { if (!obj->can_resume() || obj->is_in_extrusion_cali()) { - enable[ACTION_BTN_LOAD] = false; - enable[ACTION_BTN_UNLOAD] = false; + load_error_info = _L("The printer is busy on other print job"); + unload_error_info = _L("The printer is busy on other print job"); } } else { /*switch now*/ @@ -3509,38 +3506,45 @@ void StatusPanel::update_ams_control_state(std::string ams_id, std::string slot_ } if (in_switch_filament) { - enable[ACTION_BTN_LOAD] = false; - enable[ACTION_BTN_UNLOAD] = false; + load_error_info = _L("Current extruder is busy changing filament"); + unload_error_info = _L("Current extruder is busy changing filament"); } if (ams_id.empty() || slot_id.empty()) { - enable[ACTION_BTN_LOAD] = false; - enable[ACTION_BTN_UNLOAD] = false; + load_error_info = _L("Choose an AMS slot then press \"Load\" or \"Unload\" button to automatically load or unload filaments."); + unload_error_info = _L("Choose an AMS slot then press \"Load\" or \"Unload\" button to automatically load or unload filaments."); } else if (ams_id == std::to_string(VIRTUAL_TRAY_MAIN_ID) || ams_id == std::to_string(VIRTUAL_TRAY_DEPUTY_ID)) { for (auto ext : obj->m_extder_data.extders) { - if (ext.snow.ams_id == ams_id && ext.snow.slot_id == slot_id) { enable[ACTION_BTN_LOAD] = false; } + if (ext.snow.ams_id == ams_id && ext.snow.slot_id == slot_id) { + load_error_info = _L("Current slot has alread been loaded"); + } } } else { for (auto ext : obj->m_extder_data.extders) { - if (ext.snow.ams_id == ams_id && ext.snow.slot_id == slot_id) { enable[ACTION_BTN_LOAD] = false; } + if (ext.snow.ams_id == ams_id && ext.snow.slot_id == slot_id) { + load_error_info = _L("Current slot has alread been loaded"); + } } /*empty*/ std::map::iterator it = obj->amsList.find(ams_id); if (it == obj->amsList.end()) { - enable[ACTION_BTN_LOAD] = false; - + load_error_info = _L("Choose an AMS slot then press \"Load\" or \"Unload\" button to automatically load or unload filaments."); } else { auto tray_it = it->second->trayList.find(slot_id); + if (tray_it == it->second->trayList.end()) { + load_error_info = _L("Choose an AMS slot then press \"Load\" or \"Unload\" button to automatically load or unload filaments."); + } - if (tray_it == it->second->trayList.end()) { enable[ACTION_BTN_LOAD] = false; } - - if (!tray_it->second->is_exists) { enable[ACTION_BTN_LOAD] = false; } + if (!tray_it->second->is_exists) { + load_error_info = _L("The selected slot is empty."); + } } } } - m_ams_control->SetActionState(enable); + m_ams_control->EnableLoadFilamentBtn(load_error_info.empty(), ams_id, slot_id, load_error_info); + m_ams_control->EnableUnLoadFilamentBtn(unload_error_info.empty(), ams_id, slot_id,unload_error_info); } void StatusPanel::update_cali(MachineObject *obj) diff --git a/src/slic3r/GUI/Widgets/AMSControl.cpp b/src/slic3r/GUI/Widgets/AMSControl.cpp index 8816c9b915..d838e412c6 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.cpp +++ b/src/slic3r/GUI/Widgets/AMSControl.cpp @@ -186,6 +186,7 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons m_button_extruder_feed->SetTextColor(btn_text_green); m_button_extruder_feed->SetMinSize(wxSize(FromDIP(80),FromDIP(34))); m_button_extruder_feed->SetMaxSize(wxSize(FromDIP(80),FromDIP(34))); + m_button_extruder_feed->EnableTooltipEvenDisabled(); if (wxGetApp().app_config->get("language") == "de_DE") m_button_extruder_feed->SetFont(Label::Body_9); @@ -206,6 +207,7 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons m_button_extruder_back->SetFont(Label::Body_13); m_button_extruder_back->SetMinSize(wxSize(FromDIP(80), FromDIP(34))); m_button_extruder_back->SetMaxSize(wxSize(FromDIP(80), FromDIP(34))); + m_button_extruder_back->EnableTooltipEvenDisabled(); if (wxGetApp().app_config->get("language") == "de_DE") m_button_extruder_back->SetFont(Label::Body_9); if (wxGetApp().app_config->get("language") == "fr_FR") m_button_extruder_back->SetFont(Label::Body_9); @@ -406,13 +408,22 @@ wxColour AMSControl::GetCanColour(std::string amsid, std::string canid) return col; } -void AMSControl::SetActionState(bool button_status[]) +void AMSControl::EnableLoadFilamentBtn(bool enable, const std::string& ams_id, const std::string& can_id,const wxString& tips) { - if (button_status[ActionButton::ACTION_BTN_LOAD]) m_button_extruder_feed->Enable(); - else m_button_extruder_feed->Disable(); + m_button_extruder_feed->Enable(enable); + if (m_button_extruder_feed->GetToolTipText() != tips) { + BOOST_LOG_TRIVIAL(info) << "ams_id=" << ams_id << ", can_id=" << can_id << " Set Load Filament Button ToolTip : " << tips.ToUTF8(); + m_button_extruder_feed->SetToolTip(tips); + } +} - if (button_status[ActionButton::ACTION_BTN_UNLOAD]) m_button_extruder_back->Enable(); - else m_button_extruder_back->Disable(); +void AMSControl::EnableUnLoadFilamentBtn(bool enable, const std::string& ams_id, const std::string& can_id,const wxString& tips) +{ + m_button_extruder_back->Enable(enable); + if (m_button_extruder_back->GetToolTipText() != tips) { + BOOST_LOG_TRIVIAL(info) << "ams_id=" << ams_id << ", can_id=" << can_id << " Set Unload Filament Button ToolTip : " << tips.ToUTF8(); + m_button_extruder_back->SetToolTip(tips); + } } void AMSControl::EnterNoneAMSMode() diff --git a/src/slic3r/GUI/Widgets/AMSControl.hpp b/src/slic3r/GUI/Widgets/AMSControl.hpp index 34fa5edadf..891018f6de 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.hpp +++ b/src/slic3r/GUI/Widgets/AMSControl.hpp @@ -138,7 +138,9 @@ public: void SetAmsModel(AMSModel mode, AMSModel ext_mode) {m_ams_model = mode; m_ext_model = ext_mode;}; void AmsSelectedSwitch(wxCommandEvent& event); - void SetActionState(bool button_status[]); + void EnableLoadFilamentBtn(bool enable, const std::string& ams_id, const std::string& can_id, const wxString& tips); + void EnableUnLoadFilamentBtn(bool enable, const std::string& ams_id, const std::string& can_id,const wxString& tips); + void EnterNoneAMSMode(); void EnterGenericAMSMode(); void EnterExtraAMSMode(); diff --git a/src/slic3r/GUI/Widgets/Button.cpp b/src/slic3r/GUI/Widgets/Button.cpp index d77c38c826..ecfe90ef24 100644 --- a/src/slic3r/GUI/Widgets/Button.cpp +++ b/src/slic3r/GUI/Widgets/Button.cpp @@ -2,6 +2,7 @@ #include "Label.hpp" #include +#include #ifdef __APPLE__ #include "libslic3r/MacUtils.hpp" #endif @@ -480,4 +481,72 @@ WXLRESULT Button::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) #endif -bool Button::AcceptsFocus() const { return canFocus; } \ No newline at end of file +bool Button::AcceptsFocus() const { return canFocus; } + +void Button::EnableTooltipEvenDisabled() +{ + auto parent = this->GetParent(); + if (parent) + { + parent->Bind(wxEVT_MOTION, &Button::OnParentMotion, this); + parent->Bind(wxEVT_LEAVE_WINDOW, &Button::OnParentLeave, this); + }; +}; + +void Button::OnParentMotion(wxMouseEvent& event) +{ + auto parent = this->GetParent(); + if (!parent) return event.Skip(); + + wxPoint pos = parent->ClientToScreen(event.GetPosition()); + wxRect screen_rect = this->GetScreenRect(); + wxString tip = this->GetToolTipText(); + if (!tip.IsEmpty() && !this->IsEnabled() && screen_rect.Contains(pos)) + { + if (!tipWindow) + { + tipWindow = new wxTipWindow(this, tip); + tipWindow->Bind(wxEVT_DESTROY, [this](wxEvent& event) { this->tipWindow = nullptr;}); + tipWindow->Enable(false); + } + + if (tipWindow->GetLabel() != tip) + { + tipWindow->SetLabel(tip); + } + + tipWindow->Position(wxGetMousePosition(), wxSize(0, 0)); + tipWindow->Popup(); + } + else + { + if (tipWindow) + { + delete tipWindow; + tipWindow = nullptr; + } + } + + event.Skip(); +} + +void Button::OnParentLeave(wxMouseEvent& event) +{ + auto parent = this->GetParent(); + if (!parent) return event.Skip(); + + if (tipWindow) + { + wxPoint pos = parent->ClientToScreen(event.GetPosition()); + wxRect screen_rect = this->GetScreenRect(); + wxString tip = this->GetToolTipText(); + if (!screen_rect.Contains(pos)) + { + tipWindow->Dismiss(); + delete tipWindow; + tipWindow = nullptr; + } + } + + event.Skip(); +} diff --git a/src/slic3r/GUI/Widgets/Button.hpp b/src/slic3r/GUI/Widgets/Button.hpp index 1ff2beb5ee..a5ba989db3 100644 --- a/src/slic3r/GUI/Widgets/Button.hpp +++ b/src/slic3r/GUI/Widgets/Button.hpp @@ -26,6 +26,7 @@ enum class ButtonType{ Expanded , // Font14 Semi-Rounded For full length buttons. ex. buttons in static box }; +class wxTipWindow; class Button : public StaticBox { wxRect textSize; @@ -42,6 +43,8 @@ class Button : public StaticBox bool isCenter = true; bool vertical = false; + wxTipWindow* tipWindow = nullptr; + static const int buttonWidth = 200; static const int buttonHeight = 50; @@ -74,6 +77,7 @@ public: void SetSelected(bool selected = true) { m_selected = selected; } bool Enable(bool enable = true) override; + void EnableTooltipEvenDisabled();// The tip will be shown even if the button is disabled void SetCanFocus(bool canFocus) override; @@ -111,8 +115,13 @@ private: void mouseCaptureLost(wxMouseCaptureLostEvent &event); void keyDownUp(wxKeyEvent &event); + // void sendButtonEvent(); + // parent motion + void OnParentMotion(wxMouseEvent& event); + void OnParentLeave(wxMouseEvent& event); + DECLARE_EVENT_TABLE() };