mirror of
https://github.com/arthur-pbty/arthur-os.git
synced 2026-08-02 04:37:49 +02:00
Promote cornerRadius + focus tokens to qs.Commons.Style singleton
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
pragma Singleton
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
|
||||
// Shared structural style tokens for the shell. Color is the palette
|
||||
// singleton; Style holds the *shape* and *focus-affordance* tokens that
|
||||
// every panel surface and qs.Ui component should bind to so they stay
|
||||
// in sync as the user toggles round/sharp corners or as themes change.
|
||||
//
|
||||
// `cornerRadius` is mirrored from ~/.local/state/omarchy/toggles/quickshell-menu.json.
|
||||
// `omarchy style corners <round|sharp>` writes that file; we watch it and
|
||||
// hot-reload the binding here so every consumer rerenders.
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
property int cornerRadius: 0
|
||||
|
||||
// Focus affordances. Deliberately distinct from "selected" (which uses an
|
||||
// accent fill) so the keyboard cursor never reads as the chosen value.
|
||||
// The settings panel originated these tokens; promoting them here means
|
||||
// every Ui component picks them up uniformly.
|
||||
readonly property color focusBorderColor: Color.accent
|
||||
readonly property color focusFillColor: Qt.rgba(Color.accent.r, Color.accent.g, Color.accent.b, 0.22)
|
||||
readonly property int focusBorderWidth: 3
|
||||
|
||||
// Convenience: the standard "hot" (hover or keyboard cursor) tint used by
|
||||
// PillButton, PanelActionButton, etc. Foreground at 0.12 alpha matches the
|
||||
// value PillButton was already painting before promotion.
|
||||
readonly property color hotFill: Qt.rgba(Color.foreground.r, Color.foreground.g, Color.foreground.b, 0.12)
|
||||
|
||||
function loadStyleState(raw) {
|
||||
try {
|
||||
var s = JSON.parse(raw || "{}")
|
||||
var n = Number(s.radius)
|
||||
cornerRadius = isFinite(n) ? n : 0
|
||||
} catch (e) {
|
||||
cornerRadius = 0
|
||||
}
|
||||
}
|
||||
|
||||
property FileView styleStateFile: FileView {
|
||||
id: styleStateFile
|
||||
path: Quickshell.env("HOME") + "/.local/state/omarchy/toggles/quickshell-menu.json"
|
||||
watchChanges: true
|
||||
printErrors: false
|
||||
onLoaded: root.loadStyleState(text())
|
||||
onLoadFailed: root.loadStyleState("")
|
||||
onFileChanged: reload()
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
module qs.Commons
|
||||
singleton Color 1.0 Color.qml
|
||||
singleton Style 1.0 Style.qml
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import QtQuick
|
||||
import qs.Commons
|
||||
|
||||
// Shared visual chrome for keyboard-and-mouse-navigable items inside a panel.
|
||||
// Contract: items must NOT read `containsMouse` for color/border. Mouse
|
||||
@@ -14,7 +15,7 @@ Rectangle {
|
||||
property color foreground: "#cacccc"
|
||||
property color fill: Qt.rgba(foreground.r, foreground.g, foreground.b, 0.18)
|
||||
|
||||
radius: 4
|
||||
radius: Style.cornerRadius
|
||||
color: (hasCursor || current) ? fill : "transparent"
|
||||
border.width: hasCursor ? 1 : 0
|
||||
border.color: foreground
|
||||
|
||||
@@ -193,7 +193,7 @@ PanelWindow {
|
||||
color: Color.popups.background
|
||||
border.color: Color.popups.border
|
||||
border.width: 2
|
||||
radius: 0
|
||||
radius: Style.cornerRadius
|
||||
opacity: root.open ? 1.0 : 0
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 140; easing.type: Easing.OutCubic }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import QtQuick
|
||||
import qs.Commons
|
||||
|
||||
// Small (22×22 by default) icon button used at the right edge of panel rows
|
||||
// for inline actions — forget network, confirm passphrase, unpair device,
|
||||
@@ -27,7 +28,7 @@ Rectangle {
|
||||
|
||||
implicitWidth: size
|
||||
implicitHeight: size
|
||||
radius: 4
|
||||
radius: Style.cornerRadius
|
||||
|
||||
color: mouse.containsMouse && root.enabled
|
||||
? Qt.rgba(hoverColor.r, hoverColor.g, hoverColor.b, 0.20)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import qs.Commons
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
@@ -58,7 +59,7 @@ Rectangle {
|
||||
|
||||
implicitWidth: row.implicitWidth + horizontalPadding * 2
|
||||
implicitHeight: row.implicitHeight + verticalPadding * 2
|
||||
radius: 4
|
||||
radius: Style.cornerRadius
|
||||
|
||||
// Hot = mouse hover OR keyboard cursor. Pressed wins over both; otherwise
|
||||
// hot beats `active` (so a cursor on an already-active pill still reads
|
||||
|
||||
@@ -119,7 +119,7 @@ PopupWindow {
|
||||
color: Color.popups.background
|
||||
border.color: Color.popups.border
|
||||
border.width: 2
|
||||
radius: 0
|
||||
radius: Style.cornerRadius
|
||||
opacity: root.open ? 1.0 : 0
|
||||
|
||||
Behavior on opacity {
|
||||
|
||||
@@ -43,7 +43,6 @@ Item {
|
||||
readonly property string home: Quickshell.env("HOME")
|
||||
readonly property string userConfigPath: home + "/.config/omarchy/shell.json"
|
||||
readonly property string defaultsPath: omarchyPath + "/default/quickshell/omarchy-shell/shell-defaults.json"
|
||||
readonly property string styleStatePath: home + "/.local/state/omarchy/toggles/quickshell-menu.json"
|
||||
|
||||
// ---------------- theme --------------------------------------------------
|
||||
// Bar settings deliberately isn't a themable surface in shell.toml — it
|
||||
@@ -54,22 +53,15 @@ Item {
|
||||
property color urgent: Color.urgent
|
||||
property string fontFamily: "monospace"
|
||||
|
||||
// Source-of-truth for the shell-wide corner radius. Mirrors what the menu
|
||||
// reads from quickshell-menu.json so `omarchy style corners <sharp|round>`
|
||||
// flips both surfaces together.
|
||||
property int cornerRadius: 0
|
||||
|
||||
// ---------------- keyboard focus -----------------------------------------
|
||||
// Keyboard navigation walks the bar form directly; this panel no longer has
|
||||
// side navigation because it only edits the bar.
|
||||
|
||||
// Focus visuals — deliberately *different* from selected styling so the
|
||||
// keyboard cursor never gets confused with the current value/choice. A
|
||||
// selected control gets a 2px accent border; a focused control gets a 3px
|
||||
// accent border plus a noticeably tinted accent background.
|
||||
readonly property color focusBorderColor: accent
|
||||
readonly property color focusFillColor: Qt.rgba(accent.r, accent.g, accent.b, 0.22)
|
||||
readonly property int focusBorderWidth: 3
|
||||
// Structural style tokens live on the shared Style singleton so toggling
|
||||
// `omarchy style corners` and theme swaps update every consumer at once.
|
||||
// Aliasing them as readonly properties keeps the existing inline component
|
||||
// bindings (`root.cornerRadius`, `root.focusBorderColor`, ...) working
|
||||
// without sprinkling Style.* across the file.
|
||||
readonly property int cornerRadius: Style.cornerRadius
|
||||
readonly property color focusBorderColor: Style.focusBorderColor
|
||||
readonly property color focusFillColor: Style.focusFillColor
|
||||
readonly property int focusBorderWidth: Style.focusBorderWidth
|
||||
|
||||
// Move activeFocus to a dedicated sink Item that lives outside the body
|
||||
// tree. Just clearing focus on the previously focused descendant isn't
|
||||
@@ -312,16 +304,6 @@ Item {
|
||||
mutateSection(section, function(a) { a[index] = cloneJson(newEntry) })
|
||||
}
|
||||
|
||||
function loadStyleState(raw) {
|
||||
try {
|
||||
var s = JSON.parse(raw || "{}")
|
||||
var n = Number(s.radius)
|
||||
cornerRadius = isFinite(n) ? n : 0
|
||||
} catch (e) {
|
||||
cornerRadius = 0
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------- widget catalog -----------------------------------------
|
||||
readonly property var legacyWidgetMeta: ({
|
||||
"omarchy": { name: "Omarchy menu", description: "Launches the Omarchy menu", category: "Compositor" },
|
||||
@@ -486,14 +468,6 @@ Item {
|
||||
onFileChanged: reload()
|
||||
}
|
||||
|
||||
FileView {
|
||||
path: root.styleStatePath
|
||||
watchChanges: true
|
||||
printErrors: false
|
||||
onLoaded: root.loadStyleState(text())
|
||||
onFileChanged: reload()
|
||||
}
|
||||
|
||||
// ---------------- window -------------------------------------------------
|
||||
FloatingWindow {
|
||||
id: window
|
||||
|
||||
Reference in New Issue
Block a user