Search: Implemented cursor movement inside SearchWindow on Plater

This commit is contained in:
YuSanka 2020-04-20 17:37:03 +02:00
parent 6a8d0c5d84
commit 3b88dc2688
5 changed files with 110 additions and 10 deletions

View file

@ -4497,14 +4497,17 @@ bool GLCanvas3D::_render_search_list(float pos_x) const
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,
sidebar.get_searcher().category, sidebar.get_searcher().group,
sidebar.get_searcher().category, sidebar.get_searcher().group,
m_imgui_search_hovered_pos,
selected, edited, check_changed);
search_line = s;
delete [] s;
if (edited)
if (edited) {
sidebar.search_and_apply_tab_search_lines();
m_imgui_search_hovered_pos = -1;
}
if (check_changed) {
if (search_line == _u8L("Type here to search"))
@ -5065,7 +5068,7 @@ bool GLCanvas3D::_init_main_toolbar()
_deactivate_search_toolbar_item();
}
};
item.left.action_callback = GLToolbarItem::Default_Action_Callback;
item.left.action_callback = [this]() { m_imgui_search_hovered_pos = -1; }; //GLToolbarItem::Default_Action_Callback;
item.visibility_callback = GLToolbarItem::Default_Visibility_Callback;
item.enabling_callback = GLToolbarItem::Default_Enabling_Callback;
if (!m_main_toolbar.add_item(item))

View file

@ -505,6 +505,7 @@ private:
#endif // ENABLE_RENDER_STATISTICS
mutable int m_imgui_undo_redo_hovered_pos{ -1 };
mutable size_t m_imgui_search_hovered_pos{ size_t(-1) };
int m_selected_extruder;
Labels m_labels;

View file

@ -539,8 +539,69 @@ static bool selectable(const char* label, bool selected, ImGuiSelectableFlags fl
return pressed;
}
// Scroll so that the hovered item is at the top of the window
static void scroll_y(int hover_id)
{
if (hover_id < 0)
return;
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
float item_size_y = window->DC.PrevLineSize.y + g.Style.ItemSpacing.y;
float item_delta = 0.5 * item_size_y;
float item_top = item_size_y * hover_id;
float item_bottom = item_top + item_size_y;
float win_top = window->Scroll.y;
float win_bottom = window->Scroll.y + window->Size.y;
if (item_bottom + item_delta >= win_bottom)
ImGui::SetScrollY(win_top + item_size_y);
else if (item_top - item_delta <= win_top)
ImGui::SetScrollY(win_top - item_size_y);
}
// Scroll up for one item
static void scroll_up()
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
float item_size_y = window->DC.PrevLineSize.y + g.Style.ItemSpacing.y;
float win_top = window->Scroll.y;
ImGui::SetScrollY(win_top - item_size_y);
}
// Scroll down for one item
static void scroll_down()
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
float item_size_y = window->DC.PrevLineSize.y + g.Style.ItemSpacing.y;
float win_top = window->Scroll.y;
ImGui::SetScrollY(win_top + item_size_y);
}
// Use this function instead of ImGui::IsKeyPressed.
// ImGui::IsKeyPressed is related for *GImGui.IO.KeysDownDuration[user_key_index]
// And after first key pressing IsKeyPressed() return "true" always even if key wasn't pressed
static void process_key_down(ImGuiKey imgui_key, std::function<void()> f)
{
if (ImGui::IsKeyDown(ImGui::GetKeyIndex(imgui_key)))
{
f();
// set KeysDown to false to avoid redundant key down processing
ImGuiContext& g = *GImGui;
g.IO.KeysDown[ImGui::GetKeyIndex(imgui_key)] = false;
}
}
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)
bool& category, bool& group, size_t& hovered_id, size_t& selected, bool& edited, bool& check_changed)
{
// ImGui::ListBoxHeader("", size);
{
@ -581,30 +642,64 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co
ImGui::InputTextEx("", NULL, search_str, 20, search_size, 0, NULL, NULL);
edited = ImGui::IsItemEdited();
if (ImGui::IsItemDeactivated() && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Escape))) {
process_key_down(ImGuiKey_Escape, [&selected, search_str, str]() {
// use 9999 to mark selection as a Esc key
selected = 9999;
// ... and when Esc key was pressed, than revert search_str value
strcpy(search_str, str.c_str());
}
});
ImGui::BeginChildFrame(id, frame_bb.GetSize());
}
size_t i = 0;
const char* item_text;
int mouse_hovered = -1;
while (items_getter(i, &item_text))
{
selectable(item_text, false);
selectable(item_text, i == hovered_id);
if (ImGui::IsItemHovered())
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("%s", item_text);
hovered_id = size_t(-1);
mouse_hovered = i;
}
if (ImGui::IsItemClicked())
selected = i;
i++;
}
scroll_y(mouse_hovered);
// process Up/DownArrows and Enter
process_key_down(ImGuiKey_UpArrow, [&hovered_id, mouse_hovered]() {
if (mouse_hovered > 0)
scroll_up();
else {
if (hovered_id > 0 && hovered_id != size_t(-1))
--hovered_id;
scroll_y(hovered_id);
}
});
process_key_down(ImGuiKey_DownArrow, [&hovered_id, mouse_hovered, i]() {
if (mouse_hovered > 0)
scroll_down();
else {
if (hovered_id == size_t(-1))
hovered_id = 0;
else if (hovered_id < size_t(i - 1))
++hovered_id;
scroll_y(hovered_id);
}
});
process_key_down(ImGuiKey_Enter, [&selected, hovered_id]() {
selected = hovered_id;
});
ImGui::ListBoxFooter();
// add checkboxes for show/hide Categories and Groups

View file

@ -75,7 +75,7 @@ public:
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,
bool& category, bool& group, size_t& selected, bool& edited, bool& check_changed);
bool& category, bool& group, size_t& hovered_id, size_t& selected, bool& edited, bool& check_changed);
void disabled_begin(bool disabled);
void disabled_end();

View file

@ -10,6 +10,8 @@
#include <wx/combo.h>
#include <wx/popupwin.h>
#include "Preset.hpp"
#include "wxExtensions.hpp"
@ -175,7 +177,6 @@ public:
};
#include <wx/popupwin.h>
class PopupSearchList : public wxPopupTransientWindow
{