Willy-JL / F95Checker

GNU General Public License v3.0
101 stars 16 forks source link

Proof of concept: Managing filter sets using native imgui tabs #111

Closed r37r05p3C7 closed 5 months ago

r37r05p3C7 commented 5 months ago

After F95CheckerX died, I switched back to the regular version. I can manage with losing most of the functionality implemented there, except for the so-called 'sections.' An image taken from one of the recent forum posts:

It can be remedied with labels, but switching filters back and forth is a little bit annoying. So, I decided to take a look at littleraisins's code and see if it can be extracted and merged here. But, to be honest, I don't think it's worth saving. Hardcoding section names was a big mistake since the whole point of this tool is to be as flexible as possible to cater to all users.

My solution 'hijacks' imgui tabs, and instead of using them to switch UI blocks, it uses them to switch internal variables corresponding to different filter sets assigned by the users.

All sets persist across sessions and need to be manually deleted or renamed. If only one set is available, the tab bar is hidden, ensuring that at least one set always exists.

https://github.com/Willy-JL/F95Checker/assets/153987701/fbb59ecf-893e-4bc5-a3e6-e7acf8f2f2e5

It's a little bit rough around the edges but perfectly functional. If you think it's a good idea, we can proceed with full implementation.

r37r05p3C7 commented 5 months ago

Now, in the same post from which the above image was taken, the user mentioned that sections used to have different icons assigned to them, which works just fine when sections are hardcoded. However, dynamic tabs cannot reliably be assigned icons. Instead, I propose assigning icons to labels in the text form like "fa-whatever" and sending them to the extension along with the game IDs. Or ditching icons all together and sending label colors instead, which should be enough, imo.

Willy-JL commented 5 months ago

i really like this idea. much more comfortable with users making their own labels and creating filter tabs with the labels filtered, than juggling multiple lists and the complexity that comes with it.

as for the icons, i remember imgui had a native way to rename the tabs right from the tab bar... if this acts as a normal text box, maybe it could be possible to add the generic popup used for labels that allows users to insert icons, and insert their own in the tab titles...

either way ill have a look at the code soontm, but definitely great idea!

r37r05p3C7 commented 5 months ago

I'm mostly satisfied with the result; however, I encountered two issues.

The ordering of tabs is not preserved after closing the app, which I'm sure will annoy some users. But I'm not sure if keeping this state is worth it, considering added complexity. Right now, sets are stored in a dict[str, list[Filter]]. Keeping state would require us to change this structure to something like dict[int, dict[str, list[Filter]]] and add logic to detect and handle tab reordering. Personally, I feel like it's overkill, and we should keep things as they are now. Maybe you will find a better solution after a review.

The second issue is also related to tab interaction. Right now, tabs get selected on both left and right clicks. Although it doesn't prevent the context menu from being opened, and everything is functional, it makes it impossible to close a tab without first navigating to it. It's not a big issue, and I don't feel like delving deep into the imgui docs to figure out how to prevent this default behavior.

Willy-JL commented 5 months ago

bit of an update.

ive been discussing this with @FaceCrap to figure out how to make this work. first of all, if it were based on filters, it would need to happen after the filter rework, which i still have no clue how to go about implementing. also, in hindsight it would be confusing how each tab has its own filters and so on.

instead i think the best solution is a hibrid of this proof of concept and what littleraisins had previously. im thinking of a tab system when the user can create tabs as they prefer, and send a game to a tab manually. nothing automatic, and completely untied from filters. it would end up being sort of similar to the previous system littleraisins had, but it would be easily manageable by the user how many and which tabs they have. and of course, it would be visualized with a tab interface as you showed here, which i think works heaps better than the button system he had previously.

this would allow for filtering and search to work between tabs. you make a query/filter once, then switch tab and see what matches in each tab. in addition, there could be an option for "filter/search all tabs", which would make it so that as soon as you apply a search or a filter, it hides the tab bar and shows results from all tabs. this could be a right click option on the search bar, or a toggle in the filter area. probably on the search bar though, since im leaning towards a textual system for the filters rework eventually (similar to the search bars here on github).

so thanks for the idea and the proof of concept, but im not gonna merge this. however im already working on what i described above, and to be honest i dont think it will take that long to fully implement

r37r05p3C7 commented 5 months ago

I understand and completely agree, there's no point in merging this if you have something bigger in the works. I'm not sure why I was so laser-focused on filter sets. Having tabs decoupled from everything else is a much better solution with minimal complexity overhead. I'm excited to see where you'll take this idea!

Willy-JL commented 5 months ago

now implemented via 9fe7c046bdb9c064802c761899dba3bbfd6d2f18...087694fe65df738a500983b4f11002654630b567

sadly imgui actually doesnt yet have persistance of tab order between app launches, nor any way to retrieve the altered tab order, so i had to disable reordering. however i made it remember what tab was last selected. tabs are stored in db via IDs, so no need for complex key conflict checking thankfully. ended up with a simpler right click menu, since you can put text input widgets in there lol, and you can right click it to insert icons too. doesnt show if there are no custom tabs, and can create a first one by moving a game to a new tab.

feel like the core functionality is pretty solid like this. one other thing i can think of is showing what tab a game is located in with update popups, and maybe what i mentioned earlier with the option to search all tabs at once.

any other ideas? @FaceCrap too

FaceCrap commented 5 months ago

Man! You. Are. Fast.

I'm out today on babysitting duty. Will take a look at it when I get home tonight. But am excited to see how this works. 😁

r37r05p3C7 commented 5 months ago

Works great so far! I like how the input field can be placed right inside the context menu, some ImGui magic right there.

Some ideas for further improvements:

  1. I think some kind of confirmation before a tab is closed is a must-have, since most people(including myself) will be using tabs as a semi-permanent thing. I think a simple popup will do, with two buttons: Close tab and Close tab, remove games, along with some explanation. This will serve both as a buffer to avoid losing data and provide additional functionality so that you don't have to remove groups of games manually before deleting tabs.
  2. Just before this PR was closed, I experimented with my implementation, attempting to add an indicator showing the number of games in each tab. I was surprised by how well it worked, considering that this new code was copying globals.games and recalculating filters for each tab, each frame. Opened 50 or so tabs, and, well, no noticeable CPU load changes... computers are freaking fast. Anyway, here's what I'm talking about: image Should be easy to implement and resource efficient now, since tab property lives on Game object.
r37r05p3C7 commented 5 months ago

Non-related question: Have you considered creating a wiki in this repository and moving some of the content from the README there? Perhaps even shortening the thread on the forum and providing links to the wiki. I've noticed that many solutions to common problems are shared on the forum (a recent example), but they are challenging to find, even when using search. Content like this could be community-maintained under the 'Tips and Tricks' sections of the wiki. Plus reading subsections on the wiki is easier then navigating huge markdown file, imo. Just something to think about.

Willy-JL commented 5 months ago
  1. I think some kind of confirmation before a tab is closed is a must-have, since most people(including myself) will be using tabs as a semi-permanent thing. I think a simple popup will do, with two buttons: Close tab and Close tab, remove games, along with some explanation. This will serve both as a buffer to avoid losing data and provide additional functionality so that you don't have to remove groups of games manually before deleting tabs.

I was thinking of that option too, then remembered that you can bulk select and remove, so I though "just select all games in the tab and delete". As for the confirmation popup, yeah sure

2. Just before this PR was closed, I experimented with my implementation, attempting to add an indicator showing the number of games in each tab. I was surprised by how well it worked, considering that this new code was copying globals.games and recalculating filters for each tab, each frame. Opened 50 or so tabs, and, well, no noticeable CPU load changes... computers are freaking fast. Anyway, here's what I'm talking about: Should be easy to implement and resource efficient now, since tab property lives on Game object.

Interesting idea. Recalculating each frame is deffo a no from me. But considering how tabs are done now, could store multiple lists of sorted IDs, and when filtering or sorting changes then run sorting again for all tabs.

Non-related question: Have you considered creating a wiki in this repository and moving some of the content from the README there? Perhaps even shortening the thread on the forum and providing links to the wiki. I've noticed that many solutions to common problems are shared on the forum (a recent example), but they are challenging to find, even when using search. Content like this could be community-maintained under the 'Tips and Tricks' sections of the wiki. Plus reading subsections on the wiki is easier then navigating huge markdown file, imo. Just something to think about

Maybe? I'll think about it

Willy-JL commented 5 months ago

think i consider it done now. ended up with a somewhat clean implementation, with a reworked filter/sort pipeline with minimal copies and more efficient iterators. decided to skip on the "close tab and remove games" since thats too dangerous. instead i added ctrl+a to select all visible games easily