diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index f5624bb6a7..1e4cff2e1e 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -773,7 +773,7 @@ bool GUI_App::on_init_inner() app_config->save(); if (this->plater_ != nullptr) { if (*Semver::parse(SLIC3R_VERSION) < *Semver::parse(into_u8(evt.GetString()))) { - this->plater_->get_notification_manager()->push_notification(NotificationType::NewAppAviable, *(this->plater_->get_current_canvas3D())); + this->plater_->get_notification_manager()->push_notification(NotificationType::NewAppAvailable, *(this->plater_->get_current_canvas3D())); } } }); diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index eb54d3f27c..cb499b3c6e 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -9,7 +9,6 @@ #include #include -#include #include #include @@ -560,7 +559,7 @@ void NotificationManager::PopNotification::on_text_click() if (m_evt_handler != nullptr) wxPostEvent(m_evt_handler, PresetUpdateAvailableClickedEvent(EVT_PRESET_UPDATE_AVAILABLE_CLICKED)); break; - case NotificationType::NewAppAviable: + case NotificationType::NewAppAvailable: wxLaunchDefaultBrowser("https://github.com/prusa3d/PrusaSlicer/releases"); break; default: @@ -640,7 +639,7 @@ NotificationManager::NotificationManager(wxEvtHandler* evt_handler) : void NotificationManager::push_notification(const NotificationType type, GLCanvas3D& canvas, int timestamp) { auto it = std::find_if(basic_notifications.begin(), basic_notifications.end(), - std::bind(&NotificationData::type, _1) == type); + boost::bind(&NotificationData::type, _1) == type); assert(it != basic_notifications.end()); if (it != basic_notifications.end()) push_notification_data( *it, canvas, timestamp); @@ -651,21 +650,16 @@ void NotificationManager::push_notification(const std::string& text, GLCanvas3D& } void NotificationManager::push_notification(const std::string& text, NotificationManager::NotificationLevel level, GLCanvas3D& canvas, int timestamp) { - switch (level) - { - case Slic3r::GUI::NotificationManager::NotificationLevel::RegularNotification: - push_notification_data({ NotificationType::CustomNotification, level, 10, text }, canvas, timestamp); - break; - case Slic3r::GUI::NotificationManager::NotificationLevel::ErrorNotification: - push_notification_data({ NotificationType::CustomNotification, level, 0, text }, canvas, timestamp); - - break; - case Slic3r::GUI::NotificationManager::NotificationLevel::ImportantNotification: - push_notification_data({ NotificationType::CustomNotification, level, 0, text }, canvas, timestamp); - break; + int duration = 0; + switch (level) { + case NotificationLevel::RegularNotification: duration = 10; break; + case NotificationLevel::ErrorNotification: break; + case NotificationLevel::ImportantNotification: break; default: - break; + assert(false); + return; } + push_notification_data({ NotificationType::CustomNotification, level, duration, text }, canvas, timestamp); } void NotificationManager::push_slicing_error_notification(const std::string& text, GLCanvas3D& canvas) { @@ -823,7 +817,7 @@ void NotificationManager::render_notifications(GLCanvas3D& canvas, float overlay float current_height = 0.0f; bool request_next_frame = false; bool render_main = false; - bool hovered = false; + bool hovered = false; sort_notifications(); // iterate thru notifications and render them / erease them for (auto it = m_pop_notifications.begin(); it != m_pop_notifications.end();) { @@ -854,23 +848,30 @@ void NotificationManager::render_notifications(GLCanvas3D& canvas, float overlay if (!top_level_wnd->IsActive()) return; - if (!m_hovered && m_last_time < wxGetLocalTime()) { - if (wxGetLocalTime() - m_last_time == 1) + // Control the fade-out. + // time in seconds + long now = wxGetLocalTime(); + // Pausing fade-out when the mouse is over some notification. + if (!m_hovered && m_last_time < now) { - for(auto ¬ification : m_pop_notifications) + if (now - m_last_time == 1) { - notification->substract_remaining_time(); + for (auto ¬ification : m_pop_notifications) + { + notification->substract_remaining_time(); + } } + m_last_time = now; } - m_last_time = wxGetLocalTime(); } if (request_next_frame) + //FIXME this is very expensive for fade-out control. + // If any of the notifications is fading out, 100% of the CPU/GPU is consumed. canvas.request_extra_frame(); } - void NotificationManager::sort_notifications() { // Stable sorting, so that the order of equal ranges is stable. diff --git a/src/slic3r/GUI/NotificationManager.hpp b/src/slic3r/GUI/NotificationManager.hpp index ea43523d5e..49de00a9f4 100644 --- a/src/slic3r/GUI/NotificationManager.hpp +++ b/src/slic3r/GUI/NotificationManager.hpp @@ -40,7 +40,7 @@ enum class NotificationType // NewPresetsAviable, // Notification on the start of PrusaSlicer, when a new PrusaSlicer version is published. // Contains a hyperlink to open a web browser pointing to the PrusaSlicer download location. - NewAppAviable, + NewAppAvailable, // Notification on the start of PrusaSlicer, when updates of system profiles are detected. // Contains a hyperlink to execute installation of the new system profiles. PresetUpdateAvailable, @@ -64,10 +64,16 @@ class NotificationManager public: enum class NotificationLevel : int { - ErrorNotification = 4, - WarningNotification = 3, - ImportantNotification = 2, - RegularNotification = 1, + // 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, + // Information notification without a fade-out or with a longer fade-out. + ImportantNotification, + // Warning, no fade-out. + WarningNotification, + // Error, no fade-out. + ErrorNotification, }; NotificationManager(wxEvtHandler* evt_handler); @@ -294,8 +300,9 @@ private: // Cache of IDs to identify and reuse ImGUI windows. NotificationIDProvider m_id_provider; std::deque> m_pop_notifications; - // Last render time for fade out control. + // Last render time in seconds for fade out control. long m_last_time { 0 }; + // When mouse hovers over some notification, the fade-out of all notifications is suppressed. bool m_hovered { false }; //timestamps used for slicing finished - notification could be gone so it needs to be stored here std::unordered_set m_used_timestamps; @@ -312,8 +319,8 @@ private: // {NotificationType::Mouse3dConnected, NotificationLevel::RegularNotification, 5, _u8L("3D Mouse connected.") }, // {NotificationType::NewPresetsAviable, NotificationLevel::ImportantNotification, 20, _u8L("New Presets are available."), _u8L("See here.") }, {NotificationType::PresetUpdateAvailable, NotificationLevel::ImportantNotification, 20, _u8L("Configuration update is available."), _u8L("See more.")}, - {NotificationType::NewAppAviable, NotificationLevel::ImportantNotification, 20, _u8L("New version is available."), _u8L("See Releases page.")}, - //{NotificationType::NewAppAviable, NotificationLevel::ImportantNotification, 20, _u8L("New vesion of PrusaSlicer is available.", _u8L("Download page.") }, + {NotificationType::NewAppAvailable, NotificationLevel::ImportantNotification, 20, _u8L("New version is available."), _u8L("See Releases page.")}, + //{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 };