diff --git a/resources/images/bind_device_ping_code.svg b/resources/images/bind_device_ping_code.svg
new file mode 100644
index 000000000..5c1ff4742
--- /dev/null
+++ b/resources/images/bind_device_ping_code.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index 07c7c0d08..b86d1fed2 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -295,6 +295,8 @@ set(SLIC3R_GUI_SOURCES
GUI/ImGuiWrapper.cpp
GUI/DeviceManager.hpp
GUI/DeviceManager.cpp
+ GUI/UserManager.hpp
+ GUI/UserManager.cpp
GUI/HttpServer.hpp
GUI/HttpServer.cpp
Config/Snapshot.cpp
diff --git a/src/slic3r/GUI/BindDialog.cpp b/src/slic3r/GUI/BindDialog.cpp
index 978c6e5d4..66fb56f74 100644
--- a/src/slic3r/GUI/BindDialog.cpp
+++ b/src/slic3r/GUI/BindDialog.cpp
@@ -52,6 +52,271 @@ wxString get_fail_reason(int code)
return _L("Unknown Failure");
}
+PingCodeBindDialog::PingCodeBindDialog(Plater* plater /*= nullptr*/)
+ : DPIDialog(static_cast(wxGetApp().mainframe), wxID_ANY, _L("Bind with Pin Code"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
+{
+#ifdef __WINDOWS__
+ SetDoubleBuffered(true);
+#endif //__WINDOWS__
+ wxBoxSizer* sizer_main = new wxBoxSizer(wxVERTICAL);
+
+
+ std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
+ SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
+
+ SetBackgroundColour(*wxWHITE);
+ wxBoxSizer* m_sizer_main = new wxBoxSizer(wxVERTICAL);
+ auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
+ m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
+
+
+ m_simplebook = new wxSimplebook(this);
+ m_simplebook->SetSize(wxSize(FromDIP(460), FromDIP(240)));
+ m_simplebook->SetMinSize(wxSize(FromDIP(460), FromDIP(240)));
+ m_simplebook->SetMaxSize(wxSize(FromDIP(460), FromDIP(240)));
+
+
+ request_bind_panel = new wxPanel(m_simplebook);
+ binding_panel = new wxPanel(m_simplebook);
+
+ request_bind_panel->SetSize(wxSize(FromDIP(460), FromDIP(240)));
+ request_bind_panel->SetMinSize(wxSize(FromDIP(460), FromDIP(240)));
+ request_bind_panel->SetMaxSize(wxSize(FromDIP(460), FromDIP(240)));
+
+ binding_panel->SetSize(wxSize(FromDIP(460), FromDIP(240)));
+ binding_panel->SetMinSize(wxSize(FromDIP(460), FromDIP(240)));
+ binding_panel->SetMaxSize(wxSize(FromDIP(460), FromDIP(240)));
+
+
+ request_bind_panel->SetBackgroundColour(*wxWHITE);
+ binding_panel->SetBackgroundColour(*wxWHITE);
+
+ m_status_text = new Label(request_bind_panel, _L("Please Find the ping code in Account page on printer screen,\n and type in the ping code below."));
+ m_status_text->SetBackgroundColour(*wxWHITE);
+ m_status_text->SetFont(Label::Body_14);
+ m_status_text->SetMaxSize(wxSize(FromDIP(440), -1));
+ m_status_text->Wrap(FromDIP(440));
+ m_status_text->SetForegroundColour(wxColour(38, 46, 48));
+
+ m_link_show_ping_code_wiki = new wxStaticText(request_bind_panel, wxID_ANY, _L("Can't find pin code?"));
+ m_link_show_ping_code_wiki->SetFont(Label::Body_14);
+ m_link_show_ping_code_wiki->SetBackgroundColour(*wxWHITE);
+ m_link_show_ping_code_wiki->SetForegroundColour(wxColour(31, 142, 234));
+
+ m_link_show_ping_code_wiki->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_HAND); });
+ m_link_show_ping_code_wiki->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_ARROW); });
+
+ m_link_show_ping_code_wiki->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {
+ wxLaunchDefaultBrowser(m_ping_code_wiki);
+ });
+
+ m_text_input_title = new wxStaticText(request_bind_panel, wxID_ANY, _L("Pin Code"));
+ m_text_input_title->SetFont(Label::Body_14);
+ m_text_input_title->SetBackgroundColour(*wxWHITE);
+
+ wxBoxSizer* ping_code_input = new wxBoxSizer(wxHORIZONTAL);
+
+
+ for (int i = 0; i < PING_CODE_LENGTH; i++) {
+ m_text_input_single_code[i] = new TextInput(request_bind_panel, wxEmptyString, "", "", wxDefaultPosition, wxSize(FromDIP(38), FromDIP(38)), wxTE_PROCESS_ENTER | wxTE_CENTER);
+ wxTextAttr textAttr;
+ textAttr.SetAlignment(wxTEXT_ALIGNMENT_CENTER);
+ textAttr.SetTextColour(wxColour(34, 139, 34));
+ m_text_input_single_code[i]->GetTextCtrl()->SetDefaultStyle(textAttr);
+ m_text_input_single_code[i]->SetFont(Label::Body_16);
+ m_text_input_single_code[i]->GetTextCtrl()->SetMaxLength(1);
+ m_text_input_single_code[i]->GetTextCtrl()->Bind(wxEVT_TEXT, &PingCodeBindDialog::on_text_changed, this);
+ m_text_input_single_code[i]->GetTextCtrl()->Bind(wxEVT_KEY_DOWN, &PingCodeBindDialog::on_key_backspace, this);
+ ping_code_input->Add(m_text_input_single_code[i], 0, wxALL, FromDIP(5));
+ }
+
+ wxBoxSizer* m_sizer_button = new wxBoxSizer(wxHORIZONTAL);
+ m_sizer_button->Add(0, 0, 1, wxEXPAND, 5);
+ m_button_bind = new Button(request_bind_panel, _L("Confirm"));
+
+ StateColor btn_bg_green(std::pair(wxColour(206, 206, 206), StateColor::Disabled),
+ std::pair(wxColour(27, 136, 68), StateColor::Pressed),
+ std::pair(wxColour(61, 203, 115), StateColor::Hovered),
+ std::pair(wxColour(0, 174, 66), StateColor::Normal));
+ m_button_bind->SetBackgroundColor(btn_bg_green);
+ m_button_bind->SetBorderColor(*wxWHITE);
+ m_button_bind->SetTextColor(wxColour("#FFFFFE"));
+ m_button_bind->SetSize(BIND_DIALOG_BUTTON_SIZE);
+ m_button_bind->SetMinSize(BIND_DIALOG_BUTTON_SIZE);
+ m_button_bind->SetCornerRadius(FromDIP(12));
+ m_button_bind->Enable(false);
+
+ StateColor btn_bg_white(std::pair(wxColour(206, 206, 206), StateColor::Hovered),
+ std::pair(*wxWHITE, StateColor::Normal));
+
+ m_button_cancel = new Button(request_bind_panel, _L("Cancel"));
+ m_button_cancel->SetBackgroundColor(btn_bg_white);
+ m_button_cancel->SetBorderColor(BIND_DIALOG_GREY900);
+ m_button_cancel->SetSize(BIND_DIALOG_BUTTON_SIZE);
+ m_button_cancel->SetMinSize(BIND_DIALOG_BUTTON_SIZE);
+ m_button_cancel->SetTextColor(BIND_DIALOG_GREY900);
+ m_button_cancel->SetCornerRadius(FromDIP(12));
+
+ m_sizer_button->Add(m_button_bind, 0, wxALIGN_CENTER, 0);
+ m_sizer_button->Add(0, 0, 0, wxLEFT, FromDIP(13));
+ m_sizer_button->Add(m_button_cancel, 0, wxALIGN_CENTER, 0);
+
+
+
+ m_simplebook->AddPage(request_bind_panel, wxEmptyString, true);
+ m_simplebook->AddPage(binding_panel, wxEmptyString, false);
+
+
+ auto sizer_request = new wxBoxSizer(wxVERTICAL);
+ sizer_request->Add(0, 0, 0, wxTOP, FromDIP(10));
+ sizer_request->Add(m_status_text, 0, wxLEFT, FromDIP(13));
+ sizer_request->Add(0, 0, 0, wxTOP, FromDIP(10));
+ sizer_request->Add(m_link_show_ping_code_wiki, 0, wxLEFT, FromDIP(13));
+ sizer_request->Add(0, 0, 0, wxTOP, FromDIP(15));
+ sizer_request->Add(m_text_input_title, 0, wxLEFT, FromDIP(13));
+ sizer_request->Add(0, 0, 0, wxTOP, FromDIP(5));
+ sizer_request->Add(ping_code_input, 0, wxLEFT, FromDIP(10));
+ sizer_request->Add(0, 0, 0, wxTOP, FromDIP(10));
+ sizer_request->Add(m_sizer_button, 0, wxALIGN_RIGHT | wxRIGHT | wxBOTTOM, FromDIP(15));
+ request_bind_panel->SetSizer(sizer_request);
+ request_bind_panel->Layout();
+ request_bind_panel->Fit();
+
+
+
+ auto m_loading_txt = new Label(binding_panel, _L("Binding..."));
+ m_loading_txt->SetBackgroundColour(*wxWHITE);
+ m_loading_txt->SetFont(Label::Head_16);
+ auto m_loading_tip_txt = new Label(binding_panel, _L("Please confirm on the printer screen"));
+ m_loading_tip_txt->SetBackgroundColour(*wxWHITE);
+ m_loading_tip_txt->SetFont(Label::Body_15);
+
+ wxBoxSizer* m_sizer_binding_button = new wxBoxSizer(wxHORIZONTAL);
+ m_sizer_binding_button->Add(0, 0, 1, wxEXPAND, 5);
+
+ auto m_button_close = new Button(binding_panel, _L("Close"));
+ m_button_close->SetBackgroundColor(btn_bg_white);
+ m_button_close->SetBorderColor(BIND_DIALOG_GREY900);
+ m_button_close->SetSize(BIND_DIALOG_BUTTON_SIZE);
+ m_button_close->SetMinSize(BIND_DIALOG_BUTTON_SIZE);
+ m_button_close->SetTextColor(BIND_DIALOG_GREY900);
+ m_button_close->SetCornerRadius(FromDIP(12));
+ m_sizer_binding_button->Add(m_button_close, 0, wxALIGN_CENTER, 0);
+
+ m_button_close->Bind(wxEVT_BUTTON, [this](auto& e) {
+ wxGetApp().remove_ping_bind_dialog();
+ });
+
+ this->Bind(wxEVT_CLOSE_WINDOW, [this](auto& e) {
+ wxGetApp().remove_ping_bind_dialog();
+ });
+
+ auto sizer_binding = new wxBoxSizer(wxVERTICAL);
+ sizer_binding->Add(0, 0, 0, wxTOP, FromDIP(80));
+ sizer_binding->Add(m_loading_txt, 0, wxALIGN_CENTER, 0);
+ sizer_binding->Add(0, 0, 0, wxTOP, FromDIP(10));
+ sizer_binding->Add(m_loading_tip_txt, 0, wxALIGN_CENTER, 0);
+ sizer_binding->Add(0, 0, 0, wxTOP, FromDIP(30));
+ sizer_binding->Add(m_sizer_binding_button, 0, wxALIGN_RIGHT | wxRIGHT, FromDIP(20));
+ binding_panel->SetSizer(sizer_binding);
+ binding_panel->Layout();
+ binding_panel->Fit();
+
+
+
+ sizer_main->Add(m_line_top, 0, wxEXPAND, 0);
+ sizer_main->Add(m_simplebook, 0, wxEXPAND, 0);
+
+
+
+ SetSizer(sizer_main);
+ Layout();
+ Fit();
+
+ m_button_bind->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PingCodeBindDialog::on_bind_printer), NULL, this);
+ m_button_cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PingCodeBindDialog::on_cancel), NULL, this);
+
+ m_simplebook->SetSelection(0);
+}
+
+void PingCodeBindDialog::on_text_changed(wxCommandEvent& event) {
+ //switch focus to the text text input
+ wxTextCtrl* text_input = static_cast(event.GetEventObject());
+ int idx = -1;
+ for (int i = 0; i < PING_CODE_LENGTH; i++) {
+ if (text_input == m_text_input_single_code[i]->GetTextCtrl()) {
+ idx = i;
+ break;
+ }
+ }
+
+ if (idx != -1 && text_input->GetValue().Length() == 1) {
+ if (idx < PING_CODE_LENGTH-1) {
+ m_text_input_single_code[idx + 1]->SetFocus();
+ }
+ else if (idx == PING_CODE_LENGTH - 1) {
+ m_button_bind->Enable(true);
+ }
+ }
+
+}
+
+void PingCodeBindDialog::on_key_backspace(wxKeyEvent& event)
+{
+ wxTextCtrl* text_input = static_cast(event.GetEventObject());
+ int idx = -1;
+ for (int i = 0; i < 6; i++) {
+ if (text_input == m_text_input_single_code[i]->GetTextCtrl()) {
+ idx = i;
+ break;
+ }
+ }
+
+ if (event.GetKeyCode() == WXK_BACK && idx > 0) {
+ m_text_input_single_code[idx - 1]->SetFocus();
+ m_button_bind->Enable(false);
+ }
+ event.Skip();
+}
+
+void PingCodeBindDialog::on_bind_printer(wxCommandEvent& event)
+{
+ wxString ping_code;
+
+ for (int i = 0; i < PING_CODE_LENGTH; i++) {
+ ping_code += m_text_input_single_code[i]->GetTextCtrl()->GetValue().ToStdString();
+ }
+
+ NetworkAgent* agent = wxGetApp().getAgent();
+ if (agent && agent->is_user_login() && ping_code.length() == PING_CODE_LENGTH) {
+ auto result = agent->ping_bind(ping_code.ToStdString());
+
+ if(result < 0){
+ MessageDialog msg_wingow(nullptr, _L("Log in failed. Please check the pin code."), "", wxAPPLY | wxOK);
+ msg_wingow.ShowModal();
+ return;
+ }
+ m_simplebook->SetSelection(1);
+ }
+}
+
+void PingCodeBindDialog::on_cancel(wxCommandEvent& event)
+{
+ wxGetApp().remove_ping_bind_dialog();
+}
+
+void PingCodeBindDialog::on_dpi_changed(const wxRect& suggested_rect)
+{
+
+ Fit();
+ Refresh();
+}
+
+PingCodeBindDialog::~PingCodeBindDialog() {
+ m_button_bind->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PingCodeBindDialog::on_bind_printer), NULL, this);
+ m_button_cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PingCodeBindDialog::on_cancel), NULL, this);
+}
+
BindMachineDialog::BindMachineDialog(Plater *plater /*= nullptr*/)
: DPIDialog(static_cast(wxGetApp().mainframe), wxID_ANY, _L("Log in printer"), wxDefaultPosition, wxDefaultSize, wxCAPTION)
{
diff --git a/src/slic3r/GUI/BindDialog.hpp b/src/slic3r/GUI/BindDialog.hpp
index 8a8b878e3..e7d7a9d97 100644
--- a/src/slic3r/GUI/BindDialog.hpp
+++ b/src/slic3r/GUI/BindDialog.hpp
@@ -34,6 +34,7 @@
#define BIND_DIALOG_GREY900 wxColour(38, 46, 48)
#define BIND_DIALOG_BUTTON_SIZE wxSize(FromDIP(68), FromDIP(24))
#define BIND_DIALOG_BUTTON_PANEL_SIZE wxSize(FromDIP(450), FromDIP(30))
+#define PING_CODE_LENGTH 6
namespace Slic3r { namespace GUI {
@@ -44,6 +45,45 @@ struct MemoryStruct
size_t size;
};
+class PingCodeBindDialog : public DPIDialog
+{
+private:
+
+ Label* m_status_text;
+ wxStaticText* m_text_input_title;
+ wxStaticText* m_link_show_ping_code_wiki;
+ TextInput* m_text_input_single_code[PING_CODE_LENGTH];
+ Button* m_button_bind;
+ Button* m_button_cancel;
+ wxSimplebook* m_simplebook;
+ wxPanel* request_bind_panel;
+ wxPanel* binding_panel;
+
+ wxScrolledWindow* m_sw_bind_failed_info;
+ Label* m_bind_failed_info;
+ Label* m_st_txt_error_code{ nullptr };
+ Label* m_st_txt_error_desc{ nullptr };
+ Label* m_st_txt_extra_info{ nullptr };
+ wxHyperlinkCtrl* m_link_network_state{ nullptr };
+ wxString m_result_info;
+ wxString m_result_extra;
+ wxString m_ping_code_wiki="www.bambulab.com";
+ bool m_show_error_info_state = true;
+
+ int m_result_code;
+ std::shared_ptr m_status_bar;
+
+public:
+ PingCodeBindDialog(Plater* plater = nullptr);
+ ~PingCodeBindDialog();
+
+ void on_text_changed(wxCommandEvent& event);
+ void on_key_backspace(wxKeyEvent& event);
+ void on_cancel(wxCommandEvent& event);
+ void on_bind_printer(wxCommandEvent& event);
+ void on_dpi_changed(const wxRect& suggested_rect) override;
+};
+
class BindMachineDialog : public DPIDialog
{
private:
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index f35896fba..f909d4cac 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -3,6 +3,7 @@
#include "GUI_Init.hpp"
#include "GUI_ObjectList.hpp"
#include "GUI_Factories.hpp"
+#include "slic3r/GUI/UserManager.hpp"
#include "slic3r/GUI/TaskManager.hpp"
#include "format.hpp"
@@ -2106,6 +2107,25 @@ void GUI_App::init_networking_callbacks()
m_agent->set_on_message_fn(message_arrive_fn);
+ auto user_message_arrive_fn = [this](std::string user_id, std::string msg) {
+ if (m_is_closing) {
+ return;
+ }
+ CallAfter([this, user_id, msg] {
+ if (m_is_closing)
+ return;
+
+ //check user
+ if (user_id == m_agent->get_user_id()) {
+ this->m_user_manager->parse_json(msg);
+ }
+
+ });
+ };
+
+ m_agent->set_on_user_message_fn(user_message_arrive_fn);
+
+
auto lan_message_arrive_fn = [this](std::string dev_id, std::string msg) {
if (m_is_closing) {
return;
@@ -2419,6 +2439,11 @@ int GUI_App::OnExit()
m_device_manager = nullptr;
}
+ if (m_user_manager) {
+ delete m_user_manager;
+ m_user_manager = nullptr;
+ }
+
if (m_agent) {
// BBS avoid a crash on mac platform
#ifdef __WINDOWS__
@@ -3063,6 +3088,11 @@ __retry:
else
m_device_manager->set_agent(m_agent);
+ if (!m_user_manager)
+ m_user_manager = new Slic3r::UserManager(m_agent);
+ else
+ m_user_manager->set_agent(m_agent);
+
if (this->is_enable_multi_machine()) {
if (!m_task_manager) {
m_task_manager = new Slic3r::TaskManager(m_agent);
@@ -3103,6 +3133,9 @@ __retry:
if (!m_device_manager)
m_device_manager = new Slic3r::DeviceManager();
+
+ if (!m_user_manager)
+ m_user_manager = new Slic3r::UserManager();
}
return true;
@@ -6308,6 +6341,24 @@ std::string GUI_App::url_encode(std::string value) {
return Http::url_encode(value);
}
+void GUI_App::popup_ping_bind_dialog()
+{
+ if (m_ping_code_binding_dialog == nullptr) {
+ m_ping_code_binding_dialog = new PingCodeBindDialog();
+ m_ping_code_binding_dialog->ShowModal();
+ }
+}
+
+void GUI_App::remove_ping_bind_dialog()
+{
+ if (m_ping_code_binding_dialog != nullptr) {
+ m_ping_code_binding_dialog->Destroy();
+ delete m_mall_publish_dialog;
+ m_ping_code_binding_dialog = nullptr;
+ }
+}
+
+
void GUI_App::remove_mall_system_dialog()
{
if (m_mall_publish_dialog != nullptr) {
diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp
index a0e7f0526..0c4178578 100644
--- a/src/slic3r/GUI/GUI_App.hpp
+++ b/src/slic3r/GUI/GUI_App.hpp
@@ -14,6 +14,7 @@
#include "slic3r/Utils/NetworkAgent.hpp"
#include "slic3r/GUI/WebViewDialog.hpp"
#include "slic3r/GUI/WebUserLoginDialog.hpp"
+#include "slic3r/GUI/BindDialog.hpp"
#include "slic3r/GUI/HMS.hpp"
#include "slic3r/GUI/Jobs/UpgradeNetworkJob.hpp"
#include "slic3r/GUI/HttpServer.hpp"
@@ -58,6 +59,7 @@ class PresetBundle;
class PresetUpdater;
class ModelObject;
class Model;
+class UserManager;
class DeviceManager;
class NetworkAgent;
class TaskManager;
@@ -78,6 +80,7 @@ struct GUI_InitParams;
class ParamsDialog;
class HMSQuery;
class ModelMallDialog;
+class PingCodeBindDialog;
enum FileType
@@ -277,6 +280,7 @@ private:
//BBS
bool m_is_closing {false};
Slic3r::DeviceManager* m_device_manager { nullptr };
+ Slic3r::UserManager* m_user_manager { nullptr };
Slic3r::TaskManager* m_task_manager { nullptr };
NetworkAgent* m_agent { nullptr };
std::vector need_delete_presets; // store setting ids of preset
@@ -551,6 +555,7 @@ public:
std::string m_mall_model_download_url;
std::string m_mall_model_download_name;
ModelMallDialog* m_mall_publish_dialog{ nullptr };
+ PingCodeBindDialog* m_ping_code_binding_dialog{ nullptr };
void set_download_model_url(std::string url) {m_mall_model_download_url = url;}
void set_download_model_name(std::string name) {m_mall_model_download_name = name;}
@@ -570,6 +575,9 @@ public:
std::string url_encode(std::string value);
std::string url_decode(std::string value);
+ void popup_ping_bind_dialog();
+ void remove_ping_bind_dialog();
+
// Parameters extracted from the command line to be passed to GUI after initialization.
GUI_InitParams* init_params { nullptr };
diff --git a/src/slic3r/GUI/Jobs/BindJob.cpp b/src/slic3r/GUI/Jobs/BindJob.cpp
index 8f1908345..80b856183 100644
--- a/src/slic3r/GUI/Jobs/BindJob.cpp
+++ b/src/slic3r/GUI/Jobs/BindJob.cpp
@@ -135,9 +135,9 @@ void BindJob::process()
}
dev->update_user_machine_list_info();
- wxCommandEvent event(EVT_BIND_MACHINE_SUCCESS);
- event.SetEventObject(m_event_handle);
- wxPostEvent(m_event_handle, event);
+ wxCommandEvent event(EVT_BIND_MACHINE_SUCCESS);
+ event.SetEventObject(m_event_handle);
+ wxPostEvent(m_event_handle, event);
return;
}
diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp
index 90771916e..6e2907001 100644
--- a/src/slic3r/GUI/SelectMachine.cpp
+++ b/src/slic3r/GUI/SelectMachine.cpp
@@ -394,12 +394,42 @@ SelectMachinePopup::SelectMachinePopup(wxWindow *parent)
auto other_title = create_title_panel(_L("Other Device"));
m_sizer_other_devices = new wxBoxSizer(wxVERTICAL);
+
+ wxWindow* m_panel_ping_code = new wxWindow(m_scrolledWindow, wxID_ANY, wxDefaultPosition, SELECT_MACHINE_ITEM_SIZE, wxTAB_TRAVERSAL);
+ m_panel_ping_code->SetBackgroundColour(*wxWHITE);
+
+ wxBoxSizer* sizer_ping_code = new wxBoxSizer(wxHORIZONTAL);
+
+ m_img_ping_code = new wxStaticBitmap(m_panel_ping_code, wxID_ANY, create_scaled_bitmap("bind_device_ping_code", this, 10), wxDefaultPosition, wxSize(FromDIP(10), FromDIP(10)), 0);
+ m_img_ping_code->SetBackgroundColour(*wxWHITE);
+
+ m_ping_code_text = new Label(m_panel_ping_code, _L("Bind with Pin Code"));
+ m_ping_code_text->SetFont(::Label::Head_13);
+ m_ping_code_text->SetForegroundColour(wxColour(38, 46, 48));
+ m_ping_code_text->SetBackgroundColour(*wxWHITE);
+
+ m_panel_ping_code->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {
+ wxGetApp().popup_ping_bind_dialog();
+ });
+
+ m_ping_code_text->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {
+ wxGetApp().popup_ping_bind_dialog();
+ });
+
+
+ sizer_ping_code->Add(m_img_ping_code, 0, wxEXPAND, 0);
+ sizer_ping_code->Add(0, 0, 0, wxLEFT, FromDIP(7));
+ sizer_ping_code->Add(m_ping_code_text, 0, wxALIGN_CENTER, 0);
+
+ m_panel_ping_code->SetSizer(sizer_ping_code);
+ m_panel_ping_code->Layout();
+
m_sizxer_scrolledWindow->Add(own_title, 0, wxEXPAND | wxLEFT, FromDIP(15));
m_sizxer_scrolledWindow->Add(m_sizer_my_devices, 0, wxEXPAND, 0);
+ m_sizxer_scrolledWindow->Add(m_panel_ping_code, 0, wxEXPAND | wxLEFT, FromDIP(8));
m_sizxer_scrolledWindow->Add(other_title, 0, wxEXPAND | wxLEFT, FromDIP(15));
m_sizxer_scrolledWindow->Add(m_sizer_other_devices, 0, wxEXPAND, 0);
-
m_sizer_main->Add(m_scrolledWindow, 0, wxALL | wxEXPAND, FromDIP(2));
SetSizer(m_sizer_main);
diff --git a/src/slic3r/GUI/SelectMachine.hpp b/src/slic3r/GUI/SelectMachine.hpp
index 2ce95a060..564e02ee5 100644
--- a/src/slic3r/GUI/SelectMachine.hpp
+++ b/src/slic3r/GUI/SelectMachine.hpp
@@ -232,6 +232,8 @@ private:
int m_other_devices_count{0};
wxWindow* m_placeholder_panel{nullptr};
wxHyperlinkCtrl* m_hyperlink{nullptr};
+ Label* m_ping_code_text{nullptr};
+ wxStaticBitmap* m_img_ping_code{nullptr};
wxBoxSizer * m_sizer_body{nullptr};
wxBoxSizer * m_sizer_my_devices{nullptr};
wxBoxSizer * m_sizer_other_devices{nullptr};
diff --git a/src/slic3r/GUI/UserManager.cpp b/src/slic3r/GUI/UserManager.cpp
new file mode 100644
index 000000000..a4cfa80b1
--- /dev/null
+++ b/src/slic3r/GUI/UserManager.cpp
@@ -0,0 +1,76 @@
+#include "libslic3r/libslic3r.h"
+#include "UserManager.hpp"
+#include "DeviceManager.hpp"
+#include "NetworkAgent.hpp"
+#include "GUI.hpp"
+#include "GUI_App.hpp"
+#include "MsgDialog.hpp"
+
+
+namespace Slic3r {
+
+UserManager::UserManager(NetworkAgent* agent)
+{
+ m_agent = agent;
+}
+
+UserManager::~UserManager()
+{
+}
+
+void UserManager::set_agent(NetworkAgent* agent)
+{
+ m_agent = agent;
+}
+
+int UserManager::parse_json(std::string payload)
+{
+ bool restored_json = false;
+ json j;
+ json j_pre = json::parse(payload);
+ if (j_pre.empty()) {
+ return -1;
+ }
+
+ //bind/unbind
+
+ try {
+ if (j_pre.contains("bind")) {
+ if (j_pre["bind"].contains("command")) {
+
+ //bind
+ if (j_pre["bind"]["command"].get() == "bind") {
+ std::string dev_id;
+ std:; string result;
+
+ if (j_pre["bind"].contains("dev_id")) {
+ dev_id = j_pre["bind"]["dev_id"].get();
+ }
+
+ if (j_pre["bind"].contains("result")) {
+ result = j_pre["bind"]["result"].get();
+ }
+
+ if (result == "success") {
+ DeviceManager* dev = GUI::wxGetApp().getDeviceManager();
+ if (!dev) {return -1;}
+
+ if (GUI::wxGetApp().m_ping_code_binding_dialog && GUI::wxGetApp().m_ping_code_binding_dialog->IsShown()) {
+ GUI::MessageDialog msgdialog(nullptr, _L("Log in successful."), "", wxAPPLY | wxOK);
+ msgdialog.ShowModal();
+ GUI::wxGetApp().remove_ping_bind_dialog();
+ }
+ dev->update_user_machine_list_info();
+ dev->set_selected_machine(dev_id);
+ return 0;
+ }
+ }
+ }
+ }
+ }
+ catch (...){}
+
+ return -1;
+}
+
+} // namespace Slic3r
\ No newline at end of file
diff --git a/src/slic3r/GUI/UserManager.hpp b/src/slic3r/GUI/UserManager.hpp
new file mode 100644
index 000000000..a7f402cba
--- /dev/null
+++ b/src/slic3r/GUI/UserManager.hpp
@@ -0,0 +1,36 @@
+#ifndef slic3r_UserManager_hpp_
+#define slic3r_UserManager_hpp_
+
+#include