SpaiR / imgui-java

JNI based binding for Dear ImGui
MIT License
551 stars 90 forks source link

expose ImGuiTextFilter buffer #160

Closed phraktle closed 1 year ago

phraktle commented 1 year ago

Version

1.86.7

What part of the binding has gaps?

Dear ImGui

What is missing?

See https://github.com/ocornut/imgui/issues/6206 - is there a way to pass the buffer from an ImGuiTextFilter to an input field? If not, it would be great if it could at least be set explicitly.

SpaiR commented 1 year ago

I think it's possible to add, but usage of ImGuiTextFilter in the context of the binding is, in my opinion, very redundant.

Speaking about your use case, you can simply do:

// Class field
private ImString filter = new ImString();

// Method body
ImGui.inputTextWithHint("##filter", "Filter", filter);
String[] lines = {"aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world"};
for (String line : lines) {
    if (filter.isEmpty() || line.contains(filter.get())) {
        ImGui.bulletText(line);
    }
}

Will do absolutely what you need.

It's very useful to have an ImGuiUtil class. You can add method like:

public boolean isPassFilter(ImString filter, String str) {
    return filter.isEmpty() || line.contains(filter.get());
}

to have something like:

// Class field
private ImString filter = new ImString();

// Method body
ImGui.inputTextWithHint("##filter", "Filter", filter);
String[] lines = {"aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world"};
for (String line : lines) {
    if (ImGuiUtil.isPassFilter(filter, line)) {
        ImGui.bulletText(line);
    }
}
phraktle commented 1 year ago

Sure, one could reimplement the functionality – but it does a bit more than contains (parses OR and NOT expressions as well).

SpaiR commented 1 year ago

Agreed, that sounds like a point. 🤔

SpaiR commented 1 year ago

Added appropriate method.

Using example from the previous comment, it will work like:

// Class field
private ImString filterStr = new ImString();
private ImGuiTextFilter textFilter = new ImGuiTextFilter();

// Method body
ImGui.inputTextWithHint("##filter", "Filter", filterStr);

textFilter.setInputBuffer(filterStr.get());
textFilter.build();

String[] lines = {"aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world"};
for (String line : lines) {
    if (textFilter.passFilter(line)) {
        ImGui.bulletText(line);
    }
}
phraktle commented 1 year ago

Thanks, that works!

Note for the example: it's best to set the filter only on changes.

if (ImGui.inputTextWithHint("##filter", "Filter", filterStr)) {
    textFilter.setInputBuffer(filterStr.get());
    textFilter.build();
}