TexConvGui NG


Hey, this is a re-implementation of the small utility I made some years ago originally. It’s just a simple Gui for Microsoft’s Texconv to batch convert images.

It is based on the all new vvvv preview version 2022.5 that introduces .net6 and the bleeding edge VL.ImGui library.
While fully working now, it should be considered highly experimental, any update to VL.ImGui will likely break stuff (in TexConvGui). Latest known working commit is 6d399d62af2d1c74e1f49b6db75f5e9e937b8cf8.

Unfortunately exporting seems to be broken in the used vvvv version (2022.5.0-0101) , so no compiled binary can be provided.

To get the patch to run please follow the installation instructions of VL.ImGui first.
Afterwards clone or download the TexConvGui repo.
Now start vvvv with --package-repositories path\to\your-vl-libs and then open TexConvGui.vl.


Some random thoughts / ideas / questions that came up while working on the patch.

I wanted to “re-patch” this for quite some time already, but elementa was lacking a key component, namely a fixed size scrollable combobox / dropdown and I was too lazy to add one myself (or to even start my own Gui like @catweasel did).

Borrowed some “things” from @sebescudie’s GammLauncher. Thanks for that!

Maybe interesting to the ImGui team (@Elias / @gregsn / @robotanton / @sebescudie):

  • VL.ImGui is still under heavy development but already feels more accessible than elementa and also seems to be more performant. On the flipside it is a lot less flexible when it comes to styling/ extensibility and there are not (yet) as many widgets.

  • When re-opening a patch that contains ToSkiaLayer [ImGui] vvvv crashes

  • The BehaviorSubject of the widgets seems to “trigger” once on startup, I had to add some workarounds for that.

  • I couldn’t find a way to disable interaction on single widgets. I somehow thought it could be done using Selectable with Flags set to Disabled but it didn’t work. (There is an example inside the FileIO subpatch inside UI).

  • I couldn’t find away to change the style / color of Progressbar. In general the styling options of ImGui are a bit cryptic and the documentation of it is really bad. But I guess this will be addressed by this todo on github.

  • I am opening a modal folder browser and while the widgets can not really be interacted with, their events still trigger after closing the dialog. So if for example the source button is clicked again while the dialog is open, new dialogs will pop up after closing the one before (as many times as the button was clicked). I couldn’t find a wokaround for that. Is this a bug or a feature?

  • Some widgets cannot deal with display scaling settings > 100%.

  • Widgets need a unique label, otherwise actions on one widget will also trigger changes on an other one.

  • Add ## as pre-fix to a label to make it not show up in the gui

  • VL.ImGui.vl currently references the ImGui.NET nuget. Wouldn’t it be more practical to reference the dll directly since it already comes with VL.ImGui.dll in the lib folder?

  • I was often wondering when to do something “on the mainloop” or “inside an observable” (not sure about the terminology). Would really love some input on this. Silly example:

    (I already learned to open a modal dialog only from the ui thread…)

  • I looked at some development patterns / other apps beforehand. Like @dottore’s Model-Runtime-Editor and @sebescudie 's GammLauncher. A lot of times the stuff is “heavily fragmented” (again not sure about terminology) and using references all the time. I might be ignorant but to me it appeared to be kind of over-engineered - at least for small apps.
    Would appreciate some insights, best practice tips (especially from the devvvvs) in that regard. Also some feedback on the “structure” I used and in general ideas for improvements.

Add Two

Not Sure if this is related to / caused by the Imgui stuff but 2022.5 was a bit trying to patch with.
Timings stop showing (mostly in subpatches). Changes are not picked up by the system. For example:

  • changes made to inputs / io-boxes jump back to a previous value
  • newly added ouput-boxes don’t show changed values
  • newly added nodes are not executed
    Restarting the patch (F9) didn’t help by itself. Only thing that worked for me was saving and reloading/reverting the document and then pressing F9.

This pretty cool, thought to ask you to share prev texconvgui sources on git to add batching ;) but this even better

Added a compiled exe on the TexconvGui contribution page .

VL.ImGui still has problems with Display scaling. Added a workaround, multiplying the widget sizes by DipFactor in the patch, still the result doesn’t look quite correct for scalings other than 100%.
Another “bug” I encountered: Setting a padding for the window also increases the padding of tooltips which shouldn’t happen imho.

Hi @bjoern,

sorry for the late response and thanks so much for your feedback. We’re slowly trying to tackle all of them.
Let me for now just respond to some:

@robotanton will go through all “value widgets” and do a Channel-based version, which will not trigger once on startup. Let’s see what’s the downside of not having that ;)

I am bit confused about this one. I had a look at your patch and I would have done the same - based on the current node-design. However, shouldn’t the node look different and have a widget input? @robotanton In order to isolate that group of widgets, that shall be not selectable?

I am actually wondering if this will be fixed as soon as everything is done via Channels.

Can you be more verbose on this one?

answer unrelated to ImGui:
In vvvv beta everything was done on update and we were excited to finally be able to get a hand on every event - like a keystroke or a mouse move. With observables we now are able to react on events just in time. We however needed to learn that there is no general way of telling when you should react on some event directly or postpone that reaction. It depends on the event source.
When talking about those event sources that trigger fast (like mouse move of a high DPI mouse) it’s not so much about when you react on it, but just the fact that you don’t want to miss anything. The Sampler node collects all events and hands them as a spread on update. In this scenario there is no resource that you need to consume right-away before it’s mutating. Mouse move notifications have only immutable data in them and you can react on them on Update with a combination of Sampler and a regular ForEach. HoldLatest however only gives you the last state.

ImGui specific answer:
ImGui (and the Skia Renderer) triggers on Paint, on the same thread as the mainloop, just in between the update calls. You have the guarantee that the patch completely updated when the innards of a Reactive ForEach get called. This might sometimes be desirable when reasoning about a patch. But, actually, in immediate mode that is incorrect. In Immediate mode we are already in the Paint-moment.
So, it’s tricky in general, but I guess I can recommend something regarding ImGui:
use HoldLatest. ImGui widgets only trigger once per frame anyway. And it’s easier to work with If regions than with Reactive Foreach regions.

The main idea of that pattern is to have a model. But if you don’t need a model - no need for saving and loading configurations, no need for undo/redo - you should be ok without it.
Just had another look. I see that you split UI from Controller on a top-level. I am wondering if there is an even more direct “unfragmented” way of patching that tool? - but I might be ignorant ;)
That said: I guess, again, the Channel idea and especially the “Select Channels By Path” pattern could also change the way you want to think about Model, Controller and UI.

This is being looked at.

I think this is outdated. There is a node called Disable(d?) with a Widget input now.

All widgets that have sizes set explicitly (Witdh / Height) don’t scale correctly if the Display Scaling is set to something different than 100%. So an Input (String) with Width set to 200 for example will only be 100 wide when the display is set to 200%. I have a branch on github where I “manually” multiply all sizes with DipFactor as a workaround, which is better, but still doesn’t look quite correct.
I have seen that in ToSkiaLayer the scaling is already applied but it seems to be missing something.

If you are bored maybe give it a go :) Same goes for others that have ideas for improvements. I’d really love to have concrete examples / see different approaches. I am just too slow to comprehend abstract descriptions of design patterns.

regarding Selectable: we both had awrong intuition. The node doesn’t configure another widget. It is a widget itself.

converted some pictures and noticed that it exported with mips

bump! awsome tool.

Yeah it’s a known bug. But I have been putting off fixing it because VL.Imgui completely changed.

You can use the 1.3 version.

1 Like