Search: Implemented cursor movement inside SearchWindow on Plater
This commit is contained in:
parent
6a8d0c5d84
commit
3b88dc2688
5 changed files with 110 additions and 10 deletions
|
@ -4498,13 +4498,16 @@ bool GLCanvas3D::_render_search_list(float pos_x) const
|
||||||
|
|
||||||
imgui->search_list(ImVec2(45 * em, 30 * em), &search_string_getter, s,
|
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);
|
selected, edited, check_changed);
|
||||||
|
|
||||||
search_line = s;
|
search_line = s;
|
||||||
delete [] s;
|
delete [] s;
|
||||||
|
|
||||||
if (edited)
|
if (edited) {
|
||||||
sidebar.search_and_apply_tab_search_lines();
|
sidebar.search_and_apply_tab_search_lines();
|
||||||
|
m_imgui_search_hovered_pos = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (check_changed) {
|
if (check_changed) {
|
||||||
if (search_line == _u8L("Type here to search"))
|
if (search_line == _u8L("Type here to search"))
|
||||||
|
@ -5065,7 +5068,7 @@ bool GLCanvas3D::_init_main_toolbar()
|
||||||
_deactivate_search_toolbar_item();
|
_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.visibility_callback = GLToolbarItem::Default_Visibility_Callback;
|
||||||
item.enabling_callback = GLToolbarItem::Default_Enabling_Callback;
|
item.enabling_callback = GLToolbarItem::Default_Enabling_Callback;
|
||||||
if (!m_main_toolbar.add_item(item))
|
if (!m_main_toolbar.add_item(item))
|
||||||
|
|
|
@ -505,6 +505,7 @@ private:
|
||||||
#endif // ENABLE_RENDER_STATISTICS
|
#endif // ENABLE_RENDER_STATISTICS
|
||||||
|
|
||||||
mutable int m_imgui_undo_redo_hovered_pos{ -1 };
|
mutable int m_imgui_undo_redo_hovered_pos{ -1 };
|
||||||
|
mutable size_t m_imgui_search_hovered_pos{ size_t(-1) };
|
||||||
int m_selected_extruder;
|
int m_selected_extruder;
|
||||||
|
|
||||||
Labels m_labels;
|
Labels m_labels;
|
||||||
|
|
|
@ -539,8 +539,69 @@ static bool selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||||
return pressed;
|
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,
|
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);
|
// 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);
|
ImGui::InputTextEx("", NULL, search_str, 20, search_size, 0, NULL, NULL);
|
||||||
edited = ImGui::IsItemEdited();
|
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
|
// use 9999 to mark selection as a Esc key
|
||||||
selected = 9999;
|
selected = 9999;
|
||||||
// ... and when Esc key was pressed, than revert search_str value
|
// ... and when Esc key was pressed, than revert search_str value
|
||||||
strcpy(search_str, str.c_str());
|
strcpy(search_str, str.c_str());
|
||||||
}
|
});
|
||||||
|
|
||||||
ImGui::BeginChildFrame(id, frame_bb.GetSize());
|
ImGui::BeginChildFrame(id, frame_bb.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
const char* item_text;
|
const char* item_text;
|
||||||
|
int mouse_hovered = -1;
|
||||||
|
|
||||||
while (items_getter(i, &item_text))
|
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);
|
ImGui::SetTooltip("%s", item_text);
|
||||||
|
hovered_id = size_t(-1);
|
||||||
|
mouse_hovered = i;
|
||||||
|
}
|
||||||
|
|
||||||
if (ImGui::IsItemClicked())
|
if (ImGui::IsItemClicked())
|
||||||
selected = i;
|
selected = i;
|
||||||
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();
|
ImGui::ListBoxFooter();
|
||||||
|
|
||||||
// add checkboxes for show/hide Categories and Groups
|
// add checkboxes for show/hide Categories and Groups
|
||||||
|
|
|
@ -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 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,
|
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_begin(bool disabled);
|
||||||
void disabled_end();
|
void disabled_end();
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
#include <wx/combo.h>
|
#include <wx/combo.h>
|
||||||
|
|
||||||
|
#include <wx/popupwin.h>
|
||||||
|
|
||||||
#include "Preset.hpp"
|
#include "Preset.hpp"
|
||||||
#include "wxExtensions.hpp"
|
#include "wxExtensions.hpp"
|
||||||
|
|
||||||
|
@ -175,7 +177,6 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#include <wx/popupwin.h>
|
|
||||||
|
|
||||||
class PopupSearchList : public wxPopupTransientWindow
|
class PopupSearchList : public wxPopupTransientWindow
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue