From 9af733d6ac7648b4de4ddbd240610d8c01b12a22 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 23 May 2023 14:20:55 +0200 Subject: [PATCH] ImGuiWrapper::combo improvements. + Set label for ImGui::BeginCombo as ("##" + label).c_str() to avoid control conflicts, when several combos are placed in one imgui window. + Return TRUE value only when selection was changed + Added label_width and item_width input parameters to have possibility set a width to the label text and combo control. + GizmoCut: Use ImGuiWrapper::combo to render comboboxes --- src/slic3r/GUI/GCodeViewer.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 55 ++++++---------------------- src/slic3r/GUI/Gizmos/GLGizmoCut.hpp | 6 +-- src/slic3r/GUI/ImGuiWrapper.cpp | 14 +++++-- src/slic3r/GUI/ImGuiWrapper.hpp | 3 +- 5 files changed, 28 insertions(+), 52 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 0585ce58c..a196cf11c 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -3580,7 +3580,7 @@ void GCodeViewer::render_legend(float& legend_height) ImGui::PushStyleColor(ImGuiCol_FrameBg, { 0.1f, 0.1f, 0.1f, 0.8f }); ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, { 0.2f, 0.2f, 0.2f, 0.8f }); - imgui.combo("", { _u8L("Feature type"), + imgui.combo(std::string(), { _u8L("Feature type"), _u8L("Height (mm)"), _u8L("Width (mm)"), _u8L("Speed (mm/s)"), diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 2aaea5391..c6ede9ceb 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -179,8 +179,8 @@ GLGizmoCut3D::GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename, : GLGizmoBase(parent, icon_filename, sprite_id) , m_connectors_group_id (GrabberID::Count) , m_connector_type (CutConnectorType::Plug) - , m_connector_style (size_t(CutConnectorStyle::Prism)) - , m_connector_shape_id (size_t(CutConnectorShape::Circle)) + , m_connector_style (int(CutConnectorStyle::Prism)) + , m_connector_shape_id (int(CutConnectorShape::Circle)) { // m_modes = { _u8L("Planar"), _u8L("Grid") // , _u8L("Radial"), _u8L("Modular") @@ -465,41 +465,10 @@ void GLGizmoCut3D::set_center(const Vec3d& center, bool update_tbb /*=false*/) update_clipper(); } -bool GLGizmoCut3D::render_combo(const std::string& label, const std::vector& lines, size_t& selection_idx) +bool GLGizmoCut3D::render_combo(const std::string& label, const std::vector& lines, int& selection_idx) { ImGui::AlignTextToFramePadding(); - m_imgui->text(label); - ImGui::SameLine(m_label_width); - ImGui::PushItemWidth(m_control_width); - - size_t selection_out = selection_idx; - // It is necessary to use BeginGroup(). Otherwise, when using SameLine() is called, then other items will be drawn inside the combobox. - ImGui::BeginGroup(); - ImVec2 combo_pos = ImGui::GetCursorScreenPos(); - if (ImGui::BeginCombo(("##"+label).c_str(), "")) { - for (size_t line_idx = 0; line_idx < lines.size(); ++line_idx) { - ImGui::PushID(int(line_idx)); - if (ImGui::Selectable("", line_idx == selection_idx)) - selection_out = line_idx; - - ImGui::SameLine(); - ImGui::Text("%s", lines[line_idx].c_str()); - ImGui::PopID(); - } - - ImGui::EndCombo(); - } - - ImVec2 backup_pos = ImGui::GetCursorScreenPos(); - ImGuiStyle& style = ImGui::GetStyle(); - - ImGui::SetCursorScreenPos(ImVec2(combo_pos.x + style.FramePadding.x, combo_pos.y + style.FramePadding.y)); - ImGui::Text("%s", selection_out < lines.size() ? lines[selection_out].c_str() : UndefLabel.c_str()); - ImGui::SetCursorScreenPos(backup_pos); - ImGui::EndGroup(); - - bool is_changed = selection_idx != selection_out; - selection_idx = selection_out; + const bool is_changed = m_imgui->combo(label, lines, selection_idx, 0, m_label_width, m_control_width); if (is_changed) update_connector_shape(); @@ -1803,7 +1772,7 @@ void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors) m_imgui->disabled_begin(m_connector_type == CutConnectorType::Dowel); if (type_changed && m_connector_type == CutConnectorType::Dowel) { - m_connector_style = size_t(CutConnectorStyle::Prism); + m_connector_style = int(CutConnectorStyle::Prism); apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.style = CutConnectorStyle(m_connector_style); }); } if (render_combo(m_labels_map["Style"], m_connector_styles, m_connector_style)) @@ -1813,7 +1782,7 @@ void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors) if (render_combo(m_labels_map["Shape"], m_connector_shapes, m_connector_shape_id)) apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.shape = CutConnectorShape(m_connector_shape_id); }); - if (render_slider_double_input(m_labels_map["Depth ratio"], m_connector_depth_ratio, m_connector_depth_ratio_tolerance)) + if (render_slider_double_input(m_labels_map["Depth"], m_connector_depth_ratio, m_connector_depth_ratio_tolerance)) apply_selected_connectors([this, &connectors](size_t idx) { if (m_connector_depth_ratio > 0) connectors[idx].height = m_connector_depth_ratio; @@ -2136,10 +2105,10 @@ void GLGizmoCut3D::validate_connector_settings() if (m_connector_type == CutConnectorType::Undef) m_connector_type = CutConnectorType::Plug; - if (m_connector_style == size_t(CutConnectorStyle::Undef)) - m_connector_style = size_t(CutConnectorStyle::Prism); - if (m_connector_shape_id == size_t(CutConnectorShape::Undef)) - m_connector_shape_id = size_t(CutConnectorShape::Circle); + if (m_connector_style == int(CutConnectorStyle::Undef)) + m_connector_style = int(CutConnectorStyle::Prism); + if (m_connector_shape_id == int(CutConnectorShape::Undef)) + m_connector_shape_id = int(CutConnectorShape::Circle); } void GLGizmoCut3D::init_input_window_data(CutConnectors &connectors) @@ -2197,8 +2166,8 @@ void GLGizmoCut3D::init_input_window_data(CutConnectors &connectors) m_connector_size = 2.f * radius; m_connector_size_tolerance = 2.f * radius_tolerance; m_connector_type = type; - m_connector_style = size_t(style); - m_connector_shape_id = size_t(shape); + m_connector_style = int(style); + m_connector_shape_id = int(shape); } if (m_label_width == 0.f) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index 627f6c133..75fc54597 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -199,10 +199,10 @@ class GLGizmoCut3D : public GLGizmoBase CutConnectorType m_connector_type; std::vector m_connector_styles; - size_t m_connector_style; + int m_connector_style; std::vector m_connector_shapes; - size_t m_connector_shape_id; + int m_connector_shape_id; std::vector m_axis_names; @@ -301,7 +301,7 @@ protected: private: void set_center(const Vec3d& center, bool update_tbb = false); - bool render_combo(const std::string& label, const std::vector& lines, size_t& selection_idx); + bool render_combo(const std::string& label, const std::vector& lines, int& selection_idx); bool render_double_input(const std::string& label, double& value_in); bool render_slider_double_input(const std::string& label, float& value_in, float& tolerance_in); void render_move_center_input(int axis); diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 841ae2048..ebcd85043 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -774,27 +774,33 @@ bool ImGuiWrapper::image_button(const wchar_t icon, const wxString& tooltip) return res; } -bool ImGuiWrapper::combo(const wxString& label, const std::vector& options, int& selection, ImGuiComboFlags flags) +bool ImGuiWrapper::combo(const wxString& label, const std::vector& options, int& selection, ImGuiComboFlags flags/* = 0*/, float label_width/* = 0.0f*/, float item_width/* = 0.0f*/) +{ + return combo(into_u8(label), options, selection, flags, label_width, item_width); +} + +bool ImGuiWrapper::combo(const std::string& label, const std::vector& options, int& selection, ImGuiComboFlags flags/* = 0*/, float label_width/* = 0.0f*/, float item_width/* = 0.0f*/) { // this is to force the label to the left of the widget: if (!label.empty()) { text(label); - ImGui::SameLine(); + ImGui::SameLine(label_width); } + ImGui::PushItemWidth(item_width); int selection_out = selection; bool res = false; const char *selection_str = selection < int(options.size()) && selection >= 0 ? options[selection].c_str() : ""; - if (ImGui::BeginCombo("", selection_str, flags)) { + if (ImGui::BeginCombo(("##" + label).c_str(), selection_str, flags)) { for (int i = 0; i < (int)options.size(); i++) { if (ImGui::Selectable(options[i].c_str(), i == selection)) { selection_out = i; + res = true; } } ImGui::EndCombo(); - res = true; } selection = selection_out; diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index d95b934f1..26e58d4ad 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -120,7 +120,8 @@ public: bool image_button(const wchar_t icon, const wxString& tooltip = L""); // Use selection = -1 to not mark any option as selected - bool combo(const wxString& label, const std::vector& options, int& selection, ImGuiComboFlags flags = 0); + bool combo(const std::string& label, const std::vector& options, int& selection, ImGuiComboFlags flags = 0, float label_width = 0.0f, float item_width = 0.0f); + bool combo(const wxString& label, const std::vector& options, int& selection, ImGuiComboFlags flags = 0, float label_width = 0.0f, float item_width = 0.0f); bool undo_redo_list(const ImVec2& size, const bool is_undo, bool (*items_getter)(const bool, int, const char**), int& hovered, int& selected, int& mouse_wheel); void search_list(const ImVec2& size, bool (*items_getter)(int, const char** label, const char** tooltip), char* search_str, Search::OptionViewParameters& view_params, int& selected, bool& edited, int& mouse_wheel, bool is_localized);