Let several text stages share one named look
A picture with a title, a caption and a credit meant typing the same font, size and colour into every text stage, and changing the look meant typing them all again. A project now holds named styles: a stage follows one, and editing it moves every stage that follows it at once. The front-ends learn nothing effect-specific. A ParamSpec can be marked .styled(), saying a style carries it rather than the stage, and Effect::styleKind() names the pool it comes from -- so styleSpecs(kind) is to a style what params() is to a stage, and a second text-ish effect would slot into the styles that already exist. The look is what a style carries; the words and the placement stay on the stage, which is what lets two stages share a typography in two different corners. stageValues() resolves one in a single place, and a stage keeps a full set of values of its own beside the style, so switching it to Custom, dropping the style, or opening the project in a build that does not know it renders exactly the same picture. A style moves stages together; it never holds the only copy of anything. The command line builds no styles and passes none, so it renders what it always did. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -53,6 +53,17 @@ travel as `ParamValues` (a
|
||||
`map<string, variant<long,double,bool,string>>`), read back with
|
||||
`paramInt`/`paramDouble`/`paramBool`/`paramChoice`.
|
||||
|
||||
A param can also be marked `.styled()`, which says a *named style* carries it
|
||||
rather than the stage it sits on: the font and the colour of a text stage, but
|
||||
never its words or its placement. The pool a style comes from is named by
|
||||
`Effect::styleKind()` (empty by default — the effect takes no style; `"text"`
|
||||
for the text effect), and effects answering the same kind share one pool, so a
|
||||
second text-ish effect would slot into the styles that already exist. The
|
||||
front-ends know nothing more than that: the interface builds the style row and
|
||||
the project file writes a style's params from `styleSpecs(kind)`
|
||||
(`src/core/style.cpp`), which is to a style exactly what `params()` is to a
|
||||
stage.
|
||||
|
||||
Whether an effect works from the loaded photographs is part of the same
|
||||
contract: `Effect::needsSources()` (default true, false for blur). Only the
|
||||
first stage ever sees the sources, so `chainNeedsSources` (`src/core/chain.cpp`)
|
||||
@@ -82,6 +93,18 @@ it, which is why the status line and the file name never mention a stage that
|
||||
did not run. A chain with every stage disabled throws rather than rendering
|
||||
nothing.
|
||||
|
||||
### A style is a look several stages share
|
||||
|
||||
`ChainStage::style` names a style, and `stageValues` (`src/core/chain.cpp`) is
|
||||
the one place that resolves one: an effect's defaults, then the stage's own
|
||||
values, then the style's values for the params it carries. A stage always keeps
|
||||
a full set of values of its own beside the style, so switching it to "Custom",
|
||||
dropping the style, or opening the project in a build that does not know the
|
||||
style renders exactly the same picture — a style moves stages together, it
|
||||
never holds the only copy of anything. The interface writes an edited param to
|
||||
both the style and the stage for that reason. `renderChain` takes the pool as a
|
||||
trailing argument; the command line builds no styles and passes none.
|
||||
|
||||
The interface builds the chain in the sidebar ("Effect chain": add from the
|
||||
menu, reorder, remove, switch off with the check on the row, one stage selected
|
||||
at a time with its params below), the CLI builds it from repeated `-e`:
|
||||
@@ -104,12 +127,15 @@ pixels, so a project saved as A4 reopens as A4.
|
||||
### Projects are plain JSON
|
||||
|
||||
`src/core/project.cpp` reads and writes the whole setup — source paths, the
|
||||
chain with its params (and its `"enabled": false`, written only for a stage
|
||||
that is switched off), canvas and seed — as a small JSON file, with its own
|
||||
named styles, the chain with its params (and its `"enabled": false` and
|
||||
`"style"`, each written only when there is something to say), canvas and seed — as a small JSON file, with its own
|
||||
minimal reader rather than a JSON dependency. Writing is driven by the effects'
|
||||
`ParamSpec`s, not by whatever happens to sit in a stage's `ParamValues`, so a
|
||||
key an effect does not declare is never written and never read back: an old
|
||||
project keeps the defaults for params that did not exist when it was saved.
|
||||
project keeps the defaults for params that did not exist when it was saved. The
|
||||
same leniency covers styles: one of a kind this build does not know, one with
|
||||
no name or a repeated one, and a stage naming a style the file does not hold
|
||||
are each dropped on their own rather than refusing the project.
|
||||
Source paths under the project's own folder are written relative, so a folder
|
||||
can be moved or shared whole.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user