Improve layout of transform gizmos (#14410)

* init

* add tooltips
This commit is contained in:
yw4z
2026-07-06 14:34:36 +03:00
committed by GitHub
parent fd80ded5a8
commit cc89416055
2 changed files with 87 additions and 61 deletions

View File

@@ -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<std::string> &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<std::string> modes = {_u8L("World coordinates"), _u8L("Object coordinates")};//_u8L("Part coordinates")
std::vector<std::string> 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<std::string> modes = {_u8L("World coordinates"), _u8L("Object coordinates"), _u8L("Part coordinates")};
std::vector<std::string> 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;

View File

@@ -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);