diff --git a/resources/web/homepage/index.html b/resources/web/homepage/index.html index df5ef339ba..a8f3d85282 100644 --- a/resources/web/homepage/index.html +++ b/resources/web/homepage/index.html @@ -87,7 +87,7 @@
-
设备管理
+
Device Management
添加设备 diff --git a/resources/web/homepage/js/home.js b/resources/web/homepage/js/home.js index 898dcf4c5c..1284358c00 100644 --- a/resources/web/homepage/js/home.js +++ b/resources/web/homepage/js/home.js @@ -1,6 +1,8 @@ //var TestData={"sequence_id":"0","command":"get_recent_projects","response":[{"path":"D:\\work\\Models\\Toy\\3d-puzzle-cube-model_files\\3d-puzzle-cube.3mf","time":"2022\/3\/24 20:33:10"},{"path":"D:\\work\\Models\\Art\\Carved Stone Vase - remeshed+drainage\\Carved Stone Vase.3mf","time":"2022\/3\/24 17:11:51"},{"path":"D:\\work\\Models\\Art\\Kity & Cat\\Cat.3mf","time":"2022\/3\/24 17:07:55"},{"path":"D:\\work\\Models\\Toy\\鐩村墤.3mf","time":"2022\/3\/24 17:06:02"},{"path":"D:\\work\\Models\\Toy\\minimalistic-dual-tone-whistle-model_files\\minimalistic-dual-tone-whistle.3mf","time":"2022\/3\/22 21:12:22"},{"path":"D:\\work\\Models\\Toy\\spiral-city-model_files\\spiral-city.3mf","time":"2022\/3\/22 18:58:37"},{"path":"D:\\work\\Models\\Toy\\impossible-dovetail-puzzle-box-model_files\\impossible-dovetail-puzzle-box.3mf","time":"2022\/3\/22 20:08:40"}]}; var m_HotModelList=null; +var deviceClickCount = 0; +var deviceClickTimer = null; function OnInit() { @@ -511,6 +513,38 @@ function OnAddDevice() { SendWXMessage(JSON.stringify(tSend)); } +function OnTestBrowser(){ + var tSend = {}; + tSend['sequence_id'] = Math.round(new Date() / 1000); + tSend['command'] = "homepage_test_browser"; + + SendWXMessage(JSON.stringify(tSend)); +} + //---------------Global----------------- window.postMessage = HandleStudio; +function onDeviceManagementClick(e) { + // 阻止事件冒泡,避免触发菜单切换 + e.stopPropagation(); + + deviceClickCount++; + + // 清除之前的定时器 + if (deviceClickTimer) { + clearTimeout(deviceClickTimer); + } + + // 设置新的定时器,1秒后重置点击次数 + deviceClickTimer = setTimeout(() => { + deviceClickCount = 0; + }, 1000); + + // 检查是否达到三次点击 + if (deviceClickCount >= 3) { + deviceClickCount = 0; + clearTimeout(deviceClickTimer); + OnTestBrowser(); + } +} + diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 0e4932ce45..72f4bb66cf 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -283,6 +283,8 @@ set(SLIC3R_GUI_SOURCES GUI/WebSMUserLoginDialog.hpp GUI/WebDeviceDialog.cpp GUI/WebDeviceDialog.hpp + GUI/WebUrlDialog.cpp + GUI/WebUrlDialog.hpp GUI/ConfigManipulation.cpp GUI/ConfigManipulation.hpp GUI/Field.cpp diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 4c0ace9f88..9957f9caa5 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -9,6 +9,8 @@ #include "libslic3r_version.h" #include "Downloader.hpp" +#include "slic3r/GUI/WebUrlDialog.hpp" + // Localization headers: include libslic3r version first so everything in this file // uses the slic3r/GUI version (the macros will take precedence over the functions). // Also, there is a check that the former is not included from slic3r module. @@ -4018,6 +4020,14 @@ std::string GUI_App::handle_web_request(std::string cmd) }); return ""; } + else if (command_str.compare("homepage_test_browser") == 0) { + CallAfter([this] { + auto dialog = new WebUrlDialog(); + dialog->load_url("https://www.baidu.com"); + dialog->ShowModal(); + delete dialog; + }); + } } } catch (...) { diff --git a/src/slic3r/GUI/WebUrlDialog.cpp b/src/slic3r/GUI/WebUrlDialog.cpp new file mode 100644 index 0000000000..f878106308 --- /dev/null +++ b/src/slic3r/GUI/WebUrlDialog.cpp @@ -0,0 +1,132 @@ +// WebUrlDialog.cpp +#include "WebUrlDialog.hpp" +#include "I18N.hpp" +#include "GUI_App.hpp" +#include "MainFrame.hpp" +#include "SSWCP.hpp" +#include +#include + +namespace Slic3r { namespace GUI { + +BEGIN_EVENT_TABLE(WebUrlDialog, wxDialog) + EVT_CLOSE(WebUrlDialog::OnClose) +END_EVENT_TABLE() + +WebUrlDialog::WebUrlDialog() + : wxDialog((wxWindow*)(wxGetApp().mainframe), wxID_ANY, _L("Web View")) +{ + SetBackgroundColour(*wxWHITE); + + // 创建顶部输入区域 + auto *top_sizer = new wxBoxSizer(wxHORIZONTAL); + m_url_input = new wxTextCtrl(this, wxID_ANY, wxEmptyString, + wxDefaultPosition, FromDIP(wxSize(300, -1))); + m_load_button = new wxButton(this, wxID_ANY, _L("Load")); + + top_sizer->Add(m_url_input, 1, wxEXPAND | wxALL, 5); + top_sizer->Add(m_load_button, 0, wxALL, 5); + + // 创建WebView + m_browser = WebView::CreateWebView(this, "about:blank"); + if (m_browser == nullptr) { + wxLogError("Could not init m_browser"); + return; + } + m_browser->Hide(); + + // 绑定事件 + Bind(wxEVT_WEBVIEW_NAVIGATING, &WebUrlDialog::OnNavigationRequest, this, m_browser->GetId()); + Bind(wxEVT_WEBVIEW_NAVIGATED, &WebUrlDialog::OnNavigationComplete, this, m_browser->GetId()); + Bind(wxEVT_WEBVIEW_LOADED, &WebUrlDialog::OnDocumentLoaded, this, m_browser->GetId()); + Bind(wxEVT_WEBVIEW_ERROR, &WebUrlDialog::OnError, this, m_browser->GetId()); + Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, &WebUrlDialog::OnScriptMessage, this, m_browser->GetId()); + m_load_button->Bind(wxEVT_BUTTON, &WebUrlDialog::OnLoadUrl, this); + + // 设置主布局 + auto *main_sizer = new wxBoxSizer(wxVERTICAL); + main_sizer->Add(top_sizer, 0, wxEXPAND); + main_sizer->Add(m_browser, 1, wxEXPAND); + + SetSizer(main_sizer); + SetSize(FromDIP(wxSize(800, 600))); + CenterOnParent(); + + wxGetApp().UpdateDlgDarkUI(this); +} + +WebUrlDialog::~WebUrlDialog() +{ + SSWCP::on_webview_delete(m_browser); +} + +void WebUrlDialog::load_url(const wxString &url) +{ + m_url_input->SetValue(url); + m_browser->LoadURL(url); + m_browser->Show(); + Layout(); +} + +void WebUrlDialog::OnLoadUrl(wxCommandEvent& evt) +{ + wxString url = m_url_input->GetValue(); + if (!url.IsEmpty()) { + load_url(url); + } +} + +bool WebUrlDialog::run() +{ + if (this->ShowModal() == wxID_OK) { + return true; + } + return false; +} + +void WebUrlDialog::RunScript(const wxString &javascript) +{ + m_javascript = javascript; + if (!m_browser) return; + WebView::RunScript(m_browser, javascript); +} + +void WebUrlDialog::OnNavigationRequest(wxWebViewEvent &evt) +{ + evt.Skip(); +} + +void WebUrlDialog::OnNavigationComplete(wxWebViewEvent &evt) +{ + m_browser->Show(); + Layout(); +} + +void WebUrlDialog::OnDocumentLoaded(wxWebViewEvent &evt) +{ + evt.Skip(); +} + +void WebUrlDialog::OnError(wxWebViewEvent &evt) +{ + wxLogError("Web View Error: %s", evt.GetString()); +} + +void WebUrlDialog::OnScriptMessage(wxWebViewEvent &evt) +{ + BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << ": " << evt.GetString().ToUTF8().data(); + + if (wxGetApp().get_mode() == comDevelop) + wxLogMessage("Script message received; value = %s, handler = %s", + evt.GetString(), evt.GetMessageHandler()); + + // 处理SSWCP消息 + SSWCP::handle_web_message(evt.GetString().ToUTF8().data(), m_browser); +} + +void WebUrlDialog::OnClose(wxCloseEvent& evt) +{ + evt.Skip(); +} + +}} // namespace Slic3r::GUI \ No newline at end of file diff --git a/src/slic3r/GUI/WebUrlDialog.hpp b/src/slic3r/GUI/WebUrlDialog.hpp new file mode 100644 index 0000000000..b8c96101e8 --- /dev/null +++ b/src/slic3r/GUI/WebUrlDialog.hpp @@ -0,0 +1,43 @@ + +// WebUrlDialog.hpp +#ifndef slic3r_WebUrlDialog_hpp_ +#define slic3r_WebUrlDialog_hpp_ + +#include +#include +#include +#include +#include + +namespace Slic3r { namespace GUI { + +class WebUrlDialog : public wxDialog +{ +public: + WebUrlDialog(); + virtual ~WebUrlDialog(); + + void load_url(const wxString &url); + bool run(); + void RunScript(const wxString &javascript); + +private: + void OnClose(wxCloseEvent& evt); + void OnNavigationRequest(wxWebViewEvent &evt); + void OnNavigationComplete(wxWebViewEvent &evt); + void OnDocumentLoaded(wxWebViewEvent &evt); + void OnError(wxWebViewEvent &evt); + void OnScriptMessage(wxWebViewEvent &evt); + void OnLoadUrl(wxCommandEvent& evt); + + wxWebView* m_browser{nullptr}; + wxTextCtrl* m_url_input{nullptr}; + wxButton* m_load_button{nullptr}; + wxString m_javascript; + + DECLARE_EVENT_TABLE() +}; + +}} // namespace Slic3r::GUI + +#endif \ No newline at end of file