Skip to content

Add custom control layouts for Dragonfly reverbs (+ MOD UI toggle fix) - #562

Draft
diamondsea11 wants to merge 2 commits into
rerdavies:mainfrom
diamondsea11:upstream-pr/plugin-custom-layouts
Draft

Add custom control layouts for Dragonfly reverbs (+ MOD UI toggle fix)#562
diamondsea11 wants to merge 2 commits into
rerdavies:mainfrom
diamondsea11:upstream-pr/plugin-custom-layouts

Conversation

@diamondsea11

Copy link
Copy Markdown

From #555: "Custom layouts for various plugins (Chow Tape, Calf, Dragonfly, Dusk Reverb): definitely interested."

This delivers Dragonfly only. The other three turned out not to be what the list implied — details below.

What's here

DragonflyView.tsx groups Dragonfly's controls the way the plugin's own documentation presents them, instead of the flat knob list the generated view produces. Covers urn:dragonfly:early, :plate and :room.

Dragonfly Hall is not included. It has a different control set and would need its own layout — flagging that since the plugin family is usually thought of as four.

A MOD UI fix that comes with it

The factory loop returned a custom view unconditionally:

for (let i = 0; i < pluginFactories.length; ++i) { ... }   // ran even when showModUi

So for any plugin with both a custom view and a modgui, switching the MOD UI toggle on did nothing — the custom factory short-circuited before PluginControlView could host the modgui. The loop is now skipped when showModUi is set.

This is pre-existing behaviour rather than something I introduced, but it only becomes visible once plugins that have both start appearing.

The other three plugins from your list

Dusk — its view is written and working in the fork, but it depends on numeric LV2 patch properties: seven extra fields on Lv2PatchPropertyInfo (minValue, maxValue, defaultValue, logarithmic, integer, enumeration, toggled) plus isNumeric() / toUiControl(), populated host-side. That's the "generic numeric LV2 patch properties" item, not this one. I'd rather send it after that lands than bundle a host-model change into a layouts PR.

Worth mentioning how I found that: my first attempt at this branch included Dusk, and tsc rejected it. Reading the diff hadn't shown it.

Chow Tape and Calf — these aren't PiPedal code at all. They're MOD GUI skins (patches/chow-tape-modgui, patches/calf-modgui in the fork) that install alongside the plugins. Third-party plugin assets, so out of scope here per your own note about not mixing plugin bundles and skins into core PRs. Happy to point you at them separately if they're useful, but they're not mine to contribute.

Verification

npx tsc -b --force in vite/ exits 0 on this branch. DragonflyView.tsx is byte-identical to the fork original. Not visually re-tested in this isolated form; the fork it came from runs daily on an iPad.

Provenance

As discussed in #555: I'm not a developer, and this is AI-implemented from my descriptions. This is UI code, which you noted is where AI does worst — please review accordingly.

Targeting main since that's what the branch is based on — happy to retarget to dev.

Dragonfly's generated control view is a long flat list of knobs that gives no
hint which ones interact. DragonflyView groups them the way the plugin's own
documentation presents them, so the reverbs are usable without consulting it.

Covers urn:dragonfly:early, :plate and :room. Dragonfly Hall is NOT included --
it has a different control set and would need its own layout.

Also fixes a MOD UI interaction that this makes reachable: the factory loop
returned a custom view unconditionally, so for any plugin with both a custom
view and a modgui, switching the MOD UI toggle on had no effect -- the custom
factory short-circuited before PluginControlView could host the modgui. The
loop is now skipped when showModUi is set. This is pre-existing behaviour, but
it only becomes visible once plugins that have both start appearing.

Deliberately not included:

Dusk. Its view depends on numeric LV2 patch properties, which needs seven
additional fields on Lv2PatchPropertyInfo (minValue, maxValue, defaultValue,
logarithmic, integer, enumeration, toggled) plus isNumeric()/toUiControl(),
populated host-side. That is the "generic numeric LV2 patch properties" item,
not this one. Found by compiling rather than by reading -- tsc rejected the
first attempt at this branch, which had Dusk in it.

Chow Tape and Calf. Those are not PiPedal code at all: they are MOD GUI skins
(patches/chow-tape-modgui, patches/calf-modgui in the fork) that install
alongside the plugins themselves. Third-party plugin assets, so out of scope
for a PiPedal PR.

Verified: npx tsc -b --force in vite/ exits 0 on this branch, and
DragonflyView.tsx is byte-identical to the fork original.

Extracted from the diamondsea11/pipedal fork (feature/multipath-v1) for
independent review, per the maintainer's request in
rerdavies#555 to evaluate fork changes
one topic at a time.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
diamondsea11 pushed a commit to diamondsea11/pipedal that referenced this pull request Aug 6, 2026
"Custom layouts for Chow Tape, Calf, Dragonfly, Dusk" turned out to be three
different things, not one item:

Dragonfly is PiPedal code and is now draft PR rerdavies#562 (early/plate/room; Hall has
a different control set and is not covered). It also carries a pre-existing MOD
UI fix -- the factory returned a custom view even when showModUi was set, so
the modgui could never be shown for a plugin that had both.

Dusk is written but depends on item 3: seven extra Lv2PatchPropertyInfo fields
plus isNumeric()/toUiControl(), populated host-side. tsc rejected the first
version of the branch, which had Dusk in it -- reading the diff had not shown
the dependency.

Chow Tape and Calf are MOD GUI skins under patches/, third-party plugin assets
rather than PiPedal source, so they do not belong in a core PR at all.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Custom plugin views wrap PluginControlView, but they currently have no way to
restyle what it renders: the control-group frame, its title and the control
grid are addressable only through generated Emotion class names.

Emit stable data attributes on those elements so a custom view can restyle
them from its own stylesheet:

  plugin-control-frame, control-grid, control-group, control-group-title,
  control-group-controls, custom-control

plus data-group-name on each group, carrying the LV2 port-group name so a view
can style individual groups.

Attributes only. No behaviour change, no new dependency, nothing reads them
back, and the default appearance is byte-for-byte unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@diamondsea11

Copy link
Copy Markdown
Author

Correction to this PR — my error, flagging it before you spend time on it.

As originally submitted this branch did not work. DragonflyView styles the control groups entirely through [data-pipedal-role=...] and [data-group-name=...] selectors, and those attributes are emitted by PluginControlView in my fork but were not part of this extraction. On main none of the selectors matched, so the skin rendered as an ordinary control view with a dark background wrapper and nothing else.

I have pushed the missing commit onto this branch, so it is now self-consistent and tsc -b --force is clean. That same commit is also up on its own as #564, since the attributes are generic and useful independently of Dragonfly — if you merge #564 first, the duplicate here drops out cleanly on rebase. If you would rather this PR stay standalone, say so and I will leave it as is.

@rerdavies

Copy link
Copy Markdown
Owner

Generically, ahead of time, wrt/ all of the pull requests.

Brilliant! Thanks for this. It will take me a few days to sort through them one by one. I'll let know you know if there are any problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants