Merge p15-w3-controls-polish into dev
Phase 15 polish round 2: mute panel ground, revert WAVE scroll to a RadialKnob, add a distinct waveform glyph (DDIcons) for the waveform toggle, strong green active-state on the toggles, and refresh the popover pointer-capture comment.
This commit is contained in:
@@ -15,13 +15,15 @@
|
||||
mild modal tint (alpha from the single --deepdrft-modal-scrim-alpha token, §10.5). There is therefore
|
||||
no AnchorOrigin/TransformOrigin: a centered modal has no anchor (Phase 15 drops those parameters).
|
||||
|
||||
KNOB-DRAG SAFETY (Phase 15 §4, highest-risk detail): RadialKnob mounts its own full-viewport
|
||||
position:fixed; z-index:9999 mouse-capture div WHILE dragging (RadialKnob.razor lines 5–9). That capture
|
||||
div sits ABOVE the overlay scrim, so a knob drag's pointer-up lands on the capture div, never the scrim
|
||||
— the overlay's OnClick does not fire mid-drag, so releasing the mouse outside the panel does NOT close
|
||||
the modal. AutoClose is left OFF (the default) and dismissal is via the explicit scrim OnClick only,
|
||||
carrying the SharePopover idiom forward under the new primitive. The panel stops click propagation so a
|
||||
click INSIDE it never bubbles to the scrim's close handler.
|
||||
KNOB-DRAG SAFETY (Phase 15 §4, highest-risk detail): RadialKnob calls setPointerCapture on its own
|
||||
knob element when a drag begins, so all pointermove/pointerup/pointercancel events for that pointer are
|
||||
delivered to the knob element regardless of where the cursor moves. The synthesised click on pointerup
|
||||
is also retargeted to the knob, not to whatever element is under the cursor — so releasing outside the
|
||||
panel never fires the scrim's close handler. The full-viewport position:fixed; z-index:9999 div
|
||||
RadialKnob renders while dragging is a belt-and-suspenders UX guard (blocks stray clicks on underlying
|
||||
content) but is no longer the load-bearing anti-dismiss mechanism. AutoClose is left OFF (the default)
|
||||
and dismissal is via the explicit scrim OnClick only. The panel stops click propagation so a click
|
||||
INSIDE it never bubbles to the scrim's close handler.
|
||||
|
||||
The host owns NO control state and NO JS interop. The hosted WaveformVisualizerControls panel mutates
|
||||
the shared WaveformVisualizerControlState and raises Changed; the visualizer bridge subscribes. This
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
@using DeepDrftPublic.Client.Services
|
||||
@inject WaveformVisualizerControlState ControlState
|
||||
|
||||
@* The waveform visualizer control PANEL (Phase 12 §3d-revised → Phase 15 re-layout). The control deck for
|
||||
the lava-lamp visualizer: a deterministic THREE-ROW, sectioned layout that encodes what the visualizer
|
||||
composes — a LAVA field and a WAVEFORM ribbon, each independently toggleable (Phase 15 §3):
|
||||
@* The waveform visualizer control PANEL (Phase 12 §3d-revised → Phase 15 re-layout → Phase 15 polish).
|
||||
The control deck for the lava-lamp visualizer: a deterministic THREE-ROW, sectioned layout that encodes
|
||||
what the visualizer composes — a LAVA field and a WAVEFORM ribbon, each independently toggleable (§3):
|
||||
|
||||
Row 1 (MODE, always): lava lamp-toggle, waveform lamp-toggle, [collisions knob — only when BOTH on],
|
||||
then the color knob pinned far-right (applies to the whole field, so always visible).
|
||||
Row 1 (MODE, always): lava lamp-toggle, waveform toggle (new waveform glyph), [collisions knob — only
|
||||
when BOTH on], then the color knob pinned far-right (applies to the whole field, always visible).
|
||||
Row 2 (LAVA, only when lava on): "LAVA:" label + gravity / heat / fluid-amount / fluid-viscosity.
|
||||
Row 3 (WAVE, only when waveform on): "WAVE:" label + scroll SLIDER + width knob pinned far-right.
|
||||
Row 3 (WAVE, only when waveform on): "WAVE:" label + scroll RadialKnob + width RadialKnob (far-right).
|
||||
|
||||
The two lamp toggles are iconographic (lit LavaLampFilled / unlit LavaLamp glyph), green because they
|
||||
are INTERACTIVE (the §5 colour principle: green = interactive, light = non-interactive). The eight
|
||||
continuous dials are unchanged in tuning; the one widget-type change is scroll/zoom → a MudSlider (§8,
|
||||
bound to ScrollSpeed alone). None of these is a seek surface (read-only contract §D).
|
||||
The two toggles have STRONG ACTIVE-STATE styling: when ON the toggle chip has a green-accent background
|
||||
(unmistakably active); when OFF it is muted/dim. The lava toggle keeps the lava-lamp glyph; the waveform
|
||||
toggle uses a new distinct waveform-bars glyph (DDIcons.Waveform / WaveformFilled). Green = interactive
|
||||
(§5 colour principle); light = non-interactive. All colours are token-sourced — no hardcoded hex.
|
||||
|
||||
This is the PANEL CONTENT hosted inside WaveformVisualizerControlPopover, now a screen-centered tinted
|
||||
MudOverlay (Phase 15 §4). Because the overlay PORTALS its content out of this component's DOM subtree,
|
||||
@@ -24,10 +24,6 @@
|
||||
scoped .razor.css carries only the legacy inline-bar fallback (Mix's old non-portaled mount), which may
|
||||
now be dead post-Phase-12 but is left in place — flagged, not cut (out of Phase 15 scope).
|
||||
|
||||
COLOUR PRINCIPLE (§5): the lamp toggles + knob arcs/pointers + the slider track/thumb are green-accent
|
||||
(interactive); the "LAVA:"/"WAVE:" section labels and the knob caption icons are LIGHT (static). All
|
||||
colours are token-sourced (deepdrft-tokens.css) — no hardcoded hex.
|
||||
|
||||
It owns NO JS interop: it mutates the shared, session-scoped WaveformVisualizerControlState and raises
|
||||
its Changed event. The visualizer bridge (WaveformVisualizer) subscribes and pushes the affected dial /
|
||||
subsystem-enable to the WebGL module. RadialKnob has no icon slot (its Label renders as SVG text) and no
|
||||
@@ -43,7 +39,7 @@
|
||||
<div class="wvc-row-left">
|
||||
|
||||
<MudTooltip Text="Light the lamp — or let it go cold.">
|
||||
<div class="wvc-toggle" role="group" aria-label="Lava field on or off">
|
||||
<div class="wvc-toggle @(ControlState.LavaEnabled ? "wvc-toggle-on" : "wvc-toggle-off")" role="group" aria-label="Lava field on or off">
|
||||
<MudIconButton Icon="@(ControlState.LavaEnabled ? DDIcons.LavaLampFilled : DDIcons.LavaLamp)"
|
||||
Color="Color.Primary"
|
||||
OnClick="@ToggleLava"
|
||||
@@ -53,8 +49,8 @@
|
||||
</MudTooltip>
|
||||
|
||||
<MudTooltip Text="Show the sound, or hide the ribbon.">
|
||||
<div class="wvc-toggle" role="group" aria-label="Waveform ribbon on or off">
|
||||
<MudIconButton Icon="@(ControlState.WaveformEnabled ? DDIcons.LavaLampFilled : DDIcons.LavaLamp)"
|
||||
<div class="wvc-toggle @(ControlState.WaveformEnabled ? "wvc-toggle-on" : "wvc-toggle-off")" role="group" aria-label="Waveform ribbon on or off">
|
||||
<MudIconButton Icon="@(ControlState.WaveformEnabled ? DDIcons.WaveformFilled : DDIcons.Waveform)"
|
||||
Color="Color.Primary"
|
||||
OnClick="@ToggleWaveform"
|
||||
aria-label="Waveform ribbon on or off"
|
||||
@@ -145,19 +141,20 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
@* ── Row 3 — WAVE section (only when waveform on). Scroll is a SLIDER (§8); width pinned right. ── *@
|
||||
@* ── Row 3 — WAVE section (only when waveform on). Both controls are RadialKnobs (scroll reverted
|
||||
from MudSlider per Phase 15 polish); width pinned far-right via wvc-row-wave space-between. ── *@
|
||||
@if (ControlState.WaveformEnabled)
|
||||
{
|
||||
<div class="wvc-row wvc-row-section wvc-row-wave">
|
||||
<span class="wvc-section-label">WAVE:</span>
|
||||
|
||||
<MudTooltip Text="How fast the sound rolls by.">
|
||||
<div class="wvc-slider" role="group" aria-label="Waveform scroll speed">
|
||||
<MudSlider T="double"
|
||||
Value="@ControlState.ScrollSpeed"
|
||||
ValueChanged="@OnScrollSpeedChanged"
|
||||
Min="0" Max="1" Step="0.001"
|
||||
Color="Color.Primary" />
|
||||
<div class="waveform-visualizer-control mix-visualizer-control" role="group" aria-label="Waveform scroll speed">
|
||||
<RadialKnob Value="@ControlState.ScrollSpeed"
|
||||
ValueChanged="@OnScrollSpeedChanged"
|
||||
Min="0" Max="1" Step="0.001"
|
||||
Size="64"
|
||||
Color="Color.Primary" />
|
||||
<MudIcon Icon="@Icons.Material.Filled.Speed" Size="Size.Small" Class="waveform-visualizer-control-icon mix-visualizer-control-icon" />
|
||||
</div>
|
||||
</MudTooltip>
|
||||
|
||||
@@ -426,7 +426,7 @@ h2, h3, h4, h5, h6,
|
||||
/* ── Row layout (§3). Each row is a horizontal band. Row 1 (MODE) and row 3 (WAVE) use
|
||||
space-between so the right-pinned control (color / width) hugs the far edge. Row 2 (LAVA) uses
|
||||
flex-start so its label + four knobs group left rather than spreading edge-to-edge.
|
||||
align-items: center so the WAVE slider and section label vertically center with each other (defect #4). ── */
|
||||
align-items: center so the section label and knobs vertically center with each other. ── */
|
||||
.waveform-visualizer-control-panel .wvc-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -473,29 +473,26 @@ h2, h3, h4, h5, h6,
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
/* ── The lamp toggles (§3 row 1). Iconographic lit/unlit lamp glyph, GREEN because interactive (§5).
|
||||
Color="Color.Primary" already drives the glyph currentColor to the pinned green --mud-palette-primary;
|
||||
this just sizes the hit-target to read as a row-1 peer of the knobs. ── */
|
||||
/* ── The toggles (§3 row 1). Two state classes control the active-state chip treatment:
|
||||
ON (.wvc-toggle-on): green-accent filled chip — unmistakably active at a glance.
|
||||
OFF (.wvc-toggle-off): fully transparent background, glyph at low opacity — clearly inactive.
|
||||
The MudIconButton glyph is already driven green (Color.Primary → pinned green accent, interactive §5).
|
||||
The chip background reinforces state without recolouring the glyph further. ── */
|
||||
.waveform-visualizer-control-panel .wvc-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 6px;
|
||||
transition: background 0.15s ease;
|
||||
}
|
||||
|
||||
/* ── The scroll SLIDER (§8). Track/thumb green (the pinned --mud-palette-primary, interactive). Give it
|
||||
a sensible width so it reads as "position along a continuum" next to the rotary width knob. ── */
|
||||
.waveform-visualizer-control-panel .wvc-slider {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
min-width: 160px;
|
||||
flex: 1 1 auto;
|
||||
align-self: center;
|
||||
.waveform-visualizer-control-panel .wvc-toggle-on {
|
||||
background: color-mix(in srgb, var(--deepdrft-green-accent) 28%, transparent);
|
||||
box-shadow: 0 0 0 1px color-mix(in srgb, var(--deepdrft-green-accent) 55%, transparent);
|
||||
}
|
||||
|
||||
.waveform-visualizer-control-panel .wvc-slider .mud-slider {
|
||||
width: 100%;
|
||||
.waveform-visualizer-control-panel .wvc-toggle-off .mud-icon-button {
|
||||
opacity: 0.38;
|
||||
}
|
||||
|
||||
/* Caption icons render LIGHT (§5/§9: static/decorative = light). !important beats the scoped
|
||||
|
||||
@@ -23,6 +23,40 @@ public static class DDIcons
|
||||
</svg>
|
||||
""";
|
||||
|
||||
/// <summary>
|
||||
/// Audio waveform — outline variant, shown when the waveform subsystem is OFF.
|
||||
/// Six vertical bars of varying height centred on a 24×24 viewBox, evoking a
|
||||
/// classic sound-wave / spectrum display. Uses currentColor so it themes freely.
|
||||
/// Inner markup only — no outer <svg> wrapper; MudBlazor supplies viewBox="0 0 24 24".
|
||||
/// </summary>
|
||||
public const string Waveform = """
|
||||
<g>
|
||||
<rect x="1" y="9" width="2" height="6" rx="1" fill="none" stroke="currentColor" stroke-width="1.2"/>
|
||||
<rect x="5" y="5" width="2" height="14" rx="1" fill="none" stroke="currentColor" stroke-width="1.2"/>
|
||||
<rect x="9" y="2" width="2" height="20" rx="1" fill="none" stroke="currentColor" stroke-width="1.2"/>
|
||||
<rect x="13" y="6" width="2" height="12" rx="1" fill="none" stroke="currentColor" stroke-width="1.2"/>
|
||||
<rect x="17" y="4" width="2" height="16" rx="1" fill="none" stroke="currentColor" stroke-width="1.2"/>
|
||||
<rect x="21" y="9" width="2" height="6" rx="1" fill="none" stroke="currentColor" stroke-width="1.2"/>
|
||||
</g>
|
||||
""";
|
||||
|
||||
/// <summary>
|
||||
/// Audio waveform — filled variant, shown when the waveform subsystem is ON.
|
||||
/// Same bar layout as <see cref="Waveform"/> but bars are solid currentColor,
|
||||
/// giving a strong visual contrast for the active (ON) state.
|
||||
/// Inner markup only — no outer <svg> wrapper; MudBlazor supplies viewBox="0 0 24 24".
|
||||
/// </summary>
|
||||
public const string WaveformFilled = """
|
||||
<g>
|
||||
<rect x="1" y="9" width="2" height="6" rx="1" fill="currentColor"/>
|
||||
<rect x="5" y="5" width="2" height="14" rx="1" fill="currentColor"/>
|
||||
<rect x="9" y="2" width="2" height="20" rx="1" fill="currentColor"/>
|
||||
<rect x="13" y="6" width="2" height="12" rx="1" fill="currentColor"/>
|
||||
<rect x="17" y="4" width="2" height="16" rx="1" fill="currentColor"/>
|
||||
<rect x="21" y="9" width="2" height="6" rx="1" fill="currentColor"/>
|
||||
</g>
|
||||
""";
|
||||
|
||||
/// <summary>
|
||||
/// Lava lamp - the Mix visualizer settings glyph. Sourced from lava-lamp-svgrepo-com.svg
|
||||
/// (SVG Repo, viewBox="0 0 50 50"). Wrapped in a scale(0.48) transform to fit MudBlazor's
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
/* Modal scrim opacity — the SINGLE point of truth for the visualizer-controls overlay tint
|
||||
(Phase 15 §4/§10.5). Mild so the panel reads as modal without a blackout. Change here once. */
|
||||
--deepdrft-modal-scrim-alpha: 0.15;
|
||||
/* Panel ground — desaturated from navy-mid toward charcoal so the blue slider stands out.
|
||||
Tunable: increase blue channel (e.g. #1e2235) to recover warmth, lower (e.g. #1a1d22) to go darker. */
|
||||
--deepdrft-panel-ground: #1e2028;
|
||||
/* Panel ground — muted, desaturated charcoal beneath the controls panel.
|
||||
Tunable: increase blue channel (e.g. #1e2235) to recover warmth, lower (e.g. #191b20) to go darker. */
|
||||
--deepdrft-panel-ground: #1a1c22;
|
||||
|
||||
/* Wireframe font stack */
|
||||
--deepdrft-font-display: "Cormorant Garamond", Georgia, serif;
|
||||
|
||||
Reference in New Issue
Block a user