diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 42803f79a..7ef15d2a4 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3033,7 +3033,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) else if (evt.Moving()) { m_mouse.position = pos.cast(); - std::string tooltip = ""; + std::string tooltip = L(""); if (tooltip.empty()) tooltip = m_gizmos.get_tooltip(); @@ -3725,13 +3725,29 @@ bool GLCanvas3D::_init_undoredo_toolbar() item.icon_filename = "undo_toolbar.svg"; item.tooltip = _utf8(L("Undo")) + " [" + GUI::shortkey_ctrl_prefix() + "Z]"; item.sprite_id = 0; - item.left.toggable = false; item.left.action_callback = [this]() { post_event(SimpleEvent(EVT_GLCANVAS_UNDO)); }; item.right.toggable = true; item.right.action_callback = [this]() { m_imgui_undo_redo_hovered_pos = -1; }; item.right.render_callback = [this](float left, float right, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(true, 0.5f * (left + right)); }; - item.visibility_callback = []()->bool { return true; }; - item.enabling_callback = [this]()->bool { return wxGetApp().plater()->can_undo(); }; + item.enabling_callback = [this]()->bool { + bool can_undo = wxGetApp().plater()->can_undo(); + unsigned int id = m_undoredo_toolbar.get_item_id("undo"); + + std::string curr_additional_tooltip; + m_undoredo_toolbar.get_additional_tooltip(id, curr_additional_tooltip); + + std::string new_additional_tooltip = L(""); + if (can_undo) + wxGetApp().plater()->undo_redo_topmost_string_getter(true, new_additional_tooltip); + + if (new_additional_tooltip != curr_additional_tooltip) + { + m_undoredo_toolbar.set_additional_tooltip(id, new_additional_tooltip); + set_tooltip(L("")); + } + return can_undo; + }; + if (!m_undoredo_toolbar.add_item(item)) return false; @@ -3742,7 +3758,25 @@ bool GLCanvas3D::_init_undoredo_toolbar() item.left.action_callback = [this]() { post_event(SimpleEvent(EVT_GLCANVAS_REDO)); }; item.right.action_callback = [this]() { m_imgui_undo_redo_hovered_pos = -1; }; item.right.render_callback = [this](float left, float right, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(false, 0.5f * (left + right)); }; - item.enabling_callback = [this]()->bool { return wxGetApp().plater()->can_redo(); }; + item.enabling_callback = [this]()->bool { + bool can_redo = wxGetApp().plater()->can_redo(); + unsigned int id = m_undoredo_toolbar.get_item_id("redo"); + + std::string curr_additional_tooltip; + m_undoredo_toolbar.get_additional_tooltip(id, curr_additional_tooltip); + + std::string new_additional_tooltip = L(""); + if (can_redo) + wxGetApp().plater()->undo_redo_topmost_string_getter(false, new_additional_tooltip); + + if (new_additional_tooltip != curr_additional_tooltip) + { + m_undoredo_toolbar.set_additional_tooltip(id, new_additional_tooltip); + set_tooltip(L("")); + } + return can_redo; + }; + if (!m_undoredo_toolbar.add_item(item)) return false; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 487416a14..16773b2b9 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -649,6 +649,8 @@ public: unsigned int get_main_toolbar_item_id(const std::string& name) const { return m_main_toolbar.get_item_id(name); } void force_main_toolbar_left_action(unsigned int item_id) { m_main_toolbar.force_left_action(item_id, *this); } void force_main_toolbar_right_action(unsigned int item_id) { m_main_toolbar.force_right_action(item_id, *this); } + void get_undoredo_toolbar_additional_tooltip(unsigned int item_id, std::string& text) { return m_undoredo_toolbar.get_additional_tooltip(item_id, text); } + void set_undoredo_toolbar_additional_tooltip(unsigned int item_id, const std::string& text) { m_undoredo_toolbar.set_additional_tooltip(item_id, text); } private: bool _is_shown_on_screen() const; diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index 0ee8945e4..ca5248417 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -48,6 +48,7 @@ GLToolbarItem::Data::Data() : name("") , icon_filename("") , tooltip("") + , additional_tooltip("") , sprite_id(-1) , visible(true) , visibility_callback(Default_Visibility_Callback) @@ -365,6 +366,31 @@ void GLToolbar::force_right_action(unsigned int item_id, GLCanvas3D& parent) do_action(GLToolbarItem::Right, item_id, parent, false); } +void GLToolbar::get_additional_tooltip(unsigned int item_id, std::string& text) +{ + if (item_id < (unsigned int)m_items.size()) + { + GLToolbarItem* item = m_items[item_id]; + if (item != nullptr) + { + text = item->get_additional_tooltip(); + return; + } + } + + text = L(""); +} + +void GLToolbar::set_additional_tooltip(unsigned int item_id, const std::string& text) +{ + if (item_id < (unsigned int)m_items.size()) + { + GLToolbarItem* item = m_items[item_id]; + if (item != nullptr) + item->set_additional_tooltip(text); + } +} + bool GLToolbar::update_items_state() { bool ret = false; @@ -427,7 +453,7 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent) if (item_id == -1) { // mouse is outside the toolbar - m_tooltip = ""; + m_tooltip = L(""); } else { @@ -594,7 +620,7 @@ void GLToolbar::do_action(GLToolbarItem::EActionType type, unsigned int item_id, std::string GLToolbar::update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent) { if (!m_enabled) - return ""; + return L(""); switch (m_layout.type) { @@ -643,7 +669,15 @@ std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLC GLToolbarItem::EState state = item->get_state(); bool inside = (left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top); if (inside) + { tooltip = item->get_tooltip(); + if (!item->is_pressed()) + { + const std::string& additional_tooltip = item->get_additional_tooltip(); + if (!additional_tooltip.empty()) + tooltip += L("\n") + additional_tooltip; + } + } switch (state) { @@ -739,7 +773,15 @@ std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCan GLToolbarItem::EState state = item->get_state(); bool inside = (left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top); if (inside) + { tooltip = item->get_tooltip(); + if (!item->is_pressed()) + { + const std::string& additional_tooltip = item->get_additional_tooltip(); + if (!additional_tooltip.empty()) + tooltip += L("\n") + additional_tooltip; + } + } switch (state) { diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 9e1eef533..527317e58 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -80,6 +80,7 @@ public: std::string name; std::string icon_filename; std::string tooltip; + std::string additional_tooltip; unsigned int sprite_id; // mouse left click Option left; @@ -112,6 +113,8 @@ public: const std::string& get_name() const { return m_data.name; } const std::string& get_icon_filename() const { return m_data.icon_filename; } const std::string& get_tooltip() const { return m_data.tooltip; } + const std::string& get_additional_tooltip() const { return m_data.additional_tooltip; } + void set_additional_tooltip(const std::string& text) { m_data.additional_tooltip = text; } void do_left_action() { m_last_action_type = Left; m_data.left.action_callback(); } void do_right_action() { m_last_action_type = Right; m_data.right.action_callback(); } @@ -297,6 +300,9 @@ public: const std::string& get_tooltip() const { return m_tooltip; } + void get_additional_tooltip(unsigned int item_id, std::string& text); + void set_additional_tooltip(unsigned int item_id, const std::string& text); + // returns true if any item changed its state bool update_items_state(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 1acc24500..f05def49d 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4301,6 +4301,19 @@ bool Plater::undo_redo_string_getter(const bool is_undo, int idx, const char** o return false; } +void Plater::undo_redo_topmost_string_getter(const bool is_undo, std::string& out_text) +{ + const std::vector& ss_stack = p->undo_redo_stack.snapshots(); + const int idx_in_ss_stack = p->get_active_snapshot_index() + (is_undo ? -1 : 0); + + if (0 < idx_in_ss_stack && idx_in_ss_stack < ss_stack.size() - 1) { + out_text = ss_stack[idx_in_ss_stack].name; + return; + } + + out_text = L(""); +} + void Plater::on_extruders_change(int num_extruders) { auto& choices = sidebar().combos_filament(); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index d7e91f516..e0737c6b9 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -196,6 +196,7 @@ public: void undo_to(int selection); void redo_to(int selection); bool undo_redo_string_getter(const bool is_undo, int idx, const char** out_text); + void undo_redo_topmost_string_getter(const bool is_undo, std::string& out_text); const Slic3r::UndoRedo::Stack& undo_redo_stack() const; void on_extruders_change(int extruders_count);