mirror of
https://github.com/arthur-pbty/arthur-os.git
synced 2026-08-06 04:29:34 +02:00
Themes now drive typography the same way they drive colors: one [font] base-size in shell.toml is the rem root, and every Style.font.<token> (caption, bodySmall, body, subtitle, title, heading, display, displayLarge, iconSmall, icon, iconLarge) derives from it via a fixed multiplier. Themes can also pin individual tokens for stylistic emphasis. base-size is clamped 11..13 until row-height tokens exist. Bar dimensions move to the same singleton: [bar] size-horizontal / size-vertical replace the hardcoded 26/28 in Bar.qml, exposed as Style.bar.sizeHorizontal / sizeVertical. Style.qml also resolves the fontconfig 'monospace' alias via fc-match and exposes Style.font.resolvedFamily so panels can display the concrete family. Watches ~/.config/fontconfig/fonts.conf so it tracks 'omarchy font set <name>'. The qs.Ui kit (PillButton, Dropdown, Toggle, TextField, etc.) and every first-party plugin (bar widgets, settings, menu, clipboard, emoji, polkit, notifications, osd, image-picker, dev-gallery) now bind to Style.font.* instead of pixel literals. Only three deliberate display-scale outliers remain: the notification empty-state glyph and the weather flyout's hero temperature pair, all commented. Background plugin's applyTheme IPC fast-path also pushes shell.toml to Style so theme swaps update typography and bar size without waiting for inotify debounce. Dev gallery (omarchy dev ui-preview) now ships a Typography section that renders the full scale and theme tokens live, and its summon command is fixed (omarchy-shell-ipc -> omarchy-shell).
80 lines
2.5 KiB
QML
80 lines
2.5 KiB
QML
import QtQuick
|
|
import qs.Commons
|
|
|
|
// A single button in a mutually-exclusive choice group (a Row of these
|
|
// makes a "segmented control"). Distinct from PillButton because it has
|
|
// a real `selected` state semantic — used for picking between options
|
|
// (bar position: top/bottom/left/right), not for momentary actions.
|
|
//
|
|
// Selected styling uses the accent fill+border; focus styling uses the
|
|
// Style.focusBorderColor outline so keyboard nav can land on a non-selected
|
|
// option without it reading as the chosen one. This separation matters in
|
|
// the settings panel and any future "pick one" UI.
|
|
Rectangle {
|
|
id: root
|
|
|
|
property string text: ""
|
|
property bool selected: false
|
|
|
|
// Panel-cursor flag. Same role as PillButton.hasCursor: panels that own
|
|
// their own cursor state bind this to drive the keyboard highlight
|
|
// separately from real activeFocus. Visuals match the activeFocus look
|
|
// (foreground 2px border) so cursor and Tab focus read the same.
|
|
property bool hasCursor: false
|
|
property bool borderlessHighlight: false
|
|
|
|
property color foreground: Color.foreground
|
|
property color background: Color.background
|
|
property color accent: Color.accent
|
|
property string fontFamily: Style.font.family
|
|
property real fontSize: Style.font.body
|
|
|
|
signal clicked()
|
|
signal hovered(bool isHovered)
|
|
|
|
activeFocusOnTab: true
|
|
Keys.onReturnPressed: root.clicked()
|
|
Keys.onEnterPressed: root.clicked()
|
|
Keys.onSpacePressed: root.clicked()
|
|
|
|
implicitWidth: Math.max(56, label.implicitWidth + 22)
|
|
implicitHeight: 28
|
|
radius: Style.cornerRadius
|
|
|
|
color: selected
|
|
? Qt.rgba(accent.r, accent.g, accent.b, 0.18)
|
|
: ((mouse.containsMouse || hasCursor) ? Qt.rgba(foreground.r, foreground.g, foreground.b, 0.08) : background)
|
|
border.color: selected
|
|
? accent
|
|
: (activeFocus ? foreground : Qt.rgba(foreground.r, foreground.g, foreground.b, 0.4))
|
|
border.width: borderlessHighlight ? (activeFocus ? 2 : 0)
|
|
: (selected ? 2 : (activeFocus || hasCursor ? 2 : 1))
|
|
|
|
Behavior on color { ColorAnimation { duration: 100 } }
|
|
|
|
Text {
|
|
id: label
|
|
anchors.centerIn: parent
|
|
text: root.text
|
|
color: root.selected ? root.accent : root.foreground
|
|
font.family: root.fontFamily
|
|
font.pixelSize: root.fontSize
|
|
font.bold: root.selected
|
|
}
|
|
|
|
MouseArea {
|
|
id: mouse
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
cursorShape: Qt.PointingHandCursor
|
|
onClicked: {
|
|
root.forceActiveFocus()
|
|
root.clicked()
|
|
}
|
|
}
|
|
|
|
HoverHandler {
|
|
onHoveredChanged: root.hovered(hovered)
|
|
}
|
|
}
|