Add the ability to move filters up and down

This commit is contained in:
blankie 2023-02-24 18:23:56 +07:00
parent 43a47121e8
commit b8784cc26f
Signed by: blankie
GPG Key ID: CC15FC822C7F61F5
3 changed files with 61 additions and 12 deletions

View File

@ -1,6 +1,7 @@
#include <imgui/imgui.h> #include <imgui/imgui.h>
#include <imgui/misc/cpp/imgui_stdlib.h> #include <imgui/misc/cpp/imgui_stdlib.h>
#include "../misc.h"
#include "../group_panel.h" #include "../group_panel.h"
#include "../filters.h" #include "../filters.h"
#include "ok_buttons_fragment.h" #include "ok_buttons_fragment.h"
@ -13,7 +14,8 @@ static inline void render_priority_filter(PriorityFilter* filter);
static inline void render_group_filter(GroupFilter* filter); static inline void render_group_filter(GroupFilter* filter);
static std::unique_ptr<Filter> render_add_filter_popup(); static std::unique_ptr<Filter> render_add_filter_popup();
static void render_filter(Filter* filter, std::string* title, bool* request_removal) { static void render_filter(Filter* filter, std::string* title, bool* request_removal,
auto move_up, auto move_down, bool can_move_up, bool can_move_down) {
ImGui::PushID(filter); ImGui::PushID(filter);
ImGui::BeginGroupPanel(); ImGui::BeginGroupPanel();
@ -42,6 +44,15 @@ static void render_filter(Filter* filter, std::string* title, bool* request_remo
*request_removal = true; *request_removal = true;
} }
ImGui::SameLine();
if (ImGui::ArrowButton("##up", ImGuiDir_Up, can_move_up)) {
move_up();
}
ImGui::SameLine();
if (ImGui::ArrowButton("##down", ImGuiDir_Down, can_move_down)) {
move_down();
}
{ {
ImGui::SameLine(); ImGui::SameLine();
bool disabled = filter->disabled(); bool disabled = filter->disabled();
@ -162,16 +173,28 @@ static inline void render_group_filter(GroupFilter* filter) {
filter->type = static_cast<GroupFilter::Type>(selected_type); filter->type = static_cast<GroupFilter::Type>(selected_type);
} }
for (std::vector<std::unique_ptr<Filter>>::iterator it = filter->filters.begin(); it != filter->filters.end();) { std::vector<std::pair<size_t, size_t>> swaps_to_do;
std::vector<size_t> removals_to_do;
for (size_t i = 0; i < filter->filters.size(); i++) {
bool removal_requested = false; bool removal_requested = false;
render_filter(it->get(), nullptr, &removal_requested); render_filter(filter->filters[i].get(), nullptr, &removal_requested, [&]() {
swaps_to_do.push_back(std::make_pair(i, i - 1));
}, [&]() {
swaps_to_do.push_back(std::make_pair(i, i + 1));
}, i != 0, i + 1 != filter->filters.size());
if (removal_requested) { if (removal_requested) {
filter->filters.erase(it); removals_to_do.push_back(i);
filter->updated();
} else {
it++;
} }
} }
for (auto &[lhs, rhs] : swaps_to_do) {
std::swap(filter->filters[lhs], filter->filters[rhs]);
filter->updated();
}
for (size_t i : removals_to_do) {
filter->filters.erase(filter->filters.begin() + static_cast<ssize_t>(i));
filter->updated();
}
if (ImGui::Button("+ add filter")) { if (ImGui::Button("+ add filter")) {
ImGui::OpenPopup("add_filter"); ImGui::OpenPopup("add_filter");
@ -212,15 +235,26 @@ void filters_fragment(Filters& inactive_filters) {
ImGui::TextWrapped("You can use regex for strings by prepending \"regex:\". " ImGui::TextWrapped("You can use regex for strings by prepending \"regex:\". "
"While editing titles, press Enter to use the new title or press Escape to keep the old one"); "While editing titles, press Enter to use the new title or press Escape to keep the old one");
for (Filters::iterator it = inactive_filters.begin(); it != inactive_filters.end();) { std::vector<std::pair<size_t, size_t>> swaps_to_do;
std::vector<size_t> removals_to_do;
for (size_t i = 0; i < inactive_filters.size(); i++) {
bool removal_requested = false; bool removal_requested = false;
render_filter(it->second.get(), &it->first, &removal_requested); render_filter(inactive_filters[i].second.get(), &inactive_filters[i].first, &removal_requested, [&]() {
swaps_to_do.push_back(std::make_pair(i, i - 1));
}, [&]() {
swaps_to_do.push_back(std::make_pair(i, i + 1));
}, i != 0, i + 1 != inactive_filters.size());
if (removal_requested) { if (removal_requested) {
inactive_filters.erase(it); removals_to_do.push_back(i);
} else {
it++;
} }
} }
for (auto &[lhs, rhs] : swaps_to_do) {
std::swap(inactive_filters[lhs], inactive_filters[rhs]);
}
for (size_t i : removals_to_do) {
inactive_filters.erase(inactive_filters.begin() + static_cast<ssize_t>(i));
}
if (ImGui::Button("+ add filter")) { if (ImGui::Button("+ add filter")) {
ImGui::OpenPopup("add_filter"); ImGui::OpenPopup("add_filter");

View File

@ -62,6 +62,19 @@ bool ImGui::Button(const char* label, bool enabled) {
return res; return res;
} }
bool ImGui::ArrowButton(const char* label, ImGuiDir dir, bool enabled) {
if (!enabled) {
ImGui::BeginDisabled();
}
bool res = ImGui::ArrowButton(label, dir);
if (!enabled) {
ImGui::EndDisabled();
}
return res;
}
bool ImGui::BeginWithCloseShortcut(const char* label, bool* p_open, ImGuiWindowFlags flags) { bool ImGui::BeginWithCloseShortcut(const char* label, bool* p_open, ImGuiWindowFlags flags) {
bool res = ImGui::Begin(label, p_open, flags); bool res = ImGui::Begin(label, p_open, flags);

2
misc.h
View File

@ -3,6 +3,7 @@
#include <string> #include <string>
typedef int ImGuiWindowFlags; // forward declaration from imgui/imgui.h typedef int ImGuiWindowFlags; // forward declaration from imgui/imgui.h
typedef int ImGuiKeyChord; // forward declaration from imgui/imgui.h typedef int ImGuiKeyChord; // forward declaration from imgui/imgui.h
typedef int ImGuiDir; // forward declaration from imgui/imgui.h
std::string quote(const std::string& str); std::string quote(const std::string& str);
void throw_system_error(int err, const char* what); void throw_system_error(int err, const char* what);
@ -13,6 +14,7 @@ namespace ImGui {
void TextUnformatted(const std::string& str); void TextUnformatted(const std::string& str);
bool RedButton(const char* label); bool RedButton(const char* label);
bool Button(const char* label, bool enabled); bool Button(const char* label, bool enabled);
bool ArrowButton(const char* label, ImGuiDir dir, bool enabled);
bool BeginWithCloseShortcut(const char* label, bool* p_open, ImGuiWindowFlags flags = 0); bool BeginWithCloseShortcut(const char* label, bool* p_open, ImGuiWindowFlags flags = 0);
// don't spill __all__ of imgui_internal.h // don't spill __all__ of imgui_internal.h
bool IsKeyPressed(ImGuiKeyChord key_chord, bool repeat = true); bool IsKeyPressed(ImGuiKeyChord key_chord, bool repeat = true);