Implemented cursor movement inside SearchComboPopup

+ Added checkboxes for editing of the option's name (include "Group"/"Category" or not)
+ some code refactoring
This commit is contained in:
YuSanka 2020-04-14 17:54:15 +02:00
parent 167f7cf5de
commit 45147d887b
7 changed files with 152 additions and 50 deletions

View File

@ -4480,28 +4480,39 @@ bool GLCanvas3D::_render_search_list(float pos_x) const
size_t selected = size_t(-1);
bool edited = false;
bool check_changed = 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();
Sidebar& sidebar = wxGetApp().sidebar();
std::string& search_line = sidebar.get_search_line();
char *s = new char[255];
strcpy(s, search_line.empty() ? _u8L("Type here to search").c_str() : search_line.c_str());
imgui->search_list(ImVec2(45 * em, 30 * em), &search_string_getter, s, selected, edited);
imgui->search_list(ImVec2(45 * em, 30 * em), &search_string_getter, s,
sidebar.get_searcher().category, sidebar.get_searcher().group,
selected, edited, check_changed);
search_line = s;
delete [] s;
if (edited)
wxGetApp().sidebar().search_and_apply_tab_search_lines();
sidebar.search_and_apply_tab_search_lines();
if (check_changed) {
if (search_line == _u8L("Type here to search"))
search_line.clear();
sidebar.search_and_apply_tab_search_lines(true);
}
if (selected != size_t(-1))
{
// selected == 9999 means that Esc kye was pressed
if (selected != 9999)
wxGetApp().sidebar().jump_to_option(selected);
sidebar.jump_to_option(selected);
action_taken = true;
}

View File

@ -24,6 +24,7 @@
#include "libslic3r/Utils.hpp"
#include "3DScene.hpp"
#include "GUI.hpp"
#include "I18N.hpp"
namespace Slic3r {
namespace GUI {
@ -538,7 +539,8 @@ static bool selectable(const char* label, bool selected, ImGuiSelectableFlags fl
return pressed;
}
void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, const char**), char* search_str, size_t& selected, bool& edited)
void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, const char**), char* search_str,
bool& category, bool& group, size_t& selected, bool& edited, bool& check_changed)
{
// ImGui::ListBoxHeader("", size);
{
@ -604,6 +606,23 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co
}
ImGui::ListBoxFooter();
// add checkboxes for show/hide Categories and Groups
text(_L("Use for search")+":");
ImGui::SameLine();
bool cat = category;
checkbox(_L("Category"), cat);
if (ImGui::IsItemClicked()) {
category = !category;
check_changed = true;
}
ImGui::SameLine();
bool gr = group;
checkbox(_L("Group"), gr);
if (ImGui::IsItemClicked()) {
group = !group;
check_changed = true;
}
}
void ImGuiWrapper::disabled_begin(bool disabled)

View File

@ -74,7 +74,8 @@ public:
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 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 search_list(const ImVec2& size, bool (*items_getter)(int, const char**), char* search_str,
bool& category, bool& group, size_t& selected, bool& edited, bool& check_changed);
void disabled_begin(bool disabled);
void disabled_end();

View File

@ -1091,9 +1091,9 @@ void Sidebar::msw_rescale()
p->scrolled->Layout();
}
void Sidebar::search_and_apply_tab_search_lines()
void Sidebar::search_and_apply_tab_search_lines(bool force/* = false*/)
{
if (p->searcher.search(p->search_line))
if (p->searcher.search(p->search_line, force))
apply_search_line_on_tabs();
}

View File

@ -105,7 +105,7 @@ public:
void update_mode_sizer() const;
void update_reslice_btn_tooltip() const;
void msw_rescale();
void search_and_apply_tab_search_lines();
void search_and_apply_tab_search_lines(bool force = false);
void jump_to_option(size_t selected);
ObjectManipulation* obj_manipul();

View File

@ -186,11 +186,22 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/)
bool full_list = search.empty();
auto get_label = [this](const Option& opt)
{
wxString label;
if (category)
label += opt.category_local + " > ";
if (group)
label += opt.group_local + " > ";
label += opt.label_local;
return label;
};
for (size_t i=0; i < options.size(); i++)
{
const Option &opt = options[i];
if (full_list) {
wxString label = opt.category_local + " > " + opt.group_local + " > " + opt.label_local;
wxString label = get_label(opt);
found.emplace_back(FoundOption{ label, label, i, 0 });
continue;
}
@ -200,7 +211,8 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/)
FMFlag fuzzy_match_flag = opt.fuzzy_match(search, score);
if (fuzzy_match_flag != fmUndef)
{
wxString label = opt.category_local + " > " + opt.group_local + " > " + opt.label_local;
wxString label = get_label(opt); //opt.category_local + " > " + opt.group_local + " > " + opt.label_local;
if ( fuzzy_match_flag == fmLabel ) label += "(" + opt.label + ")";
else if (fuzzy_match_flag == fmGroup ) label += "(" + opt.group + ")";
else if (fuzzy_match_flag == fmCategory) label += "(" + opt.category + ")";
@ -243,6 +255,81 @@ void OptionsSearcher::add_key(const std::string& opt_key, const wxString& group,
}
//------------------------------------------
// SearchComboPopup
//------------------------------------------
void SearchComboPopup::Init()
{
this->Bind(wxEVT_MOTION, &SearchComboPopup::OnMouseMove, this);
this->Bind(wxEVT_LEFT_UP, &SearchComboPopup::OnMouseClick, this);
this->Bind(wxEVT_KEY_DOWN, &SearchComboPopup::OnKeyDown, this);
}
bool SearchComboPopup::Create(wxWindow* parent)
{
return wxListBox::Create(parent, 1, wxPoint(0, 0), wxDefaultSize);
}
void SearchComboPopup::SetStringValue(const wxString& s)
{
int n = wxListBox::FindString(s);
if (n >= 0 && n < wxListBox::GetCount())
wxListBox::Select(n);
// save a combo control's string
m_input_string = s;
}
void SearchComboPopup::ProcessSelection(int selection)
{
wxCommandEvent event(wxEVT_LISTBOX, GetId());
event.SetInt(selection);
event.SetEventObject(this);
ProcessEvent(event);
Dismiss();
}
void SearchComboPopup::OnMouseMove(wxMouseEvent& event)
{
wxPoint pt = wxGetMousePosition() - this->GetScreenPosition();
int selection = this->HitTest(pt);
wxListBox::Select(selection);
}
void SearchComboPopup::OnMouseClick(wxMouseEvent&)
{
int selection = wxListBox::GetSelection();
SetSelection(wxNOT_FOUND);
ProcessSelection(selection);
}
void SearchComboPopup::OnKeyDown(wxKeyEvent& event)
{
int key = event.GetKeyCode();
// change selected item in the list
if (key == WXK_UP || key == WXK_DOWN)
{
int selection = wxListBox::GetSelection();
if (key == WXK_UP && selection > 0)
selection--;
int last_item_id = int(wxListBox::GetCount() - 1);
if (key == WXK_DOWN && selection < int(wxListBox::GetCount() - 1))
selection++;
wxListBox::Select(selection);
}
// send wxEVT_LISTBOX event if "Enter" was pushed
else if (key == WXK_NUMPAD_ENTER || key == WXK_RETURN)
ProcessSelection(wxListBox::GetSelection());
else
event.Skip(); // !Needed to have EVT_CHAR generated as well
}
//------------------------------------------
// SearchCtrl
//------------------------------------------
@ -266,7 +353,12 @@ SearchCtrl::SearchCtrl(wxWindow* parent) :
this->Bind(wxEVT_TEXT, &SearchCtrl::OnInputText, this);
this->Bind(wxEVT_TEXT_ENTER, &SearchCtrl::PopupList, this);
this->Bind(wxEVT_COMBOBOX_DROPDOWN, &SearchCtrl::PopupList, this);
/*
this->Bind(wxEVT_KEY_DOWN, [this](wxKeyEvent&e)
{
});
*/
this->GetTextCtrl()->Bind(wxEVT_LEFT_UP, &SearchCtrl::OnLeftUpInTextCtrl, this);
popupListBox->Bind(wxEVT_LISTBOX, &SearchCtrl::OnSelect, this);
}

View File

@ -97,6 +97,9 @@ class OptionsSearcher
size_t found_size() const { return found.size(); }
public:
bool category{ false };
bool group{ true };
void init(std::vector<InputInfo> input_values);
bool search(const std::string& search, bool force = false);
@ -115,54 +118,30 @@ class SearchComboPopup : public wxListBox, public wxComboPopup
{
public:
// Initialize member variables
virtual void Init()
{
this->Bind(wxEVT_MOTION, &SearchComboPopup::OnMouseMove, this);
this->Bind(wxEVT_LEFT_UP, &SearchComboPopup::OnMouseClick, this);
}
void Init();
// Create popup control
virtual bool Create(wxWindow* parent)
{
return wxListBox::Create(parent, 1, wxPoint(0, 0), wxDefaultSize);
}
virtual bool Create(wxWindow* parent);
// Return pointer to the created control
virtual wxWindow* GetControl() { return this; }
// Translate string into a list selection
virtual void SetStringValue(const wxString& s)
{
int n = wxListBox::FindString(s);
if (n >= 0 && n < wxListBox::GetCount())
wxListBox::Select(n);
// save a combo control's string
m_input_string = s;
}
// Translate string into a list selection
virtual void SetStringValue(const wxString& s);
// Get list selection as a string
virtual wxString GetStringValue() const
{
virtual wxString GetStringValue() const {
// we shouldn't change a combo control's string
return m_input_string;
}
// Do mouse hot-tracking (which is typical in list popups)
void OnMouseMove(wxMouseEvent& event)
{
wxPoint pt = wxGetMousePosition() - this->GetScreenPosition();
int selection = this->HitTest(pt);
wxListBox::Select(selection);
}
// On mouse left up, set the value and close the popup
void OnMouseClick(wxMouseEvent& WXUNUSED(event))
{
int selection = wxListBox::GetSelection();
SetSelection(wxNOT_FOUND);
wxCommandEvent event(wxEVT_LISTBOX, GetId());
event.SetInt(selection);
event.SetEventObject(this);
ProcessEvent(event);
Dismiss();
}
void ProcessSelection(int selection);
// Do mouse hot-tracking (which is typical in list popups)
void OnMouseMove(wxMouseEvent& event);
// On mouse left up, set the value and close the popup
void OnMouseClick(wxMouseEvent& WXUNUSED(event));
// process Up/Down arrows and Enter press
void OnKeyDown(wxKeyEvent& event);
protected:
wxString m_input_string;
};