diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 1cd2c149bf..59605d437a 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -170,6 +170,8 @@ set(SLIC3R_GUI_SOURCES GUI/Gizmos/GLGizmosManager.hpp GUI/Gizmos/GLGizmoSVG.cpp GUI/Gizmos/GLGizmoSVG.hpp + GUI/Gizmos/GLGizmoUtils.cpp + GUI/Gizmos/GLGizmoUtils.hpp #GUI/Gizmos/GLGizmoText.cpp #GUI/Gizmos/GLGizmoText.hpp GUI/GLCanvas3D.cpp diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 3be30551c5..642ec7f36f 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -33,6 +33,7 @@ #include "format.hpp" #include "DailyTips.hpp" #include "FilamentMapDialog.hpp" +#include "Gizmos/GLGizmoUtils.hpp" #include "slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp" #include "slic3r/Utils/UndoRedo.hpp" @@ -224,43 +225,6 @@ bool GLCanvas3D::LayersEditing::is_allowed() const float GLCanvas3D::LayersEditing::s_overlay_window_width; -void GLCanvas3D::LayersEditing::show_tooltip_information(const GLCanvas3D& canvas, std::map captions_texts, float x, float y) -{ - ImTextureID normal_id = canvas.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP); - ImTextureID hover_id = canvas.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER); - - ImGuiWrapper& imgui = *wxGetApp().imgui(); - float caption_max = 0.f; - for (auto caption_text : captions_texts) { - caption_max = std::max(imgui.calc_text_size(caption_text.first).x, caption_max); - } - caption_max += GImGui->Style.WindowPadding.x + imgui.scaled(1); - - float scale = canvas.get_scale(); - #ifdef WIN32 - int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); - scale *= (float) dpi / (float) DPI_DEFAULT; - #endif // WIN32 - ImVec2 button_size = ImVec2(25 * scale, 25 * scale); // ORCA: Use exact resolution will prevent blur on icon - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, 0}); // ORCA: Dont add padding - ImGui::ImageButton3(normal_id, hover_id, button_size); - - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip2(ImVec2(x, y)); - auto draw_text_with_caption = [this, &caption_max, &imgui](const wxString& caption, const wxString& text) { - imgui.text_colored(ImGuiWrapper::COL_ACTIVE, caption); - ImGui::SameLine(caption_max); - imgui.text_colored(ImGuiWrapper::COL_WINDOW_BG, text); - }; - - for (const auto& caption_text : captions_texts) draw_text_with_caption(caption_text.first, caption_text.second); - - ImGui::EndTooltip(); - } - ImGui::PopStyleVar(2); -} - void GLCanvas3D::LayersEditing::render_variable_layer_height_dialog(const GLCanvas3D& canvas) { if (!m_enabled) return; @@ -358,15 +322,18 @@ void GLCanvas3D::LayersEditing::render_variable_layer_height_dialog(const GLCanv ImGui::Separator(); - float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + canvas.m_main_toolbar.get_height(); - std::map captions_texts = { - {_L("Left mouse button") + ":" , _L("Add detail")}, - {_L("Right mouse button") + ":", _L("Remove detail")}, - {_L("Shift+") + _L("Left mouse button") + ":", _L("Reset to base")}, - {_L("Shift+") + _L("Right mouse button") + ":", _L("Smoothing")}, - {_L("Mouse wheel:"), _L("Increase/decrease edit area")} + const wxString shift = GUI::shortkey_shift_prefix(); + std::vector> shortcuts = { + {_L("Left mouse button"), _L("Add detail")}, + {_L("Right mouse button"), _L("Remove detail")}, + {shift + _L("Left mouse button"), _L("Reset to base")}, + {shift + _L("Right mouse button"), _L("Smoothing")}, + {_L("Mouse wheel"), _L("Increase/decrease edit area")} }; - show_tooltip_information(canvas, captions_texts, x, get_cur_y); + + float y = canvas.m_main_toolbar.get_height(); + GLGizmoUtils::render_tooltip_button(&imgui, canvas, shortcuts, x, y); + ImGui::SameLine(); if (imgui.button(_L("Reset"))) wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE)); @@ -1222,13 +1189,13 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed) m_selection.set_volumes(&m_volumes.volumes); - m_assembly_view_desc["object_selection_caption"] = _L("Left mouse button"); - m_assembly_view_desc["object_selection"] = _L("Object selection"); - // FIXME: maybe should be using GUI::shortkey_alt_prefix() or equivalent? - m_assembly_view_desc["part_selection_caption"] = _L("Alt+") + _L("Left mouse button"); - m_assembly_view_desc["part_selection"] = _L("Part selection"); - m_assembly_view_desc["number_key_caption"] = "1~16 " + _L("number keys"); - m_assembly_view_desc["number_key"] = _L("Number keys can quickly change the color of objects"); + const wxString alt = GUI::shortkey_alt_prefix(); + + m_shortcuts_assembly_view = { + {_L("Left mouse button"), _L("Object Selection")}, + {alt + _L("Left mouse button"), _L("Part Selection")}, + {"1~16 " + _L("number keys"), _L("Number keys can quickly change the color of objects")}, + }; } GLCanvas3D::~GLCanvas3D() @@ -8913,45 +8880,32 @@ void GLCanvas3D::_render_paint_toolbar() const ImGui::PopStyleColor(); } -float GLCanvas3D::_show_assembly_tooltip_information(float caption_max, float x, float y) const +float GLCanvas3D::_render_assembly_tooltip_button(ImGuiWrapper* imgui_wrapper) const { - ImGuiWrapper *imgui = wxGetApp().imgui(); - ImTextureID normal_id = m_gizmos.get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP); - ImTextureID hover_id = m_gizmos.get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER); + const float text_height = imgui_wrapper->calc_text_size(_L("part selection")).y; + ImVec2 windowPos = ImGui::GetWindowPos(); + float x = windowPos.x; + float y = windowPos.y - ImGui::GetFrameHeight() - (5 * text_height); + y -= ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight(); // correct default ToolTipButton behaviour - caption_max += imgui->calc_text_size(": "sv).x + 35.f; + GLGizmoUtils::render_tooltip_button(imgui_wrapper, *this, m_shortcuts_assembly_view, x, y); + ImGui::SameLine(); + ImGui::Dummy(ImVec2(12.f, 0.f)); - float scale = get_scale(); - #ifdef WIN32 - int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); - scale *= (float) dpi / (float) DPI_DEFAULT; - #endif // WIN32 + float scale = get_scale(); +#ifdef WIN32 + int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); + scale *= (float) dpi / (float) DPI_DEFAULT; +#endif // WIN32 ImVec2 button_size = ImVec2(25 * scale, 25 * scale); // ORCA: Use exact resolution will prevent blur on icon - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, ImGui::GetStyle().FramePadding.y}); - ImGui::ImageButton3(normal_id, hover_id, button_size); + float same_line_width = button_size.x * 1.8; // with an space size + ImGui::SameLine(same_line_width); + same_line_width = imgui_wrapper->calc_text_size("|"sv).x + same_line_width + imgui_wrapper->calc_text_size(" "sv).x; + imgui_wrapper->text_colored(ImGuiWrapper::COL_ACTIVE, "|"); + ImGui::SameLine(same_line_width); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip2(ImVec2(x, y)); - auto draw_text_with_caption = [&imgui, & caption_max](const wxString &caption, const wxString &text) { - imgui->text_colored(ImGuiWrapper::COL_ACTIVE, caption); - ImGui::SameLine(caption_max); - imgui->text_colored(ImGuiWrapper::COL_WINDOW_BG, text); - }; - - for (const auto &t : std::array{"object_selection", "part_selection", "number_key"}) { - draw_text_with_caption(m_assembly_view_desc.at(t + "_caption") + ": ", m_assembly_view_desc.at(t)); - } - ImGui::EndTooltip(); - } - ImGui::PopStyleVar(2); - auto same_line_size = button_size.x * 1.8;//with an space size - ImGui::SameLine(same_line_size); - same_line_size = imgui->calc_text_size("|"sv).x + same_line_size + imgui->calc_text_size(" "sv).x; - imgui->text_colored(ImGuiWrapper::COL_ACTIVE, "|"); - ImGui::SameLine(same_line_size); - return same_line_size; + return same_line_width; // return the width of the space taken by the tooltip button and the separator } //BBS @@ -8985,19 +8939,11 @@ void GLCanvas3D::_render_assemble_control() imgui->begin(_L("Assemble Control"), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar); ImGui::AlignTextToFramePadding(); - float tip_icon_size; + float tooltip_button_width; { - float caption_max = 0.f; - for (const auto &t : std::array{"object_selection", "part_selection", "number_key"}) { - caption_max = std::max(caption_max, imgui->calc_text_size(m_assembly_view_desc.at(t + "_caption")).x); - } - const ImVec2 pos = ImGui::GetCursorScreenPos(); - const float text_y = imgui->calc_text_size(_L("Part selection")).y; - float get_cur_x = pos.x; - float get_cur_y = pos.y - ImGui::GetFrameHeight() - 4 * text_y; - tip_icon_size =_show_assembly_tooltip_information(caption_max, get_cur_x, get_cur_y); + tooltip_button_width = _render_assembly_tooltip_button(imgui); } - float same_line_width = tip_icon_size; + float same_line_width = tooltip_button_width; { float clp_dist = m_gizmos.m_assemble_view_data->model_objects_clipper()->get_position(); if (clp_dist == 0.f) { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 8a3156db15..2895b110d3 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -289,7 +289,6 @@ class GLCanvas3D bool is_enabled() const { return m_enabled; } void set_enabled(bool enabled) { m_enabled = is_allowed() && enabled; } - void show_tooltip_information(const GLCanvas3D& canvas, std::map captions_texts, float x, float y); void render_variable_layer_height_dialog(const GLCanvas3D& canvas); void render_overlay(const GLCanvas3D& canvas); void render_volumes(const GLCanvas3D& canvas, const GLVolumeCollection& volumes); @@ -521,7 +520,8 @@ private: wxGLContext* m_context; SceneRaycaster m_scene_raycaster; Bed3D &m_bed; - std::map m_assembly_view_desc; + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts_assembly_view; #if ENABLE_RETINA_GL std::unique_ptr m_retina_helper; #endif @@ -1262,7 +1262,7 @@ private: // BBS //void _render_view_toolbar() const; void _render_paint_toolbar() const; - float _show_assembly_tooltip_information(float caption_max, float x, float y) const; + float _render_assembly_tooltip_button(ImGuiWrapper* imgui_wrapper) const; void _render_assemble_control(); void _render_assemble_info() const; #if ENABLE_SHOW_CAMERA_TARGET diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index 328993beff..78d9c9839b 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -78,6 +78,11 @@ void break_to_debugger() #endif /* _WIN32 */ } +const std::string& shortkey_shift_prefix() +{ + return _u8L("Shift+"); +} + const std::string& shortkey_ctrl_prefix() { static const std::string str = diff --git a/src/slic3r/GUI/GUI.hpp b/src/slic3r/GUI/GUI.hpp index db8cf06a61..f14a2eb7c3 100644 --- a/src/slic3r/GUI/GUI.hpp +++ b/src/slic3r/GUI/GUI.hpp @@ -31,6 +31,7 @@ void break_to_debugger(); // Platform specific Ctrl+/Alt+ (Windows, Linux) vs. ⌘/⌥ (OSX) prefixes extern const std::string& shortkey_ctrl_prefix(); extern const std::string& shortkey_alt_prefix(); +extern const std::string& shortkey_shift_prefix(); // Shift is the same on all platforms, but we provide a function for consistency with Ctrl/Alt prefixes extern AppConfig* get_app_config(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoAssembly.cpp b/src/slic3r/GUI/Gizmos/GLGizmoAssembly.cpp index a737f4209b..f6ce2533f3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoAssembly.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoAssembly.cpp @@ -4,6 +4,7 @@ #include "slic3r/GUI/Plater.hpp" #include "slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp" #include "slic3r/Utils/UndoRedo.hpp" +#include "GLGizmoUtils.hpp" #include "libslic3r/PresetBundle.hpp" #include "libslic3r/MeasureUtils.hpp" @@ -43,6 +44,8 @@ std::string GLGizmoAssembly::on_get_name() const bool GLGizmoAssembly::on_init() { + GLGizmoMeasure::on_init(); + m_shortcut_key = WXK_CONTROL_Y; return true; } @@ -108,14 +111,8 @@ void GLGizmoAssembly::on_render_input_window(float x, float y, float bottom_limi ImGui::Separator(); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f)); - float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y; - float caption_max = 0.f; - float total_text_max = 0.f; - for (const auto &t : std::array{"point_selection", "reset", "unselect"}) { - caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc[t + "_caption"]).x); - total_text_max = std::max(total_text_max, m_imgui->calc_text_size(m_desc[t]).x); - } - show_tooltip_information(caption_max, x, get_cur_y); + + GLGizmoUtils::render_tooltip_button(m_imgui, m_parent, m_shortcuts, x, y); float f_scale =m_parent.get_gizmos_manager().get_layout_scale(); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f * f_scale)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBrimEars.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBrimEars.cpp index 8ec117e559..682be933ad 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBrimEars.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBrimEars.cpp @@ -7,6 +7,7 @@ #include "slic3r/GUI/Plater.hpp" #include "libslic3r/ClipperUtils.hpp" #include "libslic3r/ExPolygon.hpp" +#include "GLGizmoUtils.hpp" namespace Slic3r { namespace GUI { @@ -44,10 +45,8 @@ bool GLGizmoBrimEars::on_init() m_shortcut_key = WXK_CONTROL_E; - // FIXME: maybe should be using GUI::shortkey_ctrl_prefix() or equivalent? - const wxString ctrl = _L("Ctrl+"); - // FIXME: maybe should be using GUI::shortkey_alt_prefix() or equivalent? - const wxString alt = _L("Alt+"); + const wxString ctrl = GUI::shortkey_ctrl_prefix(); + const wxString alt = GUI::shortkey_alt_prefix(); m_desc["head_diameter"] = _L("Head diameter"); m_desc["max_angle"] = _L("Max angle"); @@ -57,14 +56,12 @@ bool GLGizmoBrimEars::on_init() m_desc["auto_generate"] = _L("Auto-generate points"); m_desc["section_view"] = _L("Section view"); - m_desc["left_click_caption"] = _L("Left click"); - m_desc["left_click"] = _L("Add a brim ear"); - m_desc["right_click_caption"] = _L("Right click"); - m_desc["right_click"] = _L("Delete a brim ear"); - m_desc["ctrl_mouse_wheel_caption"] = ctrl + _L("Mouse wheel"); - m_desc["ctrl_mouse_wheel"] = _L("Adjust head diameter"); - m_desc["alt_mouse_wheel_caption"] = alt + _L("Mouse wheel"); - m_desc["alt_mouse_wheel"] = _L("Adjust section view"); + m_shortcuts = { + {_L("Left mouse button"), _L("Add a brim ear")}, + {_L("Right mouse button"), _L("Delete a brim ear")}, + {ctrl + _L("Mouse wheel"), _L("Adjust head diameter")}, + {alt + _L("Mouse wheel"), _L("Adjust section view")}, + }; return true; } @@ -737,7 +734,8 @@ void GLGizmoBrimEars::on_render_input_window(float x, float y, float bottom_limi ImGui::PopStyleVar(1); float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y; - show_tooltip_information(x, get_cur_y); + + GLGizmoUtils::render_tooltip_button(m_imgui, m_parent, m_shortcuts, x, y); if (glb_cfg.opt_enum("brim_type") != btPainted) { ImGui::SameLine(); @@ -790,41 +788,6 @@ void GLGizmoBrimEars::on_render_input_window(float x, float y, float bottom_limi ImGuiWrapper::pop_toolbar_style(); } -void GLGizmoBrimEars::show_tooltip_information(float x, float y) -{ - std::array info_array = std::array{"left_click", "right_click", "ctrl_mouse_wheel", "alt_mouse_wheel"}; - float caption_max = 0.f; - for (const auto &t : info_array) { caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc[t + "_caption"]).x); } - - ImTextureID normal_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP); - ImTextureID hover_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER); - - caption_max += m_imgui->calc_text_size(": "sv).x + 35.f; - - float scale = m_parent.get_scale(); - #ifdef WIN32 - int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); - scale *= (float) dpi / (float) DPI_DEFAULT; - #endif // WIN32 - ImVec2 button_size = ImVec2(25 * scale, 25 * scale); // ORCA: Use exact resolution will prevent blur on icon - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, 0}); // ORCA: Dont add padding - ImGui::ImageButton3(normal_id, hover_id, button_size); - - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip2(ImVec2(x, y)); - auto draw_text_with_caption = [this, &caption_max](const wxString &caption, const wxString &text) { - m_imgui->text_colored(ImGuiWrapper::COL_ACTIVE, caption); - ImGui::SameLine(caption_max); - m_imgui->text_colored(ImGuiWrapper::COL_WINDOW_BG, text); - }; - - for (const auto &t : info_array) draw_text_with_caption(m_desc.at(t + "_caption") + ": ", m_desc.at(t)); - ImGui::EndTooltip(); - } - ImGui::PopStyleVar(2); -} - bool GLGizmoBrimEars::on_is_activable() const { const Selection &selection = m_parent.get_selection(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBrimEars.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBrimEars.hpp index 20fee730b3..8f50859130 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBrimEars.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBrimEars.hpp @@ -117,6 +117,9 @@ private: // This map holds all translated description texts, so they can be easily referenced during layout calculations // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. std::map m_desc; + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts; + GLSelectionRectangle m_selection_rectangle; @@ -159,7 +162,6 @@ protected: void on_start_dragging() override; void on_stop_dragging() override; void on_render_input_window(float x, float y, float bottom_limit) override; - void show_tooltip_information(float x, float y); std::string on_get_name() const override; bool on_is_activable() const override; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index b57bc007f2..6c5185b0d2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -12,6 +12,7 @@ #include "slic3r/Utils/UndoRedo.hpp" #include "libslic3r/AppConfig.hpp" #include "libslic3r/TriangleMeshSlicer.hpp" +#include "GLGizmoUtils.hpp" #include "imgui/imgui_internal.h" #include "slic3r/GUI/Field.hpp" @@ -1186,16 +1187,21 @@ bool GLGizmoCut3D::on_init() // initiate info shortcuts const wxString ctrl = GUI::shortkey_ctrl_prefix(); const wxString alt = GUI::shortkey_alt_prefix(); - const wxString shift = _L("Shift+"); + const wxString shift = GUI::shortkey_shift_prefix(); - m_shortcuts_cut.push_back(std::make_pair(shift + _L("Drag"), _L("Draw cut line"))); + m_shortcuts_cut = { + {_L("Drag"), _L("Move cut line")}, + {shift + _L("Drag"), _L("Draw cut line")} + }; - m_shortcuts_connector.push_back(std::make_pair(_L("Left click"), _L("Add connector"))); - m_shortcuts_connector.push_back(std::make_pair(_L("Right click"), _L("Remove connector"))); - m_shortcuts_connector.push_back(std::make_pair(_L("Drag"), _L("Move connector"))); - m_shortcuts_connector.push_back(std::make_pair(shift + _L("Left click"), _L("Add connector to selection"))); - m_shortcuts_connector.push_back(std::make_pair(alt + _L("Left click"), _L("Remove connector from selection"))); - m_shortcuts_connector.push_back(std::make_pair(ctrl + "A", _L("Select all connectors"))); + m_shortcuts_connector = { + {_L("Left mouse button"), _L("Add connector")}, + {_L("Right mouse button"), _L("Remove connector")}, + {_L("Drag"), _L("Move connector")}, + {shift + _L("Left mouse button"), _L("Add connector to selection")}, + {alt + _L("Left mouse button"), _L("Remove connector from selection")}, + {ctrl + "A", _L("Select all connectors")}, + }; return true; } @@ -2313,8 +2319,7 @@ void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors, flo ImGui::Separator(); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f)); - float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y; - show_tooltip_information(x, get_cur_y); + render_tooltip_button(x, y); float f_scale = m_parent.get_gizmos_manager().get_layout_scale(); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f * f_scale)); @@ -2757,7 +2762,7 @@ void GLGizmoCut3D::render_cut_plane_input_window(CutConnectors &connectors, floa ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f)); float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y; - show_tooltip_information(x, get_cur_y); + render_tooltip_button(x, get_cur_y); float f_scale = m_parent.get_gizmos_manager().get_layout_scale(); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f * f_scale)); @@ -2917,43 +2922,11 @@ void GLGizmoCut3D::on_render_input_window(float x, float y, float bottom_limit) render_debug_input_window(x); } -void GLGizmoCut3D::show_tooltip_information(float x, float y) +void GLGizmoCut3D::render_tooltip_button(float x, float y) { - auto &shortcuts = m_connectors_editing ? m_shortcuts_connector : m_shortcuts_cut; + auto& shortcuts = m_connectors_editing ? m_shortcuts_connector : m_shortcuts_cut; - float caption_max = 0.f; - for (const auto &short_cut : shortcuts) { - caption_max = std::max(caption_max, m_imgui->calc_text_size(short_cut.first).x); - } - - ImTextureID normal_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP); - ImTextureID hover_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER); - - caption_max += m_imgui->calc_text_size(std::string_view{": "}).x + 35.f; - - float scale = m_parent.get_scale(); - #ifdef WIN32 - int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); - scale *= (float) dpi / (float) DPI_DEFAULT; - #endif // WIN32 - ImVec2 button_size = ImVec2(25 * scale, 25 * scale); // ORCA: Use exact resolution will prevent blur on icon - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, 0}); // ORCA: Dont add padding - ImGui::ImageButton3(normal_id, hover_id, button_size); - - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip2(ImVec2(x, y)); - auto draw_text_with_caption = [this, &caption_max](const wxString &caption, const wxString &text) { - m_imgui->text_colored(ImGuiWrapper::COL_ACTIVE, caption); - ImGui::SameLine(caption_max); - m_imgui->text_colored(ImGuiWrapper::COL_WINDOW_BG, text); - }; - - for (const auto &short_cut : shortcuts) - draw_text_with_caption(short_cut.first + ": ", short_cut.second); - ImGui::EndTooltip(); - } - ImGui::PopStyleVar(2); + GLGizmoUtils::render_tooltip_button(m_imgui, m_parent, shortcuts, x, y); } bool GLGizmoCut3D::is_outside_of_cut_contour(size_t idx, const CutConnectors& connectors, const Vec3d cur_pos) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index 47a6d47f39..73838f43c3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -200,7 +200,9 @@ class GLGizmoCut3D : public GLGizmoBase PartSelection m_part_selection; + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} std::vector> m_shortcuts_cut; + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} std::vector> m_shortcuts_connector; enum class CutMode { @@ -321,7 +323,7 @@ protected: void update_plane_model(); void on_render_input_window(float x, float y, float bottom_limit) override; - void show_tooltip_information(float x, float y); + void render_tooltip_button(float x, float y); bool wants_enter_leave_snapshots() const override { return true; } std::string get_gizmo_entering_text() const override { return _u8L("Entering Cut gizmo"); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index d158efd844..4225a256fc 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -15,6 +15,7 @@ #include "slic3r/GUI/Jobs/NotificationProgressIndicator.hpp" #include "slic3r/Utils/WxFontUtils.hpp" #include "slic3r/Utils/UndoRedo.hpp" +#include "GLGizmoUtils.hpp" #include "libslic3r/Geometry.hpp" // to range pi pi #include "libslic3r/Timer.hpp" @@ -725,6 +726,10 @@ bool GLGizmoEmboss::on_init() // NOTE: It has special handling in GLGizmosManager::handle_shortcut m_shortcut_key = WXK_CONTROL_T; + m_shortcuts = { + {_L("Drag"), _L("Position on surface")} + }; + // initialize text styles m_style_manager.init(wxGetApp().app_config); @@ -918,7 +923,7 @@ void GLGizmoEmboss::on_render_input_window(float x, float y, float bottom_limit) GizmoImguiBegin(get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar); - draw_window(); + draw_window(x, y); GizmoImguiEnd(); @@ -1341,7 +1346,7 @@ void GLGizmoEmboss::close() mng.open_gizmo(GLGizmosManager::Emboss); } -void GLGizmoEmboss::draw_window() +void GLGizmoEmboss::draw_window(float x, float y) { #ifdef ALLOW_DEBUG_MODE if (ImGui::Button("re-process")) process(); @@ -1393,6 +1398,10 @@ void GLGizmoEmboss::draw_window() ImGui::Separator(); draw_model_type(); } + + ImGui::Separator(); + + GLGizmoUtils::render_tooltip_button(m_imgui, m_parent, m_shortcuts, x, y); #ifdef SHOW_WX_FONT_DESCRIPTOR if (is_selected_style) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp index 7d4d5cd3fc..f5916620f8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp @@ -112,7 +112,7 @@ private: // create volume from text - main functionality bool process(bool make_snapshot = true); void close(); - void draw_window(); + void draw_window(float x, float y); void draw_text_input(); void draw_model_type(); void draw_style_list(); @@ -229,6 +229,9 @@ private: // only temporary solution static const std::string M_ICON_FILENAME; + + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts; }; } // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index c27461e63c..6b3fd492c6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -14,6 +14,7 @@ #include "slic3r/GUI/format.hpp" #include "slic3r/GUI/GUI.hpp" #include "slic3r/Utils/UndoRedo.hpp" +#include "GLGizmoUtils.hpp" #include @@ -79,33 +80,47 @@ bool GLGizmoFdmSupports::on_init() // BBS m_shortcut_key = WXK_CONTROL_L; - // FIXME: maybe should be using GUI::shortkey_ctrl_prefix() or equivalent? - const wxString ctrl = _L("Ctrl+"); - // FIXME: maybe should be using GUI::shortkey_alt_prefix() or equivalent? - const wxString alt = _L("Alt+"); - const wxString shift = _L("Shift+"); + m_desc["perform"] = _L("Perform"); + m_desc["on_overhangs_only"] = _L("On overhangs only"); + m_desc["remove_all"] = _L("Erase all painting"); + m_desc["highlight_by_angle"] = _L("Highlight overhang areas"); + m_desc["tool_type"] = _L("Tool type"); + m_desc["gap_fill"] = _L("Gap fill"); + m_desc["reset_direction"] = _L("Reset direction"); + m_desc["clipping_of_view"] = _L("Section view"); + m_desc["cursor_size"] = _L("Pen size"); + m_desc["smart_fill_angle"] = _L("Smart fill angle"); + m_desc["gap_area"] = _L("Gap area"); - m_desc["clipping_of_view_caption"] = alt + _L("Mouse wheel"); - m_desc["clipping_of_view"] = _L("Section view"); - m_desc["reset_direction"] = _L("Reset direction"); - m_desc["cursor_size_caption"] = ctrl + _L("Mouse wheel"); - m_desc["cursor_size"] = _L("Pen size"); - m_desc["enforce_caption"] = _L("Left mouse button"); - m_desc["enforce"] = _L("Enforce supports"); - m_desc["block_caption"] = _L("Right mouse button"); - m_desc["block"] = _L("Block supports"); - m_desc["remove_caption"] = shift + _L("Left mouse button"); - m_desc["remove"] = _L("Erase"); - m_desc["remove_all"] = _L("Erase all painting"); - m_desc["highlight_by_angle"] = _L("Highlight overhang areas"); - m_desc["gap_fill"] = _L("Gap fill"); - m_desc["perform"] = _L("Perform"); - m_desc["gap_area_caption"] = ctrl + _L("Mouse wheel"); - m_desc["gap_area"] = _L("Gap area"); - m_desc["tool_type"] = _L("Tool type"); - m_desc["smart_fill_angle_caption"] = ctrl + _L("Mouse wheel"); - m_desc["smart_fill_angle"] = _L("Smart fill angle"); - m_desc["on_overhangs_only"] = _L("On overhangs only"); + + const wxString ctrl = GUI::shortkey_ctrl_prefix(); + const wxString alt = GUI::shortkey_alt_prefix(); + const wxString shift = GUI::shortkey_shift_prefix(); + + std::pair enforce_shortcut = {_L("Left mouse button"), _L("Enforce supports")}; + std::pair block_shortcut = {_L("Right mouse button"), _L("Block supports")}; + std::pair remove_shortcut = {shift + _L("Left mouse button"), _L("Erase")}; + std::pair clipping_shortcut = {alt + _L("Mouse wheel"), m_desc["clipping_of_view"]}; + + m_shortcuts_brush = { + enforce_shortcut, + block_shortcut, + remove_shortcut, + {ctrl + _L("Mouse wheel"), m_desc["cursor_size"]}, + clipping_shortcut + }; + + m_shortcuts_bucket_fill = { + enforce_shortcut, + block_shortcut, + remove_shortcut, + {ctrl + _L("Mouse wheel"), m_desc["smart_fill_angle"]}, + clipping_shortcut + }; + + m_shortcuts_gap_fill = { + {ctrl + _L("Mouse wheel"), _L("Gap area")} + }; memset(&m_print_instance, 0, sizeof(m_print_instance)); return true; @@ -414,8 +429,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l ImGui::Separator(); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f)); - float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y; - show_tooltip_information(caption_max, x, get_cur_y); + render_tooltip_button(x, y); float f_scale =m_parent.get_gizmos_manager().get_layout_scale(); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f * f_scale)); @@ -473,53 +487,22 @@ void GLGizmoFdmSupports::tool_changed(wchar_t old_tool, wchar_t new_tool) } } -void GLGizmoFdmSupports::show_tooltip_information(float caption_max, float x, float y) -{ - ImTextureID normal_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP); - ImTextureID hover_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER); - - caption_max += m_imgui->calc_text_size(std::string_view{": "}).x + 15.f; - - float scale = m_parent.get_scale(); - #ifdef WIN32 - int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); - scale *= (float) dpi / (float) DPI_DEFAULT; - #endif // WIN32 - ImVec2 button_size = ImVec2(25 * scale, 25 * scale); // ORCA: Use exact resolution will prevent blur on icon - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, 0}); // ORCA: Dont add padding - ImGui::ImageButton3(normal_id, hover_id, button_size); - - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip2(ImVec2(x, y)); - auto draw_text_with_caption = [this, &caption_max](const wxString &caption, const wxString &text) { - // BBS - m_imgui->text_colored(ImGuiWrapper::COL_ACTIVE, caption); - ImGui::SameLine(caption_max); - m_imgui->text_colored(ImGuiWrapper::COL_WINDOW_BG, text); - }; - - std::vector tip_items; - switch (m_tool_type) { - case ToolType::BRUSH: - tip_items = {"enforce", "block", "remove", "cursor_size", "clipping_of_view"}; - break; - case ToolType::BUCKET_FILL: - break; - case ToolType::SMART_FILL: - tip_items = {"enforce", "block", "remove", "smart_fill_angle", "clipping_of_view"}; - break; - case ToolType::GAP_FILL: - tip_items = {"gap_area"}; - break; +void GLGizmoFdmSupports::render_tooltip_button(float x, float y) { + auto get_shortcuts = [this]() -> std::vector> { + switch (m_current_tool) { + case ImGui::CircleButtonIcon: + case ImGui::SphereButtonIcon: + return m_shortcuts_brush; + case ImGui::FillButtonIcon: + return m_shortcuts_bucket_fill; + case ImGui::GapFillIcon: + return m_shortcuts_gap_fill; default: - break; + return {}; } - for (const auto &t : tip_items) draw_text_with_caption(m_desc.at(t + "_caption") + ": ", m_desc.at(t)); - - ImGui::EndTooltip(); - } - ImGui::PopStyleVar(2); + }; + + GLGizmoUtils::render_tooltip_button(m_imgui, m_parent, get_shortcuts(), x, y); } // BBS diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp index ec0faeab80..133e71e2f1 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp @@ -33,7 +33,7 @@ protected: std::string on_get_name() const override; void on_set_state() override; - void show_tooltip_information(float caption_max, float x, float y); + void render_tooltip_button(float x, float y); wxString handle_snapshot_action_name(bool shift_down, Button button_down) const override; std::string get_gizmo_entering_text() const override { return "Entering Paint-on supports"; } @@ -90,6 +90,13 @@ private: // This map holds all translated description texts, so they can be easily referenced during layout calculations // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. std::map m_desc; + + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts_brush; + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts_bucket_fill; + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts_gap_fill; }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFuzzySkin.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFuzzySkin.cpp index 862ae1cdcf..0c50c32e12 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFuzzySkin.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFuzzySkin.cpp @@ -10,6 +10,7 @@ #include "slic3r/GUI/MsgDialog.hpp" #include "slic3r/GUI/Plater.hpp" #include "slic3r/Utils/UndoRedo.hpp" +#include "GLGizmoUtils.hpp" #include #include @@ -31,31 +32,47 @@ bool GLGizmoFuzzySkin::on_init() { m_shortcut_key = WXK_CONTROL_H; - // FIXME: maybe should be using GUI::shortkey_ctrl_prefix() or equivalent? - const wxString ctrl = _L("Ctrl+"); - // FIXME: maybe should be using GUI::shortkey_alt_prefix() or equivalent? - const wxString alt = _L("Alt+"); - const wxString shift = _L("Shift+"); + const wxString ctrl = GUI::shortkey_ctrl_prefix(); + const wxString alt = GUI::shortkey_alt_prefix(); + const wxString shift = GUI::shortkey_shift_prefix(); - m_desc["clipping_of_view_caption"] = alt + _L("Mouse wheel"); - m_desc["clipping_of_view"] = _L("Section view"); - m_desc["reset_direction"] = _L("Reset direction"); - m_desc["cursor_size_caption"] = ctrl + _L("Mouse wheel"); - m_desc["cursor_size"] = _L("Brush size"); - m_desc["cursor_type"] = _L("Brush shape") ; - m_desc["add_fuzzy_skin_caption"] = _L("Left mouse button"); - m_desc["add_fuzzy_skin"] = _L("Add fuzzy skin"); - m_desc["remove_fuzzy_skin_caption"] = shift + _L("Left mouse button"); - m_desc["remove_fuzzy_skin"] = _L("Remove fuzzy skin"); - m_desc["remove_all"] = _L("Erase all painting"); - m_desc["circle"] = _L("Circle"); - m_desc["sphere"] = _L("Sphere"); - m_desc["pointer"] = _L("Triangles"); - m_desc["tool_type"] = _L("Tool type"); - m_desc["tool_brush"] = _L("Brush"); - m_desc["tool_smart_fill"] = _L("Smart fill"); - m_desc["smart_fill_angle_caption"] = ctrl + _L("Mouse wheel"); - m_desc["smart_fill_angle"] = _L("Smart fill angle"); + m_desc["reset_direction"] = _L("Reset direction"); + m_desc["remove_all"] = _L("Erase all painting"); + m_desc["circle"] = _L("Circle"); + m_desc["sphere"] = _L("Sphere"); + m_desc["pointer"] = _L("Triangles"); + m_desc["tool_type"] = _L("Tool type"); + m_desc["tool_brush"] = _L("Brush"); + m_desc["tool_smart_fill"] = _L("Smart fill"); + m_desc["clipping_of_view"] = _L("Section view"); + m_desc["cursor_size"] = _L("Pen size"); + m_desc["add_fuzzy_skin"] = _L("Add fuzzy skin"); + m_desc["remove_fuzzy_skin"] = _L("Remove fuzzy skin"); + m_desc["smart_fill_angle"] = _L("Smart fill angle"); + + std::pair add_fuzzy_skin_shortcut = {_L("Left mouse button"), m_desc["add_fuzzy_skin"]}; + std::pair remove_fuzzy_skin_shortcut = {shift + _L("Left mouse button"), m_desc["remove_fuzzy_skin"]}; + std::pair clipping_shortcut = {alt + _L("Mouse wheel"), m_desc["clipping_of_view"]}; + + m_shortcuts_brush = { + add_fuzzy_skin_shortcut, + remove_fuzzy_skin_shortcut, + {ctrl + _L("Mouse wheel"), m_desc["cursor_size"]}, + clipping_shortcut + }; + + m_shortcuts_triangle = { + add_fuzzy_skin_shortcut, + remove_fuzzy_skin_shortcut, + clipping_shortcut + }; + + m_shortcuts_smart_fill = { + add_fuzzy_skin_shortcut, + remove_fuzzy_skin_shortcut, + {ctrl + _L("Mouse wheel"), m_desc["smart_fill_angle"]}, + clipping_shortcut + }; return true; } @@ -80,50 +97,18 @@ void GLGizmoFuzzySkin::render_painter_gizmo() glsafe(::glDisable(GL_BLEND)); } -void GLGizmoFuzzySkin::show_tooltip_information(float caption_max, float x, float y) +void GLGizmoFuzzySkin::render_tooltip_button(float x, float y) { - ImTextureID normal_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP); - ImTextureID hover_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER); - - caption_max += m_imgui->calc_text_size(std::string_view{": "}).x + 15.f; - - float scale = m_parent.get_scale(); - #ifdef WIN32 - int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); - scale *= (float) dpi / (float) DPI_DEFAULT; - #endif // WIN32 - ImVec2 button_size = ImVec2(25 * scale, 25 * scale); // ORCA: Use exact resolution will prevent blur on icon - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, 0}); // ORCA: Dont add padding - ImGui::ImageButton3(normal_id, hover_id, button_size); - - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip2(ImVec2(x, y)); - auto draw_text_with_caption = [this, &caption_max](const wxString& caption, const wxString& text) { - m_imgui->text_colored(ImGuiWrapper::COL_ACTIVE, caption); - ImGui::SameLine(caption_max); - m_imgui->text_colored(ImGuiWrapper::COL_WINDOW_BG, text); - }; - - std::vector tip_items; + auto get_shortcuts = [this]() -> std::vector> { switch (m_tool_type) { - case ToolType::BRUSH: - if (m_cursor_type == TriangleSelector::POINTER) { - tip_items = {"add_fuzzy_skin", "remove_fuzzy_skin", "clipping_of_view"}; - } else { - tip_items = {"add_fuzzy_skin", "remove_fuzzy_skin", "cursor_size", "clipping_of_view"}; - } - break; - case ToolType::SMART_FILL: - tip_items = {"add_fuzzy_skin", "remove_fuzzy_skin", "smart_fill_angle", "clipping_of_view"}; - break; - default: - break; + case ToolType::BRUSH: return m_cursor_type == TriangleSelector::POINTER ? m_shortcuts_triangle : m_shortcuts_brush; + + case ToolType::SMART_FILL: return m_shortcuts_smart_fill; + default: return {}; } - for (const auto &t : tip_items) draw_text_with_caption(m_desc.at(t + "_caption") + ": ", m_desc.at(t)); - ImGui::EndTooltip(); - } - ImGui::PopStyleVar(2); + }; + + GLGizmoUtils::render_tooltip_button(m_imgui, m_parent, get_shortcuts(), x, y); } void GLGizmoFuzzySkin::on_render_input_window(float x, float y, float bottom_limit) @@ -314,8 +299,7 @@ void GLGizmoFuzzySkin::on_render_input_window(float x, float y, float bottom_lim ImGui::Separator(); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f)); - float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y; - show_tooltip_information(caption_max, x, get_cur_y); + render_tooltip_button(x, y); float f_scale = m_parent.get_gizmos_manager().get_layout_scale(); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f * f_scale)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFuzzySkin.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFuzzySkin.hpp index 798ff670f3..ed6a38e068 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFuzzySkin.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFuzzySkin.hpp @@ -18,7 +18,7 @@ protected: void on_render_input_window(float x, float y, float bottom_limit) override; std::string on_get_name() const override; - void show_tooltip_information(float caption_max, float x, float y); + void render_tooltip_button(float x, float y); wxString handle_snapshot_action_name(bool shift_down, Button button_down) const override; @@ -45,6 +45,13 @@ private: // This map holds all translated description texts, so they can be easily referenced during layout calculations // etc. When language changes, GUI is recreated, and this class constructed again, so the change takes effect. std::map m_desc; + + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts_brush; + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts_triangle; + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts_smart_fill; }; } // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index fac6daf1cc..efc7b82fae 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -4,6 +4,7 @@ #include "slic3r/GUI/Plater.hpp" #include "slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp" #include "slic3r/Utils/UndoRedo.hpp" +#include "GLGizmoUtils.hpp" #include "libslic3r/PresetBundle.hpp" #include "libslic3r/MeasureUtils.hpp" @@ -444,15 +445,14 @@ bool GLGizmoMeasure::on_init() { m_shortcut_key = WXK_CONTROL_U; - const wxString shift = _L("Shift+"); + const wxString shift = GUI::shortkey_shift_prefix(); - m_desc["feature_selection"] = _L("Select feature"); - m_desc["point_selection_caption"] = shift + _L("Left mouse button"); - m_desc["point_selection"] = _L("Select point"); - m_desc["reset_caption"] = _L("Delete"); - m_desc["reset"] = _L("Restart selection"); - m_desc["unselect_caption"] = _L("Esc"); - m_desc["unselect"] = _L("Cancel a feature until exit"); + m_shortcuts = { + {_L("Left mouse button"), _L("Select")}, + {shift + _L("Left mouse button"), _L("Select point")}, + {_L("Delete"), _L("Restart selection")}, + {_L("Esc"), _L("Cancel a feature until exit")}, + }; return true; } @@ -2177,16 +2177,8 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit show_distance_xyz_ui(); ImGui::Separator(); - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f)); - float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y; - float caption_max = 0.f; - float total_text_max = 0.f; - for (const auto &t : std::array{"point_selection", "reset", "unselect"}) { - caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc[t + "_caption"]).x); - total_text_max = std::max(total_text_max, m_imgui->calc_text_size(m_desc[t]).x); - } - show_tooltip_information(caption_max, x, get_cur_y); - ImGui::PopStyleVar(1); + GLGizmoUtils::render_tooltip_button(m_imgui, m_parent, m_shortcuts, x, y); + if (last_feature != m_curr_feature || last_mode != m_mode || last_selected_features != m_selected_features) { // the dialog may have changed its size, ask for an extra frame to render it properly last_feature = m_curr_feature; @@ -2239,38 +2231,6 @@ void GLGizmoMeasure::update_measurement_result() m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, Measure::SurfaceFeature(std::get<0>(m_selected_features.first.feature->get_circle()))); } -void GLGizmoMeasure::show_tooltip_information(float caption_max, float x, float y) -{ - ImTextureID normal_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP); - ImTextureID hover_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER); - - caption_max += m_imgui->calc_text_size(": "sv).x + 35.f; - - float scale = m_parent.get_scale(); - #ifdef WIN32 - int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); - scale *= (float) dpi / (float) DPI_DEFAULT; - #endif // WIN32 - ImVec2 button_size = ImVec2(25 * scale, 25 * scale); // ORCA: Use exact resolution will prevent blur on icon - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 0, 0 }); // ORCA: Dont add padding - ImGui::ImageButton3(normal_id, hover_id, button_size); - - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip2(ImVec2(x, y)); - auto draw_text_with_caption = [this, &caption_max](const wxString &caption, const wxString &text) { - m_imgui->text_colored(ImGuiWrapper::COL_ACTIVE, caption); - ImGui::SameLine(caption_max); - m_imgui->text_colored(ImGuiWrapper::COL_WINDOW_BG, text); - }; - - for (const auto &t : std::array{"point_selection", "reset", "unselect"}) - draw_text_with_caption(m_desc.at(t + "_caption") + ": ", m_desc.at(t)); - ImGui::EndTooltip(); - } - ImGui::PopStyleVar(2); -} - void GLGizmoMeasure::reset_all_pick() { std::map>().swap(m_mesh_raycaster_map); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp index 7fd54603f3..3965652c05 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp @@ -271,7 +271,6 @@ protected: void remove_selected_sphere_raycaster(int id); void update_measurement_result(); - void show_tooltip_information(float caption_max, float x, float y); void reset_all_pick(); void reset_gripper_pick(GripperType id,bool is_all = false); void register_single_mesh_pick(); @@ -303,9 +302,9 @@ protected: bool is_pick_meet_assembly_mode(const SelectedFeatures::Item& item); protected: - // This map holds all translated description texts, so they can be easily referenced during layout calculations - // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. - std::map m_desc; + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts; + bool m_show_reset_first_tip{false}; bool m_selected_wrong_feature_waring_tip{false}; EMeasureMode m_measure_mode{EMeasureMode::ONLY_MEASURE}; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp index 24c1456a6d..a351961b71 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -13,6 +13,7 @@ #include "libslic3r/PresetBundle.hpp" #include "libslic3r/Model.hpp" #include "slic3r/Utils/UndoRedo.hpp" +#include "GLGizmoUtils.hpp" #include @@ -88,55 +89,61 @@ bool GLGizmoMmuSegmentation::on_init() // BBS m_shortcut_key = WXK_CONTROL_N; - // FIXME: maybe should be using GUI::shortkey_ctrl_prefix() or equivalent? - const wxString ctrl = _L("Ctrl+"); - // FIXME: maybe should be using GUI::shortkey_alt_prefix() or equivalent? - const wxString alt = _L("Alt+"); - const wxString shift = _L("Shift+"); + const wxString ctrl = GUI::shortkey_ctrl_prefix(); + const wxString alt = GUI::shortkey_alt_prefix(); + const wxString shift = GUI::shortkey_shift_prefix(); - m_desc["clipping_of_view_caption"] = alt + _L("Mouse wheel"); - m_desc["clipping_of_view"] = _L("Section view"); - m_desc["reset_direction"] = _L("Reset direction"); - m_desc["cursor_size_caption"] = ctrl + _L("Mouse wheel"); - m_desc["cursor_size"] = _L("Pen size"); - m_desc["cursor_type"] = _L("Pen shape"); + m_desc["clipping_of_view"] = _L("Section view"); + m_desc["reset_direction"] = _L("Reset direction"); + m_desc["cursor_size"] = _L("Pen size"); + m_desc["cursor_type"] = _L("Pen shape"); + m_desc["paint"] = _L("Paint"); + m_desc["erase"] = _L("Erase"); + m_desc["shortcut_key"] = _L("Choose filament"); + m_desc["edge_detection"] = _L("Edge detection"); + m_desc["gap_area"] = _L("Gap area"); + m_desc["perform"] = _L("Perform"); + m_desc["remove_all"] = _L("Erase all painting"); + m_desc["circle"] = _L("Circle"); + m_desc["sphere"] = _L("Sphere"); + m_desc["pointer"] = _L("Triangles"); + m_desc["filaments"] = _L("Filaments"); + m_desc["tool_type"] = _L("Tool type"); + m_desc["tool_brush"] = _L("Brush"); + m_desc["tool_smart_fill"] = _L("Smart fill"); + m_desc["tool_bucket_fill"] = _L("Bucket fill"); + m_desc["smart_fill_angle"] = _L("Smart fill angle"); + m_desc["height_range"] = _L("Height range"); + m_desc["toggle_wireframe"] = _L("Toggle Wireframe"); + m_desc["perform_remap"] = _L("Remap filaments"); + m_desc["remap"] = _L("Remap"); + m_desc["cancel_remap"] = _L("Cancel"); - m_desc["paint_caption"] = _L("Left mouse button"); - m_desc["paint"] = _L("Paint"); - m_desc["erase_caption"] = shift + _L("Left mouse button"); - m_desc["erase"] = _L("Erase"); - m_desc["shortcut_key_caption"] = _L("Key 1~9"); - m_desc["shortcut_key"] = _L("Choose filament"); - m_desc["edge_detection"] = _L("Edge detection"); - m_desc["gap_area_caption"] = ctrl + _L("Mouse wheel"); - m_desc["gap_area"] = _L("Gap area"); - m_desc["perform"] = _L("Perform"); + std::pair paint_shortcut = {_L("Left mouse button"), m_desc["paint"]}; + std::pair erase_shortcut = {shift + _L("Left mouse button"), m_desc["erase"]}; + std::pair clipping_shortcut = {alt + _L("Mouse wheel"), m_desc["clipping_of_view"]}; + std::pair toggle_wireframe_shortcut = {alt + shift + _L("Enter"), m_desc["toggle_wireframe"]}; - m_desc["remove_all"] = _L("Erase all painting"); - m_desc["circle"] = _L("Circle"); - m_desc["sphere"] = _L("Sphere"); - m_desc["pointer"] = _L("Triangles"); + m_shortcuts_brush = { + paint_shortcut, + erase_shortcut, + {ctrl + _L("Mouse wheel"), m_desc["cursor_size"]}, + clipping_shortcut, + toggle_wireframe_shortcut + }; - m_desc["filaments"] = _L("Filaments"); - m_desc["tool_type"] = _L("Tool type"); - m_desc["tool_brush"] = _L("Brush"); - m_desc["tool_smart_fill"] = _L("Smart fill"); - m_desc["tool_bucket_fill"] = _L("Bucket fill"); + m_shortcuts_bucket_fill = { + paint_shortcut, + erase_shortcut, + {ctrl + _L("Mouse wheel"), m_desc["smart_fill_angle"]}, + clipping_shortcut, + toggle_wireframe_shortcut + }; - m_desc["smart_fill_angle_caption"] = ctrl + _L("Mouse wheel"); - m_desc["smart_fill_angle"] = _L("Smart fill angle"); - - m_desc["height_range_caption"] = ctrl + _L("Mouse wheel"); - m_desc["height_range"] = _L("Height range"); - - //add toggle wire frame hint - m_desc["toggle_wireframe_caption"] = alt + shift + _L("Enter"); - m_desc["toggle_wireframe"] = _L("Toggle Wireframe"); - - // Filament remapping descriptions - m_desc["perform_remap"] = _L("Remap filaments"); - m_desc["remap"] = _L("Remap"); - m_desc["cancel_remap"] = _L("Cancel"); + m_shortcuts_gap_fill = { + {ctrl + _L("Mouse wheel"), m_desc["gap_area"]}, + toggle_wireframe_shortcut + }; init_extruders_data(); @@ -279,52 +286,22 @@ static void render_extruders_combo(const std::string& label, selection_idx = selection_out; } -void GLGizmoMmuSegmentation::show_tooltip_information(float caption_max, float x, float y) +void GLGizmoMmuSegmentation::render_tooltip_button(float x, float y) { - ImTextureID normal_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP); - ImTextureID hover_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER); - - caption_max += m_imgui->calc_text_size(std::string_view{": "}).x + 15.f; - - float scale = m_parent.get_scale(); - #ifdef WIN32 - int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); - scale *= (float) dpi / (float) DPI_DEFAULT; - #endif // WIN32 - ImVec2 button_size = ImVec2(25 * scale, 25 * scale); // ORCA: Use exact resolution will prevent blur on icon - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, 0}); // ORCA: Dont add padding - ImGui::ImageButton3(normal_id, hover_id, button_size); - - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip2(ImVec2(x, y)); - auto draw_text_with_caption = [this, &caption_max](const wxString &caption, const wxString &text) { - m_imgui->text_colored(ImGuiWrapper::COL_ACTIVE, caption); - ImGui::SameLine(caption_max); - m_imgui->text_colored(ImGuiWrapper::COL_WINDOW_BG, text); - }; - - std::vector tip_items; + auto get_shortcuts = [this]() -> std::vector> { switch (m_tool_type) { - case ToolType::BRUSH: - tip_items = {"paint", "erase", "cursor_size", "clipping_of_view", "toggle_wireframe"}; - break; - case ToolType::BUCKET_FILL: - tip_items = {"paint", "erase", "smart_fill_angle", "clipping_of_view", "toggle_wireframe"}; - break; - case ToolType::SMART_FILL: - // TODO: - break; - case ToolType::GAP_FILL: - tip_items = {"gap_area", "toggle_wireframe"}; - break; - default: - break; + case ToolType::BRUSH: return m_shortcuts_brush; + + case ToolType::BUCKET_FILL: + case ToolType::SMART_FILL: return m_shortcuts_bucket_fill; + + case ToolType::GAP_FILL: return m_shortcuts_gap_fill; + + default: return {}; } - for (const auto &t : tip_items) draw_text_with_caption(m_desc.at(t + "_caption") + ": ", m_desc.at(t)); - ImGui::EndTooltip(); - } - ImGui::PopStyleVar(2); + }; + + GLGizmoUtils::render_tooltip_button(m_imgui, m_parent, get_shortcuts(), x, y); } void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bottom_limit) @@ -678,8 +655,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott ImGui::Separator(); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f)); - float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y; - show_tooltip_information(caption_max, x, get_cur_y); + render_tooltip_button(x, y); float f_scale =m_parent.get_gizmos_manager().get_layout_scale(); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f * f_scale)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp index f9bcfdee12..756ada7670 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp @@ -94,7 +94,7 @@ protected: void on_render_input_window(float x, float y, float bottom_limit) override; std::string on_get_name() const override; - void show_tooltip_information(float caption_max, float x, float y); + void render_tooltip_button(float x, float y); bool on_is_selectable() const override; bool on_is_activable() const override; @@ -149,6 +149,13 @@ private: // This map holds all translated description texts, so they can be easily referenced during layout calculations // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. std::map m_desc; + + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts_brush; + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts_bucket_fill; + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts_gap_fill; }; } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp index e68d71513a..7ebb794bef 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp @@ -10,6 +10,7 @@ #include "slic3r/GUI/GUI_ObjectList.hpp" #include "slic3r/GUI/GUI.hpp" #include "slic3r/Utils/UndoRedo.hpp" +#include "GLGizmoUtils.hpp" #include @@ -29,28 +30,29 @@ bool GLGizmoSeam::on_init() { m_shortcut_key = WXK_CONTROL_P; - // FIXME: maybe should be using GUI::shortkey_ctrl_prefix() or equivalent? - const wxString ctrl = _L("Ctrl+"); - // FIXME: maybe should be using GUI::shortkey_alt_prefix() or equivalent? - const wxString alt = _L("Alt+"); - const wxString shift = _L("Shift+"); + const wxString ctrl = GUI::shortkey_ctrl_prefix(); + const wxString alt = GUI::shortkey_alt_prefix(); + const wxString shift = GUI::shortkey_shift_prefix(); - m_desc["clipping_of_view_caption"] = alt + _L("Mouse wheel"); m_desc["clipping_of_view"] = _L("Section view"); m_desc["reset_direction"] = _L("Reset direction"); - m_desc["cursor_size_caption"] = ctrl + _L("Mouse wheel"); - m_desc["cursor_size"] = _L("Brush size"); - m_desc["cursor_type"] = _L("Brush shape"); - m_desc["enforce_caption"] = _L("Left mouse button"); + m_desc["cursor_size"] = _L("Pen size"); + m_desc["tool_type"] = _L("Tool type"); m_desc["enforce"] = _L("Enforce seam"); - m_desc["block_caption"] = _L("Right mouse button"); m_desc["block"] = _L("Block seam"); - m_desc["remove_caption"] = shift + _L("Left mouse button"); m_desc["remove"] = _L("Erase"); m_desc["remove_all"] = _L("Erase all painting"); m_desc["circle"] = _L("Circle"); m_desc["sphere"] = _L("Sphere"); + m_shortcuts = { + {_L("Left mouse button"), m_desc["enforce"]}, + {_L("Right mouse button"), m_desc["block"]}, + {shift + _L("Left mouse button"), m_desc["remove"]}, + {ctrl + _L("Mouse wheel"), m_desc["cursor_size"]}, + {alt + _L("Mouse wheel"), m_desc["clipping_of_view"]} + }; + return true; } @@ -101,36 +103,6 @@ bool GLGizmoSeam::on_key_down_select_tool_type(int keyCode) { return true; } -void GLGizmoSeam::show_tooltip_information(float caption_max, float x, float y) -{ - ImTextureID normal_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP); - ImTextureID hover_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER); - - caption_max += m_imgui->calc_text_size(std::string_view{": "}).x + 35.f; - - float scale = m_parent.get_scale(); - #ifdef WIN32 - int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); - scale *= (float) dpi / (float) DPI_DEFAULT; - #endif // WIN32 - ImVec2 button_size = ImVec2(25 * scale, 25 * scale); // ORCA: Use exact resolution will prevent blur on icon - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, 0}); // ORCA: Dont add padding - ImGui::ImageButton3(normal_id, hover_id, button_size); - - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip2(ImVec2(x, y)); - auto draw_text_with_caption = [this, &caption_max](const wxString &caption, const wxString &text) { - m_imgui->text_colored(ImGuiWrapper::COL_ACTIVE, caption); - ImGui::SameLine(caption_max); - m_imgui->text_colored(ImGuiWrapper::COL_WINDOW_BG, text); - }; - - for (const auto &t : std::array{"enforce", "block", "remove", "cursor_size", "clipping_of_view"}) draw_text_with_caption(m_desc.at(t + "_caption") + ": ", m_desc.at(t)); - ImGui::EndTooltip(); - } - ImGui::PopStyleVar(2); -} void GLGizmoSeam::tool_changed(wchar_t old_tool, wchar_t new_tool) { @@ -189,7 +161,7 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit) const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; ImGui::AlignTextToFramePadding(); - m_imgui->text(m_desc.at("cursor_type")); + m_imgui->text(m_desc.at("tool_type")); std::array tool_ids = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon }; std::array icons; if (m_is_dark_mode) @@ -283,8 +255,7 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit) ImGui::Separator(); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f)); - float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y; - show_tooltip_information(caption_max, x, get_cur_y); + GLGizmoUtils::render_tooltip_button(m_imgui, m_parent, m_shortcuts, x, y); float f_scale =m_parent.get_gizmos_manager().get_layout_scale(); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f * f_scale)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSeam.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSeam.hpp index 73242d470e..adb5acb272 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSeam.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSeam.hpp @@ -24,8 +24,6 @@ protected: std::string on_get_name() const override; PainterGizmoType get_painter_type() const override; - void show_tooltip_information(float caption_max, float x, float y); - void tool_changed(wchar_t old_tool, wchar_t new_tool); wxString handle_snapshot_action_name(bool shift_down, Button button_down) const override; @@ -51,6 +49,9 @@ private: // This map holds all translated description texts, so they can be easily referenced during layout calculations // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. std::map m_desc; + + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts; }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoUtils.cpp b/src/slic3r/GUI/Gizmos/GLGizmoUtils.cpp new file mode 100644 index 0000000000..3566bccf12 --- /dev/null +++ b/src/slic3r/GUI/Gizmos/GLGizmoUtils.cpp @@ -0,0 +1,75 @@ +#include "GLGizmoUtils.hpp" +#include "slic3r/GUI/ImGuiWrapper.hpp" +#include "GLGizmosManager.hpp" +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/GLCanvas3D.hpp" +#include +#include + +#ifdef WIN32 +#include +#endif + +/* + GizmoUI Footer Structure: + + ~ Content ~ + ---------------------------------------- + [Button1] [Button2] + ---------------------------------------- + [?] [Reset] [Confirm] [Cancel] + ---------------------------------------- + ~ Warnings ~ + + + Additional details: + - [Confirm], [Cancel], [Done], ... are buttons that close the Tool Dialog + - [Reset], [Button1], ... are buttons that do not! + - Non-consequential buttons like [Cancel] and [Done] are always the right-most buttons + - Multiple warnings can show, but should only have one ImGui::Separator above + - If no warnings is shown, dont render the ImGui::Separator + +*/ + +namespace Slic3r::GUI::GLGizmoUtils { + +void render_tooltip_button( + ImGuiWrapper* imgui_wrapper, const GLCanvas3D& canvas, const std::vector>& shortcuts, float x, float y) +{ + float caption_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y; + float caption_x_max = 0.f; + for (const auto& item : shortcuts) { + caption_x_max = std::max(caption_x_max, imgui_wrapper->calc_text_size(item.first).x); + } + caption_x_max += imgui_wrapper->calc_text_size(": "sv).x + 35.f; + + auto& gizmos_manager = canvas.get_gizmos_manager(); + ImTextureID normal_id = gizmos_manager.get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP); + ImTextureID hover_id = gizmos_manager.get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER); + + float scale = canvas.get_scale(); +#ifdef WIN32 + int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); + scale *= (float) dpi / (float) DPI_DEFAULT; +#endif + + ImVec2 button_size = ImVec2(25 * scale, 25 * scale); + + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, 0}); + + ImGui::ImageButton3(normal_id, hover_id, button_size); + + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip2(ImVec2(x, caption_y)); + for (const auto& item : shortcuts) { + imgui_wrapper->text_colored(ImGuiWrapper::COL_ACTIVE, item.first + ": "); + ImGui::SameLine(caption_x_max); + imgui_wrapper->text_colored(ImGuiWrapper::COL_WINDOW_BG, item.second); + } + ImGui::EndTooltip(); + } + ImGui::PopStyleVar(2); +} + +} // namespace Slic3r::GUI::GLGizmoUtils \ No newline at end of file diff --git a/src/slic3r/GUI/Gizmos/GLGizmoUtils.hpp b/src/slic3r/GUI/Gizmos/GLGizmoUtils.hpp new file mode 100644 index 0000000000..acdff4ddfe --- /dev/null +++ b/src/slic3r/GUI/Gizmos/GLGizmoUtils.hpp @@ -0,0 +1,25 @@ +#ifndef GL_GIZMO_UTIL_HPP +#define GL_GIZMO_UTIL_HPP + +#include +#include +#include +#include +#include "imgui.h" + +namespace Slic3r::GUI { + +// Forward declaration +class ImGuiWrapper; +class GLCanvas3D; + +namespace GLGizmoUtils { + +// Renders a tooltip button using the provided shortcuts +void render_tooltip_button( + ImGuiWrapper* imgui_wrapper, const GLCanvas3D& canvas, const std::vector>& shortcuts, float x, float y); + +} // namespace GLGizmoUtils +} // namespace Slic3r::GUI + +#endif // GL_GIZMO_UTIL_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp index 457274e32f..c40bc7d0ad 100644 --- a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp +++ b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp @@ -15,6 +15,7 @@ #include "slic3r/GUI/Selection.hpp" #include "slic3r/GUI/Plater.hpp" #include "slic3r/GUI/MainFrame.hpp" +#include "GLGizmoUtils.hpp" #include @@ -55,24 +56,22 @@ GizmoObjectManipulation::GizmoObjectManipulation(GLCanvas3D& glcanvas) m_imperial_units = wxGetApp().app_config->get("use_inches") == "1"; m_new_unit_string = m_imperial_units ? L("in") : L("mm"); - const wxString shift = _L("Shift+"); + const wxString shift = GUI::shortkey_shift_prefix(); const wxString alt = GUI::shortkey_alt_prefix(); const wxString ctrl = GUI::shortkey_ctrl_prefix(); - m_desc_move["part_selection_caption"] = alt + _L("Left mouse button"); - m_desc_move["part_selection"] = _L("Part selection"); - m_desc_move["snap_step_caption"] = shift + _L("Left mouse button"); - m_desc_move["snap_step"] = _L("Fixed step drag"); + m_shortcuts_move = { + {alt + _L("Left mouse button"), _L("Part selection")}, + {shift + _L("Left mouse button"), _L("Fixed step drag")} + }; - m_desc_rotate["part_selection_caption"] = alt + _L("Left mouse button"); - m_desc_rotate["part_selection"] = _L("Part selection"); + m_shortcuts_rotate = { + {alt + _L("Left mouse button"), _L("Part selection")}}; - m_desc_scale["part_selection_caption"] = alt + _L("Left mouse button"); - m_desc_scale["part_selection"] = _L("Part selection"); - m_desc_scale["snap_step_caption"] = shift + _L("Left mouse button"); - m_desc_scale["snap_step"] = _L("Fixed step drag"); - m_desc_scale["single_sided_caption"] = ctrl + _L("Left mouse button"); - m_desc_scale["single_sided"] = _L("Single sided scaling"); + m_shortcuts_scale = { + {alt + _L("Left mouse button"), _L("Part selection")}, + {shift + _L("Left mouse button"), _L("Fixed step drag")}, + {ctrl + _L("Left mouse button"), _L("Single sided scaling")}}; } void GizmoObjectManipulation::UpdateAndShow(const bool show) @@ -719,102 +718,6 @@ bool GizmoObjectManipulation::reset_zero_button(ImGuiWrapper *imgui_wrapper, flo return result; } -void GizmoObjectManipulation::show_move_tooltip_information(ImGuiWrapper *imgui_wrapper, float caption_max, float x, float y) -{ - ImTextureID normal_id = m_glcanvas.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP); - ImTextureID hover_id = m_glcanvas.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER); - - caption_max += imgui_wrapper->calc_text_size(": "sv).x + 35.f; - - float scale = m_glcanvas.get_scale(); - #ifdef WIN32 - int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); - scale *= (float) dpi / (float) DPI_DEFAULT; - #endif // WIN32 - ImVec2 button_size = ImVec2(25 * scale, 25 * scale); // ORCA: Use exact resolution will prevent blur on icon - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, ImGui::GetStyle().FramePadding.y}); - ImGui::ImageButton3(normal_id, hover_id, button_size); - - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip2(ImVec2(x, y)); - auto draw_text_with_caption = [this, &imgui_wrapper,& caption_max](const wxString &caption, const wxString &text) { - imgui_wrapper->text_colored(ImGuiWrapper::COL_ACTIVE, caption); - ImGui::SameLine(caption_max); - imgui_wrapper->text_colored(ImGuiWrapper::COL_WINDOW_BG, text); - }; - - for (const auto &t : std::array{"part_selection", "snap_step"}) - draw_text_with_caption(m_desc_move.at(t + "_caption") + ": ", m_desc_move.at(t)); - ImGui::EndTooltip(); - } - ImGui::PopStyleVar(2); -} - -void GizmoObjectManipulation::show_rotate_tooltip_information(ImGuiWrapper *imgui_wrapper, float caption_max, float x, float y) -{ - ImTextureID normal_id = m_glcanvas.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP); - ImTextureID hover_id = m_glcanvas.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER); - - caption_max += imgui_wrapper->calc_text_size(": "sv).x + 35.f; - - float scale = m_glcanvas.get_scale(); - #ifdef WIN32 - int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); - scale *= (float) dpi / (float) DPI_DEFAULT; - #endif // WIN32 - ImVec2 button_size = ImVec2(25 * scale, 25 * scale); // ORCA: Use exact resolution will prevent blur on icon - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, ImGui::GetStyle().FramePadding.y}); - ImGui::ImageButton3(normal_id, hover_id, button_size); - - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip2(ImVec2(x, y)); - auto draw_text_with_caption = [this, &imgui_wrapper, &caption_max](const wxString &caption, const wxString &text) { - imgui_wrapper->text_colored(ImGuiWrapper::COL_ACTIVE, caption); - ImGui::SameLine(caption_max); - imgui_wrapper->text_colored(ImGuiWrapper::COL_WINDOW_BG, text); - }; - - for (const auto &t : std::array{"part_selection"}) - draw_text_with_caption(m_desc_rotate.at(t + "_caption") + ": ", m_desc_rotate.at(t)); - ImGui::EndTooltip(); - } - ImGui::PopStyleVar(2); -} - -void GizmoObjectManipulation::show_scale_tooltip_information(ImGuiWrapper *imgui_wrapper, float caption_max, float x, float y) -{ - ImTextureID normal_id = m_glcanvas.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP); - ImTextureID hover_id = m_glcanvas.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER); - - caption_max += imgui_wrapper->calc_text_size(": "sv).x + 35.f; - - float scale = m_glcanvas.get_scale(); - #ifdef WIN32 - int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); - scale *= (float) dpi / (float) DPI_DEFAULT; - #endif // WIN32 - ImVec2 button_size = ImVec2(25 * scale, 25 * scale); // ORCA: Use exact resolution will prevent blur on icon - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, ImGui::GetStyle().FramePadding.y}); - ImGui::ImageButton3(normal_id, hover_id, button_size); - - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip2(ImVec2(x, y)); - auto draw_text_with_caption = [this, &imgui_wrapper, &caption_max](const wxString &caption, const wxString &text) { - imgui_wrapper->text_colored(ImGuiWrapper::COL_ACTIVE, caption); - ImGui::SameLine(caption_max); - imgui_wrapper->text_colored(ImGuiWrapper::COL_WINDOW_BG, text); - }; - - for (const auto &t : std::array{"part_selection", "snap_step", "single_sided"}) - draw_text_with_caption(m_desc_scale.at(t + "_caption") + ": ", m_desc_scale.at(t)); - ImGui::EndTooltip(); - } - ImGui::PopStyleVar(2); -} - void GizmoObjectManipulation::set_init_rotation(const Geometry::Transformation &value) { m_init_rotation_scale_tran = value.get_matrix_no_offset(); m_init_rotation = value.get_rotation(); @@ -957,14 +860,9 @@ void GizmoObjectManipulation::do_render_move_window(ImGuiWrapper *imgui_wrapper, } } if (!focued_on_text) m_glcanvas.handle_sidebar_focus_event("", false); - float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y; - float tip_caption_max = 0.f; - float total_text_max = 0.f; - for (const auto &t : std::array{"part_selection", "snap_step"}) { - tip_caption_max = std::max(tip_caption_max, imgui_wrapper->calc_text_size(m_desc_move[t + "_caption"]).x); - total_text_max = std::max(total_text_max, imgui_wrapper->calc_text_size(m_desc_move[t]).x); - } - show_move_tooltip_information(imgui_wrapper, tip_caption_max, x, get_cur_y); + + GLGizmoUtils::render_tooltip_button(imgui_wrapper, m_glcanvas, m_shortcuts_move, x, y); + m_last_active_item = current_active_id; last_move_input_window_width = ImGui::GetWindowWidth(); imgui_wrapper->end(); @@ -1154,14 +1052,8 @@ void GizmoObjectManipulation::do_render_rotate_window(ImGuiWrapper *imgui_wrappe if (!focued_on_text && !absolute_focued_on_text) m_glcanvas.handle_sidebar_focus_event("", false); - float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y; - float tip_caption_max = 0.f; - float total_text_max = 0.f; - for (const auto &t : std::array{"part_selection"}) { - tip_caption_max = std::max(tip_caption_max, imgui_wrapper->calc_text_size(m_desc_move[t + "_caption"]).x); - total_text_max = std::max(total_text_max, imgui_wrapper->calc_text_size(m_desc_move[t]).x); - } - show_rotate_tooltip_information(imgui_wrapper, tip_caption_max, x, get_cur_y); + GLGizmoUtils::render_tooltip_button(imgui_wrapper, m_glcanvas, m_shortcuts_rotate, x, y); + m_last_active_item = current_active_id; last_rotate_input_window_width = ImGui::GetWindowWidth(); imgui_wrapper->end(); @@ -1394,14 +1286,9 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w } if (!focued_on_text) m_glcanvas.handle_sidebar_focus_event("", false); - float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y; - float tip_caption_max = 0.f; - float total_text_max = 0.f; - for (const auto &t : std::array{"part_selection", "snap_step", "single_sided"}) { - tip_caption_max = std::max(tip_caption_max, imgui_wrapper->calc_text_size(m_desc_scale[t + "_caption"]).x); - total_text_max = std::max(total_text_max, imgui_wrapper->calc_text_size(m_desc_scale[t]).x); - } - show_scale_tooltip_information(imgui_wrapper, tip_caption_max, x, get_cur_y); + + GLGizmoUtils::render_tooltip_button(imgui_wrapper, m_glcanvas, m_shortcuts_scale, x, y); + m_last_active_item = current_active_id; last_scale_input_window_width = ImGui::GetWindowWidth(); diff --git a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp index 2f8b03c160..2f8b532733 100644 --- a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp +++ b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp @@ -143,9 +143,6 @@ public: bool reset_zero_button(ImGuiWrapper *imgui_wrapper, float caption_max, float unit_size, float space_size, float end_text_size); bool bbl_checkbox(const wxString &label, bool &value); - void show_move_tooltip_information(ImGuiWrapper *imgui_wrapper, float caption_max, float x, float y); - void show_rotate_tooltip_information(ImGuiWrapper *imgui_wrapper, float caption_max, float x, float y); - void show_scale_tooltip_information(ImGuiWrapper *imgui_wrapper, float caption_max, float x, float y); void set_init_rotation(const Geometry::Transformation &value); private: @@ -171,9 +168,14 @@ private: GLCanvas3D& m_glcanvas; unsigned int m_last_active_item { 0 }; - std::map m_desc_move; - std::map m_desc_rotate; - std::map m_desc_scale; + + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts_move; + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts_rotate; + // Contains all shortcuts in the format of {shortcut, description}, e.g. {alt + _L("Left mouse button"), _L("Part_selection")} + std::vector> m_shortcuts_scale; + Vec3d m_init_rotation; Transform3d m_init_rotation_scale_tran; };