Removes bottom status bar.
StatusBar class calls are commented out and replaced with notifications. SlicicingProgress notification shows progress of slicing, ProgressIndicator notification handles other progress information, like arrange objects etc.
This commit is contained in:
parent
3db4804e47
commit
b9dab7540e
@ -958,6 +958,8 @@ bool GUI_App::on_init_inner()
|
||||
// update_mode(); // !!! do that later
|
||||
SetTopWindow(mainframe);
|
||||
|
||||
plater_->init_notification_manager();
|
||||
|
||||
m_printhost_job_queue.reset(new PrintHostJobQueue(mainframe->printhost_queue_dlg()));
|
||||
|
||||
if (is_gcode_viewer()) {
|
||||
@ -2278,7 +2280,7 @@ wxBookCtrlBase* GUI_App::tab_panel() const
|
||||
return mainframe->m_tabpanel;
|
||||
}
|
||||
|
||||
NotificationManager* GUI_App::notification_manager()
|
||||
std::shared_ptr<NotificationManager> GUI_App::notification_manager()
|
||||
{
|
||||
return plater_->get_notification_manager();
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ public:
|
||||
ObjectLayers* obj_layers();
|
||||
Plater* plater();
|
||||
Model& model();
|
||||
NotificationManager* notification_manager();
|
||||
std::shared_ptr<NotificationManager> notification_manager();
|
||||
|
||||
// Parameters extracted from the command line to be passed to GUI after initialization.
|
||||
GUI_InitParams* init_params { nullptr };
|
||||
|
@ -734,9 +734,9 @@ void Preview::update_layers_slider(const std::vector<double>& layers_z, bool kee
|
||||
|
||||
double top_area = area(object->get_layer(int(object->layers().size()) - 1)->lslices);
|
||||
if( bottom_area - top_area > delta_area) {
|
||||
NotificationManager* notif_mngr = wxGetApp().plater()->get_notification_manager();
|
||||
std::shared_ptr<NotificationManager> notif_mngr = wxGetApp().plater()->get_notification_manager();
|
||||
notif_mngr->push_notification(
|
||||
NotificationType::SignDetected, NotificationManager::NotificationLevel::RegularNotification,
|
||||
NotificationType::SignDetected, NotificationManager::NotificationLevel::RegularNotificationLevel,
|
||||
_u8L("NOTE:") + "\n" + _u8L("Sliced object looks like the sign") + "\n",
|
||||
_u8L("Apply auto color change to print"),
|
||||
[this](wxEvtHandler*) {
|
||||
|
@ -22,7 +22,7 @@ static inline void show_notification_extruders_limit_exceeded()
|
||||
wxGetApp()
|
||||
.plater()
|
||||
->get_notification_manager()
|
||||
->push_notification(NotificationType::MmSegmentationExceededExtrudersLimit, NotificationManager::NotificationLevel::RegularNotification,
|
||||
->push_notification(NotificationType::MmSegmentationExceededExtrudersLimit, NotificationManager::NotificationLevel::RegularNotificationLevel,
|
||||
GUI::format(_L("Your printer has more extruders than the multi-material painting gizmo supports. For this reason, only the "
|
||||
"first %1% extruders will be able to be used for painting."), GLGizmoMmuSegmentation::EXTRUDERS_LIMIT));
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ void GLGizmoSimplify::on_set_state()
|
||||
auto notification_manager = wxGetApp().plater()->get_notification_manager();
|
||||
notification_manager->push_notification(
|
||||
NotificationType::CustomNotification,
|
||||
NotificationManager::NotificationLevel::RegularNotification,
|
||||
NotificationManager::NotificationLevel::RegularNotificationLevel,
|
||||
_u8L("ERROR: Wait until Simplification ends or Cancel process."));
|
||||
return;
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ bool GLGizmosManager::check_gizmos_closed_except(EType type) const
|
||||
if (get_current_type() != type && get_current_type() != Undefined) {
|
||||
wxGetApp().plater()->get_notification_manager()->push_notification(
|
||||
NotificationType::CustomSupportsAndSeamRemovedAfterRepair,
|
||||
NotificationManager::NotificationLevel::RegularNotification,
|
||||
NotificationManager::NotificationLevel::RegularNotificationLevel,
|
||||
_u8L("ERROR: Please close all manipulators available from "
|
||||
"the left toolbar first"));
|
||||
return false;
|
||||
@ -1256,7 +1256,7 @@ bool GLGizmosManager::is_in_editing_mode(bool error_notification) const
|
||||
if (error_notification)
|
||||
wxGetApp().plater()->get_notification_manager()->push_notification(
|
||||
NotificationType::QuitSLAManualMode,
|
||||
NotificationManager::NotificationLevel::ErrorNotification,
|
||||
NotificationManager::NotificationLevel::ErrorNotificationLevel,
|
||||
_u8L("You are currently editing SLA support points. Please, "
|
||||
"apply or discard your changes first."));
|
||||
|
||||
|
@ -1012,7 +1012,7 @@ void NotificationManager::HintNotification::retrieve_data(bool new_hint/* = true
|
||||
if(hint_data != nullptr)
|
||||
{
|
||||
NotificationData nd { NotificationType::DidYouKnowHint,
|
||||
NotificationLevel::RegularNotification,
|
||||
NotificationLevel::RegularNotificationLevel,
|
||||
0,
|
||||
hint_data->text,
|
||||
hint_data->hypertext, nullptr,
|
||||
|
@ -9,6 +9,7 @@ namespace Slic3r {
|
||||
class ModelInstance;
|
||||
|
||||
namespace GUI {
|
||||
class NotificationManager;
|
||||
|
||||
class ArrangeJob : public PlaterJob
|
||||
{
|
||||
@ -39,8 +40,8 @@ protected:
|
||||
void process() override;
|
||||
|
||||
public:
|
||||
ArrangeJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
|
||||
: PlaterJob{std::move(pri), plater}
|
||||
ArrangeJob(std::shared_ptr<NotificationManager> nm, Plater *plater)
|
||||
: PlaterJob{nm, plater}
|
||||
{}
|
||||
|
||||
int status_range() const override
|
||||
|
@ -6,6 +6,7 @@
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
class Plater;
|
||||
class NotificationManager;
|
||||
|
||||
class FillBedJob : public PlaterJob
|
||||
{
|
||||
@ -27,8 +28,8 @@ protected:
|
||||
void process() override;
|
||||
|
||||
public:
|
||||
FillBedJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
|
||||
: PlaterJob{std::move(pri), plater}
|
||||
FillBedJob(std::shared_ptr<NotificationManager> nm, Plater *plater)
|
||||
: PlaterJob{nm, plater}
|
||||
{}
|
||||
|
||||
int status_range() const override
|
||||
|
@ -2,9 +2,11 @@
|
||||
#include <exception>
|
||||
|
||||
#include "Job.hpp"
|
||||
#include "../NotificationManager.hpp"
|
||||
#include <libslic3r/Thread.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
void GUI::Job::run(std::exception_ptr &eptr)
|
||||
@ -30,8 +32,8 @@ void GUI::Job::update_status(int st, const wxString &msg)
|
||||
wxQueueEvent(this, evt);
|
||||
}
|
||||
|
||||
GUI::Job::Job(std::shared_ptr<ProgressIndicator> pri)
|
||||
: m_progress(std::move(pri))
|
||||
GUI::Job::Job(std::shared_ptr<NotificationManager> nm)
|
||||
: m_notifications(nm)
|
||||
{
|
||||
m_thread_evt_id = wxNewId();
|
||||
|
||||
@ -40,21 +42,21 @@ GUI::Job::Job(std::shared_ptr<ProgressIndicator> pri)
|
||||
|
||||
auto msg = evt.GetString();
|
||||
if (!msg.empty() && !m_worker_error)
|
||||
m_progress->set_status_text(msg.ToUTF8().data());
|
||||
m_notifications->progress_indicator_set_status_text(msg.ToUTF8().data());
|
||||
|
||||
if (m_finalized) return;
|
||||
|
||||
m_progress->set_progress(evt.GetInt());
|
||||
m_notifications->progress_indicator_set_progress(evt.GetInt());
|
||||
if (evt.GetInt() == status_range() || m_worker_error) {
|
||||
// set back the original range and cancel callback
|
||||
m_progress->set_range(m_range);
|
||||
m_progress->set_cancel_callback();
|
||||
m_notifications->progress_indicator_set_range(m_range);
|
||||
m_notifications->progress_indicator_set_cancel_callback();
|
||||
wxEndBusyCursor();
|
||||
|
||||
if (m_worker_error) {
|
||||
m_finalized = true;
|
||||
m_progress->set_status_text("");
|
||||
m_progress->set_progress(m_range);
|
||||
m_notifications->progress_indicator_set_status_text("");
|
||||
m_notifications->progress_indicator_set_progress(m_range);
|
||||
on_exception(m_worker_error);
|
||||
}
|
||||
else {
|
||||
@ -86,12 +88,12 @@ void GUI::Job::start()
|
||||
prepare();
|
||||
|
||||
// Save the current status indicatior range and push the new one
|
||||
m_range = m_progress->get_range();
|
||||
m_progress->set_range(status_range());
|
||||
m_range = m_notifications->progress_indicator_get_range();
|
||||
m_notifications->progress_indicator_set_range(status_range());
|
||||
|
||||
// init cancellation flag and set the cancel callback
|
||||
m_canceled.store(false);
|
||||
m_progress->set_cancel_callback(
|
||||
m_notifications->progress_indicator_set_cancel_callback(
|
||||
[this]() { m_canceled.store(true); });
|
||||
|
||||
m_finalized = false;
|
||||
|
@ -8,14 +8,13 @@
|
||||
|
||||
#include <slic3r/GUI/I18N.hpp>
|
||||
|
||||
#include "ProgressIndicator.hpp"
|
||||
|
||||
#include <wx/event.h>
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
class NotificationManager;
|
||||
// A class to handle UI jobs like arranging and optimizing rotation.
|
||||
// These are not instant jobs, the user has to be informed about their
|
||||
// state in the status progress indicator. On the other hand they are
|
||||
@ -33,7 +32,7 @@ class Job : public wxEvtHandler
|
||||
boost::thread m_thread;
|
||||
std::atomic<bool> m_running{false}, m_canceled{false};
|
||||
bool m_finalized = false, m_finalizing = false;
|
||||
std::shared_ptr<ProgressIndicator> m_progress;
|
||||
std::shared_ptr<NotificationManager> m_notifications;
|
||||
std::exception_ptr m_worker_error = nullptr;
|
||||
|
||||
void run(std::exception_ptr &);
|
||||
@ -65,7 +64,7 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
Job(std::shared_ptr<ProgressIndicator> pri);
|
||||
Job(std::shared_ptr<NotificationManager> nm);
|
||||
|
||||
bool is_finalized() const { return m_finalized; }
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
class Plater;
|
||||
class NotificationManager;
|
||||
|
||||
class PlaterJob : public Job {
|
||||
protected:
|
||||
@ -15,8 +16,8 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
PlaterJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater):
|
||||
Job{std::move(pri)}, m_plater{plater} {}
|
||||
PlaterJob(std::shared_ptr<NotificationManager> nm, Plater *plater):
|
||||
Job{nm}, m_plater{plater} {}
|
||||
};
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
@ -10,6 +10,8 @@ namespace Slic3r {
|
||||
|
||||
namespace GUI {
|
||||
|
||||
class NotificationManager;
|
||||
|
||||
class RotoptimizeJob : public PlaterJob
|
||||
{
|
||||
using FindFn = std::function<Vec2d(const ModelObject & mo,
|
||||
@ -52,8 +54,8 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
RotoptimizeJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
|
||||
: PlaterJob{std::move(pri), plater}
|
||||
RotoptimizeJob(std::shared_ptr<NotificationManager> nm, Plater *plater)
|
||||
: PlaterJob{nm, plater}
|
||||
{}
|
||||
|
||||
void finalize() override;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
||||
#include "slic3r/GUI/NotificationManager.hpp"
|
||||
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
@ -124,8 +125,8 @@ public:
|
||||
priv(Plater *plt) : plater{plt} {}
|
||||
};
|
||||
|
||||
SLAImportJob::SLAImportJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
|
||||
: PlaterJob{std::move(pri), plater}, p{std::make_unique<priv>(plater)}
|
||||
SLAImportJob::SLAImportJob(std::shared_ptr<NotificationManager> nm, Plater *plater)
|
||||
: PlaterJob{nm, plater}, p{std::make_unique<priv>(plater)}
|
||||
{}
|
||||
|
||||
SLAImportJob::~SLAImportJob() = default;
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
class NotificationManager;
|
||||
|
||||
class SLAImportJob : public PlaterJob {
|
||||
class priv;
|
||||
|
||||
@ -16,7 +18,7 @@ protected:
|
||||
void finalize() override;
|
||||
|
||||
public:
|
||||
SLAImportJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater);
|
||||
SLAImportJob(std::shared_ptr<NotificationManager> nm, Plater *plater);
|
||||
~SLAImportJob();
|
||||
|
||||
void reset();
|
||||
|
@ -155,13 +155,13 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
|
||||
SetIcon(main_frame_icon(wxGetApp().get_app_mode()));
|
||||
|
||||
// initialize status bar
|
||||
m_statusbar = std::make_shared<ProgressStatusBar>(this);
|
||||
m_statusbar->set_font(GUI::wxGetApp().normal_font());
|
||||
if (wxGetApp().is_editor())
|
||||
m_statusbar->embed(this);
|
||||
m_statusbar->set_status_text(_L("Version") + " " +
|
||||
SLIC3R_VERSION + " - " +
|
||||
_L("Remember to check for updates at https://github.com/prusa3d/PrusaSlicer/releases"));
|
||||
// m_statusbar = std::make_shared<ProgressStatusBar>(this);
|
||||
// m_statusbar->set_font(GUI::wxGetApp().normal_font());
|
||||
// if (wxGetApp().is_editor())
|
||||
// m_statusbar->embed(this);
|
||||
// m_statusbar->set_status_text(_L("Version") + " " +
|
||||
// SLIC3R_VERSION + " - " +
|
||||
// _L("Remember to check for updates at https://github.com/prusa3d/PrusaSlicer/releases"));
|
||||
|
||||
// initialize tabpanel and menubar
|
||||
init_tabpanel();
|
||||
@ -1033,7 +1033,7 @@ void MainFrame::on_sys_color_changed()
|
||||
wxGetApp().init_label_colours();
|
||||
#ifdef __WXMSW__
|
||||
wxGetApp().UpdateDarkUI(m_tabpanel);
|
||||
m_statusbar->update_dark_ui();
|
||||
// m_statusbar->update_dark_ui();
|
||||
#ifdef _MSW_DARK_MODE
|
||||
// update common mode sizer
|
||||
if (!wxGetApp().tabs_as_menu())
|
||||
|
@ -204,7 +204,7 @@ public:
|
||||
wxWindow* m_plater_page{ nullptr };
|
||||
wxProgressDialog* m_progress_dialog { nullptr };
|
||||
PrintHostQueueDialog* m_printhost_queue_dlg;
|
||||
std::shared_ptr<ProgressStatusBar> m_statusbar;
|
||||
// std::shared_ptr<ProgressStatusBar> m_statusbar;
|
||||
|
||||
#ifdef __APPLE__
|
||||
std::unique_ptr<wxTaskBarIcon> m_taskbar_icon;
|
||||
|
@ -33,32 +33,32 @@ wxDEFINE_EVENT(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED, ExportGcodeNotificationClic
|
||||
wxDEFINE_EVENT(EVT_PRESET_UPDATE_AVAILABLE_CLICKED, PresetUpdateAvailableClickedEvent);
|
||||
|
||||
const NotificationManager::NotificationData NotificationManager::basic_notifications[] = {
|
||||
{NotificationType::Mouse3dDisconnected, NotificationLevel::RegularNotification, 10, _u8L("3D Mouse disconnected.") },
|
||||
{NotificationType::PresetUpdateAvailable, NotificationLevel::ImportantNotification, 20, _u8L("Configuration update is available."), _u8L("See more."),
|
||||
{NotificationType::Mouse3dDisconnected, NotificationLevel::RegularNotificationLevel, 10, _u8L("3D Mouse disconnected.") },
|
||||
{NotificationType::PresetUpdateAvailable, NotificationLevel::ImportantNotificationLevel, 20, _u8L("Configuration update is available."), _u8L("See more."),
|
||||
[](wxEvtHandler* evnthndlr) {
|
||||
if (evnthndlr != nullptr)
|
||||
wxPostEvent(evnthndlr, PresetUpdateAvailableClickedEvent(EVT_PRESET_UPDATE_AVAILABLE_CLICKED));
|
||||
return true;
|
||||
}
|
||||
},
|
||||
{NotificationType::NewAppAvailable, NotificationLevel::ImportantNotification, 20, _u8L("New version is available."), _u8L("See Releases page."), [](wxEvtHandler* evnthndlr) {
|
||||
{NotificationType::NewAppAvailable, NotificationLevel::ImportantNotificationLevel, 20, _u8L("New version is available."), _u8L("See Releases page."), [](wxEvtHandler* evnthndlr) {
|
||||
wxGetApp().open_browser_with_warning_dialog("https://github.com/prusa3d/PrusaSlicer/releases"); return true; }},
|
||||
{NotificationType::EmptyColorChangeCode, NotificationLevel::RegularNotification, 10,
|
||||
{NotificationType::EmptyColorChangeCode, NotificationLevel::RegularNotificationLevel, 10,
|
||||
_u8L("You have just added a G-code for color change, but its value is empty.\n"
|
||||
"To export the G-code correctly, check the \"Color Change G-code\" in \"Printer Settings > Custom G-code\"") },
|
||||
{NotificationType::EmptyAutoColorChange, NotificationLevel::RegularNotification, 10,
|
||||
{NotificationType::EmptyAutoColorChange, NotificationLevel::RegularNotificationLevel, 10,
|
||||
_u8L("No color change event was added to the print. The print does not look like a sign.") },
|
||||
{NotificationType::DesktopIntegrationSuccess, NotificationLevel::RegularNotification, 10,
|
||||
{NotificationType::DesktopIntegrationSuccess, NotificationLevel::RegularNotificationLevel, 10,
|
||||
_u8L("Desktop integration was successful.") },
|
||||
{NotificationType::DesktopIntegrationFail, NotificationLevel::WarningNotification, 10,
|
||||
{NotificationType::DesktopIntegrationFail, NotificationLevel::WarningNotificationLevel, 10,
|
||||
_u8L("Desktop integration failed.") },
|
||||
{NotificationType::UndoDesktopIntegrationSuccess, NotificationLevel::RegularNotification, 10,
|
||||
{NotificationType::UndoDesktopIntegrationSuccess, NotificationLevel::RegularNotificationLevel, 10,
|
||||
_u8L("Undo desktop integration was successful.") },
|
||||
{NotificationType::UndoDesktopIntegrationFail, NotificationLevel::WarningNotification, 10,
|
||||
{NotificationType::UndoDesktopIntegrationFail, NotificationLevel::WarningNotificationLevel, 10,
|
||||
_u8L("Undo desktop integration failed.") },
|
||||
//{NotificationType::NewAppAvailable, NotificationLevel::ImportantNotification, 20, _u8L("New vesion of PrusaSlicer is available.", _u8L("Download page.") },
|
||||
//{NotificationType::LoadingFailed, NotificationLevel::RegularNotification, 20, _u8L("Loading of model has Failed") },
|
||||
//{NotificationType::DeviceEjected, NotificationLevel::RegularNotification, 10, _u8L("Removable device has been safely ejected")} // if we want changeble text (like here name of device), we need to do it as CustomNotification
|
||||
//{NotificationType::NewAppAvailable, NotificationLevel::ImportantNotificationLevel, 20, _u8L("New vesion of PrusaSlicer is available.", _u8L("Download page.") },
|
||||
//{NotificationType::LoadingFailed, NotificationLevel::RegularNotificationLevel, 20, _u8L("Loading of model has Failed") },
|
||||
//{NotificationType::DeviceEjected, NotificationLevel::RegularNotificationLevel, 10, _u8L("Removable device has been safely ejected")} // if we want changeble text (like here name of device), we need to do it as CustomNotification
|
||||
};
|
||||
|
||||
namespace {
|
||||
@ -255,13 +255,13 @@ bool NotificationManager::PopNotification::push_background_color()
|
||||
push_style_color(ImGuiCol_WindowBg, backcolor, m_state == EState::FadingOut, m_current_fade_opacity);
|
||||
return true;
|
||||
}
|
||||
if (m_data.level == NotificationLevel::ErrorNotification) {
|
||||
if (m_data.level == NotificationLevel::ErrorNotificationLevel) {
|
||||
ImVec4 backcolor = ImGui::GetStyleColorVec4(ImGuiCol_WindowBg);
|
||||
backcolor.x += 0.3f;
|
||||
push_style_color(ImGuiCol_WindowBg, backcolor, m_state == EState::FadingOut, m_current_fade_opacity);
|
||||
return true;
|
||||
}
|
||||
if (m_data.level == NotificationLevel::WarningNotification) {
|
||||
if (m_data.level == NotificationLevel::WarningNotificationLevel) {
|
||||
ImVec4 backcolor = ImGui::GetStyleColorVec4(ImGuiCol_WindowBg);
|
||||
backcolor.x += 0.3f;
|
||||
backcolor.y += 0.15f;
|
||||
@ -276,9 +276,9 @@ void NotificationManager::PopNotification::count_spaces()
|
||||
m_line_height = ImGui::CalcTextSize("A").y;
|
||||
|
||||
m_left_indentation = m_line_height;
|
||||
if (m_data.level == NotificationLevel::ErrorNotification || m_data.level == NotificationLevel::WarningNotification) {
|
||||
if (m_data.level == NotificationLevel::ErrorNotificationLevel || m_data.level == NotificationLevel::WarningNotificationLevel) {
|
||||
std::string text;
|
||||
text = (m_data.level == NotificationLevel::ErrorNotification ? ImGui::ErrorMarker : ImGui::WarningMarker);
|
||||
text = (m_data.level == NotificationLevel::ErrorNotificationLevel ? ImGui::ErrorMarker : ImGui::WarningMarker);
|
||||
float picture_width = ImGui::CalcTextSize(text.c_str()).x;
|
||||
m_left_indentation = picture_width + m_line_height / 2;
|
||||
}
|
||||
@ -505,9 +505,9 @@ void NotificationManager::PopNotification::render_close_button(ImGuiWrapper& img
|
||||
|
||||
void NotificationManager::PopNotification::render_left_sign(ImGuiWrapper& imgui)
|
||||
{
|
||||
if (m_data.level == NotificationLevel::ErrorNotification || m_data.level == NotificationLevel::WarningNotification) {
|
||||
if (m_data.level == NotificationLevel::ErrorNotificationLevel || m_data.level == NotificationLevel::WarningNotificationLevel) {
|
||||
std::string text;
|
||||
text = (m_data.level == NotificationLevel::ErrorNotification ? ImGui::ErrorMarker : ImGui::WarningMarker);
|
||||
text = (m_data.level == NotificationLevel::ErrorNotificationLevel ? ImGui::ErrorMarker : ImGui::WarningMarker);
|
||||
ImGui::SetCursorPosX(m_line_height / 3);
|
||||
ImGui::SetCursorPosY(m_window_height / 2 - m_line_height);
|
||||
imgui.text(text.c_str());
|
||||
@ -583,19 +583,23 @@ bool NotificationManager::PopNotification::update_state(bool paused, const int64
|
||||
|
||||
int64_t now = GLCanvas3D::timestamp_now();
|
||||
|
||||
// reset fade opacity for non-closing notifications or hover during fading
|
||||
if (m_state != EState::FadingOut && m_state != EState::ClosePending && m_state != EState::Finished) {
|
||||
m_current_fade_opacity = 1.0f;
|
||||
}
|
||||
|
||||
// reset timers - hovered state is set in render
|
||||
if (m_state == EState::Hovered) {
|
||||
m_current_fade_opacity = 1.0f;
|
||||
m_state = EState::Unknown;
|
||||
init();
|
||||
// Timers when not fading
|
||||
} else if (m_state != EState::NotFading && m_state != EState::FadingOut && m_data.duration != 0 && !paused) {
|
||||
} else if (m_state != EState::NotFading && m_state != EState::FadingOut && get_duration() != 0 && !paused) {
|
||||
int64_t up_time = now - m_notification_start;
|
||||
if (up_time >= m_data.duration * 1000) {
|
||||
if (up_time >= get_duration() * 1000) {
|
||||
m_state = EState::FadingOut;
|
||||
m_fading_start = now;
|
||||
} else {
|
||||
m_next_render = m_data.duration * 1000 - up_time;
|
||||
m_next_render = get_duration() * 1000 - up_time;
|
||||
}
|
||||
}
|
||||
// Timers when fading
|
||||
@ -626,53 +630,6 @@ bool NotificationManager::PopNotification::update_state(bool paused, const int64
|
||||
return false;
|
||||
}
|
||||
|
||||
NotificationManager::SlicingCompleteLargeNotification::SlicingCompleteLargeNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler, bool large) :
|
||||
NotificationManager::PopNotification(n, id_provider, evt_handler)
|
||||
{
|
||||
set_large(large);
|
||||
}
|
||||
void NotificationManager::SlicingCompleteLargeNotification::render_text(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||
{
|
||||
if (!m_is_large)
|
||||
PopNotification::render_text(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||
else {
|
||||
ImVec2 win_size(win_size_x, win_size_y);
|
||||
ImVec2 text1_size = ImGui::CalcTextSize(m_text1.c_str());
|
||||
float x_offset = m_left_indentation;
|
||||
std::string fulltext = m_text1 + m_hypertext + m_text2;
|
||||
ImVec2 text_size = ImGui::CalcTextSize(fulltext.c_str());
|
||||
float cursor_y = win_size.y / 2 - text_size.y / 2;
|
||||
if (m_has_print_info) {
|
||||
x_offset = 20;
|
||||
cursor_y = win_size.y / 2 + win_size.y / 6 - text_size.y / 2;
|
||||
ImGui::SetCursorPosX(x_offset);
|
||||
ImGui::SetCursorPosY(cursor_y);
|
||||
imgui.text(m_print_info.c_str());
|
||||
cursor_y = win_size.y / 2 - win_size.y / 6 - text_size.y / 2;
|
||||
}
|
||||
ImGui::SetCursorPosX(x_offset);
|
||||
ImGui::SetCursorPosY(cursor_y);
|
||||
imgui.text(m_text1.c_str());
|
||||
|
||||
render_hypertext(imgui, x_offset + text1_size.x + 4, cursor_y, m_hypertext);
|
||||
}
|
||||
}
|
||||
void NotificationManager::SlicingCompleteLargeNotification::set_print_info(const std::string &info)
|
||||
{
|
||||
m_print_info = info;
|
||||
m_has_print_info = true;
|
||||
if (m_is_large)
|
||||
m_lines_count = 2;
|
||||
}
|
||||
void NotificationManager::SlicingCompleteLargeNotification::set_large(bool l)
|
||||
{
|
||||
m_is_large = l;
|
||||
//FIXME this information should not be lost (change m_data?)
|
||||
// m_counting_down = !l;
|
||||
m_hypertext = l ? _u8L("Export G-Code.") : std::string();
|
||||
m_state = l ? EState::Shown : EState::Hidden;
|
||||
init();
|
||||
}
|
||||
//---------------ExportFinishedNotification-----------
|
||||
void NotificationManager::ExportFinishedNotification::count_spaces()
|
||||
{
|
||||
@ -680,9 +637,9 @@ void NotificationManager::ExportFinishedNotification::count_spaces()
|
||||
m_line_height = ImGui::CalcTextSize("A").y;
|
||||
|
||||
m_left_indentation = m_line_height;
|
||||
if (m_data.level == NotificationLevel::ErrorNotification || m_data.level == NotificationLevel::WarningNotification) {
|
||||
if (m_data.level == NotificationLevel::ErrorNotificationLevel || m_data.level == NotificationLevel::WarningNotificationLevel) {
|
||||
std::string text;
|
||||
text = (m_data.level == NotificationLevel::ErrorNotification ? ImGui::ErrorMarker : ImGui::WarningMarker);
|
||||
text = (m_data.level == NotificationLevel::ErrorNotificationLevel ? ImGui::ErrorMarker : ImGui::WarningMarker);
|
||||
float picture_width = ImGui::CalcTextSize(text.c_str()).x;
|
||||
m_left_indentation = picture_width + m_line_height / 2;
|
||||
}
|
||||
@ -793,6 +750,9 @@ void NotificationManager::ProgressBarNotification::init()
|
||||
{
|
||||
PopNotification::init();
|
||||
//m_lines_count++;
|
||||
if (m_endlines.empty()) {
|
||||
m_endlines.push_back(0);
|
||||
}
|
||||
if(m_lines_count >= 2) {
|
||||
m_lines_count = 3;
|
||||
m_multiline = true;
|
||||
@ -897,8 +857,17 @@ void NotificationManager::ProgressBarNotification::render_bar(ImGuiWrapper& imgu
|
||||
ImVec2 lineEnd = ImVec2(win_pos_x - m_window_width_offset, win_pos_y + win_size_y / 2 + (m_multiline ? m_line_height / 2 : 0));
|
||||
ImVec2 lineStart = ImVec2(win_pos_x - win_size_x + m_left_indentation, win_pos_y + win_size_y / 2 + (m_multiline ? m_line_height / 2 : 0));
|
||||
ImVec2 midPoint = ImVec2(lineStart.x + (lineEnd.x - lineStart.x) * m_percentage, lineStart.y);
|
||||
ImGui::GetWindowDrawList()->AddLine(lineStart, lineEnd, IM_COL32((int)(gray_color.x * 255), (int)(gray_color.y * 255), (int)(gray_color.z * 255), (1.0f * 255.f)), m_line_height * 0.2f);
|
||||
ImGui::GetWindowDrawList()->AddLine(lineStart, midPoint, IM_COL32((int)(orange_color.x * 255), (int)(orange_color.y * 255), (int)(orange_color.z * 255), (1.0f * 255.f)), m_line_height * 0.2f);
|
||||
ImGui::GetWindowDrawList()->AddLine(lineStart, lineEnd, IM_COL32((int)(gray_color.x * 255), (int)(gray_color.y * 255), (int)(gray_color.z * 255), (m_current_fade_opacity * 255.f)), m_line_height * 0.2f);
|
||||
ImGui::GetWindowDrawList()->AddLine(lineStart, midPoint, IM_COL32((int)(orange_color.x * 255), (int)(orange_color.y * 255), (int)(orange_color.z * 255), (m_current_fade_opacity * 255.f)), m_line_height * 0.2f);
|
||||
if (m_render_percentage) {
|
||||
std::string text;
|
||||
std::stringstream stream;
|
||||
stream << std::fixed << std::setprecision(2) << (int)(m_percentage * 100) << "%";
|
||||
text = stream.str();
|
||||
ImGui::SetCursorPosX(m_left_indentation);
|
||||
ImGui::SetCursorPosY(win_size_y / 2 + win_size_y / 6 - (m_multiline ? 0 : m_line_height / 4));
|
||||
imgui.text(text.c_str());
|
||||
}
|
||||
}
|
||||
//------PrintHostUploadNotification----------------
|
||||
void NotificationManager::PrintHostUploadNotification::init()
|
||||
@ -915,7 +884,7 @@ void NotificationManager::PrintHostUploadNotification::count_spaces()
|
||||
m_left_indentation = m_line_height;
|
||||
if (m_uj_state == UploadJobState::PB_ERROR) {
|
||||
std::string text;
|
||||
text = (m_data.level == NotificationLevel::ErrorNotification ? ImGui::ErrorMarker : ImGui::WarningMarker);
|
||||
text = (m_data.level == NotificationLevel::ErrorNotificationLevel ? ImGui::ErrorMarker : ImGui::WarningMarker);
|
||||
float picture_width = ImGui::CalcTextSize(text.c_str()).x;
|
||||
m_left_indentation = picture_width + m_line_height / 2;
|
||||
}
|
||||
@ -1102,15 +1071,382 @@ void NotificationManager::UpdatedItemsInfoNotification::render_left_sign(ImGuiWr
|
||||
imgui.text(text.c_str());
|
||||
}
|
||||
|
||||
//------SlicingProgressNotificastion
|
||||
void NotificationManager::SlicingProgressNotification::init()
|
||||
{
|
||||
if (m_sp_state == SlicingProgressState::SP_PROGRESS) {
|
||||
ProgressBarNotification::init();
|
||||
//if (m_state == EState::NotFading && m_percentage >= 1.0f)
|
||||
// m_state = EState::Shown;
|
||||
}
|
||||
else {
|
||||
PopNotification::init();
|
||||
}
|
||||
|
||||
}
|
||||
void NotificationManager::SlicingProgressNotification::set_progress_state(float percent)
|
||||
{
|
||||
if (percent < 0.f)
|
||||
set_progress_state(SlicingProgressState::SP_CANCELLED);
|
||||
else if (percent >= 1.f)
|
||||
set_progress_state(SlicingProgressState::SP_COMPLETED);
|
||||
else
|
||||
set_progress_state(SlicingProgressState::SP_PROGRESS, percent);
|
||||
}
|
||||
void NotificationManager::SlicingProgressNotification::set_progress_state(NotificationManager::SlicingProgressNotification::SlicingProgressState state, float percent/* = 0.f*/)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_NO_SLICING:
|
||||
m_state = EState::Hidden;
|
||||
set_percentage(-1);
|
||||
m_has_print_info = false;
|
||||
set_export_possible(false);
|
||||
break;
|
||||
case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_PROGRESS:
|
||||
set_percentage(percent);
|
||||
m_has_cancel_button = true;
|
||||
break;
|
||||
case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_CANCELLED:
|
||||
set_percentage(-1);
|
||||
m_has_cancel_button = false;
|
||||
m_has_print_info = false;
|
||||
set_export_possible(false);
|
||||
break;
|
||||
case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_COMPLETED:
|
||||
set_percentage(1);
|
||||
m_has_cancel_button = false;
|
||||
m_has_print_info = false;
|
||||
// m_export_possible is important only for PROGRESS state, thus we can reset it here
|
||||
set_export_possible(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_sp_state = state;
|
||||
}
|
||||
void NotificationManager::SlicingProgressNotification::set_status_text(const std::string& text)
|
||||
{
|
||||
switch (m_sp_state)
|
||||
{
|
||||
case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_NO_SLICING:
|
||||
m_state = EState::Hidden;
|
||||
break;
|
||||
case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_PROGRESS:
|
||||
{
|
||||
NotificationData data{ NotificationType::SlicingProgress, NotificationLevel::ProgressBarNotificationLevel, 0, text + ".", m_is_fff ? _u8L("Export G-Code.") : _u8L("Export.") };
|
||||
update(data);
|
||||
m_state = EState::NotFading;
|
||||
}
|
||||
break;
|
||||
case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_CANCELLED:
|
||||
{
|
||||
NotificationData data{ NotificationType::SlicingProgress, NotificationLevel::ProgressBarNotificationLevel, 0, text };
|
||||
update(data);
|
||||
m_state = EState::Shown;
|
||||
}
|
||||
break;
|
||||
case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_COMPLETED:
|
||||
{
|
||||
NotificationData data{ NotificationType::SlicingProgress, NotificationLevel::ProgressBarNotificationLevel, 0, _u8L("Slicing finished."), m_is_fff ? _u8L("Export G-Code.") : _u8L("Export.") };
|
||||
update(data);
|
||||
m_state = EState::Shown;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
void NotificationManager::SlicingProgressNotification::set_print_info(const std::string& info)
|
||||
{
|
||||
if (m_sp_state != SlicingProgressState::SP_COMPLETED) {
|
||||
set_progress_state (SlicingProgressState::SP_COMPLETED);
|
||||
} else {
|
||||
m_has_print_info = true;
|
||||
m_print_info = info;
|
||||
}
|
||||
}
|
||||
void NotificationManager::SlicingProgressNotification::set_sidebar_collapsed(bool collapsed)
|
||||
{
|
||||
m_sidebar_collapsed = collapsed;
|
||||
if (m_sp_state == SlicingProgressState::SP_COMPLETED)
|
||||
m_state = EState::Shown;
|
||||
}
|
||||
|
||||
void NotificationManager::SlicingProgressNotification::on_cancel_button()
|
||||
{
|
||||
if (m_cancel_callback){
|
||||
m_cancel_callback();
|
||||
}
|
||||
}
|
||||
int NotificationManager::SlicingProgressNotification::get_duration()
|
||||
{
|
||||
if (m_sp_state == SlicingProgressState::SP_CANCELLED)
|
||||
return 10;
|
||||
else if (m_sp_state == SlicingProgressState::SP_COMPLETED && !m_sidebar_collapsed)
|
||||
return 5;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
bool NotificationManager::SlicingProgressNotification::update_state(bool paused, const int64_t delta)
|
||||
{
|
||||
bool ret = ProgressBarNotification::update_state(paused, delta);
|
||||
// sets Estate to hidden
|
||||
if (get_state() == PopNotification::EState::ClosePending || get_state() == PopNotification::EState::Finished)
|
||||
set_progress_state(SlicingProgressState::SP_NO_SLICING);
|
||||
return ret;
|
||||
}
|
||||
void NotificationManager::SlicingProgressNotification::render_text(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||
{
|
||||
if (m_sp_state == SlicingProgressState::SP_PROGRESS || (m_sp_state == SlicingProgressState::SP_COMPLETED && !m_sidebar_collapsed)) {
|
||||
ProgressBarNotification::render_text(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||
/* // enable for hypertext during slicing (correct call of export_enabled needed)
|
||||
if (m_multiline) {
|
||||
// two lines text, one line bar
|
||||
ImGui::SetCursorPosX(m_left_indentation);
|
||||
ImGui::SetCursorPosY(m_line_height / 4);
|
||||
imgui.text(m_text1.substr(0, m_endlines[0]).c_str());
|
||||
ImGui::SetCursorPosX(m_left_indentation);
|
||||
ImGui::SetCursorPosY(m_line_height + m_line_height / 4);
|
||||
std::string line = m_text1.substr(m_endlines[0] + (m_text1[m_endlines[0]] == '\n' || m_text1[m_endlines[0]] == ' ' ? 1 : 0), m_endlines[1] - m_endlines[0] - (m_text1[m_endlines[0]] == '\n' || m_text1[m_endlines[0]] == ' ' ? 1 : 0));
|
||||
imgui.text(line.c_str());
|
||||
if (m_sidebar_collapsed && m_sp_state == SlicingProgressState::SP_PROGRESS && m_export_possible) {
|
||||
ImVec2 text_size = ImGui::CalcTextSize(line.c_str());
|
||||
render_hypertext(imgui, m_left_indentation + text_size.x + 4, m_line_height + m_line_height / 4, m_hypertext);
|
||||
}
|
||||
if (m_has_cancel_button)
|
||||
render_cancel_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||
render_bar(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||
}
|
||||
else {
|
||||
//one line text, one line bar
|
||||
ImGui::SetCursorPosX(m_left_indentation);
|
||||
ImGui::SetCursorPosY(m_line_height / 4);
|
||||
std::string line = m_text1.substr(0, m_endlines[0]);
|
||||
imgui.text(line.c_str());
|
||||
if (m_sidebar_collapsed && m_sp_state == SlicingProgressState::SP_PROGRESS && m_export_possible) {
|
||||
ImVec2 text_size = ImGui::CalcTextSize(line.c_str());
|
||||
render_hypertext(imgui, m_left_indentation + text_size.x + 4, m_line_height / 4, m_hypertext);
|
||||
}
|
||||
if (m_has_cancel_button)
|
||||
render_cancel_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||
render_bar(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||
}
|
||||
*/
|
||||
} else if (m_sp_state == SlicingProgressState::SP_COMPLETED) {
|
||||
// "Slicing Finished" on line 1 + hypertext, print info on line
|
||||
ImVec2 win_size(win_size_x, win_size_y);
|
||||
ImVec2 text1_size = ImGui::CalcTextSize(m_text1.c_str());
|
||||
float x_offset = m_left_indentation;
|
||||
std::string fulltext = m_text1 + m_hypertext + m_text2;
|
||||
ImVec2 text_size = ImGui::CalcTextSize(fulltext.c_str());
|
||||
float cursor_y = win_size.y / 2 - text_size.y / 2;
|
||||
if (m_sidebar_collapsed && m_has_print_info) {
|
||||
x_offset = 20;
|
||||
cursor_y = win_size.y / 2 + win_size.y / 6 - text_size.y / 2;
|
||||
ImGui::SetCursorPosX(x_offset);
|
||||
ImGui::SetCursorPosY(cursor_y);
|
||||
imgui.text(m_print_info.c_str());
|
||||
cursor_y = win_size.y / 2 - win_size.y / 6 - text_size.y / 2;
|
||||
}
|
||||
ImGui::SetCursorPosX(x_offset);
|
||||
ImGui::SetCursorPosY(cursor_y);
|
||||
imgui.text(m_text1.c_str());
|
||||
if (m_sidebar_collapsed)
|
||||
render_hypertext(imgui, x_offset + text1_size.x + 4, cursor_y, m_hypertext);
|
||||
} else {
|
||||
PopNotification::render_text(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||
}
|
||||
}
|
||||
void NotificationManager::SlicingProgressNotification::render_bar(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||
{
|
||||
if (!(m_sp_state == SlicingProgressState::SP_PROGRESS || (m_sp_state == SlicingProgressState::SP_COMPLETED && !m_sidebar_collapsed))) {
|
||||
return;
|
||||
}
|
||||
//std::string text;
|
||||
ProgressBarNotification::render_bar(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||
/*
|
||||
std::stringstream stream;
|
||||
stream << std::fixed << std::setprecision(2) << (int)(m_percentage * 100) << "%";
|
||||
text = stream.str();
|
||||
ImGui::SetCursorPosX(m_left_indentation);
|
||||
ImGui::SetCursorPosY(win_size_y / 2 + win_size_y / 6 - (m_multiline ? 0 : m_line_height / 4));
|
||||
imgui.text(text.c_str());
|
||||
*/
|
||||
}
|
||||
void NotificationManager::SlicingProgressNotification::render_cancel_button(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||
{
|
||||
ImVec2 win_size(win_size_x, win_size_y);
|
||||
ImVec2 win_pos(win_pos_x, win_pos_y);
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(.0f, .0f, .0f, .0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(.0f, .0f, .0f, .0f));
|
||||
push_style_color(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 1.f), m_state == EState::FadingOut, m_current_fade_opacity);
|
||||
push_style_color(ImGuiCol_TextSelectedBg, ImVec4(0, .75f, .75f, 1.f), m_state == EState::FadingOut, m_current_fade_opacity);
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(.0f, .0f, .0f, .0f));
|
||||
|
||||
|
||||
std::string button_text;
|
||||
button_text = ImGui::CancelButton;
|
||||
|
||||
if (ImGui::IsMouseHoveringRect(ImVec2(win_pos.x - win_size.x / 10.f, win_pos.y),
|
||||
ImVec2(win_pos.x, win_pos.y + win_size.y - (m_minimize_b_visible ? 2 * m_line_height : 0)),
|
||||
true))
|
||||
{
|
||||
button_text = ImGui::CancelHoverButton;
|
||||
}
|
||||
ImVec2 button_pic_size = ImGui::CalcTextSize(button_text.c_str());
|
||||
ImVec2 button_size(button_pic_size.x * 1.25f, button_pic_size.y * 1.25f);
|
||||
ImGui::SetCursorPosX(win_size.x - m_line_height * 2.75f);
|
||||
ImGui::SetCursorPosY(win_size.y / 2 - button_size.y);
|
||||
if (imgui.button(button_text.c_str(), button_size.x, button_size.y))
|
||||
{
|
||||
on_cancel_button();
|
||||
}
|
||||
|
||||
//invisible large button
|
||||
ImGui::SetCursorPosX(win_size.x - m_line_height * 2.35f);
|
||||
ImGui::SetCursorPosY(0);
|
||||
if (imgui.button(" ", m_line_height * 2.125, win_size.y - (m_minimize_b_visible ? 2 * m_line_height : 0)))
|
||||
{
|
||||
on_cancel_button();
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
void NotificationManager::SlicingProgressNotification::render_close_button(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||
{
|
||||
// Do not render close button while showing progress - cancel button is rendered instead
|
||||
if (m_sp_state != SlicingProgressState::SP_PROGRESS) {
|
||||
ProgressBarNotification::render_close_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||
}
|
||||
}
|
||||
//------ProgressIndicatorNotification-------
|
||||
void NotificationManager::ProgressIndicatorNotification::set_status_text(const char* text)
|
||||
{
|
||||
NotificationData data{ NotificationType::ProgressIndicator, NotificationLevel::ProgressBarNotificationLevel, 0, text };
|
||||
update(data);
|
||||
}
|
||||
|
||||
void NotificationManager::ProgressIndicatorNotification::init()
|
||||
{
|
||||
// skip ProgressBarNotification::init (same code here)
|
||||
PopNotification::init();
|
||||
if (m_endlines.empty()) {
|
||||
m_endlines.push_back(0);
|
||||
}
|
||||
if (m_lines_count >= 2) {
|
||||
m_lines_count = 3;
|
||||
m_multiline = true;
|
||||
while (m_endlines.size() < 3)
|
||||
m_endlines.push_back(m_endlines.back());
|
||||
}
|
||||
else {
|
||||
m_lines_count = 2;
|
||||
m_endlines.push_back(m_endlines.back());
|
||||
}
|
||||
switch (m_progress_state)
|
||||
{
|
||||
case Slic3r::GUI::NotificationManager::ProgressIndicatorNotification::ProgressIndicatorState::PIS_HIDDEN:
|
||||
m_state = EState::Hidden;
|
||||
break;
|
||||
case Slic3r::GUI::NotificationManager::ProgressIndicatorNotification::ProgressIndicatorState::PIS_PROGRESS_REQUEST:
|
||||
case Slic3r::GUI::NotificationManager::ProgressIndicatorNotification::ProgressIndicatorState::PIS_PROGRESS_UPDATED:
|
||||
m_state = EState::NotFading;
|
||||
break;
|
||||
case Slic3r::GUI::NotificationManager::ProgressIndicatorNotification::ProgressIndicatorState::PIS_COMPLETED:
|
||||
m_state = EState::Shown;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
void NotificationManager::ProgressIndicatorNotification::set_percentage(float percent)
|
||||
{
|
||||
ProgressBarNotification::set_percentage(percent);
|
||||
if (percent >= 0.0f && percent < 1.0f) {
|
||||
m_state = EState::NotFading;
|
||||
m_has_cancel_button = true;
|
||||
m_progress_state = ProgressIndicatorState::PIS_PROGRESS_REQUEST;
|
||||
} else if (percent >= 1.0f) {
|
||||
m_state = EState::Shown;
|
||||
m_progress_state = ProgressIndicatorState::PIS_COMPLETED;
|
||||
m_has_cancel_button = false;
|
||||
} else {
|
||||
m_progress_state = ProgressIndicatorState::PIS_HIDDEN;
|
||||
m_state = EState::Hidden;
|
||||
}
|
||||
}
|
||||
bool NotificationManager::ProgressIndicatorNotification::update_state(bool paused, const int64_t delta)
|
||||
{
|
||||
if (m_progress_state == ProgressIndicatorState::PIS_PROGRESS_REQUEST) {
|
||||
// percentage was changed (and it called schedule_extra_frame), now update must know this needs render
|
||||
m_next_render = 0;
|
||||
m_progress_state = ProgressIndicatorState::PIS_PROGRESS_UPDATED;
|
||||
return true;
|
||||
}
|
||||
bool ret = ProgressBarNotification::update_state(paused, delta);
|
||||
if (get_state() == PopNotification::EState::ClosePending || get_state() == PopNotification::EState::Finished)
|
||||
// go to PIS_HIDDEN state
|
||||
set_percentage(-1.0f);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NotificationManager::ProgressIndicatorNotification::render_cancel_button(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||
{
|
||||
ImVec2 win_size(win_size_x, win_size_y);
|
||||
ImVec2 win_pos(win_pos_x, win_pos_y);
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(.0f, .0f, .0f, .0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(.0f, .0f, .0f, .0f));
|
||||
push_style_color(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 1.f), m_state == EState::FadingOut, m_current_fade_opacity);
|
||||
push_style_color(ImGuiCol_TextSelectedBg, ImVec4(0, .75f, .75f, 1.f), m_state == EState::FadingOut, m_current_fade_opacity);
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(.0f, .0f, .0f, .0f));
|
||||
|
||||
|
||||
std::string button_text;
|
||||
button_text = ImGui::CancelButton;
|
||||
|
||||
if (ImGui::IsMouseHoveringRect(ImVec2(win_pos.x - win_size.x / 10.f, win_pos.y),
|
||||
ImVec2(win_pos.x, win_pos.y + win_size.y - (m_minimize_b_visible ? 2 * m_line_height : 0)),
|
||||
true))
|
||||
{
|
||||
button_text = ImGui::CancelHoverButton;
|
||||
}
|
||||
ImVec2 button_pic_size = ImGui::CalcTextSize(button_text.c_str());
|
||||
ImVec2 button_size(button_pic_size.x * 1.25f, button_pic_size.y * 1.25f);
|
||||
ImGui::SetCursorPosX(win_size.x - m_line_height * 2.75f);
|
||||
ImGui::SetCursorPosY(win_size.y / 2 - button_size.y);
|
||||
if (imgui.button(button_text.c_str(), button_size.x, button_size.y))
|
||||
{
|
||||
on_cancel_button();
|
||||
}
|
||||
|
||||
//invisible large button
|
||||
ImGui::SetCursorPosX(win_size.x - m_line_height * 2.35f);
|
||||
ImGui::SetCursorPosY(0);
|
||||
if (imgui.button(" ", m_line_height * 2.125, win_size.y - (m_minimize_b_visible ? 2 * m_line_height : 0)))
|
||||
{
|
||||
on_cancel_button();
|
||||
}
|
||||
ImGui::PopStyleColor(5);
|
||||
}
|
||||
void NotificationManager::ProgressIndicatorNotification::render_close_button(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||
{
|
||||
// Do not render close button while showing progress - cancel button is rendered instead
|
||||
if (m_percentage >= 1.0f)
|
||||
{
|
||||
ProgressBarNotification::render_close_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||
}
|
||||
}
|
||||
//------NotificationManager--------
|
||||
NotificationManager::NotificationManager(wxEvtHandler* evt_handler) :
|
||||
m_evt_handler(evt_handler)
|
||||
{
|
||||
}
|
||||
NotificationManager::~NotificationManager()
|
||||
{
|
||||
HintDatabase::get_instance().uninit();
|
||||
}
|
||||
|
||||
void NotificationManager::push_notification(const NotificationType type, int timestamp)
|
||||
{
|
||||
auto it = std::find_if(std::begin(basic_notifications), std::end(basic_notifications),
|
||||
@ -1121,7 +1457,7 @@ void NotificationManager::push_notification(const NotificationType type, int tim
|
||||
}
|
||||
void NotificationManager::push_notification(const std::string& text, int timestamp)
|
||||
{
|
||||
push_notification_data({ NotificationType::CustomNotification, NotificationLevel::RegularNotification, 10, text }, timestamp);
|
||||
push_notification_data({ NotificationType::CustomNotification, NotificationLevel::RegularNotificationLevel, 10, text }, timestamp);
|
||||
}
|
||||
|
||||
void NotificationManager::push_notification(NotificationType type,
|
||||
@ -1133,11 +1469,11 @@ void NotificationManager::push_notification(NotificationType type,
|
||||
{
|
||||
int duration = 0;
|
||||
switch (level) {
|
||||
case NotificationLevel::RegularNotification: duration = 10; break;
|
||||
case NotificationLevel::ErrorNotification: break;
|
||||
case NotificationLevel::WarningNotification: break;
|
||||
case NotificationLevel::ImportantNotification: break;
|
||||
case NotificationLevel::ProgressBarNotification: break;
|
||||
case NotificationLevel::RegularNotificationLevel: duration = 10; break;
|
||||
case NotificationLevel::ErrorNotificationLevel: break;
|
||||
case NotificationLevel::WarningNotificationLevel: break;
|
||||
case NotificationLevel::ImportantNotificationLevel: break;
|
||||
case NotificationLevel::ProgressBarNotificationLevel: break;
|
||||
default:
|
||||
assert(false);
|
||||
return;
|
||||
@ -1146,18 +1482,19 @@ void NotificationManager::push_notification(NotificationType type,
|
||||
}
|
||||
void NotificationManager::push_validate_error_notification(const std::string& text)
|
||||
{
|
||||
push_notification_data({ NotificationType::ValidateError, NotificationLevel::ErrorNotification, 0, _u8L("ERROR:") + "\n" + text }, 0);
|
||||
push_notification_data({ NotificationType::ValidateError, NotificationLevel::ErrorNotificationLevel, 0, _u8L("ERROR:") + "\n" + text }, 0);
|
||||
set_slicing_progress_hidden();
|
||||
}
|
||||
|
||||
void NotificationManager::push_slicing_error_notification(const std::string& text)
|
||||
{
|
||||
set_all_slicing_errors_gray(false);
|
||||
push_notification_data({ NotificationType::SlicingError, NotificationLevel::ErrorNotification, 0, _u8L("ERROR:") + "\n" + text }, 0);
|
||||
close_notification_of_type(NotificationType::SlicingComplete);
|
||||
push_notification_data({ NotificationType::SlicingError, NotificationLevel::ErrorNotificationLevel, 0, _u8L("ERROR:") + "\n" + text }, 0);
|
||||
set_slicing_progress_hidden();
|
||||
}
|
||||
void NotificationManager::push_slicing_warning_notification(const std::string& text, bool gray, ObjectID oid, int warning_step)
|
||||
{
|
||||
NotificationData data { NotificationType::SlicingWarning, NotificationLevel::WarningNotification, 0, _u8L("WARNING:") + "\n" + text };
|
||||
NotificationData data { NotificationType::SlicingWarning, NotificationLevel::WarningNotificationLevel, 0, _u8L("WARNING:") + "\n" + text };
|
||||
|
||||
auto notification = std::make_unique<NotificationManager::SlicingWarningNotification>(data, m_id_provider, m_evt_handler);
|
||||
notification->object_id = oid;
|
||||
@ -1168,7 +1505,7 @@ void NotificationManager::push_slicing_warning_notification(const std::string& t
|
||||
}
|
||||
void NotificationManager::push_plater_error_notification(const std::string& text)
|
||||
{
|
||||
push_notification_data({ NotificationType::PlaterError, NotificationLevel::ErrorNotification, 0, _u8L("ERROR:") + "\n" + text }, 0);
|
||||
push_notification_data({ NotificationType::PlaterError, NotificationLevel::ErrorNotificationLevel, 0, _u8L("ERROR:") + "\n" + text }, 0);
|
||||
}
|
||||
|
||||
void NotificationManager::close_plater_error_notification(const std::string& text)
|
||||
@ -1192,7 +1529,7 @@ void NotificationManager::push_plater_warning_notification(const std::string& te
|
||||
}
|
||||
}
|
||||
|
||||
NotificationData data{ NotificationType::PlaterWarning, NotificationLevel::WarningNotification, 0, _u8L("WARNING:") + "\n" + text };
|
||||
NotificationData data{ NotificationType::PlaterWarning, NotificationLevel::WarningNotificationLevel, 0, _u8L("WARNING:") + "\n" + text };
|
||||
|
||||
auto notification = std::make_unique<NotificationManager::PlaterWarningNotification>(data, m_id_provider, m_evt_handler);
|
||||
push_notification_data(std::move(notification), 0);
|
||||
@ -1252,49 +1589,12 @@ void NotificationManager::close_slicing_error_notification(const std::string& te
|
||||
}
|
||||
void NotificationManager::push_object_warning_notification(const std::string& text, ObjectID object_id, const std::string& hypertext/* = ""*/, std::function<bool(wxEvtHandler*)> callback/* = std::function<bool(wxEvtHandler*)>()*/)
|
||||
{
|
||||
NotificationData data{ NotificationType::ObjectWarning, NotificationLevel::WarningNotification, 0, text, hypertext, callback };
|
||||
NotificationData data{ NotificationType::ObjectWarning, NotificationLevel::WarningNotificationLevel, 0, text, hypertext, callback };
|
||||
auto notification = std::make_unique<NotificationManager::SlicingWarningNotification>(data, m_id_provider, m_evt_handler);
|
||||
notification->object_id = object_id;
|
||||
notification->warning_step = 0;
|
||||
push_notification_data(std::move(notification), 0);
|
||||
}
|
||||
void NotificationManager::push_slicing_complete_notification(int timestamp, bool large)
|
||||
{
|
||||
std::string hypertext;
|
||||
int time = 10;
|
||||
if (has_slicing_error_notification())
|
||||
return;
|
||||
if (large) {
|
||||
hypertext = _u8L("Export G-Code.");
|
||||
time = 0;
|
||||
}
|
||||
NotificationData data{ NotificationType::SlicingComplete, NotificationLevel::RegularNotification, time, _u8L("Slicing finished."), hypertext,
|
||||
[](wxEvtHandler* evnthndlr){
|
||||
if (evnthndlr != nullptr)
|
||||
wxPostEvent(evnthndlr, ExportGcodeNotificationClickedEvent(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
push_notification_data(std::make_unique<NotificationManager::SlicingCompleteLargeNotification>(data, m_id_provider, m_evt_handler, large), timestamp);
|
||||
}
|
||||
void NotificationManager::set_slicing_complete_print_time(const std::string &info)
|
||||
{
|
||||
for (std::unique_ptr<PopNotification> ¬ification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::SlicingComplete) {
|
||||
dynamic_cast<SlicingCompleteLargeNotification*>(notification.get())->set_print_info(info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void NotificationManager::set_slicing_complete_large(bool large)
|
||||
{
|
||||
for (std::unique_ptr<PopNotification> ¬ification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::SlicingComplete) {
|
||||
dynamic_cast<SlicingCompleteLargeNotification*>(notification.get())->set_large(large);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void NotificationManager::close_notification_of_type(const NotificationType type)
|
||||
{
|
||||
for (std::unique_ptr<PopNotification> ¬ification : m_pop_notifications) {
|
||||
@ -1324,7 +1624,7 @@ void NotificationManager::remove_object_warnings_of_released_objects(const std::
|
||||
void NotificationManager::push_exporting_finished_notification(const std::string& path, const std::string& dir_path, bool on_removable)
|
||||
{
|
||||
close_notification_of_type(NotificationType::ExportFinished);
|
||||
NotificationData data{ NotificationType::ExportFinished, NotificationLevel::RegularNotification, on_removable ? 0 : 20, _u8L("Exporting finished.") + "\n" + path };
|
||||
NotificationData data{ NotificationType::ExportFinished, NotificationLevel::RegularNotificationLevel, on_removable ? 0 : 20, _u8L("Exporting finished.") + "\n" + path };
|
||||
push_notification_data(std::make_unique<NotificationManager::ExportFinishedNotification>(data, m_id_provider, m_evt_handler, on_removable, path, dir_path), 0);
|
||||
}
|
||||
|
||||
@ -1338,7 +1638,7 @@ void NotificationManager::push_upload_job_notification(int id, float filesize,
|
||||
}
|
||||
}
|
||||
std::string text = PrintHostUploadNotification::get_upload_job_text(id, filename, host);
|
||||
NotificationData data{ NotificationType::PrintHostUpload, NotificationLevel::ProgressBarNotification, 10, text };
|
||||
NotificationData data{ NotificationType::PrintHostUpload, NotificationLevel::ProgressBarNotificationLevel, 10, text };
|
||||
push_notification_data(std::make_unique<NotificationManager::PrintHostUploadNotification>(data, m_id_provider, m_evt_handler, 0, id, filesize), 0);
|
||||
}
|
||||
void NotificationManager::set_upload_job_notification_percentage(int id, const std::string& filename, const std::string& host, float percentage)
|
||||
@ -1380,6 +1680,153 @@ void NotificationManager::upload_job_notification_show_error(int id, const std::
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NotificationManager::init_slicing_progress_notification(std::function<void()> cancel_callback)
|
||||
{
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::SlicingProgress) {
|
||||
dynamic_cast<SlicingProgressNotification*>(notification.get())->set_cancel_callback(cancel_callback);
|
||||
return;
|
||||
}
|
||||
}
|
||||
NotificationData data{ NotificationType::SlicingProgress, NotificationLevel::ProgressBarNotificationLevel, 0, std::string(),std::string(),
|
||||
[](wxEvtHandler* evnthndlr) {
|
||||
if (evnthndlr != nullptr)
|
||||
wxPostEvent(evnthndlr, ExportGcodeNotificationClickedEvent(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
push_notification_data(std::make_unique<NotificationManager::SlicingProgressNotification>(data, m_id_provider, m_evt_handler, cancel_callback), 0);
|
||||
}
|
||||
void NotificationManager::set_slicing_progress_percentage(const std::string& text, float percentage)
|
||||
{
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::SlicingProgress) {
|
||||
SlicingProgressNotification* spn = dynamic_cast<SlicingProgressNotification*>(notification.get());
|
||||
spn->set_progress_state(percentage);
|
||||
spn->set_status_text(text);
|
||||
wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Slicing progress notification was not found - init it thru plater so correct cancel callback function is appended
|
||||
wxGetApp().plater()->init_notification_manager();
|
||||
}
|
||||
|
||||
void NotificationManager::set_slicing_progress_hidden()
|
||||
{
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::SlicingProgress) {
|
||||
SlicingProgressNotification* notif = dynamic_cast<SlicingProgressNotification*>(notification.get());
|
||||
notif->set_progress_state(SlicingProgressNotification::SlicingProgressState::SP_NO_SLICING);
|
||||
wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Slicing progress notification was not found - init it thru plater so correct cancel callback function is appended
|
||||
wxGetApp().plater()->init_notification_manager();
|
||||
}
|
||||
void NotificationManager::set_slicing_complete_print_time(const std::string& info, bool sidebar_colapsed)
|
||||
{
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::SlicingProgress) {
|
||||
dynamic_cast<SlicingProgressNotification*>(notification.get())->set_sidebar_collapsed(sidebar_colapsed);
|
||||
dynamic_cast<SlicingProgressNotification*>(notification.get())->set_print_info(info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void NotificationManager::set_sidebar_collapsed(bool collapsed)
|
||||
{
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::SlicingProgress) {
|
||||
dynamic_cast<SlicingProgressNotification*>(notification.get())->set_sidebar_collapsed(collapsed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void NotificationManager::set_fff(bool fff)
|
||||
{
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::SlicingProgress) {
|
||||
dynamic_cast<SlicingProgressNotification*>(notification.get())->set_fff(fff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void NotificationManager::set_slicing_progress_export_possible()
|
||||
{
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::SlicingProgress) {
|
||||
dynamic_cast<SlicingProgressNotification*>(notification.get())->set_export_possible(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void NotificationManager::init_progress_indicator()
|
||||
{
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::ProgressIndicator) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
NotificationData data{ NotificationType::ProgressIndicator, NotificationLevel::ProgressBarNotificationLevel, 2};
|
||||
auto notification = std::make_unique<NotificationManager::ProgressIndicatorNotification>(data, m_id_provider, m_evt_handler);
|
||||
push_notification_data(std::move(notification), 0);
|
||||
}
|
||||
|
||||
void NotificationManager::progress_indicator_set_range(int range)
|
||||
{
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::ProgressIndicator) {
|
||||
dynamic_cast<ProgressIndicatorNotification*>(notification.get())->set_range(range);
|
||||
return;
|
||||
}
|
||||
}
|
||||
init_progress_indicator();
|
||||
}
|
||||
void NotificationManager::progress_indicator_set_cancel_callback(CancelFn callback/* = CancelFn()*/)
|
||||
{
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::ProgressIndicator) {
|
||||
dynamic_cast<ProgressIndicatorNotification*>(notification.get())->set_cancel_callback(callback);
|
||||
return;
|
||||
}
|
||||
}
|
||||
init_progress_indicator();
|
||||
}
|
||||
void NotificationManager::progress_indicator_set_progress(int pr)
|
||||
{
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::ProgressIndicator) {
|
||||
dynamic_cast<ProgressIndicatorNotification*>(notification.get())->set_progress(pr);
|
||||
// Ask for rendering - needs to be done on every progress. Calls to here doesnt trigger IDLE event or rendering.
|
||||
wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(100);
|
||||
return;
|
||||
}
|
||||
}
|
||||
init_progress_indicator();
|
||||
}
|
||||
void NotificationManager::progress_indicator_set_status_text(const char* text)
|
||||
{
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::ProgressIndicator) {
|
||||
dynamic_cast<ProgressIndicatorNotification*>(notification.get())->set_status_text(text);
|
||||
return;
|
||||
}
|
||||
}
|
||||
init_progress_indicator();
|
||||
}
|
||||
int NotificationManager::progress_indicator_get_range() const
|
||||
{
|
||||
for (const std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::ProgressIndicator) {
|
||||
return dynamic_cast<ProgressIndicatorNotification*>(notification.get())->get_range();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NotificationManager::push_hint_notification(bool open_next)
|
||||
{
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
@ -1389,7 +1836,7 @@ void NotificationManager::push_hint_notification(bool open_next)
|
||||
}
|
||||
}
|
||||
|
||||
NotificationData data{ NotificationType::DidYouKnowHint, NotificationLevel::RegularNotification, 300, "" };
|
||||
NotificationData data{ NotificationType::DidYouKnowHint, NotificationLevel::HintNotificationLevel, 300, "" };
|
||||
// from user - open now
|
||||
if (!open_next) {
|
||||
push_notification_data(std::make_unique<NotificationManager::HintNotification>(data, m_id_provider, m_evt_handler, open_next), 0);
|
||||
@ -1397,8 +1844,8 @@ void NotificationManager::push_hint_notification(bool open_next)
|
||||
// at startup - delay for half a second to let other notification pop up, than try every 30 seconds
|
||||
// show only if no notifications are shown
|
||||
} else {
|
||||
auto condition = [this]() {
|
||||
return this->get_notification_count() == 0;
|
||||
auto condition = [&self = std::as_const(*this)]() {
|
||||
return self.get_notification_count() == 0;
|
||||
};
|
||||
push_delayed_notification(std::make_unique<NotificationManager::HintNotification>(data, m_id_provider, m_evt_handler, open_next), condition, 500, 30000);
|
||||
}
|
||||
@ -1412,7 +1859,10 @@ bool NotificationManager::is_hint_notification_open()
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void NotificationManager::deactivate_loaded_hints()
|
||||
{
|
||||
HintDatabase::get_instance().uninit();
|
||||
}
|
||||
void NotificationManager::push_updated_item_info_notification(InfoItemType type)
|
||||
{
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
@ -1422,7 +1872,7 @@ void NotificationManager::push_updated_item_info_notification(InfoItemType type)
|
||||
}
|
||||
}
|
||||
|
||||
NotificationData data{ NotificationType::UpdatedItemsInfo, NotificationLevel::RegularNotification, 5, "" };
|
||||
NotificationData data{ NotificationType::UpdatedItemsInfo, NotificationLevel::RegularNotificationLevel, 5, "" };
|
||||
auto notification = std::make_unique<NotificationManager::UpdatedItemsInfoNotification>(data, m_id_provider, m_evt_handler, type);
|
||||
if (push_notification_data(std::move(notification), 0)) {
|
||||
(dynamic_cast<UpdatedItemsInfoNotification*>(m_pop_notifications.back().get()))->add_type(type);
|
||||
@ -1444,17 +1894,20 @@ bool NotificationManager::push_notification_data(std::unique_ptr<NotificationMan
|
||||
}
|
||||
}
|
||||
|
||||
GLCanvas3D& canvas = *wxGetApp().plater()->get_current_canvas3D();
|
||||
|
||||
bool retval = false;
|
||||
if (this->activate_existing(notification.get())) {
|
||||
m_pop_notifications.back()->update(notification->get_data());
|
||||
canvas.schedule_extra_frame(0);
|
||||
return false;
|
||||
if (m_initialized) { // ignore update action - it cant be initialized if canvas and imgui context is not ready
|
||||
m_pop_notifications.back()->update(notification->get_data());
|
||||
}
|
||||
} else {
|
||||
m_pop_notifications.emplace_back(std::move(notification));
|
||||
canvas.schedule_extra_frame(0);
|
||||
return true;
|
||||
retval = true;
|
||||
}
|
||||
if (!m_initialized)
|
||||
return retval;
|
||||
GLCanvas3D& canvas = *wxGetApp().plater()->get_current_canvas3D();
|
||||
canvas.schedule_extra_frame(0);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void NotificationManager::push_delayed_notification(std::unique_ptr<NotificationManager::PopNotification> notification, std::function<bool(void)> condition_callback, int64_t initial_delay, int64_t delay_interval)
|
||||
@ -1608,6 +2061,8 @@ void NotificationManager::set_in_preview(bool preview)
|
||||
notification->hide(preview);
|
||||
if (notification->get_type() == NotificationType::SignDetected)
|
||||
notification->hide(!preview);
|
||||
if (m_in_preview && notification->get_type() == NotificationType::DidYouKnowHint)
|
||||
notification->close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "GLCanvas3D.hpp"
|
||||
#include "Event.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "Jobs/ProgressIndicator.hpp"
|
||||
|
||||
#include <libslic3r/ObjectID.hpp>
|
||||
#include <libslic3r/Technologies.hpp>
|
||||
@ -27,6 +28,8 @@ wxDECLARE_EVENT(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED, ExportGcodeNotificationCli
|
||||
using PresetUpdateAvailableClickedEvent = SimpleEvent;
|
||||
wxDECLARE_EVENT(EVT_PRESET_UPDATE_AVAILABLE_CLICKED, PresetUpdateAvailableClickedEvent);
|
||||
|
||||
using CancelFn = std::function<void()>;
|
||||
|
||||
class GLCanvas3D;
|
||||
class ImGuiWrapper;
|
||||
enum class InfoItemType;
|
||||
@ -34,9 +37,6 @@ enum class InfoItemType;
|
||||
enum class NotificationType
|
||||
{
|
||||
CustomNotification,
|
||||
// Notification on end of slicing and G-code processing (the full G-code preview is available).
|
||||
// Contains a hyperlink to export the G-code to a removable media.
|
||||
SlicingComplete,
|
||||
// SlicingNotPossible,
|
||||
// Notification on end of export to a removable media, with hyperling to eject the external media.
|
||||
// Obsolete by ExportFinished
|
||||
@ -78,6 +78,10 @@ enum class NotificationType
|
||||
ProgressBar,
|
||||
// Progress bar with info from Print Host Upload Queue dialog.
|
||||
PrintHostUpload,
|
||||
// Progress bar with cancel button, cannot be closed
|
||||
// On end of slicing and G-code processing (the full G-code preview is available),
|
||||
// contains a hyperlink to export the G-code to a removable media or hdd.
|
||||
SlicingProgress,
|
||||
// Notification, when Color Change G-code is empty and user try to add color change on DoubleSlider.
|
||||
EmptyColorChangeCode,
|
||||
// Notification that custom supports/seams were deleted after mesh repair.
|
||||
@ -100,6 +104,8 @@ enum class NotificationType
|
||||
// Shows when ObjectList::update_info_items finds information that should be stressed to the user
|
||||
// Might contain logo taken from gizmos
|
||||
UpdatedItemsInfo,
|
||||
// Progress bar notification with methods to replace ProgressIndicator class.
|
||||
ProgressIndicator
|
||||
};
|
||||
|
||||
class NotificationManager
|
||||
@ -109,27 +115,31 @@ public:
|
||||
{
|
||||
// The notifications will be presented in the order of importance, thus these enum values
|
||||
// are sorted by the importance.
|
||||
// "Good to know" notification, usually but not always with a quick fade-out.
|
||||
RegularNotification = 1,
|
||||
// Important notification with progress bar, no fade-out, might appear again after closing. Position at the bottom.
|
||||
ProgressBarNotificationLevel = 1,
|
||||
// "Did you know" notification with special icon and buttons, Position close to bottom.
|
||||
HintNotificationLevel,
|
||||
// "Good to know" notification, usually but not always with a quick fade-out.
|
||||
RegularNotificationLevel,
|
||||
// Information notification without a fade-out or with a longer fade-out.
|
||||
ImportantNotification,
|
||||
// Important notification with progress bar, no fade-out, might appear again after closing.
|
||||
ProgressBarNotification,
|
||||
ImportantNotificationLevel,
|
||||
// Warning, no fade-out.
|
||||
WarningNotification,
|
||||
// Error, no fade-out.
|
||||
ErrorNotification,
|
||||
WarningNotificationLevel,
|
||||
// Error, no fade-out. Top most position.
|
||||
ErrorNotificationLevel,
|
||||
};
|
||||
|
||||
NotificationManager(wxEvtHandler* evt_handler);
|
||||
~NotificationManager();
|
||||
~NotificationManager(){}
|
||||
|
||||
// init is called after canvas3d is created. Notifications added before init are not showed or updated
|
||||
void init() { m_initialized = true; }
|
||||
// Push a prefabricated notification from basic_notifications (see the table at the end of this file).
|
||||
void push_notification(const NotificationType type, int timestamp = 0);
|
||||
// Push a NotificationType::CustomNotification with NotificationLevel::RegularNotification and 10s fade out interval.
|
||||
// Push a NotificationType::CustomNotification with NotificationLevel::RegularNotificationLevel and 10s fade out interval.
|
||||
void push_notification(const std::string& text, int timestamp = 0);
|
||||
// Push a NotificationType::CustomNotification with provided notification level and 10s for RegularNotification.
|
||||
// ErrorNotification and ImportantNotification are never faded out.
|
||||
// Push a NotificationType::CustomNotification with provided notification level and 10s for RegularNotificationLevel.
|
||||
// ErrorNotificationLevel and ImportantNotificationLevel are never faded out.
|
||||
void push_notification(NotificationType type, NotificationLevel level, const std::string& text, const std::string& hypertext = "",
|
||||
std::function<bool(wxEvtHandler*)> callback = std::function<bool(wxEvtHandler*)>(), int timestamp = 0);
|
||||
// Creates Validate Error notification with a custom text and no fade out.
|
||||
@ -162,25 +172,44 @@ public:
|
||||
// Close object warnings, whose ObjectID is not in the list.
|
||||
// living_oids is expected to be sorted.
|
||||
void remove_object_warnings_of_released_objects(const std::vector<ObjectID>& living_oids);
|
||||
// Creates special notification slicing complete.
|
||||
// If large = true (Plater side bar is closed), then printing time and export button is shown
|
||||
// at the notification and fade-out is disabled. Otherwise the fade out time is set to 10s.
|
||||
void push_slicing_complete_notification(int timestamp, bool large);
|
||||
// Add a print time estimate to an existing SlicingComplete notification.
|
||||
void set_slicing_complete_print_time(const std::string &info);
|
||||
// Called when the side bar changes its visibility, as the "slicing complete" notification supplements
|
||||
// the "slicing info" normally shown at the side bar.
|
||||
void set_slicing_complete_large(bool large);
|
||||
void set_sidebar_collapsed(bool collapsed);
|
||||
// Set technology for correct text in SlicingProgress.
|
||||
void set_fff(bool b);
|
||||
void set_fdm(bool b) { set_fff(b); }
|
||||
void set_sla(bool b) { set_fff(!b); }
|
||||
// Exporting finished, show this information with path, button to open containing folder and if ejectable - eject button
|
||||
void push_exporting_finished_notification(const std::string& path, const std::string& dir_path, bool on_removable);
|
||||
// notification with progress bar
|
||||
// notifications with progress bar
|
||||
// print host upload
|
||||
void push_upload_job_notification(int id, float filesize, const std::string& filename, const std::string& host, float percentage = 0);
|
||||
void set_upload_job_notification_percentage(int id, const std::string& filename, const std::string& host, float percentage);
|
||||
void upload_job_notification_show_canceled(int id, const std::string& filename, const std::string& host);
|
||||
void upload_job_notification_show_error(int id, const std::string& filename, const std::string& host);
|
||||
// slicing progress
|
||||
void init_slicing_progress_notification(std::function<void()> cancel_callback);
|
||||
// percentage negative = canceled, <0-1) = progress, 1 = completed
|
||||
void set_slicing_progress_percentage(const std::string& text, float percentage);
|
||||
// hides slicing progress notification imidietly
|
||||
void set_slicing_progress_hidden();
|
||||
// Add a print time estimate to an existing SlicingProgress notification. Set said notification to SP_COMPLETED state.
|
||||
void set_slicing_complete_print_time(const std::string& info, bool sidebar_colapsed);
|
||||
void set_slicing_progress_export_possible();
|
||||
// ProgressIndicator notification
|
||||
// init adds hidden instance of progress indi notif that should always live (goes to hidden instead of erasing)
|
||||
void init_progress_indicator();
|
||||
// functions equal to ProgressIndicator class
|
||||
void progress_indicator_set_range(int range);
|
||||
void progress_indicator_set_cancel_callback(CancelFn callback = CancelFn());
|
||||
void progress_indicator_set_progress(int pr);
|
||||
void progress_indicator_set_status_text(const char*); // utf8 char array
|
||||
int progress_indicator_get_range() const;
|
||||
// Hint (did you know) notification
|
||||
void push_hint_notification(bool open_next);
|
||||
bool is_hint_notification_open();
|
||||
// Forces Hints to reload its content when next hint should be showed
|
||||
void deactivate_loaded_hints();
|
||||
void push_updated_item_info_notification(InfoItemType type);
|
||||
// Close old notification ExportFinished.
|
||||
void new_export_began(bool on_removable);
|
||||
@ -267,7 +296,7 @@ private:
|
||||
virtual bool compare_text(const std::string& text) const;
|
||||
void hide(bool h) { if (is_finished()) return; m_state = h ? EState::Hidden : EState::Unknown; }
|
||||
// sets m_next_render with time of next mandatory rendering. Delta is time since last render.
|
||||
bool update_state(bool paused, const int64_t delta);
|
||||
virtual bool update_state(bool paused, const int64_t delta);
|
||||
int64_t next_render() const { return is_finished() ? 0 : m_next_render; }
|
||||
EState get_state() const { return m_state; }
|
||||
bool is_hovered() const { return m_state == EState::Hovered; }
|
||||
@ -303,6 +332,8 @@ private:
|
||||
virtual void count_lines();
|
||||
// returns true if PopStyleColor should be called later to pop this push
|
||||
virtual bool push_background_color();
|
||||
// used this function instead of reading directly m_data.duration. Some notifications might need to return changing value.
|
||||
virtual int get_duration() { return m_data.duration; }
|
||||
|
||||
const NotificationData m_data;
|
||||
// For reusing ImGUI windows.
|
||||
@ -359,29 +390,7 @@ private:
|
||||
wxEvtHandler* m_evt_handler;
|
||||
};
|
||||
|
||||
class SlicingCompleteLargeNotification : public PopNotification
|
||||
{
|
||||
public:
|
||||
SlicingCompleteLargeNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler, bool largeds);
|
||||
void set_large(bool l);
|
||||
bool get_large() { return m_is_large; }
|
||||
void set_print_info(const std::string &info);
|
||||
void render(GLCanvas3D& canvas, float initial_y, bool move_from_overlay, float overlay_width) override
|
||||
{
|
||||
// This notification is always hidden if !large (means side bar is collapsed)
|
||||
if (!get_large() && !is_finished())
|
||||
m_state = EState::Hidden;
|
||||
PopNotification::render(canvas, initial_y, move_from_overlay, overlay_width);
|
||||
}
|
||||
protected:
|
||||
void render_text(ImGuiWrapper& imgui,
|
||||
const float win_size_x, const float win_size_y,
|
||||
const float win_pos_x, const float win_pos_y)
|
||||
override;
|
||||
bool m_is_large;
|
||||
bool m_has_print_info { false };
|
||||
std::string m_print_info;
|
||||
};
|
||||
|
||||
|
||||
class SlicingWarningNotification : public PopNotification
|
||||
{
|
||||
@ -405,7 +414,7 @@ private:
|
||||
{
|
||||
public:
|
||||
|
||||
ProgressBarNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler, float percentage) : PopNotification(n, id_provider, evt_handler) { }
|
||||
ProgressBarNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler) : PopNotification(n, id_provider, evt_handler) { }
|
||||
virtual void set_percentage(float percent) { m_percentage = percent; }
|
||||
protected:
|
||||
virtual void init() override;
|
||||
@ -423,9 +432,10 @@ private:
|
||||
{}
|
||||
void render_minimize_button(ImGuiWrapper& imgui,
|
||||
const float win_pos_x, const float win_pos_y) override {}
|
||||
float m_percentage;
|
||||
float m_percentage {0.0f};
|
||||
|
||||
bool m_has_cancel_button {false};
|
||||
bool m_render_percentage {false};
|
||||
// local time of last hover for showing tooltip
|
||||
|
||||
};
|
||||
@ -443,7 +453,7 @@ private:
|
||||
PB_COMPLETED
|
||||
};
|
||||
PrintHostUploadNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler, float percentage, int job_id, float filesize)
|
||||
:ProgressBarNotification(n, id_provider, evt_handler, percentage)
|
||||
:ProgressBarNotification(n, id_provider, evt_handler)
|
||||
, m_job_id(job_id)
|
||||
, m_file_size(filesize)
|
||||
{
|
||||
@ -472,7 +482,117 @@ private:
|
||||
// Size of uploaded size to be displayed in MB
|
||||
float m_file_size;
|
||||
long m_hover_time{ 0 };
|
||||
UploadJobState m_uj_state{ UploadJobState::PB_PROGRESS };
|
||||
UploadJobState m_uj_state{ UploadJobState::PB_PROGRESS };
|
||||
};
|
||||
|
||||
class SlicingProgressNotification : public ProgressBarNotification
|
||||
{
|
||||
public:
|
||||
// Inner state of notification, Each state changes bahaviour of the notification
|
||||
enum class SlicingProgressState
|
||||
{
|
||||
SP_NO_SLICING, // hidden
|
||||
SP_PROGRESS, // never fades outs, no close button, has cancel button
|
||||
SP_CANCELLED, // fades after 10 seconds, simple message
|
||||
SP_COMPLETED // Has export hyperlink and print info, fades after 20 sec if sidebar is shown, otherwise no fade out
|
||||
};
|
||||
SlicingProgressNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler, std::function<void()> callback)
|
||||
: ProgressBarNotification(n, id_provider, evt_handler)
|
||||
, m_cancel_callback(callback)
|
||||
{
|
||||
set_progress_state(SlicingProgressState::SP_NO_SLICING);
|
||||
m_has_cancel_button = false;
|
||||
m_render_percentage = true;
|
||||
}
|
||||
// sets text of notification - call after setting progress state
|
||||
void set_status_text(const std::string& text);
|
||||
// sets cancel button callback
|
||||
void set_cancel_callback(std::function<void()> callback) { m_cancel_callback = callback; }
|
||||
bool has_cancel_callback() const { return m_cancel_callback != nullptr; }
|
||||
// sets SlicingProgressState, negative percent means canceled
|
||||
void set_progress_state(float percent);
|
||||
// sets SlicingProgressState, percent is used only at progress state.
|
||||
void set_progress_state(SlicingProgressState state,float percent = 0.f);
|
||||
// sets additional string of print info and puts notification into Completed state.
|
||||
void set_print_info(const std::string& info);
|
||||
// sets fading if in Completed state.
|
||||
void set_sidebar_collapsed(bool collapsed);
|
||||
// Calls inherited update_state and ensures Estate goes to hidden not closing.
|
||||
bool update_state(bool paused, const int64_t delta) override;
|
||||
// Switch between technology to provide correct text.
|
||||
void set_fff(bool b) { m_is_fff = b; }
|
||||
void set_fdm(bool b) { m_is_fff = b; }
|
||||
void set_sla(bool b) { m_is_fff = !b; }
|
||||
void set_export_possible(bool b) { m_export_possible = b; }
|
||||
protected:
|
||||
void init() override;
|
||||
void count_lines() override
|
||||
{
|
||||
if (m_sp_state == SlicingProgressState::SP_PROGRESS)
|
||||
ProgressBarNotification::count_lines();
|
||||
else
|
||||
PopNotification::count_lines();
|
||||
}
|
||||
void render_text(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y) override;
|
||||
void render_bar(ImGuiWrapper& imgui,
|
||||
const float win_size_x, const float win_size_y,
|
||||
const float win_pos_x, const float win_pos_y) override;
|
||||
void render_cancel_button(ImGuiWrapper& imgui,
|
||||
const float win_size_x, const float win_size_y,
|
||||
const float win_pos_x, const float win_pos_y) override;
|
||||
void render_close_button(ImGuiWrapper& imgui,
|
||||
const float win_size_x, const float win_size_y,
|
||||
const float win_pos_x, const float win_pos_y) override;
|
||||
void on_cancel_button();
|
||||
int get_duration() override;
|
||||
std::function<void()> m_cancel_callback;
|
||||
SlicingProgressState m_sp_state { SlicingProgressState::SP_PROGRESS };
|
||||
bool m_has_print_info { false };
|
||||
std::string m_print_info;
|
||||
bool m_sidebar_collapsed { false };
|
||||
bool m_is_fff { true };
|
||||
// if true, it is possible show export hyperlink in state SP_PROGRESS
|
||||
bool m_export_possible { false };
|
||||
};
|
||||
|
||||
class ProgressIndicatorNotification : public ProgressBarNotification
|
||||
{
|
||||
public:
|
||||
enum class ProgressIndicatorState
|
||||
{
|
||||
PIS_HIDDEN, // hidden
|
||||
PIS_PROGRESS_REQUEST, // progress was updated, request render on next update_state() call
|
||||
PIS_PROGRESS_UPDATED, // render was requested
|
||||
PIS_COMPLETED // both completed and canceled state. fades out into PIS_NO_SLICING
|
||||
};
|
||||
ProgressIndicatorNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler)
|
||||
: ProgressBarNotification(n, id_provider, evt_handler)
|
||||
{
|
||||
m_render_percentage = true;
|
||||
}
|
||||
// ProgressIndicator
|
||||
void set_range(int range) { m_range = range; }
|
||||
void set_cancel_callback(CancelFn callback) { m_cancel_callback = callback; }
|
||||
void set_progress(int pr) { set_percentage((float)pr / (float)m_range); }
|
||||
void set_status_text(const char*); // utf8 char array
|
||||
int get_range() const { return m_range; }
|
||||
// ProgressBarNotification
|
||||
void init() override;
|
||||
void set_percentage(float percent) override;
|
||||
bool update_state(bool paused, const int64_t delta) override;
|
||||
// Own
|
||||
protected:
|
||||
int m_range { 100 };
|
||||
CancelFn m_cancel_callback { nullptr };
|
||||
ProgressIndicatorState m_progress_state { ProgressIndicatorState::PIS_HIDDEN };
|
||||
|
||||
void render_close_button(ImGuiWrapper& imgui,
|
||||
const float win_size_x, const float win_size_y,
|
||||
const float win_pos_x, const float win_pos_y) override;
|
||||
void render_cancel_button(ImGuiWrapper& imgui,
|
||||
const float win_size_x, const float win_size_y,
|
||||
const float win_pos_x, const float win_pos_y) override;
|
||||
void on_cancel_button() { if (m_cancel_callback) m_cancel_callback(); }
|
||||
};
|
||||
|
||||
class ExportFinishedNotification : public PopNotification
|
||||
@ -499,7 +619,7 @@ private:
|
||||
void render_close_button(ImGuiWrapper& imgui,
|
||||
const float win_size_x, const float win_size_y,
|
||||
const float win_pos_x, const float win_pos_y) override;
|
||||
void render_eject_button(ImGuiWrapper& imgui,
|
||||
void render_eject_button(ImGuiWrapper& imgui,
|
||||
const float win_size_x, const float win_size_y,
|
||||
const float win_pos_x, const float win_pos_y);
|
||||
void render_minimize_button(ImGuiWrapper& imgui, const float win_pos_x, const float win_pos_y) override
|
||||
@ -562,13 +682,15 @@ private:
|
||||
// If there is some error notification active, then the "Export G-code" notification after the slicing is finished is suppressed.
|
||||
bool has_slicing_error_notification();
|
||||
|
||||
// set by init(), until false notifications are only added not updated and frame is not requested after push
|
||||
bool m_initialized{ false };
|
||||
// Target for wxWidgets events sent by clicking on the hyperlink available at some notifications.
|
||||
wxEvtHandler* m_evt_handler;
|
||||
// Cache of IDs to identify and reuse ImGUI windows.
|
||||
NotificationIDProvider m_id_provider;
|
||||
std::deque<std::unique_ptr<PopNotification>> m_pop_notifications;
|
||||
// delayed waiting notifications, first is remaining time
|
||||
std::deque<DelayedNotification> m_waiting_notifications;
|
||||
std::vector<DelayedNotification> m_waiting_notifications;
|
||||
//timestamps used for slicing finished - notification could be gone so it needs to be stored here
|
||||
std::unordered_set<int> m_used_timestamps;
|
||||
// True if G-code preview is active. False if the Plater is active.
|
||||
|
@ -1208,6 +1208,8 @@ void Sidebar::update_sliced_info_sizer()
|
||||
wxString t_est = std::isnan(ps.estimated_print_time) ? "N/A" : get_time_dhms(float(ps.estimated_print_time));
|
||||
p->sliced_info->SetTextAndShow(siEstimatedTime, t_est, _L("Estimated printing time") + ":");
|
||||
|
||||
p->plater->get_notification_manager()->set_slicing_complete_print_time(_utf8("Estimated printing time: ") + boost::nowide::narrow(t_est), p->plater->is_sidebar_collapsed());
|
||||
|
||||
// Hide non-SLA sliced info parameters
|
||||
p->sliced_info->SetTextAndShow(siFilament_m, "N/A");
|
||||
p->sliced_info->SetTextAndShow(siFilament_mm3, "N/A");
|
||||
@ -1296,10 +1298,7 @@ void Sidebar::update_sliced_info_sizer()
|
||||
new_label += format_wxstr("\n - %1%", _L("normal mode"));
|
||||
info_text += format_wxstr("\n%1%", short_time(ps.estimated_normal_print_time));
|
||||
|
||||
// uncomment next line to not disappear slicing finished notif when colapsing sidebar before time estimate
|
||||
//if (p->plater->is_sidebar_collapsed())
|
||||
p->plater->get_notification_manager()->set_slicing_complete_large(p->plater->is_sidebar_collapsed());
|
||||
p->plater->get_notification_manager()->set_slicing_complete_print_time("Estimated printing time: " + ps.estimated_normal_print_time);
|
||||
p->plater->get_notification_manager()->set_slicing_complete_print_time(_utf8("Estimated printing time: ") + ps.estimated_normal_print_time, p->plater->is_sidebar_collapsed());
|
||||
|
||||
}
|
||||
if (ps.estimated_silent_print_time != "N/A") {
|
||||
@ -1502,7 +1501,7 @@ struct Plater::priv
|
||||
GLToolbar view_toolbar;
|
||||
GLToolbar collapse_toolbar;
|
||||
Preview *preview;
|
||||
NotificationManager* notification_manager { nullptr };
|
||||
std::shared_ptr<NotificationManager> notification_manager;
|
||||
|
||||
ProjectDirtyStateManager dirty_state;
|
||||
|
||||
@ -1523,10 +1522,10 @@ struct Plater::priv
|
||||
public:
|
||||
Jobs(priv *_m) : m(_m)
|
||||
{
|
||||
m_arrange_id = add_job(std::make_unique<ArrangeJob>(m->statusbar(), m->q));
|
||||
m_fill_bed_id = add_job(std::make_unique<FillBedJob>(m->statusbar(), m->q));
|
||||
m_rotoptimize_id = add_job(std::make_unique<RotoptimizeJob>(m->statusbar(), m->q));
|
||||
m_sla_import_id = add_job(std::make_unique<SLAImportJob>(m->statusbar(), m->q));
|
||||
m_arrange_id = add_job(std::make_unique<ArrangeJob>(m->notification_manager, m->q));
|
||||
m_fill_bed_id = add_job(std::make_unique<FillBedJob>(m->notification_manager, m->q));
|
||||
m_rotoptimize_id = add_job(std::make_unique<RotoptimizeJob>(m->notification_manager, m->q));
|
||||
m_sla_import_id = add_job(std::make_unique<SLAImportJob>(m->notification_manager, m->q));
|
||||
}
|
||||
|
||||
void arrange()
|
||||
@ -1637,7 +1636,7 @@ struct Plater::priv
|
||||
void apply_free_camera_correction(bool apply = true);
|
||||
void update_ui_from_settings();
|
||||
void update_main_toolbar_tooltips();
|
||||
std::shared_ptr<ProgressStatusBar> statusbar();
|
||||
// std::shared_ptr<ProgressStatusBar> statusbar();
|
||||
std::string get_config(const std::string &key) const;
|
||||
BoundingBoxf bed_shape_bb() const;
|
||||
BoundingBox scaled_bed_shape_bb() const;
|
||||
@ -1788,6 +1787,8 @@ struct Plater::priv
|
||||
// extension should contain the leading dot, i.e.: ".3mf"
|
||||
wxString get_project_filename(const wxString& extension = wxEmptyString) const;
|
||||
void set_project_filename(const wxString& filename);
|
||||
// Call after plater and Canvas#D is initialized
|
||||
void init_notification_manager();
|
||||
|
||||
// Caching last value of show_action_buttons parameter for show_action_buttons(), so that a callback which does not know this state will not override it.
|
||||
mutable bool ready_to_slice = { false };
|
||||
@ -1797,6 +1798,7 @@ struct Plater::priv
|
||||
std::string last_output_dir_path;
|
||||
bool inside_snapshot_capture() { return m_prevent_snapshots != 0; }
|
||||
bool process_completed_with_error { false };
|
||||
|
||||
private:
|
||||
bool layers_height_allowed() const;
|
||||
|
||||
@ -1845,6 +1847,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
"support_material_contact_distance", "support_material_bottom_contact_distance", "raft_layers"
|
||||
}))
|
||||
, sidebar(new Sidebar(q))
|
||||
, notification_manager(std::make_shared<NotificationManager>(q))
|
||||
, m_ui_jobs(this)
|
||||
, delayed_scene_refresh(false)
|
||||
, view_toolbar(GLToolbar::Radio, "View")
|
||||
@ -2012,7 +2015,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
});
|
||||
#endif /* _WIN32 */
|
||||
|
||||
notification_manager = new NotificationManager(this->q);
|
||||
//notification_manager = new NotificationManager(this->q);
|
||||
|
||||
if (wxGetApp().is_editor()) {
|
||||
this->q->Bind(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED, [this](EjectDriveNotificationClickedEvent&) { this->q->eject_drive(); });
|
||||
this->q->Bind(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED, [this](ExportGcodeNotificationClickedEvent&) { this->q->export_gcode(true); });
|
||||
@ -2022,12 +2026,12 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
this->show_action_buttons(this->ready_to_slice);
|
||||
notification_manager->close_notification_of_type(NotificationType::ExportFinished);
|
||||
notification_manager->push_notification(NotificationType::CustomNotification,
|
||||
NotificationManager::NotificationLevel::RegularNotification,
|
||||
NotificationManager::NotificationLevel::RegularNotificationLevel,
|
||||
format(_L("Successfully unmounted. The device %s(%s) can now be safely removed from the computer."), evt.data.first.name, evt.data.first.path)
|
||||
);
|
||||
} else {
|
||||
notification_manager->push_notification(NotificationType::CustomNotification,
|
||||
NotificationManager::NotificationLevel::ErrorNotification,
|
||||
NotificationManager::NotificationLevel::ErrorNotificationLevel,
|
||||
format(_L("Ejecting of device %s(%s) has failed."), evt.data.first.name, evt.data.first.path)
|
||||
);
|
||||
}
|
||||
@ -2074,8 +2078,7 @@ Plater::priv::~priv()
|
||||
{
|
||||
if (config != nullptr)
|
||||
delete config;
|
||||
if (notification_manager != nullptr)
|
||||
delete notification_manager;
|
||||
notification_manager->deactivate_loaded_hints();
|
||||
}
|
||||
|
||||
void Plater::priv::update(unsigned int flags)
|
||||
@ -2150,6 +2153,8 @@ void Plater::priv::collapse_sidebar(bool collapse)
|
||||
new_tooltip += " [Shift+Tab]";
|
||||
int id = collapse_toolbar.get_item_id("collapse_sidebar");
|
||||
collapse_toolbar.set_tooltip(id, new_tooltip);
|
||||
|
||||
notification_manager->set_sidebar_collapsed(collapse);
|
||||
}
|
||||
|
||||
|
||||
@ -2177,10 +2182,11 @@ void Plater::priv::update_main_toolbar_tooltips()
|
||||
view3D->get_canvas3d()->update_tooltip_for_settings_item_in_main_toolbar();
|
||||
}
|
||||
|
||||
std::shared_ptr<ProgressStatusBar> Plater::priv::statusbar()
|
||||
{
|
||||
return main_frame->m_statusbar;
|
||||
}
|
||||
//std::shared_ptr<ProgressStatusBar> Plater::priv::statusbar()
|
||||
//{
|
||||
// return nullptr;
|
||||
// return main_frame->m_statusbar;
|
||||
//}
|
||||
|
||||
std::string Plater::priv::get_config(const std::string &key) const
|
||||
{
|
||||
@ -2325,7 +2331,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
for (std::string& name : names)
|
||||
notif_text += "\n - " + name;
|
||||
notification_manager->push_notification(NotificationType::CustomNotification,
|
||||
NotificationManager::NotificationLevel::RegularNotification, notif_text);
|
||||
NotificationManager::NotificationLevel::RegularNotificationLevel, notif_text);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2467,7 +2473,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
if (load_model) {
|
||||
wxGetApp().app_config->update_skein_dir(input_files[input_files.size() - 1].parent_path().make_preferred().string());
|
||||
// XXX: Plater.pm had @loaded_files, but didn't seem to fill them with the filenames...
|
||||
statusbar()->set_status_text(_L("Loaded"));
|
||||
// statusbar()->set_status_text(_L("Loaded"));
|
||||
}
|
||||
|
||||
// automatic selection of added objects
|
||||
@ -2880,7 +2886,7 @@ void Plater::priv::split_object()
|
||||
// If we splited object which is contain some parts/modifiers then all non-solid parts (modifiers) were deleted
|
||||
if (current_model_object->volumes.size() > 1 && current_model_object->volumes.size() != new_objects.size())
|
||||
notification_manager->push_notification(NotificationType::CustomNotification,
|
||||
NotificationManager::NotificationLevel::RegularNotification,
|
||||
NotificationManager::NotificationLevel::RegularNotificationLevel,
|
||||
_u8L("All non-solid parts (modifiers) were deleted"));
|
||||
|
||||
Plater::TakeSnapshot snapshot(q, _L("Split to Objects"));
|
||||
@ -2956,7 +2962,7 @@ void Plater::priv::process_validation_warning(const std::string& warning) const
|
||||
|
||||
notification_manager->push_notification(
|
||||
NotificationType::ValidateWarning,
|
||||
NotificationManager::NotificationLevel::WarningNotification,
|
||||
NotificationManager::NotificationLevel::WarningNotificationLevel,
|
||||
_u8L("WARNING:") + "\n" + text, hypertext, action_fn
|
||||
);
|
||||
}
|
||||
@ -3002,6 +3008,8 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool
|
||||
// In SLA mode, we need to reload the 3D scene every time to show the support structures.
|
||||
if (printer_technology == ptSLA || (printer_technology == ptFFF && config->opt_bool("wipe_tower")))
|
||||
return_state |= UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE;
|
||||
|
||||
notification_manager->set_slicing_progress_hidden();
|
||||
}
|
||||
|
||||
if ((invalidated != Print::APPLY_STATUS_UNCHANGED || force_validation) && ! background_process.empty()) {
|
||||
@ -3074,9 +3082,9 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool
|
||||
else
|
||||
{
|
||||
// Background data is valid.
|
||||
if ((return_state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 ||
|
||||
(return_state & UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) != 0 )
|
||||
this->statusbar()->set_status_text(_L("Ready to slice"));
|
||||
// if ((return_state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 ||
|
||||
// (return_state & UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) != 0 )
|
||||
// this->statusbar()->set_status_text(_L("Ready to slice"));
|
||||
|
||||
sidebar->set_btn_label(ActionButtonType::abExport, _(label_btn_export));
|
||||
sidebar->set_btn_label(ActionButtonType::abSendGCode, _(label_btn_send));
|
||||
@ -3113,10 +3121,10 @@ bool Plater::priv::restart_background_process(unsigned int state)
|
||||
(state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 ) ) {
|
||||
// The print is valid and it can be started.
|
||||
if (this->background_process.start()) {
|
||||
this->statusbar()->set_cancel_callback([this]() {
|
||||
this->statusbar()->set_status_text(_L("Cancelling"));
|
||||
this->background_process.stop();
|
||||
});
|
||||
// this->statusbar()->set_cancel_callback([this]() {
|
||||
// this->statusbar()->set_status_text(_L("Cancelling"));
|
||||
// this->background_process.stop();
|
||||
// });
|
||||
if (!show_warning_dialog)
|
||||
on_slicing_began();
|
||||
return true;
|
||||
@ -3753,9 +3761,9 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt)
|
||||
return;
|
||||
}
|
||||
|
||||
this->statusbar()->set_progress(evt.status.percent);
|
||||
this->statusbar()->set_status_text(_(evt.status.text) + wxString::FromUTF8("…"));
|
||||
//notification_manager->set_progress_bar_percentage("Slicing progress", (float)evt.status.percent / 100.0f);
|
||||
// this->statusbar()->set_progress(evt.status.percent);
|
||||
// this->statusbar()->set_status_text(_(evt.status.text) + wxString::FromUTF8("…"));
|
||||
notification_manager->set_slicing_progress_percentage(evt.status.text, (float)evt.status.percent / 100.0f);
|
||||
}
|
||||
if (evt.status.flags & (PrintBase::SlicingStatus::RELOAD_SCENE | PrintBase::SlicingStatus::RELOAD_SLA_SUPPORT_POINTS)) {
|
||||
switch (this->printer_technology) {
|
||||
@ -3806,7 +3814,6 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt)
|
||||
|
||||
void Plater::priv::on_slicing_completed(wxCommandEvent & evt)
|
||||
{
|
||||
notification_manager->push_slicing_complete_notification(evt.GetInt(), is_sidebar_collapsed());
|
||||
switch (this->printer_technology) {
|
||||
case ptFFF:
|
||||
this->update_fff_scene();
|
||||
@ -3829,8 +3836,8 @@ void Plater::priv::on_export_began(wxCommandEvent& evt)
|
||||
void Plater::priv::on_slicing_began()
|
||||
{
|
||||
clear_warnings();
|
||||
notification_manager->close_notification_of_type(NotificationType::SlicingComplete);
|
||||
notification_manager->close_notification_of_type(NotificationType::SignDetected);
|
||||
notification_manager->close_notification_of_type(NotificationType::ExportFinished);
|
||||
}
|
||||
void Plater::priv::add_warning(const Slic3r::PrintStateBase::Warning& warning, size_t oid)
|
||||
{
|
||||
@ -3895,8 +3902,9 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
|
||||
// At this point of time the thread should be either finished or canceled,
|
||||
// so the following call just confirms, that the produced data were consumed.
|
||||
this->background_process.stop();
|
||||
this->statusbar()->reset_cancel_callback();
|
||||
this->statusbar()->stop_busy();
|
||||
// this->statusbar()->reset_cancel_callback();
|
||||
// this->statusbar()->stop_busy();
|
||||
notification_manager->set_slicing_progress_export_possible();
|
||||
|
||||
// Reset the "export G-code path" name, so that the automatic background processing will be enabled again.
|
||||
this->background_process.reset_export();
|
||||
@ -3913,7 +3921,7 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
|
||||
show_error(q, message.first, message.second);
|
||||
} else
|
||||
notification_manager->push_slicing_error_notification(message.first);
|
||||
this->statusbar()->set_status_text(from_u8(message.first));
|
||||
// this->statusbar()->set_status_text(from_u8(message.first));
|
||||
if (evt.invalidate_plater())
|
||||
{
|
||||
const wxString invalid_str = _L("Invalid data");
|
||||
@ -3923,8 +3931,10 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
|
||||
}
|
||||
has_error = true;
|
||||
}
|
||||
if (evt.cancelled())
|
||||
this->statusbar()->set_status_text(_L("Cancelled"));
|
||||
if (evt.cancelled()) {
|
||||
// this->statusbar()->set_status_text(_L("Cancelled"));
|
||||
this->notification_manager->set_slicing_progress_percentage(_utf8("Slicing Cancelled."), -1);
|
||||
}
|
||||
|
||||
this->sidebar->show_sliced_info_sizer(evt.success());
|
||||
|
||||
@ -4128,6 +4138,20 @@ void Plater::priv::set_project_filename(const wxString& filename)
|
||||
wxGetApp().mainframe->add_to_recent_projects(filename);
|
||||
}
|
||||
|
||||
void Plater::priv::init_notification_manager()
|
||||
{
|
||||
if (!notification_manager)
|
||||
return;
|
||||
notification_manager->init();
|
||||
|
||||
auto cancel_callback = [this]() {
|
||||
this->background_process.stop();
|
||||
};
|
||||
notification_manager->init_slicing_progress_notification(cancel_callback);
|
||||
notification_manager->set_fff(printer_technology == ptFFF);
|
||||
notification_manager->init_progress_indicator();
|
||||
}
|
||||
|
||||
void Plater::priv::set_current_canvas_as_dirty()
|
||||
{
|
||||
if (current_panel == view3D)
|
||||
@ -5566,7 +5590,7 @@ void Plater::export_stl(bool extended, bool selection_only)
|
||||
}
|
||||
|
||||
Slic3r::store_stl(path_u8.c_str(), &mesh, true);
|
||||
p->statusbar()->set_status_text(format_wxstr(_L("STL file exported to %s"), path));
|
||||
// p->statusbar()->set_status_text(format_wxstr(_L("STL file exported to %s"), path));
|
||||
}
|
||||
|
||||
void Plater::export_amf()
|
||||
@ -5583,10 +5607,10 @@ void Plater::export_amf()
|
||||
bool full_pathnames = wxGetApp().app_config->get("export_sources_full_pathnames") == "1";
|
||||
if (Slic3r::store_amf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, full_pathnames)) {
|
||||
// Success
|
||||
p->statusbar()->set_status_text(format_wxstr(_L("AMF file exported to %s"), path));
|
||||
// p->statusbar()->set_status_text(format_wxstr(_L("AMF file exported to %s"), path));
|
||||
} else {
|
||||
// Failure
|
||||
p->statusbar()->set_status_text(format_wxstr(_L("Error exporting AMF file %s"), path));
|
||||
// p->statusbar()->set_status_text(format_wxstr(_L("Error exporting AMF file %s"), path));
|
||||
}
|
||||
}
|
||||
|
||||
@ -5625,12 +5649,12 @@ bool Plater::export_3mf(const boost::filesystem::path& output_path)
|
||||
bool ret = Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, full_pathnames, &thumbnail_data);
|
||||
if (ret) {
|
||||
// Success
|
||||
p->statusbar()->set_status_text(format_wxstr(_L("3MF file exported to %s"), path));
|
||||
// p->statusbar()->set_status_text(format_wxstr(_L("3MF file exported to %s"), path));
|
||||
p->set_project_filename(path);
|
||||
}
|
||||
else {
|
||||
// Failure
|
||||
p->statusbar()->set_status_text(format_wxstr(_L("Error exporting 3MF file %s"), path));
|
||||
// p->statusbar()->set_status_text(format_wxstr(_L("Error exporting 3MF file %s"), path));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -6204,6 +6228,8 @@ bool Plater::set_printer_technology(PrinterTechnology printer_technology)
|
||||
|
||||
p->sidebar->get_searcher().set_printer_technology(printer_technology);
|
||||
|
||||
p->notification_manager->set_fff(printer_technology == ptFFF);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -6224,7 +6250,7 @@ void Plater::clear_before_change_mesh(int obj_idx)
|
||||
// snapshot_time is captured by copy so the lambda knows where to undo/redo to.
|
||||
get_notification_manager()->push_notification(
|
||||
NotificationType::CustomSupportsAndSeamRemovedAfterRepair,
|
||||
NotificationManager::NotificationLevel::RegularNotification,
|
||||
NotificationManager::NotificationLevel::RegularNotificationLevel,
|
||||
_u8L("Custom supports, seams and multimaterial painting were "
|
||||
"removed after repairing the mesh."));
|
||||
// _u8L("Undo the repair"),
|
||||
@ -6237,7 +6263,7 @@ void Plater::clear_before_change_mesh(int obj_idx)
|
||||
// else
|
||||
// notification_manager->push_notification(
|
||||
// NotificationType::CustomSupportsAndSeamRemovedAfterRepair,
|
||||
// NotificationManager::NotificationLevel::RegularNotification,
|
||||
// NotificationManager::NotificationLevel::RegularNotificationLevel,
|
||||
// _u8L("Cannot undo to before the mesh repair!"));
|
||||
// return true;
|
||||
// });
|
||||
@ -6503,14 +6529,14 @@ Mouse3DController& Plater::get_mouse3d_controller()
|
||||
return p->mouse3d_controller;
|
||||
}
|
||||
|
||||
const NotificationManager* Plater::get_notification_manager() const
|
||||
std::shared_ptr<NotificationManager> Plater::get_notification_manager()
|
||||
{
|
||||
return p->notification_manager;
|
||||
}
|
||||
|
||||
NotificationManager* Plater::get_notification_manager()
|
||||
void Plater::init_notification_manager()
|
||||
{
|
||||
return p->notification_manager;
|
||||
p->init_notification_manager();
|
||||
}
|
||||
|
||||
bool Plater::can_delete() const { return p->can_delete(); }
|
||||
|
@ -359,11 +359,11 @@ public:
|
||||
void set_bed_shape() const;
|
||||
void set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false) const;
|
||||
|
||||
const NotificationManager* get_notification_manager() const;
|
||||
NotificationManager* get_notification_manager();
|
||||
std::shared_ptr<NotificationManager> get_notification_manager();
|
||||
void init_notification_manager();
|
||||
|
||||
void bring_instance_forward();
|
||||
|
||||
|
||||
// ROII wrapper for suppressing the Undo / Redo snapshot to be taken.
|
||||
class SuppressSnapshots
|
||||
{
|
||||
|
@ -194,3 +194,4 @@ void ProgressStatusBar::hide_cancel_button()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ namespace Slic3r {
|
||||
* of the Slicer main window. It consists of a message area to the left and a
|
||||
* progress indication area to the right with an optional cancel button.
|
||||
*/
|
||||
|
||||
class ProgressStatusBar : public ProgressIndicator
|
||||
{
|
||||
wxStatusBar *self; // we cheat! It should be the base class but: perl!
|
||||
|
Loading…
Reference in New Issue
Block a user