From 81cb190e2f87cfe3164e5c5237d6597b7581a17b Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 15 Oct 2021 14:54:43 +0200 Subject: [PATCH] Export ongoing notification with delay 1000ms to prevent quick opening and closing on fast systems --- src/slic3r/GUI/NotificationManager.cpp | 17 +++++++++++++++-- src/slic3r/GUI/NotificationManager.hpp | 16 ++++++++++------ src/slic3r/GUI/Plater.cpp | 5 +++++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index b12256cf0..2a27ce74a 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -60,6 +60,7 @@ const NotificationManager::NotificationData NotificationManager::basic_notificat _u8L("Undo desktop integration was successful.") }, {NotificationType::UndoDesktopIntegrationFail, NotificationLevel::WarningNotificationLevel, 10, _u8L("Undo desktop integration failed.") }, + {NotificationType::ExportOngoing, NotificationLevel::RegularNotificationLevel, 0, _u8L("Exporting.") }, //{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 @@ -1151,6 +1152,8 @@ bool NotificationManager::SlicingProgressNotification::set_progress_state(Notifi m_sp_state = state; return true; case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_COMPLETED: + if (m_sp_state != SlicingProgressState::SP_BEGAN && m_sp_state != SlicingProgressState::SP_PROGRESS) + return false; set_percentage(1); m_has_cancel_button = false; m_has_print_info = false; @@ -1508,6 +1511,16 @@ void NotificationManager::push_notification(NotificationType type, int duration = get_standart_duration(level); push_notification_data({ type, level, duration, text, hypertext, callback }, timestamp); } + +void NotificationManager::push_delayed_notification(const NotificationType type, std::function condition_callback, int64_t initial_delay, int64_t delay_interval) +{ + auto it = std::find_if(std::begin(basic_notifications), std::end(basic_notifications), + boost::bind(&NotificationData::type, boost::placeholders::_1) == type); + assert(it != std::end(basic_notifications)); + if (it != std::end(basic_notifications)) + push_delayed_notification_data(std::make_unique(*it, m_id_provider, m_evt_handler), condition_callback, initial_delay, delay_interval); +} + void NotificationManager::push_validate_error_notification(const std::string& text) { push_notification_data({ NotificationType::ValidateError, NotificationLevel::ErrorNotificationLevel, 0, _u8L("ERROR:") + "\n" + text }, 0); @@ -1911,7 +1924,7 @@ void NotificationManager::push_hint_notification(bool open_next) auto condition = [&self = std::as_const(*this)]() { return self.get_notification_count() == 0; }; - push_delayed_notification(std::make_unique(data, m_id_provider, m_evt_handler, open_next), condition, 500, 30000); + push_delayed_notification_data(std::make_unique(data, m_id_provider, m_evt_handler, open_next), condition, 500, 30000); } } @@ -1974,7 +1987,7 @@ bool NotificationManager::push_notification_data(std::unique_ptr notification, std::function condition_callback, int64_t initial_delay, int64_t delay_interval) +void NotificationManager::push_delayed_notification_data(std::unique_ptr notification, std::function condition_callback, int64_t initial_delay, int64_t delay_interval) { if (initial_delay == 0 && condition_callback()) { if( push_notification_data(std::move(notification), 0)) diff --git a/src/slic3r/GUI/NotificationManager.hpp b/src/slic3r/GUI/NotificationManager.hpp index 00065f795..2031586b8 100644 --- a/src/slic3r/GUI/NotificationManager.hpp +++ b/src/slic3r/GUI/NotificationManager.hpp @@ -109,8 +109,10 @@ enum class NotificationType // Give user advice to simplify object with big amount of triangles // Contains ObjectID for closing when object is deleted SimplifySuggestion, - // information about netfabb is finished repairing model (blocking proccess) - NetfabbFinished + // information about netfabb is finished repairing model (blocking proccess) + NetfabbFinished, + // Short meesage to fill space between start and finish of export + ExportOngoing }; class NotificationManager @@ -151,6 +153,10 @@ public: // ErrorNotificationLevel and ImportantNotificationLevel are never faded out. void push_notification(NotificationType type, NotificationLevel level, const std::string& text, const std::string& hypertext = "", std::function callback = std::function(), int timestamp = 0); + // Pushes basic_notification with delay. See push_delayed_notification_data. + void push_delayed_notification(const NotificationType type, std::function condition_callback, int64_t initial_delay, int64_t delay_interval); + // Removes all notifications of type from m_waiting_notifications + void stop_delayed_notifications_of_type(const NotificationType type); // Creates Validate Error notification with a custom text and no fade out. void push_validate_error_notification(const std::string& text); // Creates Slicing Error notification with a custom text and no fade out. @@ -699,10 +705,8 @@ private: // and condition callback is success, notification is regular pushed from update function. // Otherwise another delay interval waiting. Timestamp is 0. // Note that notification object is constructed when being added to the waiting list, but there are no updates called on it and its timer is reset at regular push. - // Also note that no control of same notification is done during push_delayed_notification but if waiting notif fails to push, it continues waiting. - void push_delayed_notification(std::unique_ptr notification, std::function condition_callback, int64_t initial_delay, int64_t delay_interval); - // Removes all notifications of type from m_waiting_notifications - void stop_delayed_notifications_of_type(const NotificationType type); + // Also note that no control of same notification is done during push_delayed_notification_data but if waiting notif fails to push, it continues waiting. + void push_delayed_notification_data(std::unique_ptr notification, std::function condition_callback, int64_t initial_delay, int64_t delay_interval); //finds older notification of same type and moves it to the end of queue. returns true if found bool activate_existing(const NotificationManager::PopNotification* notification); // Put the more important notifications to the bottom of the list. diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 0710c0916..ba0f60839 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4025,6 +4025,7 @@ void Plater::priv::on_export_began(wxCommandEvent& evt) { if (show_warning_dialog) warnings_dialog(); + notification_manager->push_delayed_notification(NotificationType::ExportOngoing, [](){return true;}, 1000, 1000); } void Plater::priv::on_slicing_began() { @@ -4157,6 +4158,10 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) if(wxGetApp().get_mode() == comSimple) { show_action_buttons(false); } + if (exporting_status != ExportingStatus::NOT_EXPORTING && !has_error) { + notification_manager->stop_delayed_notifications_of_type(NotificationType::ExportOngoing); + notification_manager->close_notification_of_type(NotificationType::ExportOngoing); + } // If writing to removable drive was scheduled, show notification with eject button if (exporting_status == ExportingStatus::EXPORTING_TO_REMOVABLE && !has_error) { show_action_buttons(false);