feat(editor): FaiEditorStyle + frosted glass panel + pattern/zoom dropdowns

Visual-effect knobs (FaiEditorStyle) the host can override —
distinct from ColorScheme, which stays orthogonal. Today
Studio passes it through FlowEditorPage's new style:
parameter; tomorrow a theme plugin can ship both colours and
effects in one move.

Two presets ship today: modern (frosted glass, gradient
backdrop, animated flow, shadowed nodes — the default) and
minimal (everything off, flat surfaces — accessibility /
reduce-motion / low-spec).

Properties panel rebuilt as a floating sidebar with
BackdropFilter blur when glass-style is on; falls back to
the pre-0.7 flush-divider layout under solid style.

Pattern + zoom controls promoted to PopupMenuButton dropdowns
so operators reach a specific zoom level / pattern in one
click instead of cycling.

Bumps fai_studio_flow_editor to 0.8.0.

Signed-off-by: flemming-it <sf@flemming.it>
This commit is contained in:
flemming-it 2026-06-01 18:10:51 +02:00
parent 7aeeae717f
commit 1f5601a461
6 changed files with 386 additions and 130 deletions

View file

@ -130,6 +130,11 @@ class FlowNode extends StatelessWidget {
/// Delete / Disconnect inputs etc.).
final void Function(Offset globalPos)? onContextMenu;
/// Whether to paint the layered drop shadows under the
/// node. Off = flat-design feel; on = depth. Driven by
/// the active editor style.
final bool elevated;
/// Live status from the most recent run, when this node is
/// a step. Coloured dot in the header so the operator can
/// glance at the canvas and see what's running.
@ -151,6 +156,7 @@ class FlowNode extends StatelessWidget {
this.onDrag,
this.onDragEnd,
this.onContextMenu,
this.elevated = true,
});
@override
@ -189,19 +195,25 @@ class FlowNode extends StatelessWidget {
// inner shadow + a softer outer halo. Selected
// nodes get a coloured accent halo on top so the
// selection state reads from across the canvas.
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: selected ? 0.32 : 0.18),
blurRadius: selected ? 18 : 10,
offset: const Offset(0, 4),
),
if (selected)
BoxShadow(
color: accent.withValues(alpha: 0.30),
blurRadius: 24,
spreadRadius: 1,
),
],
// When the active style turns elevation off, we
// drop the shadows entirely for a flat-design look.
boxShadow: elevated
? [
BoxShadow(
color: Colors.black.withValues(
alpha: selected ? 0.32 : 0.18,
),
blurRadius: selected ? 18 : 10,
offset: const Offset(0, 4),
),
if (selected)
BoxShadow(
color: accent.withValues(alpha: 0.30),
blurRadius: 24,
spreadRadius: 1,
),
]
: null,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(FaiRadius.md),