OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::anonymous_namespace{PluginHostUi.cpp} Namespace Reference

Classes

struct  GilSafeCallable
class  UiRegistry
struct  UiWindowHandle
struct  UiProgressHandle
struct  UiDockPanelHandle
class  PlaterShownWaiter

Typedefs

using CallablePtr = std::shared_ptr<GilSafeCallable>

Functions

CallablePtr make_holder (py::object obj)
GUI::WebDialog::MessageHandler make_message_adapter (py::object on_message)
GUI::WebDialog::SubmitHandler make_submit_adapter (py::object on_submit)
std::function< void()> make_close_adapter (const CallablePtr &holder)
bool app_closing ()
template<typename Fn>
auto run_on_ui_blocking (Fn &&fn) -> std::invoke_result_t< Fn & >
wxWindow * ui_parent ()
long message_style (const std::string &buttons, const std::string &icon)
std::string button_to_string (int rc)
std::string ui_message (const std::string &text, const std::string &title, const std::string &buttons, const std::string &icon)
py::object ui_create_window (const std::string &html, const std::string &title, int width, int height, py::object on_message, py::object on_close, long style, py::object on_submit)
void run_when_plater_shown (std::function< void(GUI::Plater *)> fn)
py::object ui_create_dock_panel (const std::string &html, const std::string &title, int width, int height, py::object on_message, py::object on_close, const std::string &dock)
void handle_post (int id, py::object data)
void handle_close (int id)
void handle_show (int id, bool show)
UiProgressHandle ui_create_progress_dialog (const std::string &title, const std::string &message, int maximum, int style)
UiProgressHandle * new_progress_dialog (const std::string &title, const std::string &message, int maximum, int style)
bool progress_is_open (int id)
bool progress_pulse (int id, const std::string &message)
bool progress_update (int id, int value, const std::string &message)
void progress_start_pulse (int id, int interval_ms, const std::string &message)
void progress_stop_pulse (int id)
void progress_close (int id)
void plater_notification (GUI::NotificationManager::NotificationLevel notification_level, const std::string &text, const std::string &hypertext, py::object on_click)

Variables

constexpr long WINDOW_MODELESS = 0L
constexpr long WINDOW_MODAL = 1L << 0
constexpr long PLUGIN_WX_STYLE = wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxMAXIMIZE_BOX | wxRESIZE_BORDER
constexpr const char * DOCK_POSITIONS [] = {"left", "right", "bottom", "float"}

Class Documentation

◆ Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiWindowHandle

struct Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiWindowHandle
Class Members
int id {0}

◆ Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiProgressHandle

struct Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiProgressHandle
Class Members
int id {0}

◆ Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiDockPanelHandle

struct Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiDockPanelHandle
Class Members
int id {0}

Typedef Documentation

◆ CallablePtr

using Slic3r::anonymous_namespace{PluginHostUi.cpp}::CallablePtr = std::shared_ptr<GilSafeCallable>

Function Documentation

◆ app_closing()

bool Slic3r::anonymous_namespace{PluginHostUi.cpp}::app_closing ( )
242{ return wxTheApp == nullptr || GUI::wxGetApp().is_closing(); }

References app_closing().

Referenced by app_closing(), and run_on_ui_blocking().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ button_to_string()

std::string Slic3r::anonymous_namespace{PluginHostUi.cpp}::button_to_string ( int rc)
334{
335 switch (rc) {
336 case wxID_OK: return "ok";
337 case wxID_YES: return "yes";
338 case wxID_NO: return "no";
339 default: return "cancel";
340 }
341}

References button_to_string().

Referenced by button_to_string(), and ui_message().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_close()

void Slic3r::anonymous_namespace{PluginHostUi.cpp}::handle_close ( int id)
542{
543 if (wxTheApp == nullptr)
544 return;
545 GUI::wxGetApp().CallAfter([id]() {
546 auto* window = UiRegistry::instance().get_as<wxWindow>(id);
547 if (auto* panel = dynamic_cast<GUI::DockPanel*>(window))
548 panel->request_close();
549 else
550 GUI::WebDialog::request_close(dynamic_cast<GUI::WebDialog*>(window));
551 });
552}
Definition DockPanel.hpp:19
Definition WebDialog.hpp:34
static void request_close(WebDialog *dialog)
Definition WebDialog.cpp:95
static UiRegistry & instance()
Definition PluginHostUi.cpp:154
T * get_as(int id)
Definition PluginHostUi.cpp:179

References handle_close(), Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiRegistry::instance(), and Slic3r::GUI::WebDialog::request_close().

Referenced by handle_close().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_post()

void Slic3r::anonymous_namespace{PluginHostUi.cpp}::handle_post ( int id,
py::object data )
528{
529 if (wxTheApp == nullptr)
530 return;
531 json j = py_to_json(data); // GIL held (binding body)
532 GUI::wxGetApp().CallAfter([id, j = std::move(j)]() {
533 auto* window = UiRegistry::instance().get_as<wxWindow>(id);
534 if (auto* panel = dynamic_cast<GUI::DockPanel*>(window))
535 panel->push_message(j);
536 else
537 GUI::WebDialog::post_message(dynamic_cast<GUI::WebDialog*>(window), j);
538 });
539}
static void post_message(WebDialog *dialog, const nlohmann::json &data)
Definition WebDialog.cpp:89
nlohmann::json json
Definition AssembleList.cpp:42
nlohmann::json py_to_json(const pybind11::handle &o, int depth=0)
Definition PluginFsUtils.hpp:64

References handle_post(), Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiRegistry::instance(), Slic3r::GUI::WebDialog::post_message(), and Slic3r::py_to_json().

Referenced by handle_post().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_show()

void Slic3r::anonymous_namespace{PluginHostUi.cpp}::handle_show ( int id,
bool show )
555{
556 if (wxTheApp == nullptr)
557 return;
558 GUI::wxGetApp().CallAfter([id, show]() {
559 auto* panel = UiRegistry::instance().get_as<GUI::DockPanel>(id);
560 GUI::Plater* plater = GUI::wxGetApp().plater();
561 if (panel != nullptr && plater != nullptr)
562 plater->show_dock_pane(panel, show);
563 });
564}
Definition Plater.hpp:337
void show_dock_pane(wxWindow *window, bool show)
Definition Plater.cpp:19175

References handle_show(), Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiRegistry::instance(), and Slic3r::GUI::Plater::show_dock_pane().

Referenced by handle_show().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_close_adapter()

std::function< void()> Slic3r::anonymous_namespace{PluginHostUi.cpp}::make_close_adapter ( const CallablePtr & holder)
131{
132 if (!holder)
133 return nullptr;
134 return [holder]() {
135 PythonGILState gil;
136 if (!gil)
137 return;
138 try {
139 holder->fn();
140 } catch (py::error_already_set& e) {
141 BOOST_LOG_TRIVIAL(error) << "orca.host.ui on_close handler raised: " << e.what();
142 PyErr_Clear();
143 }
144 };
145}
Definition PythonInterpreter.hpp:169

References make_close_adapter().

Referenced by make_close_adapter(), ui_create_dock_panel(), and ui_create_window().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_holder()

CallablePtr Slic3r::anonymous_namespace{PluginHostUi.cpp}::make_holder ( py::object obj)
84{
85 if (!obj || obj.is_none())
86 return nullptr;
87 return std::make_shared<GilSafeCallable>(std::move(obj));
88}

References make_holder().

Referenced by make_holder(), make_message_adapter(), make_submit_adapter(), plater_notification(), ui_create_dock_panel(), and ui_create_window().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_message_adapter()

GUI::WebDialog::MessageHandler Slic3r::anonymous_namespace{PluginHostUi.cpp}::make_message_adapter ( py::object on_message)
93{
94 CallablePtr holder = make_holder(std::move(on_message));
95 if (!holder)
96 return nullptr;
97 return [holder](const json& data) {
99 if (!gil)
100 return;
101 try {
102 holder->fn(json_to_py(data));
103 } catch (py::error_already_set& e) {
104 BOOST_LOG_TRIVIAL(error) << "orca.host.ui on_message handler raised: " << e.what();
105 PyErr_Clear();
106 }
107 };
108}
CallablePtr make_holder(py::object obj)
Definition PluginHostUi.cpp:83
std::shared_ptr< GilSafeCallable > CallablePtr
Definition PluginHostUi.cpp:81
pybind11::object json_to_py(const nlohmann::json &j, int depth=0)
Definition PluginFsUtils.hpp:33

References Slic3r::json_to_py(), make_holder(), and make_message_adapter().

Referenced by make_message_adapter(), ui_create_dock_panel(), and ui_create_window().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_submit_adapter()

GUI::WebDialog::SubmitHandler Slic3r::anonymous_namespace{PluginHostUi.cpp}::make_submit_adapter ( py::object on_submit)
111{
112 CallablePtr holder = make_holder(std::move(on_submit));
113 if (!holder)
114 return nullptr;
115 return [holder](const json& data) {
116 PythonGILState gil;
117 if (!gil)
118 return;
119 try {
120 holder->fn(json_to_py(data));
121 } catch (py::error_already_set& e) {
122 BOOST_LOG_TRIVIAL(error) << "orca.host.ui on_submit handler raised: " << e.what();
123 PyErr_Clear();
124 }
125 };
126}

References Slic3r::json_to_py(), make_holder(), and make_submit_adapter().

Referenced by make_submit_adapter(), and ui_create_window().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ message_style()

long Slic3r::anonymous_namespace{PluginHostUi.cpp}::message_style ( const std::string & buttons,
const std::string & icon )
313{
314 long style = wxOK;
315 if (buttons == "ok_cancel")
316 style = wxOK | wxCANCEL;
317 else if (buttons == "yes_no")
318 style = wxYES_NO;
319 else if (buttons == "yes_no_cancel")
320 style = wxYES_NO | wxCANCEL;
321
322 if (icon == "warning")
323 style |= wxICON_WARNING;
324 else if (icon == "error")
325 style |= wxICON_ERROR;
326 else if (icon == "question")
327 style |= wxICON_QUESTION;
328 else
329 style |= wxICON_INFORMATION;
330 return style;
331}
#define style
Definition WipeTowerDialog.cpp:101

References message_style(), and style.

Referenced by message_style(), and ui_message().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ new_progress_dialog()

UiProgressHandle * Slic3r::anonymous_namespace{PluginHostUi.cpp}::new_progress_dialog ( const std::string & title,
const std::string & message,
int maximum,
int style )
586{
587 return new UiProgressHandle(ui_create_progress_dialog(title, message, maximum, style));
588}
UiProgressHandle ui_create_progress_dialog(const std::string &title, const std::string &message, int maximum, int style)
Definition PluginHostUi.cpp:566

References new_progress_dialog(), style, and ui_create_progress_dialog().

Referenced by new_progress_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ plater_notification()

void Slic3r::anonymous_namespace{PluginHostUi.cpp}::plater_notification ( GUI::NotificationManager::NotificationLevel notification_level,
const std::string & text,
const std::string & hypertext,
py::object on_click )
637{
638 const std::string plugin_key = PluginAuditManager::instance().current_plugin();
639 CallablePtr holder = make_holder(std::move(on_click));
640 if (holder)
641 UiRegistry::instance().bind_callback(holder, plugin_key);
642
643 std::function<bool(wxEvtHandler*)> callback;
644 if (holder) {
645 callback = [holder](wxEvtHandler*) -> bool {
646 if (!holder->active.load(std::memory_order_acquire))
647 return false;
648
649 PythonGILState gil;
650 if (!gil)
651 return false;
652 try {
653 py::object result = holder->fn();
654 return result.is_none() || result.cast<bool>();
655 } catch (py::error_already_set& e) {
656 BOOST_LOG_TRIVIAL(error) << "orca.host.ui notification callback raised: " << e.what();
657 PyErr_Clear();
658 return false;
659 } catch (const std::exception& e) {
660 BOOST_LOG_TRIVIAL(error) << "orca.host.ui notification callback raised: " << e.what();
661 return false;
662 } catch (...) {
663 BOOST_LOG_TRIVIAL(error) << "orca.host.ui notification callback raised an unknown exception";
664 return false;
665 }
666 };
667 }
668
669 run_on_ui_blocking([notification_level, text, hypertext, callback = std::move(callback)]() mutable {
670 GUI::wxGetApp().plater()->get_notification_manager()->push_notification(GUI::NotificationType::CustomNotification, notification_level, text,
671 hypertext, std::move(callback));
672 });
673}
static PluginAuditManager & instance()
Definition PluginAuditManager.cpp:535
std::string current_plugin() const
Definition PluginAuditManager.cpp:543
void bind_callback(const CallablePtr &callback, const std::string &plugin_key)
Definition PluginHostUi.cpp:210
@ CustomNotification
Definition NotificationManager.hpp:66
auto run_on_ui_blocking(Fn &&fn) -> std::invoke_result_t< Fn & >
Definition PluginHostUi.cpp:255
std::atomic_bool active
Definition PluginHostUi.cpp:65

References Slic3r::PluginAuditManager::current_plugin(), Slic3r::GUI::CustomNotification, Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiRegistry::instance(), Slic3r::PluginAuditManager::instance(), make_holder(), plater_notification(), and run_on_ui_blocking().

Referenced by plater_notification().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ progress_close()

void Slic3r::anonymous_namespace{PluginHostUi.cpp}::progress_close ( int id)
628{
629 run_on_ui_blocking([&]() {
632 });
633}
Definition PluginProgressDialog.hpp:30
static void request_close(PluginProgressDialog *dialog)
Definition PluginProgressDialog.cpp:70

References Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiRegistry::instance(), progress_close(), Slic3r::GUI::PluginProgressDialog::request_close(), and run_on_ui_blocking().

Referenced by progress_close().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ progress_is_open()

bool Slic3r::anonymous_namespace{PluginHostUi.cpp}::progress_is_open ( int id)
591{
592 return UiRegistry::instance().is_open(id);
593}
bool is_open(int id)
Definition PluginHostUi.cpp:187

References Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiRegistry::instance(), and progress_is_open().

Referenced by progress_is_open().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ progress_pulse()

bool Slic3r::anonymous_namespace{PluginHostUi.cpp}::progress_pulse ( int id,
const std::string & message )
596{
597 return run_on_ui_blocking([&]() {
599 return GUI::PluginProgressDialog::pulse(d, wxString::FromUTF8(message));
600 });
601}
static bool pulse(PluginProgressDialog *dialog, const wxString &message=wxEmptyString)
Definition PluginProgressDialog.cpp:48

References Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiRegistry::instance(), progress_pulse(), Slic3r::GUI::PluginProgressDialog::pulse(), and run_on_ui_blocking().

Referenced by progress_pulse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ progress_start_pulse()

void Slic3r::anonymous_namespace{PluginHostUi.cpp}::progress_start_pulse ( int id,
int interval_ms,
const std::string & message )
612{
613 run_on_ui_blocking([&]() {
615 GUI::PluginProgressDialog::start_pulse(d, interval_ms, wxString::FromUTF8(message));
616 });
617}
static void start_pulse(PluginProgressDialog *dialog, int interval_ms, const wxString &message=wxEmptyString)
Definition PluginProgressDialog.cpp:58

References Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiRegistry::instance(), progress_start_pulse(), run_on_ui_blocking(), and Slic3r::GUI::PluginProgressDialog::start_pulse().

Referenced by progress_start_pulse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ progress_stop_pulse()

void Slic3r::anonymous_namespace{PluginHostUi.cpp}::progress_stop_pulse ( int id)
620{
621 run_on_ui_blocking([&]() {
624 });
625}
void stop_pulse()
Definition PluginProgressDialog.cpp:113

References Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiRegistry::instance(), progress_stop_pulse(), run_on_ui_blocking(), and Slic3r::GUI::PluginProgressDialog::stop_pulse().

Referenced by progress_stop_pulse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ progress_update()

bool Slic3r::anonymous_namespace{PluginHostUi.cpp}::progress_update ( int id,
int value,
const std::string & message )
604{
605 return run_on_ui_blocking([&]() {
607 return GUI::PluginProgressDialog::update(d, value, wxString::FromUTF8(message));
608 });
609}
static bool update(PluginProgressDialog *dialog, int value, const wxString &message=wxEmptyString)
Definition PluginProgressDialog.cpp:53

References Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiRegistry::instance(), progress_update(), run_on_ui_blocking(), and Slic3r::GUI::PluginProgressDialog::update().

Referenced by progress_update().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ run_on_ui_blocking()

template<typename Fn>
auto Slic3r::anonymous_namespace{PluginHostUi.cpp}::run_on_ui_blocking ( Fn && fn) ->std::invoke_result_t< Fn & >
256{
257 using R = std::invoke_result_t<Fn&>;
258 if (wxTheApp == nullptr)
259 throw std::runtime_error("OrcaSlicer application is not initialized");
260
261 if (wxIsMainThread()) {
262 py::gil_scoped_release nogil;
263 return fn();
264 }
265
266 if (app_closing())
267 throw std::runtime_error("OrcaSlicer is closing");
268
269 enum : int { Pending, Claimed, Abandoned };
270 // Shared with the queued task, which can outlive an abandoned wait. The task only touches fn
271 // after claiming the call, and a claimed call is always waited for, so fn is still alive then.
272 struct Call
273 {
274 std::promise<R> prom;
275 std::atomic<int> state{Pending};
276 };
277 auto call = std::make_shared<Call>();
278 std::future<R> fut = call->prom.get_future();
279
280 py::gil_scoped_release nogil;
281 GUI::wxGetApp().CallAfter([call, &fn]() {
282 int expected = Pending;
283 if (!call->state.compare_exchange_strong(expected, Claimed))
284 return;
285 try {
286 if constexpr (std::is_void_v<R>) {
287 fn();
288 call->prom.set_value();
289 } else {
290 call->prom.set_value(fn());
291 }
292 } catch (...) {
293 call->prom.set_exception(std::current_exception());
294 }
295 });
296 while (fut.wait_for(std::chrono::milliseconds(50)) != std::future_status::ready) {
297 int expected = Pending;
298 if (app_closing() && call->state.compare_exchange_strong(expected, Abandoned))
299 throw std::runtime_error("OrcaSlicer is closing");
300 }
301 return fut.get();
302}
bool app_closing()
Definition PluginHostUi.cpp:242

References app_closing(), and run_on_ui_blocking().

Referenced by plater_notification(), progress_close(), progress_pulse(), progress_start_pulse(), progress_stop_pulse(), progress_update(), run_on_ui_blocking(), ui_create_progress_dialog(), and ui_message().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ run_when_plater_shown()

void Slic3r::anonymous_namespace{PluginHostUi.cpp}::run_when_plater_shown ( std::function< void(GUI::Plater *)> fn)
478{
479 GUI::wxGetApp().CallAfter([fn = std::move(fn)]() mutable {
480 auto* waiter = new PlaterShownWaiter(std::move(fn));
481 if (!waiter->try_run())
482 waiter->Start(100);
483 });
484}

References run_when_plater_shown().

Referenced by run_when_plater_shown(), and ui_create_dock_panel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ui_create_dock_panel()

py::object Slic3r::anonymous_namespace{PluginHostUi.cpp}::ui_create_dock_panel ( const std::string & html,
const std::string & title,
int width,
int height,
py::object on_message,
py::object on_close,
const std::string & dock )
488{
489 if (std::find(std::begin(DOCK_POSITIONS), std::end(DOCK_POSITIONS), dock) == std::end(DOCK_POSITIONS))
490 throw std::invalid_argument("orca.host.ui.create_dock_panel dock must be \"left\", \"right\", \"bottom\" or \"float\"");
491
492 auto msg_adapter = make_message_adapter(std::move(on_message));
493 CallablePtr close_holder = make_holder(std::move(on_close));
494 const std::string plugin_key = PluginAuditManager::instance().current_plugin();
495 const int w = width > 0 ? width : 320;
496 const int h = height > 0 ? height : 480;
497
498 if (wxTheApp == nullptr)
499 throw std::runtime_error("OrcaSlicer application is not initialized");
500
501 // Deferred and pre-bound for the same reasons as create_window().
502 const int new_id = UiRegistry::instance().reserve_id();
503 UiRegistry::instance().bind(new_id, nullptr, plugin_key);
504
505 run_when_plater_shown([new_id, plugin_key, html, title, dock, w, h,
506 msg_adapter = std::move(msg_adapter),
507 close_holder = std::move(close_holder)](GUI::Plater* plater) mutable {
508 if (!UiRegistry::instance().is_open(new_id))
509 return;
510
511 if (plater == nullptr) {
513 return;
514 }
515
516 auto on_destroyed = [new_id]() { UiRegistry::instance().remove(new_id); };
517 auto* panel = new GUI::DockPanel(plater, html, std::move(msg_adapter), make_close_adapter(close_holder),
518 std::move(on_destroyed));
519 UiRegistry::instance().bind(new_id, panel, plugin_key);
520 plater->add_dock_pane(panel, GUI::plugin_pane_name(plugin_key, title), wxString::FromUTF8(title), dock,
521 wxSize(w, h), [panel]() { panel->fire_close(); });
522 });
523
524 return py::cast(UiDockPanelHandle{new_id});
525}
void add_dock_pane(wxWindow *window, const std::string &name, const wxString &caption, const std::string &dock, const wxSize &size, std::function< void()> on_close)
Definition Plater.cpp:19164
int reserve_id()
Definition PluginHostUi.cpp:160
void bind(int id, wxWindow *window, const std::string &plugin_key)
Definition PluginHostUi.cpp:165
void remove(int id)
Definition PluginHostUi.cpp:171
std::string plugin_pane_name(const std::string &plugin_key, const std::string &title)
Definition DockPanel.cpp:18
std::function< void()> make_close_adapter(const CallablePtr &holder)
Definition PluginHostUi.cpp:130
void run_when_plater_shown(std::function< void(GUI::Plater *)> fn)
Definition PluginHostUi.cpp:477
GUI::WebDialog::MessageHandler make_message_adapter(py::object on_message)
Definition PluginHostUi.cpp:92
constexpr const char * DOCK_POSITIONS[]
Definition PluginHostUi.cpp:441

References Slic3r::GUI::Plater::add_dock_pane(), Slic3r::PluginAuditManager::current_plugin(), DOCK_POSITIONS, Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiRegistry::instance(), Slic3r::PluginAuditManager::instance(), make_close_adapter(), make_holder(), make_message_adapter(), Slic3r::GUI::plugin_pane_name(), run_when_plater_shown(), and ui_create_dock_panel().

Referenced by ui_create_dock_panel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ui_create_progress_dialog()

UiProgressHandle Slic3r::anonymous_namespace{PluginHostUi.cpp}::ui_create_progress_dialog ( const std::string & title,
const std::string & message,
int maximum,
int style )
567{
568 const std::string plugin_key = PluginAuditManager::instance().current_plugin();
569 const int max_value = maximum > 0 ? maximum : 100;
570
571 return run_on_ui_blocking([&]() -> UiProgressHandle {
572 const int new_id = UiRegistry::instance().reserve_id();
573
574 // Registry cleanup: GIL-free, runs from the dialog destructor on every path.
575 auto on_destroyed = [new_id]() { UiRegistry::instance().remove(new_id); };
576
577 auto* dlg = GUI::PluginProgressDialog::create_dialog(ui_parent(), wxString::FromUTF8(title),
578 wxString::FromUTF8(message), max_value, style,
579 std::move(on_destroyed));
580 UiRegistry::instance().bind(new_id, dlg, plugin_key);
581 return UiProgressHandle{new_id};
582 });
583}
static PluginProgressDialog * create_dialog(wxWindow *parent, const wxString &title, const wxString &message, int maximum, int style, CloseHandler on_destroyed)
Definition PluginProgressDialog.cpp:38
wxWindow * ui_parent()
Definition PluginHostUi.cpp:304

References Slic3r::GUI::PluginProgressDialog::create_dialog(), Slic3r::PluginAuditManager::current_plugin(), Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiRegistry::instance(), Slic3r::PluginAuditManager::instance(), run_on_ui_blocking(), style, ui_create_progress_dialog(), and ui_parent().

Referenced by new_progress_dialog(), and ui_create_progress_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ui_create_window()

py::object Slic3r::anonymous_namespace{PluginHostUi.cpp}::ui_create_window ( const std::string & html,
const std::string & title,
int width,
int height,
py::object on_message,
py::object on_close,
long style,
py::object on_submit )
372{
373 auto msg_adapter = make_message_adapter(std::move(on_message));
374 auto submit_adapter = make_submit_adapter(std::move(on_submit));
375 CallablePtr close_holder = make_holder(std::move(on_close));
376 const std::string plugin_key = PluginAuditManager::instance().current_plugin();
377 const int w = width > 0 ? width : 820;
378 const int h = height > 0 ? height : 600;
379
380 if ((style & ~WINDOW_MODAL) != 0)
381 throw std::invalid_argument("unsupported orca.host.ui.create_window style flags");
382 const bool modal = (style & WINDOW_MODAL) != 0;
383
384 if (wxTheApp == nullptr)
385 throw std::runtime_error("OrcaSlicer application is not initialized");
386
387 // The whole wxWindow/webview creation is deferred to a clean main-loop iteration.
388 // The WebKit backends deliver script messages synchronously from inside the native
389 // callback (GTK: HandleWindowEvent in wxgtk_webview_webkit_script_message_received,
390 // wx src/gtk/webview_webkit2.cpp; macOS: ProcessWindowEvent in the
391 // WKScriptMessageHandler delegate, src/osx/webview_webkit.mm), so a script-triggered
392 // create_window otherwise runs with the plugins-dialog webview's signal/delegate
393 // frame still on the stack — creating and presenting a second webview window from
394 // there crashed on Linux (observed at a since-removed Raise(): gtk_window_present
395 // right after a Show() whose real map can still be deferred behind the X11
396 // frame-extents handshake, wx src/gtk/toplevel.cpp). WebView2 already queues script
397 // messages (AddPendingEvent), so on Windows this deferral merely matches wx's own
398 // delivery model.
399 //
400 // The id is pre-bound with a null window so the returned handle is live at once:
401 // is_open() keys on registry presence, post()/close() are CallAfter-marshaled and
402 // FIFO-ordered after the creation below, and a plugin teardown claims the pending
403 // id (take_for_plugin), which the creation detects and skips — no orphan window.
404 const int new_id = UiRegistry::instance().reserve_id();
405 UiRegistry::instance().bind(new_id, nullptr, plugin_key);
406
407 GUI::wxGetApp().CallAfter([new_id, plugin_key, html, title, w, h,
408 msg_adapter = std::move(msg_adapter),
409 submit_adapter = std::move(submit_adapter),
410 close_holder = std::move(close_holder), modal]() mutable {
411 // Torn down (plugin unload / app shutdown) before the window materialized.
412 if (!UiRegistry::instance().is_open(new_id))
413 return;
414
415 GUI::WebDialog::CloseHandler on_close = make_close_adapter(close_holder);
416 // Registry cleanup: GIL-free, runs from the dialog destructor on every path.
417 auto on_destroyed = [new_id]() { UiRegistry::instance().remove(new_id); };
418
419 auto* dlg = new GUI::WebDialog(ui_parent(), wxString::FromUTF8(title), html,
420 wxSize(w, h), std::move(msg_adapter), std::move(submit_adapter),
421 std::move(on_close), std::move(on_destroyed), PLUGIN_WX_STYLE);
422 UiRegistry::instance().bind(new_id, dlg, plugin_key);
423 if (modal) {
424 dlg->ShowModal();
425 // Plugin teardown may already have removed and destroyed this dialog
426 // while its modal loop was running.
427 if (UiRegistry::instance().is_open(new_id))
428 dlg->Destroy();
429 } else {
430 dlg->use_normal_window_type();
431 dlg->Show();
432 }
433 });
434
435 return py::cast(UiWindowHandle{new_id});
436}
std::function< void()> CloseHandler
Definition WebDialog.hpp:38
GUI::WebDialog::SubmitHandler make_submit_adapter(py::object on_submit)
Definition PluginHostUi.cpp:110
constexpr long PLUGIN_WX_STYLE
Definition PluginHostUi.cpp:356
constexpr long WINDOW_MODAL
Definition PluginHostUi.cpp:355

References Slic3r::PluginAuditManager::current_plugin(), Slic3r::anonymous_namespace{PluginHostUi.cpp}::UiRegistry::instance(), Slic3r::PluginAuditManager::instance(), make_close_adapter(), make_holder(), make_message_adapter(), make_submit_adapter(), PLUGIN_WX_STYLE, style, ui_create_window(), ui_parent(), and WINDOW_MODAL.

Referenced by ui_create_window().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ui_message()

std::string Slic3r::anonymous_namespace{PluginHostUi.cpp}::ui_message ( const std::string & text,
const std::string & title,
const std::string & buttons,
const std::string & icon )
345{
346 const long style = message_style(buttons, icon);
347 return run_on_ui_blocking([&]() -> std::string {
348 GUI::MessageDialog dlg(nullptr, wxString::FromUTF8(text), wxString::FromUTF8(title), style);
349 return button_to_string(dlg.ShowModal());
350 });
351}
Definition MsgDialog.hpp:169
long message_style(const std::string &buttons, const std::string &icon)
Definition PluginHostUi.cpp:312
std::string button_to_string(int rc)
Definition PluginHostUi.cpp:333

References button_to_string(), message_style(), run_on_ui_blocking(), Slic3r::GUI::DPIAware< P >::ShowModal(), style, and ui_message().

Referenced by ui_message().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ui_parent()

wxWindow * Slic3r::anonymous_namespace{PluginHostUi.cpp}::ui_parent ( )
305{
306 return wxTheApp == nullptr ? nullptr : dynamic_cast<wxWindow*>(GUI::wxGetApp().mainframe);
307}

References ui_parent().

Referenced by ui_create_progress_dialog(), ui_create_window(), and ui_parent().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ DOCK_POSITIONS

const char* Slic3r::anonymous_namespace{PluginHostUi.cpp}::DOCK_POSITIONS[] = {"left", "right", "bottom", "float"}
constexpr
441{"left", "right", "bottom", "float"};

Referenced by ui_create_dock_panel().

◆ PLUGIN_WX_STYLE

long Slic3r::anonymous_namespace{PluginHostUi.cpp}::PLUGIN_WX_STYLE = wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxMAXIMIZE_BOX | wxRESIZE_BORDER
constexpr

Referenced by ui_create_window().

◆ WINDOW_MODAL

long Slic3r::anonymous_namespace{PluginHostUi.cpp}::WINDOW_MODAL = 1L << 0
constexpr

Referenced by ui_create_window().

◆ WINDOW_MODELESS

long Slic3r::anonymous_namespace{PluginHostUi.cpp}::WINDOW_MODELESS = 0L
constexpr