refactor(manifold): remove redundant UI copy
This commit is contained in:
parent
32c4825a69
commit
ae256ecfbd
3 changed files with 4 additions and 108 deletions
|
|
@ -161,7 +161,7 @@ for the narrow pane.
|
||||||
controls are available in both condensed and expanded views; the output rows fill the remaining drawer height
|
controls are available in both condensed and expanded views; the output rows fill the remaining drawer height
|
||||||
and scroll independently at both depths. The orange drawer tab uses `<` to expand and `>` to condense.
|
and scroll independently at both depths. The orange drawer tab uses `<` to expand and `>` to condense.
|
||||||
- **settings** — icon style (monochrome/colour), input-map shape (xy/joystick/rect/circular), corner radius.
|
- **settings** — icon style (monochrome/colour), input-map shape (xy/joystick/rect/circular), corner radius.
|
||||||
- **help** — keymap pills + loop explanation.
|
- **help** — keymap pills + explainer link.
|
||||||
- `src/dock/` holds the output-routing internals used by the `route` drawer:
|
- `src/dock/` holds the output-routing internals used by the `route` drawer:
|
||||||
- `output-state.ts` — the per-output control model: `OutputControl` (state/muted/armed/min/max/
|
- `output-state.ts` — the per-output control model: `OutputControl` (state/muted/armed/min/max/
|
||||||
curve/fixedValue + backend specs `MidiCcSpec`/`OscSpec`/`VcvSpec`), `toOutputControl()`,
|
curve/fixedValue + backend specs `MidiCcSpec`/`OscSpec`/`VcvSpec`), `toOutputControl()`,
|
||||||
|
|
|
||||||
|
|
@ -214,20 +214,9 @@ export function CompositeStage({
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
gap: 10,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{renderPad(s)}
|
{renderPad(s)}
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 10,
|
|
||||||
color: 'var(--fg-mute)',
|
|
||||||
fontFamily: 'var(--font-mono)',
|
|
||||||
fontVariantNumeric: 'tabular-nums',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{pos[0].toFixed(2)}, {pos[1].toFixed(2)}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
* "Particle/Visual" drawers are REMOVED — their config now
|
* "Particle/Visual" drawers are REMOVED — their config now
|
||||||
* lives here under the active Mode (TOP dock selector).
|
* lives here under the active Mode (TOP dock selector).
|
||||||
* settings — Settings : icon style, input-map shape + feature flags
|
* settings — Settings : icon style, input-map shape + feature flags
|
||||||
* help — Help : keymap + the loop explanation
|
* help — Help : keymap + explainer link
|
||||||
*
|
*
|
||||||
* The TOP dock selector ("Mode") chooses the active OUTPUT backend/target; this
|
* The TOP dock selector ("Mode") chooses the active OUTPUT backend/target; this
|
||||||
* drawer renders whatever that backend needs.
|
* drawer renders whatever that backend needs.
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
*/
|
*/
|
||||||
import { useState, type ReactNode } from 'react';
|
import { useState, type ReactNode } from 'react';
|
||||||
import { Badge, Button, PillToggle, Slider, Switch } from '../primitives';
|
import { Badge, Button, PillToggle, Slider, Switch } from '../primitives';
|
||||||
import type { ConsoleCtx, DrawerDepth, DrawerKey, FeedbackModeUI, SoloMode } from './types';
|
import type { ConsoleCtx, DrawerDepth, DrawerKey, FeedbackModeUI } from './types';
|
||||||
import type { InputMode } from '../inputs';
|
import type { InputMode } from '../inputs';
|
||||||
import { OutputControlRow } from '../dock/OutputControlRow';
|
import { OutputControlRow } from '../dock/OutputControlRow';
|
||||||
import { OutputsBackendConfig, BackendStatusChip } from '../dock/OutputsBackendConfig';
|
import { OutputsBackendConfig, BackendStatusChip } from '../dock/OutputsBackendConfig';
|
||||||
|
|
@ -140,24 +140,6 @@ const FEEDBACK_DESC: Record<FeedbackModeUI, string> = {
|
||||||
'explore-and-place':
|
'explore-and-place':
|
||||||
'Down re-rolls the whole net into a scratchpad you audition; + places a liked sound (Mode 2).',
|
'Down re-rolls the whole net into a scratchpad you audition; + places a liked sound (Mode 2).',
|
||||||
};
|
};
|
||||||
/**
|
|
||||||
* Solo behaviour. `mask-gradients` is the only variant the core actually
|
|
||||||
* implements — `soloMode` has no other observable effect today (the other two
|
|
||||||
* options need the C API's `train_masked` step). Rendered as a fixed,
|
|
||||||
* non-selectable label rather than a picker that offers dead choices
|
|
||||||
* (simplification audit L20).
|
|
||||||
*/
|
|
||||||
const SOLO_OPTS: { value: SoloMode; label: string }[] = [
|
|
||||||
{ value: 'mask-gradients', label: 'Mask gradients' },
|
|
||||||
{ value: 'zero-loss', label: 'Zero loss' },
|
|
||||||
{ value: 'dont-care', label: "Don't-care mask" },
|
|
||||||
];
|
|
||||||
const SOLO_DESC: Record<SoloMode, string> = {
|
|
||||||
'mask-gradients': 'Column-freeze (default) — only the armed output moves; the rest stay bit-identical.',
|
|
||||||
'zero-loss': 'Expressive, but armed and unarmed outputs share hidden weights, so others can drift.',
|
|
||||||
'dont-care': 'Each example stores a per-output mask so stale labels never pull unarmed outputs.',
|
|
||||||
};
|
|
||||||
|
|
||||||
function ModelArchitecture() {
|
function ModelArchitecture() {
|
||||||
const engine = useEngine();
|
const engine = useEngine();
|
||||||
useEngineVersion(engine);
|
useEngineVersion(engine);
|
||||||
|
|
@ -308,9 +290,6 @@ function LearningDrawer(ctx: ConsoleCtx, depth: DrawerDepth) {
|
||||||
>
|
>
|
||||||
Jolt {ctx.joltActive ? '(morphing…)' : '(hold)'}
|
Jolt {ctx.joltActive ? '(morphing…)' : '(hold)'}
|
||||||
</Button>
|
</Button>
|
||||||
<span style={{ fontSize: 'var(--fs-xs)', color: 'var(--fg-dim)' }}>
|
|
||||||
hold to morph the whole net live · release to freeze
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<Slider
|
<Slider
|
||||||
label="explore · output wander"
|
label="explore · output wander"
|
||||||
|
|
@ -320,14 +299,6 @@ function LearningDrawer(ctx: ConsoleCtx, depth: DrawerDepth) {
|
||||||
step={0.01}
|
step={0.01}
|
||||||
onChange={ctx.setExploreIntensity}
|
onChange={ctx.setExploreIntensity}
|
||||||
/>
|
/>
|
||||||
{depth === 'expanded' && (
|
|
||||||
<p style={{ fontSize: 'var(--fs-xs)', color: 'var(--fg-dim)', margin: 0, lineHeight: 1.6 }}>
|
|
||||||
Explore adds a slow random walk (Ornstein-Uhlenbeck) on the outputs so the sound roams;
|
|
||||||
likes and dislikes registered mid-wander steer the net toward what you want. 0 = off. Jolt
|
|
||||||
(firmware TogB1) and Explore (RVX1) drive the same core gestures as the MEMLNaut hardware.
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<SectionLabel>Recorded examples</SectionLabel>
|
<SectionLabel>Recorded examples</SectionLabel>
|
||||||
<div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
|
<div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
|
||||||
<Chip>
|
<Chip>
|
||||||
|
|
@ -357,13 +328,6 @@ function LearningDrawer(ctx: ConsoleCtx, depth: DrawerDepth) {
|
||||||
: 'every live output learns'}
|
: 'every live output learns'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<SectionLabel>Solo behaviour</SectionLabel>
|
|
||||||
<Chip tone="var(--accent)">{SOLO_OPTS.find((o) => o.value === ctx.soloMode)?.label}</Chip>
|
|
||||||
<p style={{ fontSize: 'var(--fs-xs)', color: 'var(--fg-dim)', margin: 0, lineHeight: 1.6 }}>
|
|
||||||
{SOLO_DESC[ctx.soloMode]} Solo only freezes the rest as far as a shared network allows.
|
|
||||||
The other two behaviours need real core support (`train_masked`) and aren't selectable yet.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<SectionLabel>Live training params</SectionLabel>
|
<SectionLabel>Live training params</SectionLabel>
|
||||||
<Slider label="noise cap" value={ctx.noiseCap} min={0} max={0.5} step={0.01} onChange={ctx.setNoiseCap} />
|
<Slider label="noise cap" value={ctx.noiseCap} min={0} max={0.5} step={0.01} onChange={ctx.setNoiseCap} />
|
||||||
</>
|
</>
|
||||||
|
|
@ -371,12 +335,6 @@ function LearningDrawer(ctx: ConsoleCtx, depth: DrawerDepth) {
|
||||||
|
|
||||||
{depth === 'expanded' && (
|
{depth === 'expanded' && (
|
||||||
<>
|
<>
|
||||||
<SectionLabel>Feedback lab</SectionLabel>
|
|
||||||
<p style={{ fontSize: 'var(--fs-xs)', color: 'var(--fg-dim)', margin: 0, lineHeight: 1.6 }}>
|
|
||||||
State machine: idle → exploring → commit / cancel. While Explore & place is exploring,
|
|
||||||
training is paused and the joystick auditions a random scratchpad net; + commits a placed
|
|
||||||
anchor and restores the real net.
|
|
||||||
</p>
|
|
||||||
{ctx.xavierSpreadEnabled && (
|
{ctx.xavierSpreadEnabled && (
|
||||||
<Switch checked={ctx.spread} onChange={ctx.setSpread} label="Xavier (centred) weight regime" />
|
<Switch checked={ctx.spread} onChange={ctx.setSpread} label="Xavier (centred) weight regime" />
|
||||||
)}
|
)}
|
||||||
|
|
@ -679,17 +637,7 @@ function ModeConfig(ctx: ConsoleCtx, depth: DrawerDepth) {
|
||||||
<Button size="sm" variant={ctx.audioStarted ? 'secondary' : 'primary'} onClick={ctx.onToggleAudio}>
|
<Button size="sm" variant={ctx.audioStarted ? 'secondary' : 'primary'} onClick={ctx.onToggleAudio}>
|
||||||
{ctx.audioStarted ? 'pause' : 'play'}
|
{ctx.audioStarted ? 'pause' : 'play'}
|
||||||
</Button>
|
</Button>
|
||||||
<span style={{ fontSize: 'var(--fs-xs)', color: 'var(--fg-dim)' }}>audio starts on the play gesture</span>
|
|
||||||
</div>
|
</div>
|
||||||
{depth === 'expanded' && (
|
|
||||||
<p style={{ fontSize: 'var(--fs-xs)', color: 'var(--fg-dim)', margin: 0, lineHeight: 1.6 }}>
|
|
||||||
The active engine follows the selected mode ({ctx.mode.label}).
|
|
||||||
{/* TODO(dock-spec §5): arpeggiator + tiered synth presets + the
|
|
||||||
18-section group-override matrix are workstream E. Master
|
|
||||||
volume + bpm sliders were deleted (simplification audit
|
|
||||||
S16) — they drove no engine parameter. */}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
case 'editor':
|
case 'editor':
|
||||||
|
|
@ -700,12 +648,7 @@ function ModeConfig(ctx: ConsoleCtx, depth: DrawerDepth) {
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
case 'particles':
|
case 'particles':
|
||||||
return depth === 'expanded' ? (
|
return null;
|
||||||
<p style={{ fontSize: 'var(--fs-xs)', color: 'var(--fg-dim)', margin: 0, lineHeight: 1.6 }}>
|
|
||||||
Flow-field visualiser driven by the first {Math.min(20, ctx.params.length)} outputs (no audio).
|
|
||||||
{/* TODO(backends-spec §4): port FlowFieldVisualizer + visual preset chips. */}
|
|
||||||
</p>
|
|
||||||
) : null;
|
|
||||||
case 'midi':
|
case 'midi':
|
||||||
// The full MIDI config (port picker, CC count, per-output CC/channel/name)
|
// The full MIDI config (port picker, CC count, per-output CC/channel/name)
|
||||||
// + preset bar render via OutputsBackendConfig in RoutingDrawer below.
|
// + preset bar render via OutputsBackendConfig in RoutingDrawer below.
|
||||||
|
|
@ -864,10 +807,6 @@ function SettingsDrawer({ depth }: { ctx: ConsoleCtx; depth: DrawerDepth }) {
|
||||||
onChange={(v) => set('unfocusedIconColour', v as UnfocusedIconColour)}
|
onChange={(v) => set('unfocusedIconColour', v as UnfocusedIconColour)}
|
||||||
options={ICON_COLOUR_OPTS}
|
options={ICON_COLOUR_OPTS}
|
||||||
/>
|
/>
|
||||||
<p style={{ fontSize: 9, color: 'var(--fg-dim)', margin: 0, lineHeight: 1.6 }}>
|
|
||||||
Focused / active icons are always accent orange. This sets the resting colour of unfocused
|
|
||||||
icons (preview below).
|
|
||||||
</p>
|
|
||||||
<div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
|
<div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
|
||||||
<span style={{ color: unfocusedIconCss(settings.unfocusedIconColour), display: 'inline-flex' }}>
|
<span style={{ color: unfocusedIconCss(settings.unfocusedIconColour), display: 'inline-flex' }}>
|
||||||
<SettingsIcon size={20} />
|
<SettingsIcon size={20} />
|
||||||
|
|
@ -885,13 +824,6 @@ function SettingsDrawer({ depth }: { ctx: ConsoleCtx; depth: DrawerDepth }) {
|
||||||
onChange={(v) => set('inputMap', v as InputMapMode)}
|
onChange={(v) => set('inputMap', v as InputMapMode)}
|
||||||
options={INPUT_MAP_OPTS}
|
options={INPUT_MAP_OPTS}
|
||||||
/>
|
/>
|
||||||
{depth === 'expanded' && (
|
|
||||||
<p style={{ fontSize: 9, color: 'var(--fg-dim)', margin: 0, lineHeight: 1.6 }}>
|
|
||||||
The 2D input surface: a rectangular XY map or a circular joystick-style disc. "Follow mode"
|
|
||||||
uses the active mode's declared input (joystick → circular, else rectangular).
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<SectionLabel>I/O editing</SectionLabel>
|
<SectionLabel>I/O editing</SectionLabel>
|
||||||
<div style={{ fontSize: 'var(--fs-xs)', color: 'var(--fg-dim)' }}>Network size</div>
|
<div style={{ fontSize: 'var(--fs-xs)', color: 'var(--fg-dim)' }}>Network size</div>
|
||||||
<PillToggle
|
<PillToggle
|
||||||
|
|
@ -909,11 +841,6 @@ function SettingsDrawer({ depth }: { ctx: ConsoleCtx; depth: DrawerDepth }) {
|
||||||
/>
|
/>
|
||||||
{depth === 'expanded' && (
|
{depth === 'expanded' && (
|
||||||
<>
|
<>
|
||||||
<p style={{ fontSize: 9, color: 'var(--fg-dim)', margin: 0, lineHeight: 1.6 }}>
|
|
||||||
Keep capacity edits mappings in place and reconstructs only when the active cards outgrow
|
|
||||||
the network. Exact I/O keeps network arity equal to the cards. Surviving dimensions retain
|
|
||||||
their identity and weights; exploration scratch state resets after an I/O edit.
|
|
||||||
</p>
|
|
||||||
<Slider
|
<Slider
|
||||||
label="New input example value"
|
label="New input example value"
|
||||||
value={settings.addedInputExampleValue}
|
value={settings.addedInputExampleValue}
|
||||||
|
|
@ -943,26 +870,12 @@ function SettingsDrawer({ depth }: { ctx: ConsoleCtx; depth: DrawerDepth }) {
|
||||||
unit="px"
|
unit="px"
|
||||||
onChange={(v) => set('cornerRadius', Math.round(v))}
|
onChange={(v) => set('cornerRadius', Math.round(v))}
|
||||||
/>
|
/>
|
||||||
{depth === 'expanded' && (
|
|
||||||
<p style={{ fontSize: 9, color: 'var(--fg-dim)', margin: 0, lineHeight: 1.6 }}>
|
|
||||||
Roundness of buttons, control rows, dock icons and panels. Pills and the circular verdict
|
|
||||||
buttons are intentionally exempt. Default 2px.
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<SectionLabel>Experimental features</SectionLabel>
|
<SectionLabel>Experimental features</SectionLabel>
|
||||||
<Switch
|
<Switch
|
||||||
checked={settings.xavierSpreadEnabled}
|
checked={settings.xavierSpreadEnabled}
|
||||||
onChange={(v) => set('xavierSpreadEnabled', v)}
|
onChange={(v) => set('xavierSpreadEnabled', v)}
|
||||||
label="Xavier / spread randomisation"
|
label="Xavier / spread randomisation"
|
||||||
/>
|
/>
|
||||||
{depth === 'expanded' && (
|
|
||||||
<p style={{ fontSize: 9, color: 'var(--fg-dim)', margin: 0, lineHeight: 1.6 }}>
|
|
||||||
Off by default: new networks and re-rolls use full-range uniform weights for broad,
|
|
||||||
strongly varied mappings. Enable this to restore the legacy centred regime and its
|
|
||||||
Learning-drawer switch.
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1004,12 +917,6 @@ function HelpDrawer() {
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<SectionLabel>The loop</SectionLabel>
|
|
||||||
<p style={{ fontSize: 'var(--fs-xs)', color: 'var(--fg-dim)', margin: 0, lineHeight: 1.7 }}>
|
|
||||||
Drag the manifold to explore. Hear something good → + to keep it. Wrong → − to push away or
|
|
||||||
re-roll (set the behaviour in the Learning drawer). Went too far → undo. The dock reveals
|
|
||||||
exactly as much machinery as you reach for.
|
|
||||||
</p>
|
|
||||||
<SectionLabel>Learn more</SectionLabel>
|
<SectionLabel>Learn more</SectionLabel>
|
||||||
<a
|
<a
|
||||||
href="animations/"
|
href="animations/"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue