Give a list its own tab instead of a comma line
A list property in the inspector was a single text field holding a comma
separated line -- unreadable past a handful of items, and it could not
carry anything but text. It becomes a button ("3 items") that opens a
sixth centre tab, where every item is a row built by the very widget the
inspector would build for that item kind.
The renderer was free: a PropertyDef of kind 'list' already carries
`items`, so item i becomes a synthetic def of that kind -- number, text,
boolean and colour rows appear without a new branch.
The way into the tab goes through the state (EditorState.listSlot,
openList(), event 'list'), like every other tab switch here; a tab may
not call showTab itself. ListSlot lives next to Selection rather than in
the tab folder, or state.ts would have to import upwards.
A row's handlers must not close over a snapshot of the list: they outlive
a commit, since the tab only rebuilds when the length changes, and the
second edited row would otherwise revive the value the first replaced.
showTab switched five `visible` lines by hand, where a sixth tab is
silently forgotten; it is a Record<CentreTab, Widget> now.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5a440ba433
commit
e52e95c0e9
15 files changed
+750
-70
No files matched your search
@@ -17,7 +17,7 @@ import { Button, Label } from '../../ui';
|
||||
import { createFieldRow, type FieldHandlers } from './fieldFactory';
|
||||
import { addGap, addNote, addTitle, type InspectorHost } from './host';
|
||||
import { buildPortSection } from './portSection';
|
||||
import { previewingHandlers } from './previewHandlers';
|
||||
import { listOpener, previewingHandlers } from './previewHandlers';
|
||||
|
||||
/** Structure-defining facts of a node selection: ports, connected inputs, declared variables. */
|
||||
export function nodeSignature(project: Project, assetId: string, nodeId: string): string {
|
||||
@@ -60,7 +60,7 @@ export function buildNodeSection(host: InspectorHost, assetId: string, nodeId: s
|
||||
host,
|
||||
effective,
|
||||
node.params[param.key] ?? effective.default,
|
||||
paramHandlers(host, assetId, nodeId, param.key),
|
||||
paramHandlers(host, assetId, nodeId, effective),
|
||||
);
|
||||
host.fields.set(`param:${param.key}`, row);
|
||||
host.body.add(row.row);
|
||||
@@ -74,7 +74,7 @@ export function buildNodeSection(host: InspectorHost, assetId: string, nodeId: s
|
||||
host,
|
||||
inline,
|
||||
node.params[port.key] ?? inline.default,
|
||||
paramHandlers(host, assetId, nodeId, port.key),
|
||||
paramHandlers(host, assetId, nodeId, inline),
|
||||
);
|
||||
host.fields.set(`input:${port.key}`, row);
|
||||
host.body.add(row.row);
|
||||
@@ -116,14 +116,23 @@ function resolveParamDef(param: PropertyDef, asset: Asset): PropertyDef {
|
||||
}
|
||||
|
||||
/** Previews straight into the node's params; the command records the value from before the preview. */
|
||||
function paramHandlers(host: InspectorHost, assetId: string, nodeId: string, key: string): FieldHandlers {
|
||||
return previewingHandlers<GraphNode>(host, {
|
||||
target: () => currentNode(host.state.project, assetId, nodeId)?.node,
|
||||
read: (node) => node.params[key],
|
||||
write: (node, value) => (node.params[key] = value),
|
||||
remove: (node) => delete node.params[key],
|
||||
commit: (value) => new SetNodeParamCommand(assetId, nodeId, key, value),
|
||||
});
|
||||
function paramHandlers(
|
||||
host: InspectorHost,
|
||||
assetId: string,
|
||||
nodeId: string,
|
||||
def: PropertyDef,
|
||||
): FieldHandlers {
|
||||
const key = def.key;
|
||||
return {
|
||||
...previewingHandlers<GraphNode>(host, {
|
||||
target: () => currentNode(host.state.project, assetId, nodeId)?.node,
|
||||
read: (node) => node.params[key],
|
||||
write: (node, value) => (node.params[key] = value),
|
||||
remove: (node) => delete node.params[key],
|
||||
commit: (value) => new SetNodeParamCommand(assetId, nodeId, key, value),
|
||||
}),
|
||||
...listOpener(host.state, def, () => ({ kind: 'node', assetId, nodeId, key })),
|
||||
};
|
||||
}
|
||||
|
||||
/** The node together with the graph it sits in, because its ports are derived from both. */
|
||||
|
||||
Reference in new issue
Block a user