Implemented Search on Plater, usint imGui
This commit is contained in:
parent
4ab83af9e4
commit
14703fe561
4
resources/icons/search_.svg
Normal file
4
resources/icons/search_.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24px" height="24px">
|
||||||
|
<path fill="#FFFFFF" d="M 13.261719 14.867188 L 15.742188 17.347656 C 15.363281 18.070313 15.324219 18.789063 15.722656 19.1875 L 20.25 23.714844 C 20.820313 24.285156 22.0625 23.972656 23.015625 23.015625 C 23.972656 22.058594 24.285156 20.820313 23.714844 20.25 L 19.191406 15.722656 C 18.789063 15.324219 18.070313 15.363281 17.347656 15.738281 L 14.867188 13.261719 Z M 8.5 0 C 3.804688 0 0 3.804688 0 8.5 C 0 13.195313 3.804688 17 8.5 17 C 13.195313 17 17 13.195313 17 8.5 C 17 3.804688 13.195313 0 8.5 0 Z M 8.5 15 C 4.910156 15 2 12.089844 2 8.5 C 2 4.910156 4.910156 2 8.5 2 C 12.089844 2 15 4.910156 15 8.5 C 15 12.089844 12.089844 15 8.5 15 Z"/>
|
||||||
|
<path fill="#ED6B21" d="M 13.261719 14.867188 L 19.191406 15.722656 C 18.789063 15.324219 18.070313 15.363281 17.347656 15.738281 M 8.5 0 C 3.804688 0 0 3.804688 0 8.5 C 0 13.195313 3.804688 17 8.5 17 C 13.195313 17 17 13.195313 17 8.5 C 17 3.804688 13.195313 0 8.5 0 Z M 8.5 15 C 4.910156 15 2 12.089844 2 8.5 C 2 4.910156 4.910156 2 8.5 2 C 12.089844 2 15 4.910156 15 8.5 C 15 12.089844 12.089844 15 8.5 15 Z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
@ -1450,6 +1450,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, wxKeyEvent);
|
|||||||
wxDEFINE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent);
|
wxDEFINE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent);
|
||||||
|
wxDEFINE_EVENT(EVT_GLCANVAS_COLLAPSE_SIDEBAR, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>);
|
wxDEFINE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>);
|
||||||
wxDEFINE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent);
|
wxDEFINE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent);
|
||||||
@ -4205,6 +4206,55 @@ bool GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) const
|
|||||||
return action_taken;
|
return action_taken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Getter for the const char*[] for the search list
|
||||||
|
static bool search_string_getter(int idx, const char** out_text)
|
||||||
|
{
|
||||||
|
return wxGetApp().plater()->search_string_getter(idx, out_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GLCanvas3D::_render_search_list(float pos_x) const
|
||||||
|
{
|
||||||
|
bool action_taken = false;
|
||||||
|
ImGuiWrapper* imgui = wxGetApp().imgui();
|
||||||
|
|
||||||
|
const float x = pos_x * (float)get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width();
|
||||||
|
imgui->set_next_window_pos(x, m_undoredo_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f);
|
||||||
|
std::string title = L("Search");
|
||||||
|
imgui->begin(_(title), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
|
||||||
|
|
||||||
|
size_t selected = size_t(-1);
|
||||||
|
bool edited = false;
|
||||||
|
float em = static_cast<float>(wxGetApp().em_unit());
|
||||||
|
#if ENABLE_RETINA_GL
|
||||||
|
em *= m_retina_helper->get_scale_factor();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::string& search_line = wxGetApp().sidebar().get_search_line();
|
||||||
|
char *s = new char[255];
|
||||||
|
strcpy(s, search_line.empty() ? _utf8(L("Type here to search")).c_str() : search_line.c_str());
|
||||||
|
|
||||||
|
imgui->search_list(ImVec2(22 * em, 30 * em), &search_string_getter, s, selected, edited);
|
||||||
|
|
||||||
|
search_line = s;
|
||||||
|
delete [] s;
|
||||||
|
|
||||||
|
if (selected != size_t(-1))
|
||||||
|
{
|
||||||
|
wxGetApp().sidebar().jump_to_option(selected);
|
||||||
|
action_taken = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edited)
|
||||||
|
{
|
||||||
|
wxGetApp().sidebar().apply_search_filter();
|
||||||
|
action_taken = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
imgui->end();
|
||||||
|
|
||||||
|
return action_taken;
|
||||||
|
}
|
||||||
|
|
||||||
#define ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT 0
|
#define ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT 0
|
||||||
#if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT
|
#if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT
|
||||||
static void debug_output_thumbnail(const ThumbnailData& thumbnail_data)
|
static void debug_output_thumbnail(const ThumbnailData& thumbnail_data)
|
||||||
@ -4723,6 +4773,23 @@ bool GLCanvas3D::_init_main_toolbar()
|
|||||||
if (!m_main_toolbar.add_item(item))
|
if (!m_main_toolbar.add_item(item))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!m_main_toolbar.add_separator())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
item.name = "search";
|
||||||
|
item.icon_filename = "search_.svg";
|
||||||
|
item.tooltip = _utf8(L("Search"));
|
||||||
|
item.sprite_id = 11;
|
||||||
|
item.left.render_callback = [this](float left, float right, float, float) {
|
||||||
|
if (m_canvas != nullptr)
|
||||||
|
{
|
||||||
|
_render_search_list(0.5f * (left + right));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
item.enabling_callback = []()->bool { return true; };
|
||||||
|
if (!m_main_toolbar.add_item(item))
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4829,6 +4896,18 @@ bool GLCanvas3D::_init_undoredo_toolbar()
|
|||||||
return can_redo;
|
return can_redo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!m_undoredo_toolbar.add_item(item))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!m_undoredo_toolbar.add_separator())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
item.name = "collapse_sidebar";
|
||||||
|
item.icon_filename = "cross.svg";
|
||||||
|
item.tooltip = _utf8(L("Collapse right panel"));
|
||||||
|
item.sprite_id = 2;
|
||||||
|
item.left.action_callback = [this]() { post_event(SimpleEvent(EVT_GLCANVAS_COLLAPSE_SIDEBAR)); };
|
||||||
|
item.enabling_callback = []()->bool { return true; };
|
||||||
if (!m_undoredo_toolbar.add_item(item))
|
if (!m_undoredo_toolbar.add_item(item))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -104,6 +104,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, wxKeyEvent);
|
|||||||
wxDECLARE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent);
|
wxDECLARE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent);
|
wxDECLARE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent);
|
wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent);
|
||||||
|
wxDECLARE_EVENT(EVT_GLCANVAS_COLLAPSE_SIDEBAR, SimpleEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent);
|
wxDECLARE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>);
|
wxDECLARE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>);
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent);
|
wxDECLARE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent);
|
||||||
@ -725,6 +726,7 @@ private:
|
|||||||
void _render_sla_slices() const;
|
void _render_sla_slices() const;
|
||||||
void _render_selection_sidebar_hints() const;
|
void _render_selection_sidebar_hints() const;
|
||||||
bool _render_undo_redo_stack(const bool is_undo, float pos_x) const;
|
bool _render_undo_redo_stack(const bool is_undo, float pos_x) const;
|
||||||
|
bool _render_search_list(float pos_x) const;
|
||||||
void _render_thumbnail_internal(ThumbnailData& thumbnail_data, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const;
|
void _render_thumbnail_internal(ThumbnailData& thumbnail_data, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const;
|
||||||
// render thumbnail using an off-screen framebuffer
|
// render thumbnail using an off-screen framebuffer
|
||||||
void _render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const;
|
void _render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const;
|
||||||
|
@ -400,6 +400,61 @@ bool ImGuiWrapper::undo_redo_list(const ImVec2& size, const bool is_undo, bool (
|
|||||||
return is_hovered;
|
return is_hovered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, const char**), char* search_str, size_t& selected, bool& edited)
|
||||||
|
{
|
||||||
|
// ImGui::ListBoxHeader("", size);
|
||||||
|
{
|
||||||
|
// rewrote part of function to add a TextInput instead of label Text
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||||
|
if (window->SkipItems)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
const ImGuiStyle& style = g.Style;
|
||||||
|
|
||||||
|
// Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar.
|
||||||
|
ImVec2 size = ImGui::CalcItemSize(size_, ImGui::CalcItemWidth(), ImGui::GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y);
|
||||||
|
ImRect frame_bb(window->DC.CursorPos, ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y + size.y));
|
||||||
|
|
||||||
|
ImRect bb(frame_bb.Min, frame_bb.Max);
|
||||||
|
window->DC.LastItemRect = bb; // Forward storage for ListBoxFooter.. dodgy.
|
||||||
|
g.NextItemData.ClearFlags();
|
||||||
|
|
||||||
|
if (!ImGui::IsRectVisible(bb.Min, bb.Max))
|
||||||
|
{
|
||||||
|
ImGui::ItemSize(bb.GetSize(), style.FramePadding.y);
|
||||||
|
ImGui::ItemAdd(bb, 0, &frame_bb);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
|
||||||
|
const ImGuiID id = ImGui::GetID(search_str);
|
||||||
|
ImVec2 search_size = ImVec2(size.x, ImGui::GetTextLineHeightWithSpacing() + style.ItemSpacing.y);
|
||||||
|
|
||||||
|
ImGui::InputTextEx("", NULL, search_str, 20, search_size, 0, NULL, NULL);
|
||||||
|
edited = ImGui::IsItemEdited();
|
||||||
|
|
||||||
|
ImGui::BeginChildFrame(id, frame_bb.GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
const char* item_text;
|
||||||
|
while (items_getter(i, &item_text))
|
||||||
|
{
|
||||||
|
ImGui::Selectable(item_text, false);
|
||||||
|
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
ImGui::SetTooltip("%s", item_text);
|
||||||
|
|
||||||
|
if (ImGui::IsItemClicked())
|
||||||
|
selected = i;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::ListBoxFooter();
|
||||||
|
}
|
||||||
|
|
||||||
void ImGuiWrapper::disabled_begin(bool disabled)
|
void ImGuiWrapper::disabled_begin(bool disabled)
|
||||||
{
|
{
|
||||||
wxCHECK_RET(!m_disabled, "ImGUI: Unbalanced disabled_begin() call");
|
wxCHECK_RET(!m_disabled, "ImGUI: Unbalanced disabled_begin() call");
|
||||||
|
@ -74,6 +74,7 @@ public:
|
|||||||
bool slider_float(const wxString& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f);
|
bool slider_float(const wxString& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f);
|
||||||
bool combo(const wxString& label, const std::vector<std::string>& options, int& selection); // Use -1 to not mark any option as selected
|
bool combo(const wxString& label, const std::vector<std::string>& options, int& selection); // Use -1 to not mark any option as selected
|
||||||
bool undo_redo_list(const ImVec2& size, const bool is_undo, bool (*items_getter)(const bool, int, const char**), int& hovered, int& selected);
|
bool undo_redo_list(const ImVec2& size, const bool is_undo, bool (*items_getter)(const bool, int, const char**), int& hovered, int& selected);
|
||||||
|
void search_list(const ImVec2& size, bool (*items_getter)(int, const char**), char* search_str, size_t& selected, bool& edited);
|
||||||
|
|
||||||
void disabled_begin(bool disabled);
|
void disabled_begin(bool disabled);
|
||||||
void disabled_end();
|
void disabled_end();
|
||||||
|
@ -701,7 +701,6 @@ struct Sidebar::priv
|
|||||||
|
|
||||||
wxBoxSizer *sizer_params;
|
wxBoxSizer *sizer_params;
|
||||||
FreqChangedParams *frequently_changed_parameters{ nullptr };
|
FreqChangedParams *frequently_changed_parameters{ nullptr };
|
||||||
SearchComboBox *search_cb{ nullptr };
|
|
||||||
ObjectList *object_list{ nullptr };
|
ObjectList *object_list{ nullptr };
|
||||||
ObjectManipulation *object_manipulation{ nullptr };
|
ObjectManipulation *object_manipulation{ nullptr };
|
||||||
ObjectSettings *object_settings{ nullptr };
|
ObjectSettings *object_settings{ nullptr };
|
||||||
@ -715,6 +714,9 @@ struct Sidebar::priv
|
|||||||
ScalableButton *btn_remove_device;
|
ScalableButton *btn_remove_device;
|
||||||
ScalableButton* btn_export_gcode_removable; //exports to removable drives (appears only if removable drive is connected)
|
ScalableButton* btn_export_gcode_removable; //exports to removable drives (appears only if removable drive is connected)
|
||||||
|
|
||||||
|
SearchOptions search_list;
|
||||||
|
std::string search_line;
|
||||||
|
|
||||||
priv(Plater *plater) : plater(plater) {}
|
priv(Plater *plater) : plater(plater) {}
|
||||||
~priv();
|
~priv();
|
||||||
|
|
||||||
@ -828,10 +830,6 @@ Sidebar::Sidebar(Plater *parent)
|
|||||||
p->frequently_changed_parameters = new FreqChangedParams(p->scrolled);
|
p->frequently_changed_parameters = new FreqChangedParams(p->scrolled);
|
||||||
p->sizer_params->Add(p->frequently_changed_parameters->get_sizer(), 0, wxEXPAND | wxTOP | wxBOTTOM, wxOSX ? 1 : margin_5);
|
p->sizer_params->Add(p->frequently_changed_parameters->get_sizer(), 0, wxEXPAND | wxTOP | wxBOTTOM, wxOSX ? 1 : margin_5);
|
||||||
|
|
||||||
// Search combobox
|
|
||||||
// p->search_cb = new SearchComboBox(p->scrolled);
|
|
||||||
// p->sizer_params->Add(p->search_cb, 0, wxEXPAND | wxTOP | wxBOTTOM, wxOSX ? 1 : margin_5);
|
|
||||||
|
|
||||||
// Object List
|
// Object List
|
||||||
p->object_list = new ObjectList(p->scrolled);
|
p->object_list = new ObjectList(p->scrolled);
|
||||||
p->sizer_params->Add(p->object_list->get_sizer(), 1, wxEXPAND);
|
p->sizer_params->Add(p->object_list->get_sizer(), 1, wxEXPAND);
|
||||||
@ -1085,6 +1083,17 @@ void Sidebar::msw_rescale()
|
|||||||
p->scrolled->Layout();
|
p->scrolled->Layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sidebar::apply_search_filter()
|
||||||
|
{
|
||||||
|
p->search_list.apply_filters(p->search_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sidebar::jump_to_option(size_t selected)
|
||||||
|
{
|
||||||
|
const SearchOptions::Option& opt = p->search_list.get_option(selected);
|
||||||
|
wxGetApp().get_tab(opt.type)->activate_option(opt.opt_key, opt.category);
|
||||||
|
}
|
||||||
|
|
||||||
ObjectManipulation* Sidebar::obj_manipul()
|
ObjectManipulation* Sidebar::obj_manipul()
|
||||||
{
|
{
|
||||||
return p->object_manipulation;
|
return p->object_manipulation;
|
||||||
@ -1357,21 +1366,14 @@ static std::vector<SearchInput> get_search_inputs(ConfigOptionMode mode)
|
|||||||
|
|
||||||
void Sidebar::update_search_list()
|
void Sidebar::update_search_list()
|
||||||
{
|
{
|
||||||
if (p->search_cb)
|
p->search_list.init(get_search_inputs(m_mode));
|
||||||
p->search_cb->init(get_search_inputs(m_mode));
|
|
||||||
|
|
||||||
std::vector<SearchInput> search_list{};
|
|
||||||
|
|
||||||
auto& tabs_list = wxGetApp().tabs_list;
|
auto& tabs_list = wxGetApp().tabs_list;
|
||||||
auto print_tech = wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology();
|
auto print_tech = wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology();
|
||||||
|
|
||||||
for (auto tab : tabs_list)
|
for (auto tab : tabs_list)
|
||||||
if (tab->supports_printer_technology(print_tech))
|
if (tab->supports_printer_technology(print_tech))
|
||||||
search_list.emplace_back(SearchInput{ tab->get_config(), tab->type(), m_mode });
|
tab->get_search_cb()->init(p->search_list);
|
||||||
|
|
||||||
for (auto tab : tabs_list)
|
|
||||||
if (tab->supports_printer_technology(print_tech))
|
|
||||||
tab->get_search_cb()->init(search_list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sidebar::update_mode()
|
void Sidebar::update_mode()
|
||||||
@ -1398,6 +1400,16 @@ std::vector<PresetComboBox*>& Sidebar::combos_filament()
|
|||||||
return p->combos_filament;
|
return p->combos_filament;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SearchOptions& Sidebar::get_search_list()
|
||||||
|
{
|
||||||
|
return p->search_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string& Sidebar::get_search_line()
|
||||||
|
{
|
||||||
|
return p->search_line;
|
||||||
|
}
|
||||||
|
|
||||||
// Plater::DropTarget
|
// Plater::DropTarget
|
||||||
|
|
||||||
class PlaterDropTarget : public wxFileDropTarget
|
class PlaterDropTarget : public wxFileDropTarget
|
||||||
@ -2143,6 +2155,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||||||
view3D_canvas->Bind(EVT_GLCANVAS_RESETGIZMOS, [this](SimpleEvent&) { reset_all_gizmos(); });
|
view3D_canvas->Bind(EVT_GLCANVAS_RESETGIZMOS, [this](SimpleEvent&) { reset_all_gizmos(); });
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_UNDO, [this](SimpleEvent&) { this->undo(); });
|
view3D_canvas->Bind(EVT_GLCANVAS_UNDO, [this](SimpleEvent&) { this->undo(); });
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_REDO, [this](SimpleEvent&) { this->redo(); });
|
view3D_canvas->Bind(EVT_GLCANVAS_REDO, [this](SimpleEvent&) { this->redo(); });
|
||||||
|
view3D_canvas->Bind(EVT_GLCANVAS_COLLAPSE_SIDEBAR, [this](SimpleEvent&) { /*this->redo();*/ });
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, [this](SimpleEvent&) { this->view3D->get_canvas3d()->reset_layer_height_profile(); });
|
view3D_canvas->Bind(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, [this](SimpleEvent&) { this->view3D->get_canvas3d()->reset_layer_height_profile(); });
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, [this](Event<float>& evt) { this->view3D->get_canvas3d()->adaptive_layer_height_profile(evt.data); });
|
view3D_canvas->Bind(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, [this](Event<float>& evt) { this->view3D->get_canvas3d()->adaptive_layer_height_profile(evt.data); });
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, [this](HeightProfileSmoothEvent& evt) { this->view3D->get_canvas3d()->smooth_layer_height_profile(evt.data); });
|
view3D_canvas->Bind(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, [this](HeightProfileSmoothEvent& evt) { this->view3D->get_canvas3d()->smooth_layer_height_profile(evt.data); });
|
||||||
@ -5249,6 +5262,18 @@ void Plater::undo_redo_topmost_string_getter(const bool is_undo, std::string& ou
|
|||||||
out_text = "";
|
out_text = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Plater::search_string_getter(int idx, const char** out_text)
|
||||||
|
{
|
||||||
|
const SearchOptions& search_list = p->sidebar->get_search_list();
|
||||||
|
|
||||||
|
if (0 <= idx && (size_t)idx < search_list.size()) {
|
||||||
|
search_list[idx].get_label(out_text);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Plater::on_extruders_change(size_t num_extruders)
|
void Plater::on_extruders_change(size_t num_extruders)
|
||||||
{
|
{
|
||||||
auto& choices = sidebar().combos_filament();
|
auto& choices = sidebar().combos_filament();
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "libslic3r/BoundingBox.hpp"
|
#include "libslic3r/BoundingBox.hpp"
|
||||||
#include "wxExtensions.hpp"
|
#include "wxExtensions.hpp"
|
||||||
|
#include "SearchComboBox.hpp"
|
||||||
|
|
||||||
class wxButton;
|
class wxButton;
|
||||||
class ScalableButton;
|
class ScalableButton;
|
||||||
@ -100,6 +101,8 @@ public:
|
|||||||
void update_mode_sizer() const;
|
void update_mode_sizer() const;
|
||||||
void update_reslice_btn_tooltip() const;
|
void update_reslice_btn_tooltip() const;
|
||||||
void msw_rescale();
|
void msw_rescale();
|
||||||
|
void apply_search_filter();
|
||||||
|
void jump_to_option(size_t selected);
|
||||||
|
|
||||||
ObjectManipulation* obj_manipul();
|
ObjectManipulation* obj_manipul();
|
||||||
ObjectList* obj_list();
|
ObjectList* obj_list();
|
||||||
@ -126,6 +129,9 @@ public:
|
|||||||
void update_search_list();
|
void update_search_list();
|
||||||
|
|
||||||
std::vector<PresetComboBox*>& combos_filament();
|
std::vector<PresetComboBox*>& combos_filament();
|
||||||
|
SearchOptions& get_search_list();
|
||||||
|
std::string& get_search_line();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct priv;
|
struct priv;
|
||||||
std::unique_ptr<priv> p;
|
std::unique_ptr<priv> p;
|
||||||
@ -220,6 +226,7 @@ public:
|
|||||||
void redo_to(int selection);
|
void redo_to(int selection);
|
||||||
bool undo_redo_string_getter(const bool is_undo, int idx, const char** out_text);
|
bool undo_redo_string_getter(const bool is_undo, int idx, const char** out_text);
|
||||||
void undo_redo_topmost_string_getter(const bool is_undo, std::string& out_text);
|
void undo_redo_topmost_string_getter(const bool is_undo, std::string& out_text);
|
||||||
|
bool search_string_getter(int idx, const char **out_text);
|
||||||
// For the memory statistics.
|
// For the memory statistics.
|
||||||
const Slic3r::UndoRedo::Stack& undo_redo_stack_main() const;
|
const Slic3r::UndoRedo::Stack& undo_redo_stack_main() const;
|
||||||
// Enter / leave the Gizmos specific Undo / Redo stack. To be used by the SLA support point editing gizmo.
|
// Enter / leave the Gizmos specific Undo / Redo stack. To be used by the SLA support point editing gizmo.
|
||||||
|
@ -48,6 +48,10 @@ bool SearchOptions::Option::is_matched_option(const wxString& search, int& outSc
|
|||||||
fts::fuzzy_match(search_pattern, opt_key_str , outScore) );
|
fts::fuzzy_match(search_pattern, opt_key_str , outScore) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SearchOptions::Filter::get_label(const char** out_text) const
|
||||||
|
{
|
||||||
|
*out_text = label.utf8_str();
|
||||||
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void change_opt_key(std::string& opt_key, DynamicPrintConfig* config)
|
void change_opt_key(std::string& opt_key, DynamicPrintConfig* config)
|
||||||
@ -82,21 +86,42 @@ void SearchOptions::append_options(DynamicPrintConfig* config, Preset::Type type
|
|||||||
label += _(opt.category) + " : ";
|
label += _(opt.category) + " : ";
|
||||||
label += _(opt.full_label.empty() ? opt.label : opt.full_label);
|
label += _(opt.full_label.empty() ? opt.label : opt.full_label);
|
||||||
|
|
||||||
|
if (!label.IsEmpty())
|
||||||
options.emplace_back(Option{ label, opt_key, opt.category, type });
|
options.emplace_back(Option{ label, opt_key, opt.category, type });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchOptions::apply_filters(const wxString& search)
|
void SearchOptions::apply_filters(const std::string& search)
|
||||||
{
|
{
|
||||||
clear_filters();
|
clear_filters();
|
||||||
for (auto option : options) {
|
|
||||||
int score;
|
bool full_list = search.empty();
|
||||||
if (option.is_matched_option(search, score))
|
for (size_t i=0; i < options.size(); i++) {
|
||||||
filters.emplace_back(Filter{ option.label, score });
|
int score=0;
|
||||||
|
if (full_list || options[i].is_matched_option(search, score))
|
||||||
|
filters.emplace_back(Filter{ options[i].label, i, score });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!full_list)
|
||||||
sort_filters();
|
sort_filters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SearchOptions::init(std::vector<SearchInput> input_values)
|
||||||
|
{
|
||||||
|
clear_options();
|
||||||
|
for (auto i : input_values)
|
||||||
|
append_options(i.config, i.type, i.mode);
|
||||||
|
sort_options();
|
||||||
|
|
||||||
|
apply_filters("");
|
||||||
|
}
|
||||||
|
|
||||||
|
const SearchOptions::Option& SearchOptions::get_option(size_t pos_in_filter) const
|
||||||
|
{
|
||||||
|
assert(pos_in_filter != size_t(-1) && filters[pos_in_filter].option_idx != size_t(-1));
|
||||||
|
return options[filters[pos_in_filter].option_idx];
|
||||||
|
}
|
||||||
|
|
||||||
SearchComboBox::SearchComboBox(wxWindow *parent) :
|
SearchComboBox::SearchComboBox(wxWindow *parent) :
|
||||||
wxBitmapComboBox(parent, wxID_ANY, _(L("Type here to search")) + dots, wxDefaultPosition, wxSize(25 * wxGetApp().em_unit(), -1)),
|
wxBitmapComboBox(parent, wxID_ANY, _(L("Type here to search")) + dots, wxDefaultPosition, wxSize(25 * wxGetApp().em_unit(), -1)),
|
||||||
em_unit(wxGetApp().em_unit())
|
em_unit(wxGetApp().em_unit())
|
||||||
@ -177,6 +202,13 @@ void SearchComboBox::init(std::vector<SearchInput> input_values)
|
|||||||
update_combobox();
|
update_combobox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SearchComboBox::init(const SearchOptions& new_search_list)
|
||||||
|
{
|
||||||
|
search_list = new_search_list;
|
||||||
|
|
||||||
|
update_combobox();
|
||||||
|
}
|
||||||
|
|
||||||
void SearchComboBox::update_combobox()
|
void SearchComboBox::update_combobox()
|
||||||
{
|
{
|
||||||
wxString search_str = this->GetValue();
|
wxString search_str = this->GetValue();
|
||||||
|
@ -42,14 +42,17 @@ public:
|
|||||||
|
|
||||||
struct Filter {
|
struct Filter {
|
||||||
wxString label;
|
wxString label;
|
||||||
|
size_t option_idx {0};
|
||||||
int outScore {0};
|
int outScore {0};
|
||||||
|
|
||||||
|
void get_label(const char** out_text) const;
|
||||||
};
|
};
|
||||||
std::vector<Filter> filters {};
|
std::vector<Filter> filters {};
|
||||||
|
|
||||||
void clear_options() { options.clear(); }
|
void clear_options() { options.clear(); }
|
||||||
void clear_filters() { filters.clear(); }
|
void clear_filters() { filters.clear(); }
|
||||||
void append_options(DynamicPrintConfig* config, Preset::Type type, ConfigOptionMode mode);
|
void append_options(DynamicPrintConfig* config, Preset::Type type, ConfigOptionMode mode);
|
||||||
void apply_filters(const wxString& search);
|
void apply_filters(const std::string& search);
|
||||||
|
|
||||||
void sort_options() {
|
void sort_options() {
|
||||||
std::sort(options.begin(), options.end(), [](const Option& o1, const Option& o2) {
|
std::sort(options.begin(), options.end(), [](const Option& o1, const Option& o2) {
|
||||||
@ -59,6 +62,15 @@ public:
|
|||||||
std::sort(filters.begin(), filters.end(), [](const Filter& f1, const Filter& f2) {
|
std::sort(filters.begin(), filters.end(), [](const Filter& f1, const Filter& f2) {
|
||||||
return f1.outScore > f2.outScore; });
|
return f1.outScore > f2.outScore; });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void init(std::vector<SearchInput> input_values);
|
||||||
|
size_t options_size() const { return options.size(); }
|
||||||
|
size_t filters_size() const { return filters.size(); }
|
||||||
|
|
||||||
|
size_t size() const { return filters_size(); }
|
||||||
|
|
||||||
|
const Filter& operator[](const size_t pos) const noexcept { return filters[pos]; }
|
||||||
|
const Option& get_option(size_t pos_in_filter) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SearchComboBox : public wxBitmapComboBox
|
class SearchComboBox : public wxBitmapComboBox
|
||||||
@ -86,6 +98,7 @@ public:
|
|||||||
|
|
||||||
void init(DynamicPrintConfig* config, Preset::Type type, ConfigOptionMode mode);
|
void init(DynamicPrintConfig* config, Preset::Type type, ConfigOptionMode mode);
|
||||||
void init(std::vector<SearchInput> input_values);
|
void init(std::vector<SearchInput> input_values);
|
||||||
|
void init(const SearchOptions& new_search_list);
|
||||||
void update_combobox();
|
void update_combobox();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user