diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 2c9ac72c7e..fef848ff3c 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -8281,15 +8281,15 @@ void GUI_App::open_speed_dial() { if (!mainframe) return; - if (!m_speed_dial_popup) { - m_speed_dial_popup = new SpeedDialWebPopup(mainframe); - m_speed_dial_popup->Bind(wxEVT_DESTROY, [this](wxWindowDestroyEvent& event) { - if (event.GetEventObject() == m_speed_dial_popup) - m_speed_dial_popup = nullptr; + if (!m_speed_dial_dialog) { + m_speed_dial_dialog = new SpeedDialWebDialog(mainframe); + m_speed_dial_dialog->Bind(wxEVT_DESTROY, [this](wxWindowDestroyEvent& event) { + if (event.GetEventObject() == m_speed_dial_dialog) + m_speed_dial_dialog = nullptr; event.Skip(); }); } - m_speed_dial_popup->request_show(); + m_speed_dial_dialog->request_show(); } void GUI_App::open_exportpresetbundledialog(size_t open_on_tab, const std::string& highlight_option) diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 1a5205071b..d8a8e07d80 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -87,7 +87,7 @@ class ModelMallDialog; class PingCodeBindDialog; class NetworkErrorDialog; class PluginsDialog; -class SpeedDialWebPopup; +class SpeedDialWebDialog; class TerminalDialog; @@ -555,7 +555,7 @@ public: PresetBundleDialog* m_preset_bundle_dlg{nullptr}; PluginsDialog* m_plugins_dlg{nullptr}; - SpeedDialWebPopup* m_speed_dial_popup{nullptr}; + SpeedDialWebDialog* m_speed_dial_dialog{nullptr}; TerminalDialog* m_terminal_dlg{nullptr}; ActionRegistry m_action_registry; diff --git a/src/slic3r/GUI/SpeedDialPopup.cpp b/src/slic3r/GUI/SpeedDialPopup.cpp index b03374b089..8a614d0a47 100644 --- a/src/slic3r/GUI/SpeedDialPopup.cpp +++ b/src/slic3r/GUI/SpeedDialPopup.cpp @@ -300,4 +300,130 @@ void SpeedDialWebPopup::send_actions() {"favourites", std::move(snap["favourites"])}}); } +SpeedDialWebDialog::SpeedDialWebDialog(wxWindow* parent) + : WebViewHostDialog(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, + wxBORDER_NONE | wxFRAME_NO_TASKBAR) +{ + SetBackgroundColour(bg_color()); + Bind(wxEVT_ACTIVATE, [this](wxActivateEvent& event) { + if (!event.GetActive() && IsShown()) + Hide(); + event.Skip(); + }); + if (!create_webview("web/dialog/SpeedDial/index.html", wxEmptyString, + wxSize(kPopupWidth, kPopupMaxHeight), wxSize(kPopupWidth, kPopupMinHeight))) { + auto* sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(new wxStaticText(this, wxID_ANY, wxS("wxWebView unavailable")), + wxSizerFlags().Border(wxALL, 20)); + SetSizer(sizer); + SetClientSize(FromDIP(wxSize(kPopupWidth, kPopupMinHeight))); + } +} + +void SpeedDialWebDialog::request_show() +{ + if (IsShown()) { + Raise(); + if (browser()) + browser()->SetFocus(); + return; + } + + Show(); + Raise(); + if (m_page_ready) + send_actions(); + if (browser()) + browser()->SetFocus(); +} + +void SpeedDialWebDialog::on_script_message(const nlohmann::json& payload) +{ + if (handle_common_script_command(payload)) + return; + + const std::string command = payload.value("command", ""); + if (command == "request_actions") { + m_page_ready = true; + send_actions(); + } + else if (command == "toggle_favourite") + wxGetApp().action_registry().set_favourite(payload.value("id", ""), payload.value("fav", false)); + else if (command == "reorder_favourites") { + std::vector ids; + if (payload.contains("ids") && payload["ids"].is_array()) + for (const auto& id : payload["ids"]) + if (id.is_string()) + ids.push_back(id.get()); + wxGetApp().action_registry().reorder_favourites(ids); + } + else if (command == "run_action") + run_action(payload.value("id", ""), payload.value("title", "")); + else if (command == "resize") + resize_to_content(json_int_or(payload, "height", 0)); +} + +void SpeedDialWebDialog::resize_to_content(int height) +{ + if (height <= 0) + return; + + int display_index = wxDisplay::GetFromWindow(this); + if (display_index == wxNOT_FOUND) + display_index = 0; + const int screen_dip = ToDIP(wxDisplay(display_index).GetClientArea().GetHeight()); + const int max_dip = std::max(kPopupMinHeight, screen_dip * 85 / 100); + const int height_dip = std::max(kPopupMinHeight, std::min(height, max_dip)); + SetClientSize(FromDIP(wxSize(kPopupWidth, height_dip))); + Layout(); +} + +void SpeedDialWebDialog::run_action(const std::string& id, const std::string& title) +{ + ActionRegistry& reg = wxGetApp().action_registry(); + const AppAction* a = reg.by_id(id); + if (!a) + return; + + const bool ask = reg.should_ask(id); + const std::string atitle = a->title(); + if (IsModal()) + EndModal(wxID_CANCEL); + else + Hide(); + + if (ask) { + const wxString label = title.empty() ? from_u8(atitle) : from_u8(title); + RichMessageDialog dlg(wxGetApp().mainframe, wxString::Format(_L("Run \"%s\"?"), label), + _L("Run plugin"), wxOK | wxCANCEL); + dlg.ShowCheckBox(_L("Don't ask again for this action")); + if (dlg.ShowModal() != wxID_OK) + return; + if (dlg.IsCheckBoxChecked()) + wxGetApp().action_registry().suppress_ask(id); + } + + wxGetApp().CallAfter([id] { + if (wxGetApp().is_closing()) + return; + AppActionRunResult result = wxGetApp().action_registry().run(id); + if (result.level == AppActionRunResult::Level::Busy) + return; + if (!result.message.IsEmpty() && wxGetApp().plater()) + wxGetApp().plater()->get_notification_manager()->push_notification( + NotificationType::CustomNotification, + result.level == AppActionRunResult::Level::Error ? NotificationManager::NotificationLevel::ErrorNotificationLevel : + NotificationManager::NotificationLevel::RegularNotificationLevel, + into_u8(result.message)); + }); +} + +void SpeedDialWebDialog::send_actions() +{ + nlohmann::json snap = wxGetApp().action_registry().snapshot(); + call_web_handler({{"command", "list_actions"}, + {"actions", std::move(snap["actions"])}, + {"favourites", std::move(snap["favourites"])}}); +} + }} diff --git a/src/slic3r/GUI/SpeedDialPopup.hpp b/src/slic3r/GUI/SpeedDialPopup.hpp index 6dea4f74de..44c04f4c02 100644 --- a/src/slic3r/GUI/SpeedDialPopup.hpp +++ b/src/slic3r/GUI/SpeedDialPopup.hpp @@ -3,6 +3,7 @@ #include "Widgets/PopupWindow.hpp" +#include #include #include #include @@ -32,6 +33,21 @@ private: bool m_pending_show{false}; }; +class SpeedDialWebDialog : public WebViewHostDialog +{ +public: + explicit SpeedDialWebDialog(wxWindow* parent); + void request_show(); + +private: + void on_script_message(const nlohmann::json& payload) override; + void resize_to_content(int height); + void run_action(const std::string& id, const std::string& title); + void send_actions(); + + bool m_page_ready{false}; +}; + }} #endif