From cc894160558777d33e4db81b6ddeed5fed3e8d0d Mon Sep 17 00:00:00 2001 From: yw4z Date: Mon, 6 Jul 2026 14:34:36 +0300 Subject: [PATCH] Improve layout of transform gizmos (#14410) * init * add tooltips --- .../GUI/Gizmos/GizmoObjectManipulation.cpp | 144 +++++++++++------- .../GUI/Gizmos/GizmoObjectManipulation.hpp | 4 +- 2 files changed, 87 insertions(+), 61 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp index 6dcf289789..8680ee13a3 100644 --- a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp +++ b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp @@ -504,9 +504,12 @@ void GizmoObjectManipulation::on_change(const std::string &opt_key, int axis, do bool GizmoObjectManipulation::render_combo( ImGuiWrapper *imgui_wrapper, const std::string &label, const std::vector &lines, size_t &selection_idx, float label_width, float item_width) { - ImGui::AlignTextToFramePadding(); - imgui_wrapper->text(label); - ImGui::SameLine(label_width); + if(!label.empty()){ + ImGui::AlignTextToFramePadding(); + imgui_wrapper->text(label); + ImGui::SameLine(label_width); + } + ImGui::PushItemWidth(item_width); size_t selection_out = selection_idx; @@ -642,8 +645,9 @@ static const char* label_scale_values[2][3] = { { "##size_x", "##size_y", "##size_z"} }; -bool GizmoObjectManipulation::reset_button(ImGuiWrapper *imgui_wrapper, float caption_max, float unit_size, float space_size, float end_text_size) +bool GizmoObjectManipulation::reset_button(ImGuiWrapper *imgui_wrapper, bool enabled) { + imgui_wrapper->disabled_begin(!enabled); bool pressed = false; ImTextureID normal_id = m_glcanvas.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_RESET); ImTextureID hover_id = m_glcanvas.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_RESET_HOVER); @@ -657,14 +661,17 @@ bool GizmoObjectManipulation::reset_button(ImGuiWrapper *imgui_wrapper, float ca ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - pressed = ImGui::ImageButton3(normal_id, hover_id, button_size); + pressed = ImGui::ImageButton3(normal_id, hover_id, button_size, {0,0}, {1,1}, -1, {0,0,0,0}, {1,1,1, enabled ? 1.f : 0.f}); // ORCA make icon invisible to prevent changes on layout ImGui::PopStyleVar(1); + + imgui_wrapper->disabled_end(); return pressed; } -bool GizmoObjectManipulation::reset_zero_button(ImGuiWrapper *imgui_wrapper, float caption_max, float unit_size, float space_size, float end_text_size) +bool GizmoObjectManipulation::reset_zero_button(ImGuiWrapper *imgui_wrapper, bool enabled) { + imgui_wrapper->disabled_begin(!enabled); bool pressed = false; ImTextureID normal_id = m_glcanvas.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_RESET_ZERO); ImTextureID hover_id = m_glcanvas.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_RESET_ZERO_HOVER); @@ -678,9 +685,11 @@ bool GizmoObjectManipulation::reset_zero_button(ImGuiWrapper *imgui_wrapper, flo ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - pressed = ImGui::ImageButton3(normal_id, hover_id, button_size); + pressed = ImGui::ImageButton3(normal_id, hover_id, button_size, {0,0}, {1,1}, -1, {0,0,0,0}, {1,1,1, enabled ? 1.f : 0.f}); // ORCA make icon invisible to prevent changes on layout ImGui::PopStyleVar(1); + + imgui_wrapper->disabled_end(); return pressed; } @@ -765,8 +774,17 @@ void GizmoObjectManipulation::do_render_move_window(ImGuiWrapper *imgui_wrapper, }; float space_size = imgui_wrapper->get_style_scaling() * 8; - float position_size = imgui_wrapper->calc_text_size(_L("Position")).x + space_size; - float caption_max = imgui_wrapper->calc_text_size(_L("Object coordinates")).x + 2 * space_size; + //ORCA + float coord_combo_width = std::max({ + imgui_wrapper->calc_text_size(_L("World")).x, + imgui_wrapper->calc_text_size(_L("Object")).x, + imgui_wrapper->calc_text_size(_L("Part")).x + }) + imgui_wrapper->calc_text_size("xxx"sv).x + imgui_wrapper->scaled(3.5f); + float label_max = std::max({ + imgui_wrapper->calc_text_size(_L("Position")).x, + imgui_wrapper->calc_text_size(_L("Relative")).x + }); + float caption_max = std::max(label_max, coord_combo_width - 3 * space_size); float end_text_size = imgui_wrapper->calc_text_size(this->m_new_unit_string).x; // position @@ -786,7 +804,7 @@ void GizmoObjectManipulation::do_render_move_window(ImGuiWrapper *imgui_wrapper, unsigned int current_active_id = ImGui::GetActiveID(); Selection & selection = m_glcanvas.get_selection(); - std::vector modes = {_u8L("World coordinates"), _u8L("Object coordinates")};//_u8L("Part coordinates") + std::vector modes = {_u8L("World"), _u8L("Object")};//_u8L("Part") // ORCA use shorter terms to make UI more compact if (selection.is_multiple_full_object() || selection.is_wipe_tower()) { modes.pop_back(); } @@ -796,16 +814,17 @@ void GizmoObjectManipulation::do_render_move_window(ImGuiWrapper *imgui_wrapper, selection_idx = 0; } - float caption_cs_size = imgui_wrapper->calc_text_size(""sv).x; - float caption_size = caption_cs_size + 2 * space_size; - float combox_content_size = imgui_wrapper->calc_text_size(_L("Object coordinates")).x * 1.2 + imgui_wrapper->calc_text_size("xxx"sv).x + imgui_wrapper->scaled(3); ImGuiWrapper::push_combo_style(m_glcanvas.get_scale()); bool combox_changed = false; - if (render_combo(imgui_wrapper, "", modes, selection_idx, caption_size, combox_content_size)) { + if (render_combo(imgui_wrapper, "", modes, selection_idx, 0, coord_combo_width)) { combox_changed = true; } + if (ImGui::IsItemHovered()) { + auto tooltip_str = _L("Coordinate system used for transform actions."); + imgui_wrapper->tooltip(tooltip_str, imgui_wrapper->calc_text_size(tooltip_str).x + 3 * space_size); + } ImGuiWrapper::pop_combo_style(); - caption_max = combox_content_size - 4 * space_size; + // ORCA use TextColored to match axes color float offset_to_center = (unit_size - ImGui::CalcTextSize("O").x) / 2; ImGui::SameLine(caption_max + index * space_size + offset_to_center); @@ -819,7 +838,7 @@ void GizmoObjectManipulation::do_render_move_window(ImGuiWrapper *imgui_wrapper, index_unit = 1; ImGui::AlignTextToFramePadding(); if (selection.is_single_full_instance() && is_instance_coordinates()) { - imgui_wrapper->text(_L("Translate(Relative)")); + imgui_wrapper->text(_L("Relative")); // ORCA } else { imgui_wrapper->text(_L("Position")); @@ -924,10 +943,15 @@ void GizmoObjectManipulation::do_render_rotate_window(ImGuiWrapper *imgui_wrappe }; float space_size = imgui_wrapper->get_style_scaling() * 8; - float position_size = imgui_wrapper->calc_text_size(_L("Rotate (relative)")).x + space_size; - float World_size = imgui_wrapper->calc_text_size(_L("World coordinates")).x + space_size; - float caption_max = std::max(position_size, World_size) + 2 * space_size; - float end_text_size = imgui_wrapper->calc_text_size(this->m_new_unit_string).x; + // ORCA + float caption_max = std::max({ + imgui_wrapper->calc_text_size(_L("Relative")).x, + imgui_wrapper->calc_text_size(_L("Absolute")).x, + imgui_wrapper->calc_text_size(_L("World")).x + //imgui_wrapper->calc_text_size(_L("Object")).x, + //imgui_wrapper->calc_text_size(_L("Part")).x + }) + 3.f * space_size; + float end_text_size = ImGui::CalcTextSize("°").x; // ORCA rotate gizmo not uses mm or inch // position Vec3d original_position; @@ -946,7 +970,11 @@ void GizmoObjectManipulation::do_render_rotate_window(ImGuiWrapper *imgui_wrappe ImGui::AlignTextToFramePadding(); unsigned int current_active_id = ImGui::GetActiveID(); ImGui::PushItemWidth(caption_max); - imgui_wrapper->text(_L("World coordinates")); + imgui_wrapper->text(_L("World")); // ORCA + if (ImGui::IsItemHovered()) { + auto tooltip_str = _L("Coordinate system used for transform actions."); + imgui_wrapper->tooltip(tooltip_str, imgui_wrapper->calc_text_size(tooltip_str).x + 3 * space_size); + } // ORCA use TextColored to match axes color float offset_to_center = (unit_size - ImGui::CalcTextSize("O").x) / 2; ImGui::SameLine(caption_max + index * space_size + offset_to_center); @@ -962,7 +990,7 @@ void GizmoObjectManipulation::do_render_rotate_window(ImGuiWrapper *imgui_wrappe // ImGui::PushItemWidth(unit_size * 2); bool is_relative_input = false; ImGui::AlignTextToFramePadding(); - imgui_wrapper->text(_L("Rotate (relative)")); + imgui_wrapper->text(_L("Relative")); // ORCA ImGui::SameLine(caption_max + index * space_size); ImGui::PushItemWidth(unit_size); if (ImGui::BBLInputDouble(label_values[1][0], &rotation[0], 0.0f, 0.0f, "%.2f")) { @@ -991,19 +1019,14 @@ void GizmoObjectManipulation::do_render_rotate_window(ImGuiWrapper *imgui_wrappe } } - if (m_show_clear_rotation) { - ImGui::SameLine(caption_max + 3 * unit_size + 4 * space_size + end_text_size); - if (reset_button(imgui_wrapper, caption_max, unit_size, space_size, end_text_size)) { - reset_rotation_value(true); - } - if (ImGui::IsItemHovered()) { - float tooltip_size = imgui_wrapper->calc_text_size(_L("Reset current rotation to the value when open the rotation tool.")).x + 3 * space_size; - imgui_wrapper->tooltip(_u8L("Reset current rotation to the value when open the rotation tool."), tooltip_size); - } - } else { - ImGui::SameLine(caption_max + 3 * unit_size + 5 * space_size + end_text_size); - ImGui::InvisibleButton("", ImVec2(ImGui::GetFontSize(), ImGui::GetFontSize())); + ImGui::SameLine(caption_max + index_unit * unit_size + (++index) * space_size + end_text_size); + if (reset_button(imgui_wrapper, m_show_clear_rotation)) // ORCA reserve icon space to prevent changes on layout + reset_rotation_value(true); + if (m_show_clear_rotation && ImGui::IsItemHovered()) { + float tooltip_size = imgui_wrapper->calc_text_size(_L("Reset current rotation to the value when open the rotation tool.")).x + 3 * space_size; + imgui_wrapper->tooltip(_u8L("Reset current rotation to the value when open the rotation tool."), tooltip_size); } + // send focus to m_glcanvas bool focued_on_text = false; for (int j = 0; j < 3; j++) { @@ -1018,7 +1041,7 @@ void GizmoObjectManipulation::do_render_rotate_window(ImGuiWrapper *imgui_wrappe index = 1; index_unit = 1; ImGui::AlignTextToFramePadding(); - imgui_wrapper->text(_L("Rotate (absolute)")); + imgui_wrapper->text(_L("Absolute")); ImGui::SameLine(caption_max + index * space_size); ImGui::PushItemWidth(unit_size); bool is_absolute_input = false; @@ -1048,13 +1071,12 @@ void GizmoObjectManipulation::do_render_rotate_window(ImGuiWrapper *imgui_wrappe } } - if (m_show_reset_0_rotation) { - ImGui::SameLine(caption_max + 3 * unit_size + 4 * space_size + end_text_size); - if (reset_zero_button(imgui_wrapper, caption_max, unit_size, space_size, end_text_size)) { reset_rotation_value(false); } - if (ImGui::IsItemHovered()) { - float tooltip_size = imgui_wrapper->calc_text_size(_L("Reset current rotation to real zeros.")).x + 3 * space_size; - imgui_wrapper->tooltip(_L("Reset current rotation to real zeros."), tooltip_size); - } + ImGui::SameLine(caption_max + index_unit * unit_size + (++index) * space_size + end_text_size); + if (reset_zero_button(imgui_wrapper, m_show_reset_0_rotation)) // ORCA reserve icon space to prevent changes on layout + reset_rotation_value(false); + if (m_show_reset_0_rotation && ImGui::IsItemHovered()) { + float tooltip_size = imgui_wrapper->calc_text_size(_L("Reset current rotation to real zeros.")).x + 3 * space_size; + imgui_wrapper->tooltip(_L("Reset current rotation to real zeros."), tooltip_size); } // send focus to m_glcanvas bool absolute_focued_on_text = false; @@ -1132,8 +1154,17 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w }; float space_size = imgui_wrapper->get_style_scaling() * 8; - float scale_size = imgui_wrapper->calc_text_size(_L("Scale")).x + space_size; - float caption_max = imgui_wrapper->calc_text_size(_L("Object coordinates")).x + 2 * space_size; + // ORCA + float coord_combo_width = std::max({ + imgui_wrapper->calc_text_size(_L("World")).x, + imgui_wrapper->calc_text_size(_L("Object")).x, + imgui_wrapper->calc_text_size(_L("Part")).x + }) + imgui_wrapper->calc_text_size("xxx"sv).x + imgui_wrapper->scaled(3.5f); + float label_max = std::max({ + imgui_wrapper->calc_text_size(_L("Scale")).x, + imgui_wrapper->calc_text_size(_L("Size")).x + }); + float caption_max = std::max(label_max, coord_combo_width - 3 * space_size); float end_text_size = imgui_wrapper->calc_text_size(this->m_new_unit_string).x; ImGui::AlignTextToFramePadding(); unsigned int current_active_id = ImGui::GetActiveID(); @@ -1150,7 +1181,7 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w int index_unit = 1; Selection & selection = m_glcanvas.get_selection(); - std::vector modes = {_u8L("World coordinates"), _u8L("Object coordinates"), _u8L("Part coordinates")}; + std::vector modes = {_u8L("World"), _u8L("Object"), _u8L("Part")}; // ORCA use shorter terms to make UI more compact if (selection.is_single_full_object()) { modes.pop_back(); } if (selection.is_multiple_full_object()) { modes.pop_back(); @@ -1162,17 +1193,17 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w selection_idx = 0; } - float caption_cs_size = imgui_wrapper->calc_text_size(""sv).x; - float caption_size = caption_cs_size + 2 * space_size; - float combox_content_size = imgui_wrapper->calc_text_size(_L("Object coordinates")).x * 1.2 + imgui_wrapper->calc_text_size("xxx"sv).x + imgui_wrapper->scaled(3); ImGuiWrapper::push_combo_style(m_glcanvas.get_scale()); bool combox_changed = false; - if (render_combo(imgui_wrapper, "", modes, selection_idx, caption_size, combox_content_size)) { + if (render_combo(imgui_wrapper, "", modes, selection_idx, 0, coord_combo_width)) { combox_changed = true; } + if (ImGui::IsItemHovered()) { + auto tooltip_str = _L("Coordinate system used for transform actions."); + imgui_wrapper->tooltip(tooltip_str, imgui_wrapper->calc_text_size(tooltip_str).x + 3 * space_size); + } ImGuiWrapper::pop_combo_style(); - caption_max = combox_content_size - 4 * space_size; - //ImGui::Dummy(ImVec2(caption_max, -1)); + // ORCA use TextColored to match axes color float offset_to_center = (unit_size - ImGui::CalcTextSize("O").x) / 2; ImGui::SameLine(caption_max + space_size + offset_to_center); @@ -1203,14 +1234,9 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w m_buffered_scale = scale; } - if (m_show_clear_scale) { - ImGui::SameLine(caption_max + 3 * unit_size + 4 * space_size + end_text_size); - if (reset_button(imgui_wrapper, caption_max, unit_size, space_size, end_text_size)) - reset_scale_value(); - } else { - ImGui::SameLine(caption_max + 3 * unit_size + 5 * space_size + end_text_size); - ImGui::InvisibleButton("", ImVec2(ImGui::GetFontSize(), ImGui::GetFontSize())); - } + ImGui::SameLine(caption_max + 3 * unit_size + 4 * space_size + end_text_size); + if (reset_button(imgui_wrapper, m_show_clear_scale)) + reset_scale_value(); //Size Vec3d original_size; diff --git a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp index 2f8b532733..84ff8ebe62 100644 --- a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp +++ b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp @@ -139,8 +139,8 @@ public: void do_render_rotate_window(ImGuiWrapper *imgui_wrapper, std::string window_name, float x, float y, float bottom_limit); void do_render_scale_input_window(ImGuiWrapper* imgui_wrapper, std::string window_name, float x, float y, float bottom_limit); float max_unit_size(int number, Vec3d &vec1, Vec3d &vec2,std::string str); - bool reset_button(ImGuiWrapper *imgui_wrapper, float caption_max, float unit_size, float space_size, float end_text_size); - bool reset_zero_button(ImGuiWrapper *imgui_wrapper, float caption_max, float unit_size, float space_size, float end_text_size); + bool reset_button(ImGuiWrapper *imgui_wrapper, bool enabled); + bool reset_zero_button(ImGuiWrapper *imgui_wrapper, bool enabled); bool bbl_checkbox(const wxString &label, bool &value); void set_init_rotation(const Geometry::Transformation &value);