From 5477495d49c7b1b543152f80ec29ea9eb5a54cfe Mon Sep 17 00:00:00 2001 From: "liz.li" Date: Fri, 27 Oct 2023 17:05:48 +0800 Subject: [PATCH] ENH: add a duration before slicing complete for showing dailytips jira: new Change-Id: I3c30eb45fa99f6c973bac6621f5ddf1de3eb2bfe --- .../images/notification_slicing_complete.svg | 10 +++ src/imgui/imconfig.h | 1 + src/slic3r/GUI/ImGuiWrapper.cpp | 1 + .../GUI/SlicingProgressNotification.cpp | 86 +++++++++++++++++-- .../GUI/SlicingProgressNotification.hpp | 12 +-- 5 files changed, 96 insertions(+), 14 deletions(-) create mode 100644 resources/images/notification_slicing_complete.svg diff --git a/resources/images/notification_slicing_complete.svg b/resources/images/notification_slicing_complete.svg new file mode 100644 index 000000000..82bc8ea17 --- /dev/null +++ b/resources/images/notification_slicing_complete.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/imgui/imconfig.h b/src/imgui/imconfig.h index 8f49006a2..ac0226042 100644 --- a/src/imgui/imconfig.h +++ b/src/imgui/imconfig.h @@ -206,6 +206,7 @@ namespace ImGui const wchar_t OpenArrowIcon = 0x0840; const wchar_t CollapseArrowIcon = 0x0841; const wchar_t ExpandArrowIcon = 0x0842; + const wchar_t CompleteIcon = 0x0843; // void MyFunction(const char* name, const MyMatrix44& v); } diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 1483dc803..1034aa592 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -127,6 +127,7 @@ static const std::map font_icons_large = { {ImGui::PrevArrowHoverBtnIcon, "notification_arrow_left_hovered" }, {ImGui::NextArrowBtnIcon, "notification_arrow_right" }, {ImGui::NextArrowHoverBtnIcon, "notification_arrow_right_hovered" }, + {ImGui::CompleteIcon, "notification_slicing_complete" }, }; static const std::map font_icons_extra_large = { diff --git a/src/slic3r/GUI/SlicingProgressNotification.cpp b/src/slic3r/GUI/SlicingProgressNotification.cpp index d18a8bdfc..4d6133168 100644 --- a/src/slic3r/GUI/SlicingProgressNotification.cpp +++ b/src/slic3r/GUI/SlicingProgressNotification.cpp @@ -17,6 +17,9 @@ namespace { } } +static constexpr int BEFORE_COMPLETE_DURATION = 3000; //ms +static constexpr int REFRESH_TIMEOUT = 100; //ms + void NotificationManager::SlicingProgressNotification::init() { if (m_sp_state == SlicingProgressState::SP_PROGRESS) { @@ -48,8 +51,14 @@ bool NotificationManager::SlicingProgressNotification::set_progress_state(float { if (percent < 0.f) return true;//set_progress_state(SlicingProgressState::SP_CANCELLED); - else if (percent >= 1.f) - return set_progress_state(SlicingProgressState::SP_COMPLETED); + else if (percent >= 1.f) { + if (m_dailytips_panel->is_expanded()) { + m_before_complete_start = GLCanvas3D::timestamp_now(); + return set_progress_state(SlicingProgressState::SP_BEFORE_COMPLETED); + } + else + return set_progress_state(SlicingProgressState::SP_COMPLETED); + } else return set_progress_state(SlicingProgressState::SP_PROGRESS, percent); } @@ -90,9 +99,17 @@ bool NotificationManager::SlicingProgressNotification::set_progress_state(Notifi set_export_possible(false); m_sp_state = state; return true; - case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_COMPLETED: + case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_BEFORE_COMPLETED: if (m_sp_state != SlicingProgressState::SP_BEGAN && m_sp_state != SlicingProgressState::SP_PROGRESS) return false; + m_has_print_info = false; + // m_export_possible is important only for SP_PROGRESS state, thus we can reset it here + set_export_possible(false); + 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 && m_sp_state != SlicingProgressState::SP_BEFORE_COMPLETED) + return false; set_percentage(1); m_has_print_info = false; // m_export_possible is important only for SP_PROGRESS state, thus we can reset it here @@ -126,6 +143,13 @@ void NotificationManager::SlicingProgressNotification::set_status_text(const std m_state = EState::Shown; } break; + case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_BEFORE_COMPLETED: + { + NotificationData data{ NotificationType::SlicingProgress, NotificationLevel::ProgressBarNotificationLevel, 0, _u8L("Slice ok.") }; + update(data); + m_state = EState::Shown; + } + break; case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_COMPLETED: { NotificationData data{ NotificationType::SlicingProgress, NotificationLevel::ProgressBarNotificationLevel, 0, _u8L("Slice ok.") }; @@ -177,6 +201,9 @@ int NotificationManager::SlicingProgressNotification::get_duration() bool NotificationManager::SlicingProgressNotification::update_state(bool paused, const int64_t delta) { bool ret = PopNotification::update_state(paused, delta); + if (m_sp_state == SlicingProgressState::SP_BEFORE_COMPLETED || m_sp_state == SlicingProgressState::SP_COMPLETED) + ret = true; + // sets Estate to hidden if (get_state() == PopNotification::EState::ClosePending || get_state() == PopNotification::EState::Finished) set_progress_state(SlicingProgressState::SP_NO_SLICING); @@ -259,7 +286,7 @@ void NotificationManager::SlicingProgressNotification::render(GLCanvas3D& canvas render_show_dailytips(view_dailytips_text_pos); } - if (m_sp_state == SlicingProgressState::SP_PROGRESS) { + if (m_sp_state == SlicingProgressState::SP_PROGRESS || m_sp_state == SlicingProgressState::SP_BEFORE_COMPLETED) { std::string child_name = "##SlicingProgressPanel" + std::to_string(parent_window->ID); ImGui::SetNextWindowPos(parent_window->Pos + progress_child_window_padding); @@ -273,8 +300,10 @@ void NotificationManager::SlicingProgressNotification::render(GLCanvas3D& canvas ImVec2 text_pos = ImVec2(progress_bar_pos.x, progress_bar_pos.y - m_line_height * 1.2f); render_text(text_pos); - render_bar(progress_bar_pos, progress_bar_size); - render_cancel_button(button_pos, button_size); + if (m_sp_state == SlicingProgressState::SP_PROGRESS) { + render_bar(progress_bar_pos, progress_bar_size); + render_cancel_button(button_pos, button_size); + } } ImGui::EndChild(); @@ -312,9 +341,48 @@ void Slic3r::GUI::NotificationManager::SlicingProgressNotification::render_text( { ImGuiWrapper& imgui = *wxGetApp().imgui(); - //one line text - ImGui::SetCursorScreenPos(pos); - imgui.text(m_text1.substr(0, m_endlines[0]).c_str()); + if (m_sp_state == SlicingProgressState::SP_BEFORE_COMPLETED) { + // complete icon + 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)); + + ImVec2 icon_size = ImVec2(38.f, 38.f) * m_scale; + ImGui::SetCursorScreenPos(pos); + std::wstring icon_text; + icon_text = ImGui::CompleteIcon; + imgui.button(icon_text.c_str()); + + ImGui::PopStyleColor(5); + + // complete text + imgui.push_bold_font(); + ImGui::SetCursorScreenPos(ImVec2(pos.x + icon_size.x, pos.y)); + imgui.text(m_text1.substr(0, m_endlines[0]).c_str()); + imgui.pop_bold_font(); + + // before closing text + int64_t now = GLCanvas3D::timestamp_now(); + int64_t duration_time = now - m_before_complete_start; + if (duration_time > BEFORE_COMPLETE_DURATION) { + set_progress_state(SlicingProgressState::SP_COMPLETED); + return; + } + boost::format fmt(_u8L("Closing in %ds")); + fmt % (3 - duration_time / 1000); + ImGui::PushStyleColor(ImGuiCol_Text, ImColor(144, 144, 144).Value); + ImGui::SetCursorScreenPos(ImVec2(pos.x + icon_size.x, pos.y + m_line_height + m_line_height / 2)); + imgui.text(fmt.str()); + ImGui::PopStyleColor(); + + } + else { + //one line text + ImGui::SetCursorScreenPos(pos); + imgui.text(m_text1.substr(0, m_endlines[0]).c_str()); + } } void Slic3r::GUI::NotificationManager::SlicingProgressNotification::render_bar(const ImVec2& pos, const ImVec2& size) diff --git a/src/slic3r/GUI/SlicingProgressNotification.hpp b/src/slic3r/GUI/SlicingProgressNotification.hpp index 137fc0b6b..544e3783e 100644 --- a/src/slic3r/GUI/SlicingProgressNotification.hpp +++ b/src/slic3r/GUI/SlicingProgressNotification.hpp @@ -13,11 +13,12 @@ public: // Inner state of notification, Each state changes bahaviour of the notification enum class SlicingProgressState { - SP_NO_SLICING, // hidden - SP_BEGAN, // still hidden but allows to go to SP_PROGRESS state. This prevents showing progress after slicing was canceled. - 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 + SP_NO_SLICING, // hidden + SP_BEGAN, // still hidden but allows to go to SP_PROGRESS state. This prevents showing progress after slicing was canceled. + SP_PROGRESS, // never fades outs, no close button, has cancel button + SP_CANCELLED, // fades after 10 seconds, simple message + SP_BEFORE_COMPLETED, // to keep displaying DailyTips for 3 seconds + 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 callback) : PopNotification(n, id_provider, evt_handler) @@ -64,6 +65,7 @@ protected: protected: float m_percentage{ 0.0f }; + int64_t m_before_complete_start; // if returns false, process was already canceled std::function m_cancel_callback; SlicingProgressState m_sp_state{ SlicingProgressState::SP_PROGRESS };