New scriptable UI COMP

I’m not sure exactly what form this should take, but I increasingly feel like TouchDesigner is missing a fully scriptable UI component.

In the AI era, I’m developing tools and the code behind them faster than ever, but I keep getting slowed down when it comes to actually building the UI for tools in TouchDesigner. The current Container COMP workflow is powerful, but for tooling it can feel quite slow and manual compared to how quickly I can now mock up an interface in Python, HTML/CSS, etc.

And the more complex the tool gets, the worse this becomes. At some point, the UI almost turns into a project of its own, with its own structure, logic, replication, layout issues and headaches.

I don’t think Containers should go away at all. I’d still use them for final user-facing interfaces where I want everything to be very explicitly built in TD.

What I’m imagining is maybe a new COMP type whose UI is primarily defined through script.

A few things that would seem important to me:

  • Containers and this new COMP type should share the same layout system, so things like parent, filling/sizing, depth/layout order, alignment and positioning behave consistently between them so both types can be mixed together naturally.

  • The scripted UI could have direct access to the TouchDesigner session. It should be possible to directly reference operators, parameters, TOPs, CHOPs, DATs and POPs from the UI script itself. For example:

slider(value=op('settings').par.Gain)
viewer(op('render1'))
label(op('info')[0, 0])
  • The scripted UI could expose its controls and interaction state back to TouchDesigner in a simple, native way, so the network can reference them rather than requiring the UI script to directly modify operators. For example:
op('newUIcomp').slider('Gain')
op('newUIcomp').toggle('Enabled')
op('newUIcomp').button('Reset')
  • Scripted UI elements could expose normal TD-style panel information such as u, v, select, rollover, lselect, mselect, etc., and the UI COMP itself could provide callbacks for those panel changes across any element. Embedded OP viewers would simply be one useful case of that. For example:
op('newUIcomp').viewer('Render').sourceOp()
op('newUIcomp').button('Reset').select
op('newUIcomp').slider('Gain').rollover
def onPanelValueChange(panel, name, value):
    if name == 'select' and value:
        debug(panel.name, panel.u, panel.v)

The main appeal would be iteration speed. Today I can describe a tool UI to an AI and get a surprisingly good HTML or Python mockup almost instantly, but recreating that same thing using Containers, replicators, panel values, parameter expressions, etc. can easily become the slowest part of developing the tool.

I also think this could make tools much easier to understand, maintain and modified when they are handed over to someone else. Instead of having to dig through a cascade of nested Containers just to understand how part of the interface is built or move something around, a large part of the UI structure could potentially be readable in one place.

With TouchDesigner handling the actual logic and data underneath, a scriptable UI layer like this could be extremely powerful.

I’m not sure what the actual implementation should look like. Since Python already has direct access to the TD session, maybe this could be some kind of native UI library/API exposed to Python, with constructors for controls, layout, OP display, interaction, etc.

The important part would be being able to define an interface very quickly in code while still having native access to everything in the TD network.

2 Likes

Agreed on this – the more API, the better!

I imagine that the TouchDesigner UI system will be overhauled at some point. For now, I recommend my tool Embody for creating native TouchDesigner UIs with AI. I’ve put quite some time into it, especially around skills for TouchDesigner-specific features like Container COMPs. I’ve seen developers using it for Touch UIs with incredible results so far.