Phase-2 Slice 12c (user directive: use the app's circular controls, no invented buttons; fix the glyph-stuck-left bug). - Hero §3.6: deleted the local ActionCircle; the 4 hero controls are now the shared CircleAction (Play primary = filled white disc + black glyph; the loading spinner is now available = more 1:1). Added `enabled` to CircleAction (additive). - All MyQBZ modal footers (Create / Edit / Mix / AddTo / Discography) now use the shared QbzPrimaryButton (+ a new `destructive` variant for Delete) and a new shared SecondaryButton (promoted from AppearanceSettings' inline copy). QbzPrimaryButton auto-sizes as a footer chip while staying full-width in login (verified: login stretches it in a VerticalLayout; footers take preferred width). - Kept legitimately-local icon+label controls (grid "+ New" CTA, AddToMixtape picker chips, toolbar sort/filter/view-mode pills) but verified every glyph is centered. - Fixed 3 glyph-stuck-left bugs (DiscographyBuilder checkboxes used non-snapped centering -> the Math.round(.../1px)*1px crisp idiom). Backend crates untouched. cargo check -p qbz-slint green. cc
77 lines
3.1 KiB
Plaintext
77 lines
3.1 KiB
Plaintext
// Circular header/action button — matches the album-card hover OVERLAY
|
|
// buttons: a semi-transparent white fill (stable hit surface) with a bright
|
|
// 1.5px ring, white icon; `primary` is a solid white circle with a dark icon
|
|
// (the play affordance). Shared by the album/artist/label page headers, their
|
|
// Popular Tracks clusters, and the ephemeral pane.
|
|
|
|
import { Theme } from "../foundation/semantic-colors.slint";
|
|
import { QbzIcon } from "QbzIcon.slint";
|
|
import { LoadingSpinner } from "LoadingSpinner.slint";
|
|
import { TooltipState } from "../state.slint";
|
|
|
|
export component CircleAction inherits Rectangle {
|
|
in property <image> icon;
|
|
in property <bool> primary: false;
|
|
// Stays "pressed" — same surface as hover, icon tinted accent.
|
|
in property <bool> active: false;
|
|
// While the album's first track is fetching, the icon swaps for a spinner.
|
|
in property <bool> loading: false;
|
|
in property <length> diameter: 40px;
|
|
// When false the button dims and the click is gated (e.g. an empty
|
|
// collection's hero CTAs). Additive — existing callers default to enabled.
|
|
in property <bool> enabled: true;
|
|
// Optional hover tooltip (empty = none), using the global TooltipOverlay.
|
|
in property <string> tooltip;
|
|
callback clicked();
|
|
|
|
width: root.diameter;
|
|
height: root.diameter;
|
|
border-radius: root.diameter / 2;
|
|
opacity: root.enabled ? 1.0 : 0.4;
|
|
// Overlay-matched contrast: solid white for the primary play, semi-
|
|
// transparent white fill + bright 1.5px ring otherwise.
|
|
background: root.primary
|
|
? (ta.has-hover ? #ffffffd6 : #ffffff)
|
|
: ((ta.has-hover || root.active) ? #ffffff3d : #ffffff24);
|
|
border-width: root.primary ? 0px : 1.5px;
|
|
border-color: #ffffffcc;
|
|
|
|
if !root.loading: QbzIcon {
|
|
source: root.icon;
|
|
width: root.primary ? 19px : 17px;
|
|
height: root.primary ? 19px : 17px;
|
|
x: Math.round((parent.width - self.width) / 2 / 1px) * 1px;
|
|
y: Math.round((parent.height - self.height) / 2 / 1px) * 1px;
|
|
tint: root.active
|
|
? Theme.accent
|
|
: (root.primary ? #000000 : #ffffff);
|
|
}
|
|
|
|
if root.loading: LoadingSpinner {
|
|
size: root.diameter * 0.45;
|
|
// Dark on the solid white primary disc, white on the ghost variant.
|
|
tint: root.primary ? #000000 : #ffffff;
|
|
x: Math.round((parent.width - self.width) / 2 / 1px) * 1px;
|
|
y: Math.round((parent.height - self.height) / 2 / 1px) * 1px;
|
|
}
|
|
|
|
ta := TouchArea {
|
|
mouse-cursor: root.enabled ? pointer : default;
|
|
clicked => {
|
|
if (root.enabled) {
|
|
root.clicked();
|
|
}
|
|
}
|
|
changed has-hover => {
|
|
if (self.has-hover && root.tooltip != "") {
|
|
TooltipState.text = root.tooltip;
|
|
TooltipState.anchor-x = root.absolute-position.x + root.width / 2;
|
|
TooltipState.anchor-y = root.absolute-position.y;
|
|
TooltipState.show = true;
|
|
} else if (!self.has-hover) {
|
|
TooltipState.show = false;
|
|
}
|
|
}
|
|
}
|
|
}
|