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
This commit is contained in:
YuSanka 2023-05-23 14:20:55 +02:00
parent 6ad9aba454
commit 9af733d6ac
5 changed files with 28 additions and 52 deletions

View file

@ -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_FrameBg, { 0.1f, 0.1f, 0.1f, 0.8f });
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, { 0.2f, 0.2f, 0.2f, 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("Height (mm)"),
_u8L("Width (mm)"), _u8L("Width (mm)"),
_u8L("Speed (mm/s)"), _u8L("Speed (mm/s)"),

View file

@ -179,8 +179,8 @@ GLGizmoCut3D::GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename,
: GLGizmoBase(parent, icon_filename, sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id)
, m_connectors_group_id (GrabberID::Count) , m_connectors_group_id (GrabberID::Count)
, m_connector_type (CutConnectorType::Plug) , m_connector_type (CutConnectorType::Plug)
, m_connector_style (size_t(CutConnectorStyle::Prism)) , m_connector_style (int(CutConnectorStyle::Prism))
, m_connector_shape_id (size_t(CutConnectorShape::Circle)) , m_connector_shape_id (int(CutConnectorShape::Circle))
{ {
// m_modes = { _u8L("Planar"), _u8L("Grid") // m_modes = { _u8L("Planar"), _u8L("Grid")
// , _u8L("Radial"), _u8L("Modular") // , _u8L("Radial"), _u8L("Modular")
@ -465,41 +465,10 @@ void GLGizmoCut3D::set_center(const Vec3d& center, bool update_tbb /*=false*/)
update_clipper(); update_clipper();
} }
bool GLGizmoCut3D::render_combo(const std::string& label, const std::vector<std::string>& lines, size_t& selection_idx) bool GLGizmoCut3D::render_combo(const std::string& label, const std::vector<std::string>& lines, int& selection_idx)
{ {
ImGui::AlignTextToFramePadding(); ImGui::AlignTextToFramePadding();
m_imgui->text(label); const bool is_changed = m_imgui->combo(label, lines, selection_idx, 0, m_label_width, m_control_width);
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;
if (is_changed) if (is_changed)
update_connector_shape(); update_connector_shape();
@ -1803,7 +1772,7 @@ void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors)
m_imgui->disabled_begin(m_connector_type == CutConnectorType::Dowel); m_imgui->disabled_begin(m_connector_type == CutConnectorType::Dowel);
if (type_changed && 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); }); 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)) 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)) 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); }); 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) { apply_selected_connectors([this, &connectors](size_t idx) {
if (m_connector_depth_ratio > 0) if (m_connector_depth_ratio > 0)
connectors[idx].height = m_connector_depth_ratio; connectors[idx].height = m_connector_depth_ratio;
@ -2136,10 +2105,10 @@ void GLGizmoCut3D::validate_connector_settings()
if (m_connector_type == CutConnectorType::Undef) if (m_connector_type == CutConnectorType::Undef)
m_connector_type = CutConnectorType::Plug; m_connector_type = CutConnectorType::Plug;
if (m_connector_style == size_t(CutConnectorStyle::Undef)) if (m_connector_style == int(CutConnectorStyle::Undef))
m_connector_style = size_t(CutConnectorStyle::Prism); m_connector_style = int(CutConnectorStyle::Prism);
if (m_connector_shape_id == size_t(CutConnectorShape::Undef)) if (m_connector_shape_id == int(CutConnectorShape::Undef))
m_connector_shape_id = size_t(CutConnectorShape::Circle); m_connector_shape_id = int(CutConnectorShape::Circle);
} }
void GLGizmoCut3D::init_input_window_data(CutConnectors &connectors) 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 = 2.f * radius;
m_connector_size_tolerance = 2.f * radius_tolerance; m_connector_size_tolerance = 2.f * radius_tolerance;
m_connector_type = type; m_connector_type = type;
m_connector_style = size_t(style); m_connector_style = int(style);
m_connector_shape_id = size_t(shape); m_connector_shape_id = int(shape);
} }
if (m_label_width == 0.f) { if (m_label_width == 0.f) {

View file

@ -199,10 +199,10 @@ class GLGizmoCut3D : public GLGizmoBase
CutConnectorType m_connector_type; CutConnectorType m_connector_type;
std::vector<std::string> m_connector_styles; std::vector<std::string> m_connector_styles;
size_t m_connector_style; int m_connector_style;
std::vector<std::string> m_connector_shapes; std::vector<std::string> m_connector_shapes;
size_t m_connector_shape_id; int m_connector_shape_id;
std::vector<std::string> m_axis_names; std::vector<std::string> m_axis_names;
@ -301,7 +301,7 @@ protected:
private: private:
void set_center(const Vec3d& center, bool update_tbb = false); void set_center(const Vec3d& center, bool update_tbb = false);
bool render_combo(const std::string& label, const std::vector<std::string>& lines, size_t& selection_idx); bool render_combo(const std::string& label, const std::vector<std::string>& lines, int& selection_idx);
bool render_double_input(const std::string& label, double& value_in); 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); bool render_slider_double_input(const std::string& label, float& value_in, float& tolerance_in);
void render_move_center_input(int axis); void render_move_center_input(int axis);

View file

@ -774,27 +774,33 @@ bool ImGuiWrapper::image_button(const wchar_t icon, const wxString& tooltip)
return res; return res;
} }
bool ImGuiWrapper::combo(const wxString& label, const std::vector<std::string>& options, int& selection, ImGuiComboFlags flags) bool ImGuiWrapper::combo(const wxString& label, const std::vector<std::string>& 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<std::string>& 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: // this is to force the label to the left of the widget:
if (!label.empty()) { if (!label.empty()) {
text(label); text(label);
ImGui::SameLine(); ImGui::SameLine(label_width);
} }
ImGui::PushItemWidth(item_width);
int selection_out = selection; int selection_out = selection;
bool res = false; bool res = false;
const char *selection_str = selection < int(options.size()) && selection >= 0 ? options[selection].c_str() : ""; 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++) { for (int i = 0; i < (int)options.size(); i++) {
if (ImGui::Selectable(options[i].c_str(), i == selection)) { if (ImGui::Selectable(options[i].c_str(), i == selection)) {
selection_out = i; selection_out = i;
res = true;
} }
} }
ImGui::EndCombo(); ImGui::EndCombo();
res = true;
} }
selection = selection_out; selection = selection_out;

View file

@ -120,7 +120,8 @@ public:
bool image_button(const wchar_t icon, const wxString& tooltip = L""); bool image_button(const wchar_t icon, const wxString& tooltip = L"");
// Use selection = -1 to not mark any option as selected // Use selection = -1 to not mark any option as selected
bool combo(const wxString& label, const std::vector<std::string>& options, int& selection, ImGuiComboFlags flags = 0); bool combo(const std::string& label, const std::vector<std::string>& options, int& selection, ImGuiComboFlags flags = 0, float label_width = 0.0f, float item_width = 0.0f);
bool combo(const wxString& label, const std::vector<std::string>& 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); 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, 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); Search::OptionViewParameters& view_params, int& selected, bool& edited, int& mouse_wheel, bool is_localized);