mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-15 04:57:34 +00:00
Give speed-dial popup GUI_App ownership
This commit is contained in:
@@ -8277,7 +8277,20 @@ void GUI_App::open_terminal_dialog()
|
|||||||
m_terminal_dlg->Raise();
|
m_terminal_dlg->Raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI_App::open_speed_dial() { open_speed_dial_popup(); }
|
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;
|
||||||
|
event.Skip();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
m_speed_dial_popup->request_show();
|
||||||
|
}
|
||||||
|
|
||||||
void GUI_App::open_exportpresetbundledialog(size_t open_on_tab, const std::string& highlight_option)
|
void GUI_App::open_exportpresetbundledialog(size_t open_on_tab, const std::string& highlight_option)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ class ModelMallDialog;
|
|||||||
class PingCodeBindDialog;
|
class PingCodeBindDialog;
|
||||||
class NetworkErrorDialog;
|
class NetworkErrorDialog;
|
||||||
class PluginsDialog;
|
class PluginsDialog;
|
||||||
|
class SpeedDialWebPopup;
|
||||||
class TerminalDialog;
|
class TerminalDialog;
|
||||||
|
|
||||||
|
|
||||||
@@ -554,6 +555,7 @@ public:
|
|||||||
|
|
||||||
PresetBundleDialog* m_preset_bundle_dlg{nullptr};
|
PresetBundleDialog* m_preset_bundle_dlg{nullptr};
|
||||||
PluginsDialog* m_plugins_dlg{nullptr};
|
PluginsDialog* m_plugins_dlg{nullptr};
|
||||||
|
SpeedDialWebPopup* m_speed_dial_popup{nullptr};
|
||||||
TerminalDialog* m_terminal_dlg{nullptr};
|
TerminalDialog* m_terminal_dlg{nullptr};
|
||||||
ActionRegistry m_action_registry;
|
ActionRegistry m_action_registry;
|
||||||
|
|
||||||
|
|||||||
@@ -130,12 +130,11 @@ if(document.documentElement)
|
|||||||
})();)JS";
|
})();)JS";
|
||||||
}
|
}
|
||||||
|
|
||||||
class SpeedDialWebPopup : public ::PopupWindow
|
}
|
||||||
{
|
|
||||||
public:
|
SpeedDialWebPopup::SpeedDialWebPopup(wxWindow* parent)
|
||||||
explicit SpeedDialWebPopup(wxWindow* parent)
|
|
||||||
: ::PopupWindow(parent, wxBORDER_NONE | wxPU_CONTAINS_CONTROLS)
|
: ::PopupWindow(parent, wxBORDER_NONE | wxPU_CONTAINS_CONTROLS)
|
||||||
{
|
{
|
||||||
SetBackgroundColour(bg_color());
|
SetBackgroundColour(bg_color());
|
||||||
|
|
||||||
auto* sizer = new wxBoxSizer(wxVERTICAL);
|
auto* sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
@@ -153,10 +152,10 @@ public:
|
|||||||
SetClientSize(FromDIP(wxSize(kPopupWidth, kPopupMaxHeight))); // DIP -> physical (see resize_to_content)
|
SetClientSize(FromDIP(wxSize(kPopupWidth, kPopupMaxHeight))); // DIP -> physical (see resize_to_content)
|
||||||
if (m_browser)
|
if (m_browser)
|
||||||
WebView::LoadUrl(m_browser, dialog_url());
|
WebView::LoadUrl(m_browser, dialog_url());
|
||||||
}
|
}
|
||||||
|
|
||||||
void request_show()
|
void SpeedDialWebPopup::request_show()
|
||||||
{
|
{
|
||||||
if (IsShown()) {
|
if (IsShown()) {
|
||||||
focus_browser();
|
focus_browser();
|
||||||
return;
|
return;
|
||||||
@@ -166,19 +165,16 @@ public:
|
|||||||
send_actions();
|
send_actions();
|
||||||
else if (!m_browser)
|
else if (!m_browser)
|
||||||
show_ready();
|
show_ready();
|
||||||
}
|
}
|
||||||
|
|
||||||
void focus_browser()
|
void SpeedDialWebPopup::focus_browser()
|
||||||
{
|
{
|
||||||
if (m_browser)
|
if (m_browser)
|
||||||
m_browser->SetFocus();
|
m_browser->SetFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
void SpeedDialWebPopup::on_script_message(wxWebViewEvent& event)
|
||||||
void OnDismiss() override {}
|
{
|
||||||
|
|
||||||
void on_script_message(wxWebViewEvent& event)
|
|
||||||
{
|
|
||||||
nlohmann::json p = nlohmann::json::parse(event.GetString().utf8_string(), nullptr, false);
|
nlohmann::json p = nlohmann::json::parse(event.GetString().utf8_string(), nullptr, false);
|
||||||
if (!p.is_object())
|
if (!p.is_object())
|
||||||
return;
|
return;
|
||||||
@@ -197,21 +193,21 @@ private:
|
|||||||
else if (cmd == "run_action") run_action(p.value("id", ""), p.value("title", ""));
|
else if (cmd == "run_action") run_action(p.value("id", ""), p.value("title", ""));
|
||||||
else if (cmd == "resize") resize_to_content(json_int_or(p, "height", 0));
|
else if (cmd == "resize") resize_to_content(json_int_or(p, "height", 0));
|
||||||
else if (cmd == "close_page") Dismiss();
|
else if (cmd == "close_page") Dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_webview_recreated(wxCommandEvent&)
|
void SpeedDialWebPopup::on_webview_recreated(wxCommandEvent&)
|
||||||
{
|
{
|
||||||
apply_host_theme();
|
apply_host_theme();
|
||||||
}
|
}
|
||||||
|
|
||||||
void apply_host_theme()
|
void SpeedDialWebPopup::apply_host_theme()
|
||||||
{
|
{
|
||||||
if (m_browser)
|
if (m_browser)
|
||||||
WebView::RunScript(m_browser, wxString::FromUTF8(host_theme_apply_js()));
|
WebView::RunScript(m_browser, wxString::FromUTF8(host_theme_apply_js()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize_to_content(int height)
|
void SpeedDialWebPopup::resize_to_content(int height)
|
||||||
{
|
{
|
||||||
if (height <= 0)
|
if (height <= 0)
|
||||||
return;
|
return;
|
||||||
// why: HTML is the source of truth - size the popup to the measured content height so
|
// why: HTML is the source of truth - size the popup to the measured content height so
|
||||||
@@ -232,23 +228,23 @@ private:
|
|||||||
show_ready();
|
show_ready();
|
||||||
else if (IsShown())
|
else if (IsShown())
|
||||||
SetPosition(clamped_position(GetPosition(), GetSize()));
|
SetPosition(clamped_position(GetPosition(), GetSize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void show_ready()
|
void SpeedDialWebPopup::show_ready()
|
||||||
{
|
{
|
||||||
if (!m_pending_show)
|
if (!m_pending_show)
|
||||||
return;
|
return;
|
||||||
SetPosition(clamped_position(popup_position(GetSize()), GetSize()));
|
SetPosition(clamped_position(popup_position(GetSize()), GetSize()));
|
||||||
Popup();
|
Popup();
|
||||||
focus_browser();
|
focus_browser();
|
||||||
m_pending_show = false;
|
m_pending_show = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide FIRST (scripts may open their own modals that must not stack under this
|
// Hide FIRST (scripts may open their own modals that must not stack under this
|
||||||
// launcher), gate on a native run-confirm unless suppressed, then run on the next
|
// launcher), gate on a native run-confirm unless suppressed, then run on the next
|
||||||
// tick via the registry (which re-resolves the capability and bumps stats).
|
// tick via the registry (which re-resolves the capability and bumps stats).
|
||||||
void run_action(const std::string& id, const std::string& title)
|
void SpeedDialWebPopup::run_action(const std::string& id, const std::string& title)
|
||||||
{
|
{
|
||||||
ActionRegistry& reg = wxGetApp().action_registry();
|
ActionRegistry& reg = wxGetApp().action_registry();
|
||||||
const AppAction* a = reg.by_id(id);
|
const AppAction* a = reg.by_id(id);
|
||||||
if (!a)
|
if (!a)
|
||||||
@@ -283,46 +279,25 @@ private:
|
|||||||
NotificationManager::NotificationLevel::RegularNotificationLevel,
|
NotificationManager::NotificationLevel::RegularNotificationLevel,
|
||||||
into_u8(o.message));
|
into_u8(o.message));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// C++ -> JS push. Same escaping as WebViewHostDialog::call_web_handler: the ignore error
|
// C++ -> JS push. Same escaping as WebViewHostDialog::call_web_handler: the ignore error
|
||||||
// handler keeps a stray non-UTF-8 byte in a plugin name from throwing and aborting the send;
|
// handler keeps a stray non-UTF-8 byte in a plugin name from throwing and aborting the send;
|
||||||
// concatenation (not wxString::Format) avoids a '%' in a title being read as a format token.
|
// concatenation (not wxString::Format) avoids a '%' in a title being read as a format token.
|
||||||
void push(const nlohmann::json& j)
|
void SpeedDialWebPopup::push(const nlohmann::json& j)
|
||||||
{
|
{
|
||||||
if (!m_browser)
|
if (!m_browser)
|
||||||
return;
|
return;
|
||||||
const wxString payload = wxString::FromUTF8(j.dump(-1, ' ', false, nlohmann::json::error_handler_t::ignore));
|
const wxString payload = wxString::FromUTF8(j.dump(-1, ' ', false, nlohmann::json::error_handler_t::ignore));
|
||||||
WebView::RunScript(m_browser, wxT("window.HandleStudio(") + payload + wxT(")"));
|
WebView::RunScript(m_browser, wxT("window.HandleStudio(") + payload + wxT(")"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_actions()
|
void SpeedDialWebPopup::send_actions()
|
||||||
{
|
{
|
||||||
nlohmann::json snap = wxGetApp().action_registry().snapshot();
|
nlohmann::json snap = wxGetApp().action_registry().snapshot();
|
||||||
push({{"command", "list_actions"},
|
push({{"command", "list_actions"},
|
||||||
{"actions", std::move(snap["actions"])},
|
{"actions", std::move(snap["actions"])},
|
||||||
{"favourites", std::move(snap["favourites"])}});
|
{"favourites", std::move(snap["favourites"])}});
|
||||||
}
|
|
||||||
|
|
||||||
wxWebView* m_browser{nullptr};
|
|
||||||
bool m_page_ready{false};
|
|
||||||
bool m_pending_show{false};
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void open_speed_dial_popup()
|
|
||||||
{
|
|
||||||
wxWindow* parent = wxGetApp().mainframe;
|
|
||||||
if (!parent)
|
|
||||||
return;
|
|
||||||
|
|
||||||
static SpeedDialWebPopup* popup = nullptr;
|
|
||||||
if (!popup) {
|
|
||||||
popup = new SpeedDialWebPopup(parent);
|
|
||||||
popup->Bind(wxEVT_DESTROY, [](wxWindowDestroyEvent&) { popup = nullptr; });
|
|
||||||
}
|
|
||||||
popup->request_show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,11 +1,36 @@
|
|||||||
#ifndef slic3r_GUI_SpeedDialPopup_hpp_
|
#ifndef slic3r_GUI_SpeedDialPopup_hpp_
|
||||||
#define slic3r_GUI_SpeedDialPopup_hpp_
|
#define slic3r_GUI_SpeedDialPopup_hpp_
|
||||||
|
|
||||||
#include <wx/string.h>
|
#include "Widgets/PopupWindow.hpp"
|
||||||
|
|
||||||
|
#include <wx/webview.h>
|
||||||
|
#include <nlohmann/json_fwd.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace Slic3r { namespace GUI {
|
namespace Slic3r { namespace GUI {
|
||||||
|
|
||||||
void open_speed_dial_popup();
|
class SpeedDialWebPopup : public ::PopupWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit SpeedDialWebPopup(wxWindow* parent);
|
||||||
|
void request_show();
|
||||||
|
void focus_browser();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void OnDismiss() override {}
|
||||||
|
void on_script_message(wxWebViewEvent& event);
|
||||||
|
void on_webview_recreated(wxCommandEvent&);
|
||||||
|
void apply_host_theme();
|
||||||
|
void resize_to_content(int height);
|
||||||
|
void show_ready();
|
||||||
|
void run_action(const std::string& id, const std::string& title);
|
||||||
|
void push(const nlohmann::json& j);
|
||||||
|
void send_actions();
|
||||||
|
|
||||||
|
wxWebView* m_browser{nullptr};
|
||||||
|
bool m_page_ready{false};
|
||||||
|
bool m_pending_show{false};
|
||||||
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user