theme: soften the YoRHa shapes; SUPER+D opens the dashboard
The square markers, block meters and hard-cornered fills read as boxy next to the porthole. The desktop is now soft throughout: the porthole is the shape everything is built around and every smaller surface echoes it. - Theme gains radiusS / radiusM / radiusL. radiusL is frameRadius - padS, so anything inset padS inside one of the frame's curves is concentric with it. - P5Panel and Skew draw rounded rectangles (Geom.roundedRect) whenever they neither lean nor are chopped, which is always now; the polygon path is kept for shapes brought back on purpose. - Markers are dots; workspace pips, toggles, transport and media chips, notification actions and today's date are pills or discs; the slider handle is round. Meters are one continuous rounded line that glides to its level instead of a row of segments. - Album art is rounded with ClippingRectangle in the bar, the media popout and the dashboard. - Free-standing panels (launcher, ask) drop the corner brackets and take the frame radius. - Fix: a hovered notification's wash was a full-bleed square, so in the drawer's bottom corner it ran past the drawer's curve. It is inset by padS/2 and rounded by radiusL, which keeps it inside the curve. Hyprland: the discord special workspace and its window rule are gone, SUPER+S stays the only scratchpad, and SUPER+D now opens the dashboard (it was on SUPER+I). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d6de04eaaf
commit
a8c19961e2
24 files changed
+188
-110
No files matched your search
@@ -9,7 +9,7 @@ end
|
|||||||
shell("lock", { key = mod .. " + CTRL + L", description = "lock screen" })
|
shell("lock", { key = mod .. " + CTRL + L", description = "lock screen" })
|
||||||
shell("power", { key = mod .. " + P", description = "power menu" })
|
shell("power", { key = mod .. " + P", description = "power menu" })
|
||||||
shell("ask", { key = mod .. " + A", description = "ask claude" })
|
shell("ask", { key = mod .. " + A", description = "ask claude" })
|
||||||
shell("dashboard", { key = mod .. " + I", description = "dashboard" })
|
shell("dashboard", { key = mod .. " + D", description = "dashboard" })
|
||||||
shell("toggleDnd", { key = mod .. " + SHIFT + N", description = "toggle do not disturb" })
|
shell("toggleDnd", { key = mod .. " + SHIFT + N", description = "toggle do not disturb" })
|
||||||
shell("clearNotifications", { key = mod .. " + CTRL + SHIFT + N", description = "clear notifications" })
|
shell("clearNotifications", { key = mod .. " + CTRL + SHIFT + N", description = "clear notifications" })
|
||||||
shell("reloadConfig", { key = mod .. " + SHIFT + R", description = "reload shell config" })
|
shell("reloadConfig", { key = mod .. " + SHIFT + R", description = "reload shell config" })
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
-- Workspaces, including the two scratchpads.
|
-- Workspaces, including the scratchpad.
|
||||||
|
|
||||||
local mod = "SUPER"
|
local mod = "SUPER"
|
||||||
|
|
||||||
@@ -13,10 +13,6 @@ end
|
|||||||
hl.bind(mod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" }))
|
hl.bind(mod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" }))
|
||||||
hl.bind(mod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" }))
|
hl.bind(mod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" }))
|
||||||
|
|
||||||
-- Scratchpads: S holds anything virtual, D holds chat.
|
-- Scratchpad: S holds anything virtual. Chat opens wherever it is launched.
|
||||||
local special = { S = "virtual", D = "discord" }
|
hl.bind(mod .. " + S", hl.dsp.workspace.toggle_special("virtual"))
|
||||||
|
hl.bind(mod .. " + SHIFT + S", hl.dsp.window.move({ workspace = "special:virtual" }))
|
||||||
for key, name in pairs(special) do
|
|
||||||
hl.bind(mod .. " + " .. key, hl.dsp.workspace.toggle_special(name))
|
|
||||||
hl.bind(mod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = "special:" .. name }))
|
|
||||||
end
|
|
||||||
@@ -54,7 +54,6 @@ hl.window_rule({ match = { class = GAMESCOPE }, workspace = "1" })
|
|||||||
|
|
||||||
-- Special workspaces
|
-- Special workspaces
|
||||||
hl.window_rule({ match = { class = "^(Spotify|spotify)$" }, workspace = "special:virtual" })
|
hl.window_rule({ match = { class = "^(Spotify|spotify)$" }, workspace = "special:virtual" })
|
||||||
hl.window_rule({ match = { class = "^(discord|vesktop)$" }, workspace = "special:discord" })
|
|
||||||
|
|
||||||
-- ==========================================
|
-- ==========================================
|
||||||
-- STEAM & GAMING
|
-- STEAM & GAMING
|
||||||
|
|||||||
+18
-13
@@ -3,7 +3,7 @@
|
|||||||
A NieR:Automata flavoured Quickshell desktop for Hyprland, kept dark and lit
|
A NieR:Automata flavoured Quickshell desktop for Hyprland, kept dark and lit
|
||||||
like its wallpaper: a lone figure at a porthole, the void outside, one planet's
|
like its wallpaper: a lone figure at a porthole, the void outside, one planet's
|
||||||
light. The planet white for anything live, the hull red for anything wrong,
|
light. The planet white for anything live, the hull red for anything wrong,
|
||||||
grey-green for everything else. Hairlines, square markers, corner ticks,
|
grey-green for everything else. Hairlines, small dots, soft rounded corners,
|
||||||
letter-spaced capitals, and selection shown by inverting the row. The bar, the
|
letter-spaced capitals, and selection shown by inverting the row. The bar, the
|
||||||
rail and a thin border are one hull around the desktop, and the desktop is the
|
rail and a thin border are one hull around the desktop, and the desktop is the
|
||||||
porthole cut out of it.
|
porthole cut out of it.
|
||||||
@@ -91,7 +91,7 @@ left a thin strip of opening between itself and the rail.
|
|||||||
## Dashboard
|
## Dashboard
|
||||||
|
|
||||||
`dashboard/Dashboard.qml` is a drawer that slides down out of the underside of
|
`dashboard/Dashboard.qml` is a drawer that slides down out of the underside of
|
||||||
the bar — clock click, `SUPER + I`, or `qs ipc call shell dashboard`. It is
|
the bar — clock click, `SUPER + D`, or `qs ipc call shell dashboard`. It is
|
||||||
painted in the hull colour and joins the bar through two concave fillets, so it
|
painted in the hull colour and joins the bar through two concave fillets, so it
|
||||||
reads as more of the hull rather than as a floating card (caelestia's idea).
|
reads as more of the hull rather than as a floating card (caelestia's idea).
|
||||||
Four columns divided by hairlines: operator and time, the month, the system
|
Four columns divided by hairlines: operator and time, the month, the system
|
||||||
@@ -262,10 +262,9 @@ brings the marker up to full light, but never inverts. Destructive-active is
|
|||||||
the same slab in red. The `treatment*` tokens in `Theme.qml` encode all of
|
the same slab in red. The `treatment*` tokens in `Theme.qml` encode all of
|
||||||
this; use them rather than picking colours per widget.
|
this; use them rather than picking colours per widget.
|
||||||
|
|
||||||
**Markers, not slashes.** The current row, a button under the pointer and the
|
**Dots, not slashes.** The current row, a button under the pointer, the end of
|
||||||
end of a header rule carry a small square (`Theme.marker`). Popouts are framed
|
a header rule and a notification's urgency carry a small dot (`Theme.marker`).
|
||||||
by corner ticks (`Theme.tick`) in their tone colour; the border itself is
|
Borders are structure and stay neutral.
|
||||||
structure and stays neutral.
|
|
||||||
|
|
||||||
**Flicker, not print.** Display text (`SplitText`) is upright, tracked by
|
**Flicker, not print.** Display text (`SplitText`) is upright, tracked by
|
||||||
`Theme.tracking`, on a one-pixel soft drop. The two ghosts either side of it
|
`Theme.tracking`, on a one-pixel soft drop. The two ghosts either side of it
|
||||||
@@ -332,16 +331,22 @@ inside the ship and the windows sit in the porthole. The bar and the rail draw
|
|||||||
no surface of their own and ignore exclusive zones; Frame reserves all four
|
no surface of their own and ignore exclusive zones; Frame reserves all four
|
||||||
zones itself, so every piece is placed from the screen edge.
|
zones itself, so every piece is placed from the screen edge.
|
||||||
|
|
||||||
**Rectangles, everywhere else.** NieR panels are plain boxes. `Theme.skew` and
|
**Soft, everywhere else.** The porthole is the shape the desktop is built
|
||||||
`Theme.cut` are both `0`, so `P5Panel`, `Skew` and `Geom` all collapse to
|
around, and every smaller surface is a gentler echo of it. `Theme.skew` and
|
||||||
rectangles; the knobs are kept so a shape can be brought back on purpose. The
|
`Theme.cut` are `0`; `P5Panel` and `Skew` draw `Geom.roundedRect` with
|
||||||
porthole's curve is the only one on screen, which is what lets it read.
|
`Theme.radiusS` (pills, chips, meter tracks), `radiusM` (rows, buttons) or
|
||||||
|
`radiusL`. `radiusL` is `frameRadius - padS`: anything inset by `padS` inside
|
||||||
|
one of the frame's curves — a hovered notification in the drawer's corner —
|
||||||
|
gets a corner concentric with it, so the gap stays even and nothing pokes past
|
||||||
|
the curve. Free-standing panels (launcher, ask) take `frameRadius` itself.
|
||||||
|
Toggles, transport buttons, workspace pips and today's date are pills or
|
||||||
|
discs; album art is rounded via `ClippingRectangle`.
|
||||||
|
|
||||||
**Motion glides.** No overshoot anywhere: things ease in on `OutCubic` or
|
**Motion glides.** No overshoot anywhere: things ease in on `OutCubic` or
|
||||||
`OutExpo` and settle. Nothing scales up or nudges sideways on hover either;
|
`OutExpo` and settle. Nothing scales up or nudges sideways on hover either;
|
||||||
hover brightens and marks, the way NieR's menus do. Meters are thin segment
|
hover brightens and marks, the way NieR's menus do. Meters are one continuous
|
||||||
rows, album art sits square in a hairline frame, and the bar's player shows a
|
rounded line that glides to its level, and the bar's player shows a
|
||||||
five-hairline signal meter.
|
five-line signal meter.
|
||||||
|
|
||||||
Each surface is **one continuous slab**, with modules divided by hairline rules
|
Each surface is **one continuous slab**, with modules divided by hairline rules
|
||||||
rather than by gaps. A row of separate floating cards reads as clutter; that is
|
rather than by gaps. A row of separate floating cards reads as clutter; that is
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import QtQuick
|
|||||||
import QtQuick.Shapes
|
import QtQuick.Shapes
|
||||||
import QtQuick.Window
|
import QtQuick.Window
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
import Quickshell.Widgets
|
||||||
import "root:/config"
|
import "root:/config"
|
||||||
import "root:/components"
|
import "root:/components"
|
||||||
import "root:/services"
|
import "root:/services"
|
||||||
@@ -41,12 +42,13 @@ BarPill {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
spacing: Theme.padS
|
spacing: Theme.padS
|
||||||
|
|
||||||
// Album art in a hairline frame.
|
// Album art, rounded, in a hairline frame.
|
||||||
Rectangle {
|
ClippingRectangle {
|
||||||
id: artFrame
|
id: artFrame
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: 24
|
width: 24
|
||||||
height: 24
|
height: 24
|
||||||
|
radius: Theme.radiusS
|
||||||
color: Theme.surface
|
color: Theme.surface
|
||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: Theme.overlay
|
border.color: Theme.overlay
|
||||||
@@ -111,9 +113,9 @@ BarPill {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signal meter: five hairline bars, NieR's audio readout rather than a
|
// Signal meter: five thin rounded bars, NieR's audio readout rather than a
|
||||||
// chunky equaliser. It moves only while audio is playing and settles
|
// chunky equaliser. It moves only while audio is playing and settles
|
||||||
// into a row of square dots when paused — the channel is open, there
|
// into a row of dots when paused — the channel is open, there
|
||||||
// is just nothing on it.
|
// is just nothing on it.
|
||||||
//
|
//
|
||||||
// Sampled from a timer rather than tweened by an infinite
|
// Sampled from a timer rather than tweened by an infinite
|
||||||
@@ -181,7 +183,8 @@ BarPill {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
required property int index
|
required property int index
|
||||||
width: 1
|
width: 2
|
||||||
|
radius: 1
|
||||||
height: Media.playing ? eq.level(index) : 2
|
height: Media.playing ? eq.level(index) : 2
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
color: Media.playing ? Theme.primary : Theme.muted
|
color: Media.playing ? Theme.primary : Theme.muted
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ Item {
|
|||||||
anchors.leftMargin: root.wipeInset
|
anchors.leftMargin: root.wipeInset
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: 2
|
width: 2
|
||||||
|
radius: 1
|
||||||
height: root.hovered ? Theme.marker * 2 : 0
|
height: root.hovered ? Theme.marker * 2 : 0
|
||||||
color: Theme.glow
|
color: Theme.glow
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import Quickshell.Hyprland
|
|||||||
import "root:/config"
|
import "root:/config"
|
||||||
import "root:/components"
|
import "root:/components"
|
||||||
|
|
||||||
// Workspace indicator: leaning ticks that stretch open when focused. Occupied
|
// Workspace indicator: soft pills that stretch open when focused. Occupied
|
||||||
// workspaces fill in, urgent ones snap to the alarm colour.
|
// workspaces fill in, urgent ones snap to the alarm colour.
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
@@ -82,6 +82,7 @@ Item {
|
|||||||
Skew {
|
Skew {
|
||||||
id: tick
|
id: tick
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
radius: height / 2
|
||||||
|
|
||||||
// Focused is a solid accent block. Urgent is a solid alarm
|
// Focused is a solid accent block. Urgent is a solid alarm
|
||||||
// block — it used to be the accent too, which made an
|
// block — it used to be the accent too, which made an
|
||||||
@@ -132,6 +133,7 @@ Item {
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
visible: pip.info !== undefined && pip.info.fullscreen && !pip.focused
|
visible: pip.info !== undefined && pip.info.fullscreen && !pip.focused
|
||||||
width: 4; height: 4
|
width: 4; height: 4
|
||||||
|
radius: 2
|
||||||
color: Theme.accent
|
color: Theme.accent
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.top: parent.bottom
|
anchors.top: parent.bottom
|
||||||
|
|||||||
@@ -18,4 +18,5 @@ P5Panel {
|
|||||||
slashColor: tone
|
slashColor: tone
|
||||||
slashWidth: 2
|
slashWidth: 2
|
||||||
padding: Theme.padS
|
padding: Theme.padS
|
||||||
|
radius: Theme.radiusM
|
||||||
}
|
}
|
||||||
@@ -3,9 +3,10 @@ pragma Singleton
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
|
||||||
// Polygon maths for panel shapes. Under the YoRHa theme nothing leans and
|
// Shape maths for panels. Under the YoRHa theme nothing leans and nothing is
|
||||||
// nothing is chopped (Theme.skew and Theme.cut are 0), so these collapse to
|
// chopped (Theme.skew and Theme.cut are 0); surfaces are rounded rectangles
|
||||||
// plain rectangles; they are kept so a shape can be brought back on purpose.
|
// (roundedRect). The polygon helpers are kept so a shape can be brought back
|
||||||
|
// on purpose.
|
||||||
// Originally the Persona 5 panel language: everything leans, and corners
|
// Originally the Persona 5 panel language: everything leans, and corners
|
||||||
// get chopped rather than rounded.
|
// get chopped rather than rounded.
|
||||||
Singleton {
|
Singleton {
|
||||||
@@ -89,6 +90,25 @@ Singleton {
|
|||||||
return root.closed(out);
|
return root.closed(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A polygon as an SVG path string, for PathSvg.
|
||||||
|
function svg(pts: var): string {
|
||||||
|
if (pts.length === 0) return "";
|
||||||
|
let d = `M ${pts[0].x} ${pts[0].y}`;
|
||||||
|
for (let i = 1; i < pts.length; i++) d += ` L ${pts[i].x} ${pts[i].y}`;
|
||||||
|
return d + " Z";
|
||||||
|
}
|
||||||
|
|
||||||
|
// A w x h rectangle with every corner rounded by `r`, clamped so a short
|
||||||
|
// piece becomes a pill rather than folding over itself.
|
||||||
|
function roundedRect(w: real, h: real, r: real): string {
|
||||||
|
const k = Math.max(0, Math.min(r, w / 2, h / 2));
|
||||||
|
if (k <= 0) return root.svg([Qt.point(0, 0), Qt.point(w, 0), Qt.point(w, h), Qt.point(0, h)]);
|
||||||
|
return `M ${k} 0 H ${w - k} A ${k} ${k} 0 0 1 ${w} ${k}`
|
||||||
|
+ ` V ${h - k} A ${k} ${k} 0 0 1 ${w - k} ${h}`
|
||||||
|
+ ` H ${k} A ${k} ${k} 0 0 1 0 ${h - k}`
|
||||||
|
+ ` V ${k} A ${k} ${k} 0 0 1 ${k} 0 Z`;
|
||||||
|
}
|
||||||
|
|
||||||
function closed(pts: var): var {
|
function closed(pts: var): var {
|
||||||
if (pts.length === 0) return pts;
|
if (pts.length === 0) return pts;
|
||||||
const out = pts.slice();
|
const out = pts.slice();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import "root:/config"
|
|||||||
// came out as a faint milky film. This is the one row they share now.
|
// came out as a faint milky film. This is the one row they share now.
|
||||||
//
|
//
|
||||||
// Rest is bare. Hover lifts the row onto the surface tone. The current item —
|
// Rest is bare. Hover lifts the row onto the surface tone. The current item —
|
||||||
// connected, in use — carries the NieR square marker at its leading edge and
|
// connected, in use — carries a dot at its leading edge and
|
||||||
// an accent glyph, and its label goes to full weight.
|
// an accent glyph, and its label goes to full weight.
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
@@ -30,6 +30,7 @@ Item {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
radius: Theme.radiusM
|
||||||
color: root.hovered ? Theme.treatmentHoverFill : "transparent"
|
color: root.hovered ? Theme.treatmentHoverFill : "transparent"
|
||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
@@ -43,6 +44,7 @@ Item {
|
|||||||
anchors.leftMargin: 2
|
anchors.leftMargin: 2
|
||||||
width: root.current ? Theme.marker : 0
|
width: root.current ? Theme.marker : 0
|
||||||
height: width
|
height: width
|
||||||
|
radius: width / 2
|
||||||
color: Theme.accent
|
color: Theme.accent
|
||||||
|
|
||||||
Behavior on width {
|
Behavior on width {
|
||||||
|
|||||||
@@ -2,8 +2,12 @@ import QtQuick
|
|||||||
import "root:/config"
|
import "root:/config"
|
||||||
import "root:/components"
|
import "root:/components"
|
||||||
|
|
||||||
// A segmented load meter — upright ticks that light up left to right. Reads as
|
// A load meter: a soft rounded track with the level filling it from the left.
|
||||||
// a gauge at a glance and keeps the panel language consistent.
|
// It used to be a row of separate segments; one continuous line reads calmer,
|
||||||
|
// and a level that glides reads as a quantity rather than as a count.
|
||||||
|
//
|
||||||
|
// `segments`, `segmentWidth` and `spacing` are accepted and ignored, so the
|
||||||
|
// call sites that still size a segmented meter do not have to be chased down.
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
@@ -12,42 +16,33 @@ Item {
|
|||||||
property real segmentWidth: 4
|
property real segmentWidth: 4
|
||||||
property real spacing: 3
|
property real spacing: 3
|
||||||
property color activeColor: Theme.heat(value)
|
property color activeColor: Theme.heat(value)
|
||||||
property color idleColor: Theme.alpha(Theme.outline, 0.55)
|
property color idleColor: Theme.alpha(Theme.outline, 0.35)
|
||||||
property real lean: Theme.skew
|
property real lean: Theme.skew
|
||||||
|
|
||||||
readonly property int litCount: Math.round(Math.max(0, Math.min(100, value)) / 100 * segments)
|
|
||||||
|
|
||||||
implicitWidth: segments * segmentWidth + (segments - 1) * spacing
|
implicitWidth: segments * segmentWidth + (segments - 1) * spacing
|
||||||
implicitHeight: 14
|
implicitHeight: 4
|
||||||
|
|
||||||
Row {
|
readonly property real fraction: Math.max(0, Math.min(100, root.value)) / 100
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: root.spacing
|
radius: height / 2
|
||||||
|
color: root.idleColor
|
||||||
|
}
|
||||||
|
|
||||||
Repeater {
|
Rectangle {
|
||||||
model: root.segments
|
height: parent.height
|
||||||
|
// Never narrower than its own height, so a near-zero level is a dot
|
||||||
|
// rather than a sliver.
|
||||||
|
width: root.fraction > 0 ? Math.max(height, parent.width * root.fraction) : 0
|
||||||
|
radius: height / 2
|
||||||
|
color: root.activeColor
|
||||||
|
|
||||||
Item {
|
Behavior on width {
|
||||||
required property int index
|
NumberAnimation { duration: Theme.durSlow; easing.type: Easing.OutCubic }
|
||||||
width: root.segmentWidth
|
}
|
||||||
height: root.height
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: Theme.durBase }
|
||||||
Skew {
|
|
||||||
width: root.segmentWidth
|
|
||||||
height: root.height
|
|
||||||
lean: root.lean
|
|
||||||
color: parent.index < root.litCount ? root.activeColor : root.idleColor
|
|
||||||
|
|
||||||
// Peak segments glow, so a pegged CPU is visible peripherally.
|
|
||||||
opacity: parent.index < root.litCount
|
|
||||||
? (parent.index >= root.segments - 2 ? 1.0 : 0.9)
|
|
||||||
: 1.0
|
|
||||||
|
|
||||||
Behavior on color {
|
|
||||||
ColorAnimation { duration: Theme.durBase }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
import Quickshell.Widgets
|
||||||
import Quickshell.Services.Notifications
|
import Quickshell.Services.Notifications
|
||||||
import "root:/config"
|
import "root:/config"
|
||||||
import "root:/components"
|
import "root:/components"
|
||||||
@@ -7,14 +8,14 @@ import "root:/services"
|
|||||||
|
|
||||||
// One notification, used both in the history list and in the toast drawer.
|
// One notification, used both in the history list and in the toast drawer.
|
||||||
//
|
//
|
||||||
// Laid out like an entry in NieR's message log rather than as a card: a square
|
// Laid out like an entry in NieR's message log rather than as a card: a dot
|
||||||
// marker and the sender's name running into a hairline, the summary, the body,
|
// and the sender's name running into a hairline, the summary, the body, and
|
||||||
// and hairline buttons for any actions. There is no panel of its own — both
|
// pill buttons for any actions. There is no panel of its own — both places it
|
||||||
// places it appears are already hull surfaces — so rest is bare, hover lifts
|
// appears are already hull surfaces — so rest is bare, hover lifts the entry
|
||||||
// the row onto the surface tone, and entries are divided by the hairline in
|
// onto a soft rounded wash, and entries are divided by the hairline in their
|
||||||
// their own header.
|
// own header.
|
||||||
//
|
//
|
||||||
// Urgency is the marker: the light for normal, grey for low, red for critical.
|
// Urgency is the dot: the light for normal, grey for low, red for critical.
|
||||||
// A critical entry also takes the red into its sender line, and nothing else.
|
// A critical entry also takes the red into its sender line, and nothing else.
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
@@ -38,8 +39,14 @@ Item {
|
|||||||
|
|
||||||
implicitHeight: layout.implicitHeight + Theme.padM * 2
|
implicitHeight: layout.implicitHeight + Theme.padM * 2
|
||||||
|
|
||||||
|
// Hover wash. Inset by padS and rounded by radiusL, which is the frame's
|
||||||
|
// radius less that inset: an entry in the bottom corner of the drawer gets
|
||||||
|
// a corner concentric with the drawer's own, instead of a square one that
|
||||||
|
// ran out past the drawer's curve.
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.padS / 2
|
||||||
|
radius: Theme.radiusL
|
||||||
color: root.hovered ? Theme.treatmentHoverFill : "transparent"
|
color: root.hovered ? Theme.treatmentHoverFill : "transparent"
|
||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
@@ -66,6 +73,7 @@ Item {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: Theme.marker
|
width: Theme.marker
|
||||||
height: Theme.marker
|
height: Theme.marker
|
||||||
|
radius: width / 2
|
||||||
color: root.tone
|
color: root.tone
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,12 +170,13 @@ Item {
|
|||||||
renderType: Text.NativeRendering
|
renderType: Text.NativeRendering
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inline image, when the sender supplied one, in a hairline frame.
|
// Inline image, when the sender supplied one, rounded in a hairline frame.
|
||||||
Rectangle {
|
ClippingRectangle {
|
||||||
x: Theme.marker + Theme.padS
|
x: Theme.marker + Theme.padS
|
||||||
visible: inline.source != "" && inline.status === Image.Ready
|
visible: inline.source != "" && inline.status === Image.Ready
|
||||||
width: inline.width + 2
|
width: inline.width + 2
|
||||||
height: inline.height + 2
|
height: inline.height + 2
|
||||||
|
radius: Theme.radiusM
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: Theme.overlay
|
border.color: Theme.overlay
|
||||||
@@ -192,8 +201,7 @@ Item {
|
|||||||
Repeater {
|
Repeater {
|
||||||
model: root.notif?.actions ?? []
|
model: root.notif?.actions ?? []
|
||||||
|
|
||||||
// A hairline button with a marker, the P5Button pattern at a
|
// A hairline pill. Hover lifts and lights it; it never inverts.
|
||||||
// smaller size. Hover lifts and lights it; it never inverts.
|
|
||||||
Item {
|
Item {
|
||||||
id: actionChip
|
id: actionChip
|
||||||
required property var modelData
|
required property var modelData
|
||||||
@@ -203,6 +211,7 @@ Item {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
radius: height / 2
|
||||||
color: actionHover.hovered ? Theme.treatmentHoverFill : "transparent"
|
color: actionHover.hovered ? Theme.treatmentHoverFill : "transparent"
|
||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: actionHover.hovered ? Theme.treatmentHoverMark : Theme.overlay
|
border.color: actionHover.hovered ? Theme.treatmentHoverMark : Theme.overlay
|
||||||
@@ -221,6 +230,7 @@ Item {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: 4
|
width: 4
|
||||||
height: 4
|
height: 4
|
||||||
|
radius: 2
|
||||||
color: actionLabel.color
|
color: actionLabel.color
|
||||||
opacity: actionHover.hovered ? 1 : 0.4
|
opacity: actionHover.hovered ? 1 : 0.4
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ FocusScope {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: Theme.marker
|
width: Theme.marker
|
||||||
height: Theme.marker
|
height: Theme.marker
|
||||||
|
radius: width / 2
|
||||||
color: label.color
|
color: label.color
|
||||||
opacity: root.highlighted ? 1.0 : 0.35
|
opacity: root.highlighted ? 1.0 : 0.35
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,8 @@ import "root:/config"
|
|||||||
import "root:/components"
|
import "root:/components"
|
||||||
|
|
||||||
// The base surface for everything in this shell. Under the YoRHa theme it is a
|
// The base surface for everything in this shell. Under the YoRHa theme it is a
|
||||||
// plain rectangle with a hairline border, an optional dot wash, an optional
|
// rounded rectangle with a hairline border, an optional dot wash, an optional
|
||||||
// accent bar down its leading edge, and optional corner ticks — the brackets
|
// accent bar down its leading edge, and optional corner ticks.
|
||||||
// NieR frames its panels with.
|
|
||||||
//
|
//
|
||||||
// The lean and chop knobs still exist and still work, so a caller can bring a
|
// The lean and chop knobs still exist and still work, so a caller can bring a
|
||||||
// shape back on purpose, but Theme.skew and Theme.cut are both zero.
|
// shape back on purpose, but Theme.skew and Theme.cut are both zero.
|
||||||
@@ -34,6 +33,10 @@ Item {
|
|||||||
property real chop: Theme.cut
|
property real chop: Theme.cut
|
||||||
property var chopCorners: [1, 3]
|
property var chopCorners: [1, 3]
|
||||||
|
|
||||||
|
// Corner radius. Used whenever the panel neither leans nor is chopped,
|
||||||
|
// which under the YoRHa theme is always.
|
||||||
|
property real radius: Theme.radiusM
|
||||||
|
|
||||||
// Accent bar down the leading edge.
|
// Accent bar down the leading edge.
|
||||||
property bool slash: false
|
property bool slash: false
|
||||||
property color slashColor: Theme.accent
|
property color slashColor: Theme.accent
|
||||||
@@ -67,6 +70,11 @@ Item {
|
|||||||
readonly property real leanInset:
|
readonly property real leanInset:
|
||||||
(vertical ? width : height) * Math.abs(lean)
|
(vertical ? width : height) * Math.abs(lean)
|
||||||
|
|
||||||
|
// The outline every layer below is drawn from.
|
||||||
|
readonly property string outline: root.lean === 0 && root.chop <= 0
|
||||||
|
? Geom.roundedRect(root.width, root.height, root.radius)
|
||||||
|
: Geom.svg(Geom.chamfer(root.polygon, root.chop, root.chopCorners).slice(0, -1))
|
||||||
|
|
||||||
readonly property var polygon: vertical
|
readonly property var polygon: vertical
|
||||||
? (leanLeft ? Geom.parallelogramVL(width, height, lean)
|
? (leanLeft ? Geom.parallelogramVL(width, height, lean)
|
||||||
: Geom.parallelogramV(width, height, lean))
|
: Geom.parallelogramV(width, height, lean))
|
||||||
@@ -99,8 +107,8 @@ Item {
|
|||||||
strokeColor: "transparent"
|
strokeColor: "transparent"
|
||||||
joinStyle: ShapePath.MiterJoin
|
joinStyle: ShapePath.MiterJoin
|
||||||
|
|
||||||
PathPolyline {
|
PathSvg {
|
||||||
path: Geom.chamfer(root.polygon, root.chop, root.chopCorners)
|
path: root.outline
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,8 +131,8 @@ Item {
|
|||||||
strokeColor: "transparent"
|
strokeColor: "transparent"
|
||||||
joinStyle: ShapePath.MiterJoin
|
joinStyle: ShapePath.MiterJoin
|
||||||
|
|
||||||
PathPolyline {
|
PathSvg {
|
||||||
path: Geom.chamfer(root.polygon, root.chop, root.chopCorners)
|
path: root.outline
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,8 +156,8 @@ Item {
|
|||||||
joinStyle: ShapePath.MiterJoin
|
joinStyle: ShapePath.MiterJoin
|
||||||
capStyle: ShapePath.FlatCap
|
capStyle: ShapePath.FlatCap
|
||||||
|
|
||||||
PathPolyline {
|
PathSvg {
|
||||||
path: Geom.chamfer(root.polygon, root.chop, root.chopCorners)
|
path: root.outline
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,8 +169,8 @@ Item {
|
|||||||
joinStyle: ShapePath.MiterJoin
|
joinStyle: ShapePath.MiterJoin
|
||||||
capStyle: ShapePath.FlatCap
|
capStyle: ShapePath.FlatCap
|
||||||
|
|
||||||
PathPolyline {
|
PathSvg {
|
||||||
path: Geom.chamfer(root.polygon, root.chop, root.chopCorners)
|
path: root.outline
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import QtQuick
|
|||||||
import "root:/config"
|
import "root:/config"
|
||||||
import "root:/components"
|
import "root:/components"
|
||||||
|
|
||||||
// Hairline slider with a square handle, the NieR settings-menu slider. Drag or
|
// Hairline slider with a round handle. Drag or click anywhere on the rail.
|
||||||
// click anywhere on the rail.
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
@@ -68,6 +67,7 @@ Item {
|
|||||||
Skew {
|
Skew {
|
||||||
id: handle
|
id: handle
|
||||||
width: height
|
width: height
|
||||||
|
radius: height / 2
|
||||||
height: root.activeFocus || hover.hovered || drag.active ? 12 : 10
|
height: root.activeFocus || hover.hovered || drag.active ? 12 : 10
|
||||||
color: root.enabled ? Theme.text : Theme.treatmentDisabledText
|
color: root.enabled ? Theme.text : Theme.treatmentDisabledText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import QtQuick.Shapes
|
|||||||
import "root:/config"
|
import "root:/config"
|
||||||
import "root:/components"
|
import "root:/components"
|
||||||
|
|
||||||
// A leaning block — the small-scale counterpart to P5Panel.
|
// A small block — the small-scale counterpart to P5Panel. Upright and rounded
|
||||||
|
// under the YoRHa theme; it still leans if given a lean.
|
||||||
//
|
//
|
||||||
// Every tick, rule, meter segment and slider rail in this shell leans at
|
// Every tick, rule, meter segment and slider rail in this shell leans at
|
||||||
// Theme.skew. Shearing a plain Rectangle with a Matrix4x4 does that, but Qt
|
// Theme.skew. Shearing a plain Rectangle with a Matrix4x4 does that, but Qt
|
||||||
@@ -31,6 +32,11 @@ Shape {
|
|||||||
// rail slab.
|
// rail slab.
|
||||||
property bool vertical: false
|
property bool vertical: false
|
||||||
|
|
||||||
|
// Corner radius for an upright piece, clamped to a pill. Small by default,
|
||||||
|
// so a meter segment or a hover wash reads soft rather than as a block;
|
||||||
|
// a hairline stays a hairline.
|
||||||
|
property real radius: Theme.radiusS
|
||||||
|
|
||||||
// NOTE ON SIZING. The lean shifts one edge by `lean * height` (or by
|
// NOTE ON SIZING. The lean shifts one edge by `lean * height` (or by
|
||||||
// `lean * width` when vertical), and the piece that actually gets painted is
|
// `lean * width` when vertical), and the piece that actually gets painted is
|
||||||
// what is left: a Skew declared 1px wide and 20px tall does not draw a 1px
|
// what is left: a Skew declared 1px wide and 20px tall does not draw a 1px
|
||||||
@@ -55,14 +61,16 @@ Shape {
|
|||||||
joinStyle: ShapePath.MiterJoin
|
joinStyle: ShapePath.MiterJoin
|
||||||
capStyle: ShapePath.FlatCap
|
capStyle: ShapePath.FlatCap
|
||||||
|
|
||||||
PathPolyline {
|
PathSvg {
|
||||||
path: {
|
path: {
|
||||||
const w = root.width, h = root.height, l = root.lean;
|
const w = root.width, h = root.height, l = root.lean;
|
||||||
|
if (l === 0)
|
||||||
|
return Geom.roundedRect(w, h, root.radius);
|
||||||
if (root.vertical)
|
if (root.vertical)
|
||||||
return Geom.closed(root.leanLeft ? Geom.parallelogramVL(w, h, l)
|
return Geom.svg(root.leanLeft ? Geom.parallelogramVL(w, h, l)
|
||||||
: Geom.parallelogramV(w, h, l));
|
: Geom.parallelogramV(w, h, l));
|
||||||
return Geom.closed(root.leanLeft ? Geom.parallelogramL(w, h, l)
|
return Geom.svg(root.leanLeft ? Geom.parallelogramL(w, h, l)
|
||||||
: Geom.parallelogram(w, h, l));
|
: Geom.parallelogram(w, h, l));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,9 +190,8 @@ Singleton {
|
|||||||
readonly property int frame: 8
|
readonly property int frame: 8
|
||||||
readonly property int frameRadius: 18
|
readonly property int frameRadius: 18
|
||||||
|
|
||||||
// Nothing leans and nothing is chopped. NieR panels are plain rectangles;
|
// Nothing leans and nothing is chopped. Both knobs are kept so the shape
|
||||||
// their character comes from hairlines, square markers and corner ticks.
|
// code still has one place to ask.
|
||||||
// Both knobs are kept so the shape code still has one place to ask.
|
|
||||||
readonly property real skew: 0
|
readonly property real skew: 0
|
||||||
readonly property int cut: 0
|
readonly property int cut: 0
|
||||||
readonly property int stroke: 1
|
readonly property int stroke: 1
|
||||||
@@ -202,8 +201,21 @@ Singleton {
|
|||||||
readonly property real dropOffset: 0
|
readonly property real dropOffset: 0
|
||||||
readonly property real keylineWidth: 0
|
readonly property real keylineWidth: 0
|
||||||
|
|
||||||
// The square bullet that marks the current row, and the length of the
|
// Corners. Everything is soft — the porthole is the shape the whole
|
||||||
// corner ticks that frame a panel.
|
// desktop is built around, and every smaller surface is a gentler echo of
|
||||||
|
// it rather than a hard block.
|
||||||
|
//
|
||||||
|
// radiusS pills and small chips: buttons, tags, meter tracks
|
||||||
|
// radiusM rows and panels inside a surface
|
||||||
|
// radiusL anything that sits a padS inside the frame's own curve:
|
||||||
|
// frameRadius - padS, so its corner is concentric with the
|
||||||
|
// corner it sits in and the gap between them stays even
|
||||||
|
readonly property int radiusS: 6
|
||||||
|
readonly property int radiusM: 10
|
||||||
|
readonly property int radiusL: frameRadius - padS
|
||||||
|
|
||||||
|
// The dot that marks the current row, and the length of the corner
|
||||||
|
// ticks a panel can still ask for.
|
||||||
readonly property int marker: 6
|
readonly property int marker: 6
|
||||||
readonly property int tick: 8
|
readonly property int tick: 8
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Shapes
|
import QtQuick.Shapes
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
import Quickshell.Widgets
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
@@ -241,7 +242,7 @@ PanelWindow {
|
|||||||
|
|
||||||
Rule { height: root.columnHeight }
|
Rule { height: root.columnHeight }
|
||||||
|
|
||||||
// The month, Monday first. Today is the NieR cursor: an inverted square.
|
// The month, Monday first. Today is the NieR cursor: an inverted disc.
|
||||||
Item {
|
Item {
|
||||||
id: month
|
id: month
|
||||||
implicitWidth: 238
|
implicitWidth: 238
|
||||||
@@ -311,7 +312,8 @@ PanelWindow {
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: 22
|
width: 22
|
||||||
height: 20
|
height: 22
|
||||||
|
radius: 11
|
||||||
visible: parent.modelData.today
|
visible: parent.modelData.today
|
||||||
color: Theme.treatmentSelectedFill
|
color: Theme.treatmentSelectedFill
|
||||||
}
|
}
|
||||||
@@ -418,10 +420,11 @@ PanelWindow {
|
|||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
visible: Media.hasPlayer
|
visible: Media.hasPlayer
|
||||||
|
|
||||||
Rectangle {
|
ClippingRectangle {
|
||||||
id: artFrame
|
id: artFrame
|
||||||
width: 96
|
width: 96
|
||||||
height: 96
|
height: 96
|
||||||
|
radius: Theme.radiusL
|
||||||
color: Theme.surface
|
color: Theme.surface
|
||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: Theme.overlay
|
border.color: Theme.overlay
|
||||||
@@ -506,6 +509,7 @@ PanelWindow {
|
|||||||
x: parent.width * Media.progress - width / 2
|
x: parent.width * Media.progress - width / 2
|
||||||
width: Theme.marker
|
width: Theme.marker
|
||||||
height: Theme.marker
|
height: Theme.marker
|
||||||
|
radius: width / 2
|
||||||
color: Theme.accent
|
color: Theme.accent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -596,7 +600,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A square hairline button. Hover lifts it; nothing here inverts, since
|
// A round hairline button. Hover lifts it; nothing here inverts, since
|
||||||
// inversion is reserved for the keyboard's cursor.
|
// inversion is reserved for the keyboard's cursor.
|
||||||
component Transport: Item {
|
component Transport: Item {
|
||||||
id: tb
|
id: tb
|
||||||
@@ -609,6 +613,7 @@ PanelWindow {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
radius: width / 2
|
||||||
color: tbHover.hovered ? Theme.treatmentHoverFill : "transparent"
|
color: tbHover.hovered ? Theme.treatmentHoverFill : "transparent"
|
||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: tbHover.hovered ? Theme.treatmentHoverMark : Theme.overlay
|
border.color: tbHover.hovered ? Theme.treatmentHoverMark : Theme.overlay
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: -Theme.padS
|
anchors.leftMargin: -Theme.padS
|
||||||
anchors.rightMargin: -Theme.padS
|
anchors.rightMargin: -Theme.padS
|
||||||
|
radius: Theme.radiusM
|
||||||
color: root.selected ? Theme.treatmentSelectedFill : "transparent"
|
color: root.selected ? Theme.treatmentSelectedFill : "transparent"
|
||||||
opacity: root.selected ? 1 : 0
|
opacity: root.selected ? 1 : 0
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,8 @@ Popout {
|
|||||||
Skew {
|
Skew {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: 26
|
width: 26
|
||||||
height: 24
|
height: 26
|
||||||
|
radius: 13
|
||||||
visible: cell.modelData.today
|
visible: cell.modelData.today
|
||||||
color: Theme.accent
|
color: Theme.accent
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Shapes
|
import QtQuick.Shapes
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
import Quickshell.Widgets
|
||||||
import "root:/config"
|
import "root:/config"
|
||||||
import "root:/components"
|
import "root:/components"
|
||||||
import "root:/services"
|
import "root:/services"
|
||||||
@@ -32,14 +33,15 @@ Popout {
|
|||||||
subtitle: Media.identity
|
subtitle: Media.identity
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cover art in a hairline frame.
|
// Cover art, rounded, in a hairline frame.
|
||||||
Rectangle {
|
ClippingRectangle {
|
||||||
id: artFrame
|
id: artFrame
|
||||||
anchors.top: header.bottom
|
anchors.top: header.bottom
|
||||||
anchors.topMargin: Theme.padM
|
anchors.topMargin: Theme.padM
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
width: 108
|
width: 108
|
||||||
height: 108
|
height: 108
|
||||||
|
radius: Theme.radiusL
|
||||||
color: Theme.surface
|
color: Theme.surface
|
||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: Theme.overlay
|
border.color: Theme.overlay
|
||||||
@@ -216,6 +218,7 @@ Popout {
|
|||||||
|
|
||||||
Skew {
|
Skew {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
radius: height / 2
|
||||||
color: !chip.enabled
|
color: !chip.enabled
|
||||||
? Theme.treatmentDisabledFill
|
? Theme.treatmentDisabledFill
|
||||||
: (chip.activeFocus
|
: (chip.activeFocus
|
||||||
@@ -287,6 +290,7 @@ Popout {
|
|||||||
|
|
||||||
Skew {
|
Skew {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
radius: width / 2
|
||||||
color: {
|
color: {
|
||||||
if (!tb.enabled) return "transparent";
|
if (!tb.enabled) return "transparent";
|
||||||
if (tb.activeFocus) return Theme.treatmentFocusFill;
|
if (tb.activeFocus) return Theme.treatmentFocusFill;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import "root:/config"
|
|||||||
import "root:/components"
|
import "root:/components"
|
||||||
|
|
||||||
// Title bar for a popout, in the NieR header pattern: glyph, tracked heading,
|
// Title bar for a popout, in the NieR header pattern: glyph, tracked heading,
|
||||||
// right-aligned status text, and a hairline rule that ends in a square.
|
// right-aligned status text, and a hairline rule that ends in a dot.
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
@@ -62,6 +62,7 @@ Item {
|
|||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
width: Theme.marker
|
width: Theme.marker
|
||||||
height: Theme.marker
|
height: Theme.marker
|
||||||
|
radius: width / 2
|
||||||
color: Theme.accent
|
color: Theme.accent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,14 +17,16 @@ P5Panel {
|
|||||||
// Zero, not a transparent fill: P5Panel re-applies this opacity to the
|
// Zero, not a transparent fill: P5Panel re-applies this opacity to the
|
||||||
// fill colour, which turned "transparent" into 97% black.
|
// fill colour, which turned "transparent" into 97% black.
|
||||||
fillOpacity: attached ? 0 : 0.97
|
fillOpacity: attached ? 0 : 0.97
|
||||||
// The frame is structure: a neutral hairline. The tone goes into the
|
// The frame is structure: a neutral hairline. A free-standing panel takes
|
||||||
// corner ticks, which is where NieR puts the one bright mark on a panel.
|
// the frame's own corner radius, so it reads as a piece of the hull set
|
||||||
|
// down somewhere else rather than as a hard card.
|
||||||
border: Theme.surfaceAlt
|
border: Theme.surfaceAlt
|
||||||
borderWidth: attached ? 0 : Theme.stroke
|
borderWidth: attached ? 0 : Theme.stroke
|
||||||
halftone: textured
|
halftone: textured
|
||||||
halftoneColor: tone
|
halftoneColor: tone
|
||||||
halftoneOpacity: 0.06
|
halftoneOpacity: 0.06
|
||||||
ticks: !attached
|
ticks: false
|
||||||
|
radius: Theme.frameRadius
|
||||||
tickColor: tone
|
tickColor: tone
|
||||||
padding: Theme.padM
|
padding: Theme.padM
|
||||||
}
|
}
|
||||||
@@ -106,6 +106,7 @@ Column {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: Theme.padS
|
anchors.leftMargin: Theme.padS
|
||||||
anchors.rightMargin: Theme.padS
|
anchors.rightMargin: Theme.padS
|
||||||
|
radius: Theme.radiusM
|
||||||
color: row.hovered ? Theme.accent : "transparent"
|
color: row.hovered ? Theme.accent : "transparent"
|
||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
|
|||||||
Reference in new issue
Block a user