Skip to content

Commit

Permalink
feat: add recursive functionality to filter_set
Browse files Browse the repository at this point in the history
Thanks to this functionality now the filter set can work with sublists. This means that if we have more widgets nested and we want to filter them showing them even if their parents don't match, now it's possible.
(Still not tested a lot)
  • Loading branch information
SamuMazzi committed Feb 26, 2024
1 parent c6b7197 commit 71c6b8c
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 18 deletions.
4 changes: 2 additions & 2 deletions dearpygui/_dearpygui.pyi

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion dearpygui/_dearpygui_RTD.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 7 additions & 5 deletions dearpygui/dearpygui.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion src/dearpygui_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -2660,7 +2660,6 @@ destroy_context(PyObject* self, PyObject* args, PyObject* kwargs)
GContext->started = false; // return to false after
});

// Doesn't pass tests
if (GContext->viewport != nullptr)
mvCleanupViewport(*GContext->viewport);

Expand Down
2 changes: 2 additions & 0 deletions src/mvAppItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2265,6 +2265,8 @@ DearPyGui::GetEntityParser(mvAppItemType type)
MV_PARSER_ARG_SHOW)
);

args.push_back({ mvPyDataType::Bool, "recursive", mvArgType::KEYWORD_ARG, "False", "Recursive behaviour for the filter. If a child matches the filter, also the parents will do it. (This is still an experimental feature and it can have a slight impact on the performance)" });

setup.about = "Helper to parse and apply text filters (e.g. aaaaa[, bbbbb][, ccccc])";
setup.category = { "Containers", "Widgets" };
setup.createContextManager = true;
Expand Down
71 changes: 62 additions & 9 deletions src/mvBasicWidgets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,14 @@ DearPyGui::fill_configuration_dict(const mvTooltipConfig& inConfig, PyObject* ou
PyDict_SetItemString(outDict, "hide_on_activity", mvPyObject(ToPyBool(inConfig.hide_on_move)));
}

void
DearPyGui::fill_configuration_dict(const mvFilterSetConfig& inConfig, PyObject* outDict)
{
if (outDict == nullptr)
return;

PyDict_SetItemString(outDict, "recursive", mvPyObject(ToPyBool(inConfig.recursive)));
}
//-----------------------------------------------------------------------------
// [SECTION] configure_item(...) specifics
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -1792,6 +1800,15 @@ DearPyGui::set_configuration(PyObject* inDict, mvTooltipConfig& outConfig)
if (PyObject* item = PyDict_GetItemString(inDict, "hide_on_activity")) outConfig.hide_on_move = ToBool(item);
}

void
DearPyGui::set_configuration(PyObject* inDict, mvFilterSetConfig& outConfig)
{
if (inDict == nullptr)
return;

if (PyObject* item = PyDict_GetItemString(inDict, "recursive")) outConfig.recursive = ToBool(item);
}

void
DearPyGui::set_configuration(PyObject* inDict, mvKnobFloatConfig& outConfig)
{
Expand Down Expand Up @@ -6299,6 +6316,41 @@ DearPyGui::draw_image_button(ImDrawList* drawlist, mvAppItem& item, mvImageButto
apply_drag_drop(&item);
}

void set_visibility(mvAppItem& item, bool visible) {
item.config.show = visible;
item.info.hiddenLastFrame = !visible;
item.info.shownLastFrame = visible;
}

bool
can_be_visible(ImDrawList* drawlist, mvAppItem& item, mvFilterSetConfig& config, bool forceTrue)
{
// Let's dive into the children to check them first
bool show_from_children = false;
for (auto& childset : item.childslots)
{
for (auto& child : childset)
{
if (can_be_visible(drawlist, *child, config, forceTrue)) {
// config._filtered[item.uuid] = true;
show_from_children = true;
}
}
}

if (forceTrue || show_from_children) {
set_visibility(item, true);
return true;
}

// If it has no children then we can check the item itself with the filter
bool show = config.imguiFilter.PassFilter(item.config.filter.c_str());

// We update the visibility of the item
set_visibility(item, show);
return show;
}

void
DearPyGui::draw_filter_set(ImDrawList* drawlist, mvAppItem& item, mvFilterSetConfig& config)
{
Expand All @@ -6307,23 +6359,24 @@ DearPyGui::draw_filter_set(ImDrawList* drawlist, mvAppItem& item, mvFilterSetCon
if (item.config.width != 0)
ImGui::PushItemWidth((float)item.config.width);

if (config.imguiFilter.IsActive())
{
if (config.imguiFilter.IsActive()) {
if (config.recursive) {
config._was_active = true;
can_be_visible(drawlist, item, config, false);
}
for (auto& childset : item.childslots)
{
for (auto& child : childset)
{
if (!config.imguiFilter.PassFilter(child->config.filter.c_str()))
continue;

child->draw(drawlist, ImGui::GetCursorPosX(), ImGui::GetCursorPosY());
}
}

}
else
{

if (config._was_active && config.recursive) {
/* Reset the situation */
config._was_active = false;
can_be_visible(drawlist, item, config, true);
}
for (auto& childset : item.childslots)
{
for (auto& child : childset)
Expand Down
7 changes: 7 additions & 0 deletions src/mvBasicWidgets.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ namespace DearPyGui
void fill_configuration_dict(const mvImageButtonConfig& inConfig, PyObject* outDict);
void fill_configuration_dict(const mvKnobFloatConfig& inConfig, PyObject* outDict);
void fill_configuration_dict(const mvTooltipConfig& inConfig, PyObject* outDict);
void fill_configuration_dict(const mvFilterSetConfig& inConfig, PyObject* outDict);

// specific part of `configure_item(...)`
void set_configuration(PyObject* inDict, mvSimplePlotConfig& outConfig);
Expand Down Expand Up @@ -109,6 +110,7 @@ namespace DearPyGui
void set_configuration(PyObject* inDict, mvImageConfig& outConfig);
void set_configuration(PyObject* inDict, mvImageButtonConfig& outConfig);
void set_configuration(PyObject* inDict, mvTooltipConfig& outConfig);
void set_configuration(PyObject* inDict, mvFilterSetConfig& outConfig);
void set_configuration(PyObject* inDict, mvKnobFloatConfig& outConfig);

// positional args TODO: combine with above
Expand Down Expand Up @@ -573,6 +575,9 @@ struct mvImageButtonConfig
struct mvFilterSetConfig
{
ImGuiTextFilter imguiFilter;
bool recursive = false;
// std::unordered_map<mvUUID, bool> _checked_in_frame; /* Elements already checked in this frame*/
bool _was_active = false; /* Was the filter active in the last frame */
};

struct mvTooltipConfig
Expand Down Expand Up @@ -1057,6 +1062,8 @@ class mvFilterSet : public mvAppItem
mvFilterSetConfig configData{};
explicit mvFilterSet(mvUUID uuid) : mvAppItem(uuid) {}
void draw(ImDrawList* drawlist, float x, float y) override { DearPyGui::draw_filter_set(drawlist, *this, configData); }
void handleSpecificKeywordArgs(PyObject* dict) override { DearPyGui::set_configuration(dict, configData); }
void getSpecificConfiguration(PyObject* dict) override { DearPyGui::fill_configuration_dict(configData, dict); }
void setPyValue(PyObject* value) override;
PyObject* getPyValue() override { return ToPyString(std::string(configData.imguiFilter.InputBuf)); }
};
Expand Down

0 comments on commit 71c6b8c

Please sign in to comment.