Files
deepdrft/DeepDrftPublic.Client/Controls/WaveformVisualizerControlPopover.razor
T
daniel-c-harvey 2fbb1c9b95 fix(theme): green hero Share/Play/Queue glyphs in dark via shared .dd-accent-icon
Fold Session/Mix hero glyphs into the reusable accent-icon treatment so they reach
the glyph (beating .mud-secondary-text) green-accent in both themes; drop the dead
wrapper white rule and the redundant dark-only hero override. Light pixel-identical.
2026-06-20 02:21:11 -04:00

67 lines
3.8 KiB
Plaintext

@namespace DeepDrftPublic.Client.Controls
@using DeepDrftShared.Client.Common
@* The single controls affordance, placed by an icon anywhere (Phase 12 §3d-revised, re-primitived
Phase 15 §4). Closed state is just the lava-lamp icon; clicking it floats the control panel as a
SCREEN-CENTERED, tinted MODAL over the whole surface. One panel, one host, reused on every host (Mix,
Cut, Session, NowPlaying) — the SOLID seam.
PRIMITIVE (Phase 15 §4): a centered MudOverlay, NOT an anchored MudPopover. The panel must read as
screen-centered regardless of where the lava-lamp icon sits (Mix corner, Cut/Session ambient,
NowPlaying corner). An anchored popover positions off the trigger's bounding rect — the wrong model
for "centered on the screen." So the icon is just an opener; the overlay hosts the panel in its centre
(the overlay is a full-viewport flex container — its content is centered by .waveform-visualizer-control-
overlay in the GLOBAL sheet, since the overlay portals out of this subtree). DarkBackground gives the
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 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
host only toggles open/closed and centers the panel — it stays purely presentational. *@
<div class="dd-accent-icon">
<MudTooltip Text="Visualizer settings">
<MudIconButton Icon="@(_open ? DDIcons.LavaLampFilled : DDIcons.LavaLamp)"
Size="@IconSize"
Color="Color.Secondary"
Disabled="@(!RendererInfo.IsInteractive)"
OnClick="@Toggle"
aria-label="Visualizer settings"
aria-expanded="@_open" />
</MudTooltip>
</div>
@* The tinted modal scrim that also HOLDS the panel. DarkBackground = the mild tint; OnClick on the scrim
dismisses (knob-drag-safe, see header). The panel is the overlay's centered child; it stops click
propagation so an inside click is not a dismissal. Modal so focus/scroll stay on the panel. *@
<MudOverlay Visible="@_open"
DarkBackground="true"
Modal="true"
OnClick="@Close"
Class="waveform-visualizer-control-overlay">
<div class="waveform-visualizer-control-modal" @onclick:stopPropagation="true">
<WaveformVisualizerControls PanelChrome="true" />
</div>
</MudOverlay>
@code {
/// <summary>Trigger-icon size. Defaults Large to match the Phase 10 Mix lava-lamp button.</summary>
[Parameter] public Size IconSize { get; set; } = Size.Large;
private bool _open;
private void Toggle() => _open = !_open;
private void Close() => _open = false;
}