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
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue