From 25bee293b0de5ea022c5f7c1640f5ee2ae234a8f Mon Sep 17 00:00:00 2001 From: zach Date: Mon, 21 Sep 2026 15:37:45 +0200 Subject: [PATCH] feat: fontbuilder to streamline font styling --- Components/BaseStyledSlider.qml | 63 ++-- Components/ButtonBase.qml | 6 +- Components/CustomRadioButton.qml | 7 +- Components/CustomSlider.qml | 16 +- Components/CustomText.qml | 9 +- Components/CustomTextField.qml | 6 +- Components/GeminiGlow.qml | 42 +++ Components/IconButton.qml | 3 +- Components/IconTextButton.qml | 3 +- Components/MaterialIcon.qml | 20 +- Components/SearchBar.qml | 2 +- Components/TextAreaBase.qml | 2 +- Components/TextEditBase.qml | 12 +- Components/TextFieldBase.qml | 11 +- Components/Toast/ToastItem.qml | 7 +- Helpers/Picker.qml | 2 +- Helpers/Picker/AnnotationToolbar.qml | 14 +- Modules/Bar/Components/Clock.qml | 9 +- Modules/Bar/Components/Common/BatteryIcon.qml | 6 +- Modules/Bar/Components/HyprsunsetWidget.qml | 5 +- Modules/Bar/Components/MediaWidget.qml | 12 +- Modules/Bar/Components/NotifBell.qml | 8 +- Modules/Bar/Components/Resource.qml | 5 +- .../Components/StatusIcons/AudioWidget.qml | 11 +- .../Bar/Components/StatusIcons/MicWidget.qml | 11 +- .../Components/StatusIcons/UPowerWidget.qml | 14 +- Modules/Bar/Components/UpdatesWidget.qml | 3 +- Modules/Bar/Components/WindowTitle.qml | 6 +- Modules/Bar/Popouts/UPowerPopout.qml | 5 +- Modules/Bar/Popouts/UpdatesPopout.qml | 12 +- Modules/Clipboard/Content.qml | 6 +- Modules/Dashboard/Dash/DateTime.qml | 51 --- Modules/Dashboard/Dash/User.qml | 7 +- Modules/Dashboard/Dash/Weather.qml | 5 +- Modules/Dashboard/Media.qml | 6 +- Modules/Dashboard/Media/Details.qml | 18 +- Modules/Dashboard/Media/LyricList.qml | 8 +- Modules/Dashboard/Media/LyricsAndSelector.qml | 4 +- Modules/Dashboard/Media/LyricsInfo.qml | 4 +- Modules/Dashboard/Tabs.qml | 2 +- Modules/Dashboard/Weather/Graphs.qml | 4 +- Modules/Dashboard/WeatherTab.qml | 29 +- .../DesktopIcons/BackgroundContextMenu.qml | 302 ++++++++------- .../DesktopIcons/DesktopIconContextMenu.qml | 13 +- Modules/Drawing/Content.qml | 4 +- Modules/Drawing/Wrapper.qml | 8 +- Modules/Launcher/ContentList.qml | 16 +- Modules/Launcher/Items/ActionItem.qml | 5 +- Modules/Launcher/Items/AppItem.qml | 3 +- Modules/Launcher/Items/CalcItem.qml | 6 +- Modules/Launcher/Items/FilesItem.qml | 4 +- Modules/Launcher/Items/VariantItem.qml | 7 +- Modules/Launcher/Items/WallpaperTile.qml | 3 +- Modules/Lock/Center.qml | 37 +- Modules/Lock/InputField.qml | 15 +- Modules/Lock/LockSurface.qml | 3 +- Modules/Lock/Media.qml | 3 +- Modules/Lock/NotifDock.qml | 7 +- Modules/Lock/NotifGroup.qml | 20 +- Modules/Lock/Resources.qml | 5 +- Modules/Lock/Weather/BriefInfo.qml | 8 +- Modules/Lock/Weather/Forecast.qml | 13 +- Modules/Notifications/Notification.qml | 31 +- .../Sidebar/Chat/ChatContent.qml | 12 +- .../Sidebar/Chat/ChatDelegate.qml | 12 +- .../Notifications/Sidebar/Chat/ChatInput.qml | 53 +++ .../Notifications/Sidebar/Chat/ChatList.qml | 12 +- .../Sidebar/Chat/Content/Actions.qml | 3 +- .../Sidebar/Chat/Content/BubbleEdit.qml | 2 +- .../Sidebar/Chat/Content/CodeBlockView.qml | 26 +- .../Sidebar/Chat/Content/ContentBubble.qml | 2 +- .../Sidebar/Chat/Content/EmptyBackground.qml | 38 +- .../Sidebar/Chat/Content/ErrorBubble.qml | 4 +- .../Sidebar/Chat/Content/MarkdownBlocks.qml | 9 +- .../Sidebar/Chat/Content/MathBlockView.qml | 3 +- .../Sidebar/Chat/Content/MessageDelegate.qml | 2 +- .../Sidebar/Chat/Content/ProcessBlock.qml | 8 +- .../Sidebar/Chat/SidebarView.qml | 2 +- Modules/Notifications/Sidebar/NotifDock.qml | 32 +- Modules/Notifications/Sidebar/Tabs.qml | 11 +- .../Sidebar/Utils/Cards/Record.qml | 26 +- .../Sidebar/Utils/Cards/RecordingList.qml | 7 +- .../Sidebar/Utils/Cards/Toggles.qml | 2 +- .../Sidebar/Utils/IdleInhibit.qml | 20 +- Modules/Polkit/Polkit.qml | 12 +- Modules/Resources/Cards/HeroCard.qml | 13 +- Modules/Resources/Cards/MemoryCard.qml | 5 +- Modules/Resources/Cards/StorageCard.qml | 10 +- Modules/Resources/Cards/VramCard.qml | 5 +- Modules/Settings/Common/AudioDeviceList.qml | 9 +- Modules/Settings/Common/BlobPopup.qml | 8 +- Modules/Settings/Common/DialogRowButton.qml | 2 +- .../Settings/Common/DialogSelectButton.qml | 3 +- Modules/Settings/Common/InfoRow.qml | 8 +- Modules/Settings/Common/ItemList.qml | 7 +- Modules/Settings/Common/ListEditor.qml | 13 +- Modules/Settings/Common/NavRow.qml | 69 +--- Modules/Settings/Common/PageBase.qml | 3 +- Modules/Settings/Common/PopupRow.qml | 6 +- Modules/Settings/Common/RowButton.qml | 7 +- Modules/Settings/Common/SearchPopup.qml | 9 +- Modules/Settings/Common/SectionHeader.qml | 2 +- Modules/Settings/Common/SelectRow.qml | 4 +- Modules/Settings/Common/SliderRow.qml | 4 +- Modules/Settings/Common/SpinRow.qml | 4 +- Modules/Settings/Common/TextFieldRow.qml | 1 - Modules/Settings/Common/TimeDialogRow.qml | 2 +- Modules/Settings/Common/TimeDialogToggle.qml | 4 +- Modules/Settings/Common/TimeInput.qml | 4 +- Modules/Settings/Common/ToggleRow.qml | 5 +- Modules/Settings/NavPane.qml | 9 +- Modules/Settings/NavPane/NavLocations.qml | 24 +- Modules/Settings/PageCompRegistry.qml | 2 +- Modules/Settings/Pages/AboutPage.qml | 4 +- Modules/Settings/Pages/Apps/AllApps.qml | 8 +- Modules/Settings/Pages/Apps/AppInfo.qml | 7 +- Modules/Settings/Pages/AppsPage.qml | 8 +- Modules/Settings/Pages/Audio/AppVolumes.qml | 1 - Modules/Settings/Pages/AudioPage.qml | 8 +- Modules/Settings/Pages/Panels/BarPanel.qml | 6 +- .../Pages/Panels/Sidebar/SidebarLlm.qml | 2 +- Modules/Settings/Pages/PanelsPage.qml | 10 +- Modules/Settings/Pages/ServicesPage.qml | 2 +- .../Pages/Wallpaper/WallpaperSelect.qml | 2 +- Plugins/ZShell/Config/CMakeLists.txt | 4 + Plugins/ZShell/Config/appearance.hpp | 351 +++++++++++++++++- Plugins/ZShell/Config/configobject.cpp | 16 +- Plugins/ZShell/Config/font.cpp | 290 +++++++++++++++ Plugins/ZShell/Config/font.hpp | 200 ++++++++++ Plugins/ZShell/Config/fontbuilder.cpp | 105 ++++++ Plugins/ZShell/Config/fontbuilder.hpp | 41 ++ Plugins/ZShell/Config/tokens.hpp | 137 ++----- assets/shaders/geminiglow.frag | 93 +++++ assets/shaders/geminiglow.frag.qsb | Bin 0 -> 3721 bytes 134 files changed, 1813 insertions(+), 1011 deletions(-) create mode 100755 Components/GeminiGlow.qml delete mode 100644 Modules/Dashboard/Dash/DateTime.qml create mode 100644 Plugins/ZShell/Config/font.cpp create mode 100644 Plugins/ZShell/Config/font.hpp create mode 100644 Plugins/ZShell/Config/fontbuilder.cpp create mode 100644 Plugins/ZShell/Config/fontbuilder.hpp create mode 100755 assets/shaders/geminiglow.frag create mode 100644 assets/shaders/geminiglow.frag.qsb diff --git a/Components/BaseStyledSlider.qml b/Components/BaseStyledSlider.qml index 9d3b654..0ebb4ad 100644 --- a/Components/BaseStyledSlider.qml +++ b/Components/BaseStyledSlider.qml @@ -80,49 +80,29 @@ Slider { property bool moving - function update(): void { - animate = !moving; - binding.when = moving; - font.pointSize = moving ? Tokens.font.size.small : Tokens.font.size.larger; - font.family = moving ? Config.appearance.font.family.sans : Config.appearance.font.family.material; - } - anchors.centerIn: parent + anchors.verticalCenterOffset: 1 + text: moving ? Math.round(root.value * 100) : root.icon color: Colors.palette.m3inverseOnSurface - text: root.icon + font: moving ? Tokens.font.body.small : Tokens.font.icon.medium - onMovingChanged: anim.restart() - - Binding { - id: binding - - property: "text" - target: icon - value: Math.round(root.value * root.multiplier) - when: false - } - - SequentialAnimation { - id: anim - - Anim { - duration: Tokens.anim.durations.normal / 2 - easing: Tokens.anim.standardAccel - property: "scale" - target: icon - to: 0 - } - - ScriptAction { - script: icon.update() - } - - Anim { - duration: Tokens.anim.durations.normal / 2 - easing: Tokens.anim.standardDecel - property: "scale" - target: icon - to: 1 + Behavior on moving { + SequentialAnimation { + Anim { + target: icon + property: "scale" + to: 0.3 + duration: Tokens.anim.durations.small / 2 + easing: Tokens.anim.standardAccel + } + PropertyAction {} + Anim { + target: icon + property: "scale" + to: 1 + duration: Tokens.anim.durations.normal / 2 + easing: Tokens.anim.standardDecel + } } } } @@ -130,7 +110,7 @@ Slider { } Behavior on value { Anim { - duration: Tokens.anim.durations.large + type: Anim.StandardLarge } } @@ -138,7 +118,6 @@ Slider { onValueChanged: { if (!initialized) { initialized = true; - oldValue = value; return; } diff --git a/Components/ButtonBase.qml b/Components/ButtonBase.qml index ec11a7d..9b9e7bd 100644 --- a/Components/ButtonBase.qml +++ b/Components/ButtonBase.qml @@ -20,11 +20,7 @@ CustomRect { property color disabledColor: Qt.alpha(Colors.palette.m3onSurface, 0.1) property color disabledOnColor: Qt.alpha(Colors.palette.m3onSurface, 0.38) property bool fillWidth - property font font: ({ - family: Config.appearance.font.family.sans, - pointSize: Tokens.font.size.larger, - bold: false - }) + property font font: Tokens.font.body.small property real horizontalPadding: padding readonly property alias hovered: stateLayer.containsMouse required implicitHeight diff --git a/Components/CustomRadioButton.qml b/Components/CustomRadioButton.qml index aca7899..aca0f4c 100644 --- a/Components/CustomRadioButton.qml +++ b/Components/CustomRadioButton.qml @@ -6,7 +6,7 @@ import qs.Services RadioButton { id: root - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.medium implicitHeight: Math.max(implicitIndicatorHeight, implicitContentHeight) implicitWidth: implicitIndicatorWidth + implicitContentWidth + contentItem.anchors.leftMargin @@ -14,7 +14,7 @@ RadioButton { anchors.left: outerCircle.right anchors.leftMargin: 10 anchors.verticalCenter: parent.verticalCenter - font.pointSize: root.font.pointSize + font: root.font text: root.text } indicator: Rectangle { @@ -29,8 +29,7 @@ RadioButton { radius: Tokens.rounding.full Behavior on border.color { - CAnim { - } + CAnim {} } StateLayer { diff --git a/Components/CustomSlider.qml b/Components/CustomSlider.qml index 39c5339..5acd92b 100644 --- a/Components/CustomSlider.qml +++ b/Components/CustomSlider.qml @@ -100,15 +100,19 @@ Slider { anchors.bottom: parent.bottom anchors.top: parent.top color: root.insetColor - font.pixelSize: Tokens.font.size.smaller * 2 + fontStyle: { + if (root.height < 96) + return Tokens.font.icon.pixelSize(24).build(); + else + return Tokens.font.icon.pixelSize(32).build(); + } text: root.insetIcon verticalAlignment: Text.AlignVCenter visible: !root.wavy && root.insetIcon !== "" x: Tokens.spacing.extraSmall + dockT * (handle.x + Tokens.spacing.small) Behavior on dockT { - Anim { - } + Anim {} } } @@ -138,8 +142,7 @@ Slider { startX: x Behavior on color { - CAnim { - } + CAnim {} } Anim on waveProgress { duration: root.waveDuration @@ -156,8 +159,7 @@ Slider { Behavior on filledWidth { id: widthBehavior - Anim { - } + Anim {} } Component.onCompleted: { diff --git a/Components/CustomText.qml b/Components/CustomText.qml index 08ae9ee..144665e 100644 --- a/Components/CustomText.qml +++ b/Components/CustomText.qml @@ -14,15 +14,13 @@ Text { property real animateTo: 1 color: Colors.palette.m3onSurface - font.family: Config.appearance.font.family.sans - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.small linkColor: Colors.palette.m3onPrimaryFixedVariant renderType: Text.NativeRendering textFormat: Text.PlainText Behavior on color { - CAnim { - } + CAnim {} } Behavior on text { enabled: root.animate @@ -34,8 +32,7 @@ Text { type: Anim.FastEffects } - PropertyAction { - } + PropertyAction {} TAnim { target: root diff --git a/Components/CustomTextField.qml b/Components/CustomTextField.qml index 66141b8..ab2ff06 100644 --- a/Components/CustomTextField.qml +++ b/Components/CustomTextField.qml @@ -29,7 +29,7 @@ TextFieldBase { property string supportingText property string trailingIcon - property int smallFontSize: Tokens.font.size.small + property int smallFontSize: Tokens.font.label.small.pointSize property int type: CustomTextField.Outlined property var validate // Regex or function @@ -151,6 +151,7 @@ TextFieldBase { sourceComponent: MaterialIcon { color: Colors.palette.m3onSurfaceVariant text: root.leadingIcon + fontStyle: Tokens.font.icon.builders.medium.scale(0.9).build() } } @@ -165,6 +166,7 @@ TextFieldBase { sourceComponent: MaterialIcon { color: Colors.palette.m3onSurfaceVariant text: root.trailingIcon + fontStyle: Tokens.font.icon.builders.medium.scale(0.9).build() } } } @@ -179,7 +181,7 @@ TextFieldBase { sourceComponent: CustomText { color: root.isError ? Colors.palette.m3error : Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.small + font: Tokens.font.label.small text: root.effectiveSupportingText } } diff --git a/Components/GeminiGlow.qml b/Components/GeminiGlow.qml new file mode 100755 index 0000000..443ef07 --- /dev/null +++ b/Components/GeminiGlow.qml @@ -0,0 +1,42 @@ +import QtQuick +import Quickshell + +ShaderEffect { + id: root + + property Item target: parent + + property real glowSize: 40 + property real innerGlow: 0 + property real lineWidth: 2 + property real intensity: 1.0 + property real speed: 1.0 + property int period: 6000 + property bool running: true + + property color color1: "#4285F4" + property color color2: "#9B72CB" + property color color3: "#D96570" + property color color4: "#F2A54A" + + readonly property size itemSize: Qt.size(width, height) + readonly property size rectSize: target ? Qt.size(target.width, target.height) : Qt.size(0, 0) + readonly property real radius: (target as Rectangle).radius ?? 0 + property real phase: 0 + + anchors.fill: target + anchors.margins: -glowSize + z: -1 + + enabled: false + + fragmentShader: Qt.resolvedUrl(`${Quickshell.shellDir}/assets/shaders/geminiglow.frag.qsb`) + + FrameAnimation { + running: root.running && root.visible + onTriggered: { + const dt = frameTime * 1000; + root.phase = (root.phase + dt * root.speed / root.period) % 1.0; + } + } +} diff --git a/Components/IconButton.qml b/Components/IconButton.qml index 0210520..3bdfc48 100644 --- a/Components/IconButton.qml +++ b/Components/IconButton.qml @@ -8,6 +8,7 @@ ButtonBase { property alias icon: label.text readonly property alias label: label + font: Tokens.font.icon.medium activeColor: type === IconButton.Filled ? Colors.palette.m3primary : Colors.palette.m3secondary activeOnColor: type === IconButton.Filled ? Colors.palette.m3onPrimary : type === IconButton.Tonal ? Colors.palette.m3onSecondary : Colors.palette.m3primary implicitHeight: { @@ -36,7 +37,7 @@ ButtonBase { anchors.verticalCenterOffset: 1 color: root.onColor fill: !root.isToggle || root.internalChecked ? 1 : 0 - font.pointSize: root.font.pointSize + fontStyle: root.font Behavior on fill { Anim { diff --git a/Components/IconTextButton.qml b/Components/IconTextButton.qml index 6190121..fb568f6 100644 --- a/Components/IconTextButton.qml +++ b/Components/IconTextButton.qml @@ -46,10 +46,9 @@ ButtonBase { Layout.alignment: Qt.AlignVCenter color: root.onColor fill: root.internalChecked ? 1 : 0 - font: { + fontStyle: { const f = Qt.font(root.font); f.pointSize = Math.round(root.font.pointSize * 1.2); - f.family = "Material Symbols Rounded"; return f; } diff --git a/Components/MaterialIcon.qml b/Components/MaterialIcon.qml index 0e81d10..b93e38c 100644 --- a/Components/MaterialIcon.qml +++ b/Components/MaterialIcon.qml @@ -1,27 +1,13 @@ +import QtQuick import ZShell.Config import qs.Services CustomText { id: root - readonly property list allowed: [20, 24, 40, 48] property real fill: 0 property int grade: Colors.light ? 0 : -25 - readonly property int opsz: clampOpsz(optical) - property int optical: fontInfo.pixelSize + property font fontStyle: Tokens.font.icon.small - function clampOpsz(value): int { - return allowed.reduce((closest, current) => { - return Math.abs(current - value) < Math.abs(closest - value) ? current : closest; - }); - } - - font.family: "Material Symbols Rounded" - font.pointSize: Tokens.font.size.larger - font.variableAxes: ({ - FILL: fill, - GRAD: grade, - opsz: opsz, - wght: fontInfo.weight - }) + font: Tokens.font.icon.size(fontStyle.pointSize).weight(fontStyle.weight).vaxes(fontStyle.variableAxes).fill(fill.toFixed(1)).grade(grade).build() } diff --git a/Components/SearchBar.qml b/Components/SearchBar.qml index f14b51e..5642d73 100644 --- a/Components/SearchBar.qml +++ b/Components/SearchBar.qml @@ -62,7 +62,7 @@ TextFieldBase { anchors.leftMargin: Tokens.padding.large anchors.verticalCenter: parent.verticalCenter color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.builders.medium.scale(0.9).build() text: "search" } diff --git a/Components/TextAreaBase.qml b/Components/TextAreaBase.qml index a96b9c0..5408a2d 100644 --- a/Components/TextAreaBase.qml +++ b/Components/TextAreaBase.qml @@ -8,7 +8,7 @@ TextArea { color: Colors.palette.m3onSurface cursorVisible: !readOnly - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small implicitHeight: contentHeight + topPadding + bottomPadding implicitWidth: contentWidth + leftPadding + rightPadding placeholderTextColor: Colors.palette.m3onSurfaceVariant // No anim cause placeholder is custom diff --git a/Components/TextEditBase.qml b/Components/TextEditBase.qml index 8eb49a3..e0931f3 100644 --- a/Components/TextEditBase.qml +++ b/Components/TextEditBase.qml @@ -11,22 +11,18 @@ TextEdit { color: Colors.palette.m3onSurface cursorVisible: !readOnly - font.pointSize: Tokens.font.size.small - font.family: Config.appearance.font.family.sans + font: Tokens.font.body.small renderType: TextField.NativeRendering selectedTextColor: color selectionColor: Qt.alpha(Colors.palette.m3primary, 0.4) verticalAlignment: TextInput.AlignVCenter Behavior on color { - CAnim { - } - } - cursorDelegate: Item { + CAnim {} } + cursorDelegate: Item {} Behavior on selectionColor { - CAnim { - } + CAnim {} } CustomRect { diff --git a/Components/TextFieldBase.qml b/Components/TextFieldBase.qml index b68318b..0edd409 100644 --- a/Components/TextFieldBase.qml +++ b/Components/TextFieldBase.qml @@ -8,7 +8,7 @@ TextField { color: Colors.palette.m3onSurface cursorVisible: !readOnly - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small implicitHeight: contentHeight + topPadding + bottomPadding implicitWidth: contentWidth + leftPadding + rightPadding placeholderTextColor: Colors.palette.m3onSurfaceVariant // No anim cause placeholder is custom @@ -18,14 +18,11 @@ TextField { verticalAlignment: TextInput.AlignVCenter Behavior on color { - CAnim { - } - } - cursorDelegate: Item { + CAnim {} } + cursorDelegate: Item {} Behavior on selectionColor { - CAnim { - } + CAnim {} } CustomRect { diff --git a/Components/Toast/ToastItem.qml b/Components/Toast/ToastItem.qml index b37ead8..254e20c 100644 --- a/Components/Toast/ToastItem.qml +++ b/Components/Toast/ToastItem.qml @@ -36,8 +36,7 @@ CustomRect { radius: Tokens.rounding.medium Behavior on border.color { - CAnim { - } + CAnim {} } Elevation { @@ -84,7 +83,7 @@ CustomRect { return Colors.palette.m3onError; return Colors.palette.m3onSurfaceVariant; } - font.pointSize: Math.round(Tokens.font.size.large * 1.2) + fontStyle: Tokens.font.icon.builders.large.scale(1.2).build() text: root.modelData.icon } } @@ -107,7 +106,7 @@ CustomRect { return Colors.palette.m3onSurface; } elide: Text.ElideRight - font.pointSize: Tokens.font.size.normal + font: Tokens.font.title.small text: root.modelData.title } diff --git a/Helpers/Picker.qml b/Helpers/Picker.qml index b87f53e..4519fe7 100755 --- a/Helpers/Picker.qml +++ b/Helpers/Picker.qml @@ -42,7 +42,7 @@ Item { readonly property real scaleRatio: Hypr.monitorFor(screen).scale required property ShellScreen screen property real sh: Math.abs(sy - ey) - readonly property color shadowColor: Hypr.options.decoration.shadow.color + readonly property color shadowColor: Hypr.options.decoration.shadow?.color ?? "black" readonly property bool shadowEnabled: Hypr.options.decoration.shadow.enabled readonly property var shadowOffset: Hypr.options.decoration.shadow.offset readonly property int shadowRange: Hypr.options.decoration.shadow.range diff --git a/Helpers/Picker/AnnotationToolbar.qml b/Helpers/Picker/AnnotationToolbar.qml index d95eb37..fb6b673 100755 --- a/Helpers/Picker/AnnotationToolbar.qml +++ b/Helpers/Picker/AnnotationToolbar.qml @@ -73,7 +73,7 @@ CustomRect { required property var modelData color: root.tool === modelData.id ? "#3584e4" : "transparent" - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.medium icon: tool.modelData.glyph inactiveColor: root.tool === modelData.id ? Colors.palette.m3primary : "transparent" inactiveOnColor: root.tool === modelData.id ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface @@ -103,7 +103,7 @@ CustomRect { required property color modelData fillWidth: false - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.medium icon: "" implicitHeight: buttonSize implicitWidth: buttonSize @@ -128,7 +128,7 @@ CustomRect { spacing: Tokens.spacing.extraSmall IconButton { - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.medium icon: "undo" inactiveColor: "transparent" inactiveOnColor: Colors.palette.m3onSurface @@ -140,7 +140,7 @@ CustomRect { } IconButton { - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.medium icon: "delete_history" inactiveColor: "transparent" inactiveOnColor: Colors.palette.m3onSurface @@ -152,7 +152,7 @@ CustomRect { } IconButton { - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.medium icon: "content_copy" inactiveColor: "transparent" inactiveOnColor: Colors.palette.m3onSurface @@ -164,7 +164,7 @@ CustomRect { } IconButton { - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.medium icon: "delete_forever" inactiveColor: "transparent" inactiveOnColor: Colors.palette.m3onSurface @@ -176,7 +176,7 @@ CustomRect { } IconButton { - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.medium icon: "check" inactiveColor: "transparent" inactiveOnColor: Colors.palette.m3onSurface diff --git a/Modules/Bar/Components/Clock.qml b/Modules/Bar/Components/Clock.qml index 4e3033e..a71fd96 100644 --- a/Modules/Bar/Components/Clock.qml +++ b/Modules/Bar/Components/Clock.qml @@ -13,6 +13,7 @@ import qs.Services WidgetBase { id: root + readonly property font font: Tokens.font.clock.family(Config.appearance.font.family.clock).build() readonly property color contentColor: screenState.dashboard ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface readonly property string effectiveFormat: { let fmt = Config.general.dateFormat; @@ -57,7 +58,7 @@ WidgetBase { anchors.centerIn: parent color: root.contentColor - font.family: Config.appearance.font.family.clock // qmllint disable incompatible-type + font: root.font height: implicitHeight text: Time.dateStr visible: root.horizontal @@ -83,7 +84,7 @@ WidgetBase { Layout.alignment: Qt.AlignHCenter color: root.contentColor - font.family: Config.appearance.font.family.clock // qmllint disable incompatible-type + font: root.font text: Qt.formatDateTime(Time.date, modelData) Behavior on color { @@ -112,7 +113,7 @@ WidgetBase { Layout.alignment: Qt.AlignHCenter color: root.contentColor - font.family: Config.appearance.font.family.clock // qmllint disable incompatible-type + font: root.font text: { if (modelData.includes("h")) return Time.hourStr; @@ -132,7 +133,7 @@ WidgetBase { CustomText { Layout.alignment: Qt.AlignHCenter color: root.contentColor - font.family: Config.appearance.font.family.clock // qmllint disable incompatible-type + font: root.font text: Qt.formatDateTime(Time.date, "AP") visible: Config.services.useTwelveHourClock && root.formatParts.timeTokens.length > 0 diff --git a/Modules/Bar/Components/Common/BatteryIcon.qml b/Modules/Bar/Components/Common/BatteryIcon.qml index 2f13bc9..6a78dfa 100644 --- a/Modules/Bar/Components/Common/BatteryIcon.qml +++ b/Modules/Bar/Components/Common/BatteryIcon.qml @@ -28,8 +28,7 @@ Row { CustomText { color: Battery.getColors(root.percentage, root.devState).fg - font.pointSize: Tokens.font.size.larger / 1.5 - font.weight: 800 + font: Tokens.font.body.builders.small.size(11).weight(Font.Bold).build() height: track.height horizontalAlignment: Text.AlignHCenter text: Math.round(root.percentage * 100) @@ -60,8 +59,7 @@ Row { clip: true color: Battery.getColors(root.percentage, root.devState).bg - font.pointSize: Tokens.font.size.larger / 1.5 - font.weight: 800 + font: Tokens.font.body.builders.small.size(11).weight(Font.Bold).build() height: track.height horizontalAlignment: Text.AlignHCenter text: Math.round(root.percentage * 100) diff --git a/Modules/Bar/Components/HyprsunsetWidget.qml b/Modules/Bar/Components/HyprsunsetWidget.qml index 8afd545..f409a29 100644 --- a/Modules/Bar/Components/HyprsunsetWidget.qml +++ b/Modules/Bar/Components/HyprsunsetWidget.qml @@ -25,12 +25,11 @@ WidgetBase { animate: true color: root.tempEnabled ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface fill: root.tempEnabled ? 1 : 0 - font.pointSize: Tokens.font.size.larger + fontStyle: Tokens.font.icon.small text: root.tempEnabled ? "lightbulb" : "light_off" Behavior on fill { - Anim { - } + Anim {} } } } diff --git a/Modules/Bar/Components/MediaWidget.qml b/Modules/Bar/Components/MediaWidget.qml index 32fb007..7d2297f 100644 --- a/Modules/Bar/Components/MediaWidget.qml +++ b/Modules/Bar/Components/MediaWidget.qml @@ -19,14 +19,12 @@ WidgetBase { Behavior on implicitHeight { enabled: !root.horizontal - Anim { - } + Anim {} } Behavior on implicitWidth { enabled: root.horizontal - Anim { - } + Anim {} } TextMetrics { @@ -47,15 +45,14 @@ WidgetBase { columns: root.horizontal ? -1 : 1 Behavior on implicitWidth { - Anim { - } + Anim {} } MaterialIcon { Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter animate: true color: Players.active?.isPlaying ? Colors.palette.m3primary : Colors.palette.m3onSurface - font.pointSize: Tokens.font.size.larger + fontStyle: Tokens.font.icon.small text: Players.active?.isPlaying ? "music_note" : "music_off" } @@ -65,7 +62,6 @@ WidgetBase { Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter animate: true color: Players.active?.isPlaying ? Colors.palette.m3primary : Colors.palette.m3onSurface - font.pointSize: Tokens.font.size.normal horizontalAlignment: Text.AlignHCenter implicitHeight: root.horizontal ? root.implicitHeight : root.textWidth implicitWidth: root.horizontal ? root.textWidth : root.implicitWidth diff --git a/Modules/Bar/Components/NotifBell.qml b/Modules/Bar/Components/NotifBell.qml index 34b4c68..dfeb760 100644 --- a/Modules/Bar/Components/NotifBell.qml +++ b/Modules/Bar/Components/NotifBell.qml @@ -22,16 +22,14 @@ WidgetBase { anchors.centerIn: parent color: root.screenState.sidebar ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface fill: root.screenState.sidebar ? 1 : 0 - font.pointSize: Tokens.font.size.larger + fontStyle: Tokens.font.icon.size(16).build() text: NotifServer.list.length ? "\uf4fe" : "\ue7f4" Behavior on color { - CAnim { - } + CAnim {} } Behavior on fill { - Anim { - } + Anim {} } } diff --git a/Modules/Bar/Components/Resource.qml b/Modules/Bar/Components/Resource.qml index 4314ee7..cce4285 100644 --- a/Modules/Bar/Components/Resource.qml +++ b/Modules/Bar/Components/Resource.qml @@ -27,8 +27,7 @@ GridLayout { percentage: 0 Behavior on animatedPercentage { - Anim { - } + Anim {} } Component.onCompleted: animatedPercentage = percentage @@ -44,7 +43,7 @@ GridLayout { Layout.preferredWidth: 16 color: root.iconColor - font.pointSize: Tokens.font.size.larger + fontStyle: Tokens.font.icon.small text: root.icon } diff --git a/Modules/Bar/Components/StatusIcons/AudioWidget.qml b/Modules/Bar/Components/StatusIcons/AudioWidget.qml index 93c4752..a6fab2a 100644 --- a/Modules/Bar/Components/StatusIcons/AudioWidget.qml +++ b/Modules/Bar/Components/StatusIcons/AudioWidget.qml @@ -13,19 +13,16 @@ MaterialIcon { animate: true color: Audio.muted ? Colors.palette.m3error : Colors.palette.m3onSurface fill: 1 - font.pointSize: Tokens.font.size.larger + fontStyle: Tokens.font.icon.small text: Audio.muted ? "volume_off" : "volume_up" Behavior on Layout.maximumWidth { - Anim { - } + Anim {} } Behavior on opacity { - Anim { - } + Anim {} } Behavior on scale { - Anim { - } + Anim {} } } diff --git a/Modules/Bar/Components/StatusIcons/MicWidget.qml b/Modules/Bar/Components/StatusIcons/MicWidget.qml index 8f58616..cb61bee 100644 --- a/Modules/Bar/Components/StatusIcons/MicWidget.qml +++ b/Modules/Bar/Components/StatusIcons/MicWidget.qml @@ -13,19 +13,16 @@ MaterialIcon { animate: true color: (Audio.sourceMuted ?? false) ? Colors.palette.m3error : Colors.palette.m3onSurface fill: 1 - font.pointSize: Tokens.font.size.larger + fontStyle: Tokens.font.icon.small text: Audio.sourceMuted ? "mic_off" : "mic" Behavior on Layout.maximumWidth { - Anim { - } + Anim {} } Behavior on opacity { - Anim { - } + Anim {} } Behavior on scale { - Anim { - } + Anim {} } } diff --git a/Modules/Bar/Components/StatusIcons/UPowerWidget.qml b/Modules/Bar/Components/StatusIcons/UPowerWidget.qml index 8cdc2a7..48c1b71 100644 --- a/Modules/Bar/Components/StatusIcons/UPowerWidget.qml +++ b/Modules/Bar/Components/StatusIcons/UPowerWidget.qml @@ -15,20 +15,16 @@ Item { implicitWidth: currentItem?.implicitWidth ?? 0 Behavior on Layout.preferredHeight { - Anim { - } + Anim {} } Behavior on Layout.preferredWidth { - Anim { - } + Anim {} } Behavior on opacity { - Anim { - } + Anim {} } Behavior on scale { - Anim { - } + Anim {} } Component.onCompleted: Battery.startDaemon() @@ -67,7 +63,7 @@ Item { Layout.alignment: Qt.AlignVCenter animate: true fill: 1 - font.pointSize: Tokens.font.size.larger + fontStyle: Tokens.font.icon.small text: { if (PowerProfiles.profile === PowerProfile.PowerSaver) return "energy_savings_leaf"; diff --git a/Modules/Bar/Components/UpdatesWidget.qml b/Modules/Bar/Components/UpdatesWidget.qml index a525040..a44c0de 100644 --- a/Modules/Bar/Components/UpdatesWidget.qml +++ b/Modules/Bar/Components/UpdatesWidget.qml @@ -27,14 +27,13 @@ WidgetBase { MaterialIcon { Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter - font.pointSize: root.horizontal ? Tokens.font.size.larger : Tokens.font.size.large + fontStyle: Tokens.font.icon.small text: "package_2" } CustomText { Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter color: root.textColor - font.pointSize: Tokens.font.size.normal text: root.countUpdates } } diff --git a/Modules/Bar/Components/WindowTitle.qml b/Modules/Bar/Components/WindowTitle.qml index c213072..7515093 100644 --- a/Modules/Bar/Components/WindowTitle.qml +++ b/Modules/Bar/Components/WindowTitle.qml @@ -52,8 +52,7 @@ Item { elide: Qt.ElideRight elideWidth: root.maxSize - (root.horizontal ? root.current.anchors.leftMargin : 0) - font.family: "Rubik" - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.small text: Hypr.activeToplevel?.title ?? qsTr("Desktop") onElideWidthChanged: root.current.text = elidedText @@ -81,8 +80,7 @@ Item { width: root.horizontal ? implicitWidth : implicitHeight Behavior on opacity { - Anim { - } + Anim {} } transform: [ Translate { diff --git a/Modules/Bar/Popouts/UPowerPopout.qml b/Modules/Bar/Popouts/UPowerPopout.qml index b702dd7..09c94e1 100644 --- a/Modules/Bar/Popouts/UPowerPopout.qml +++ b/Modules/Bar/Popouts/UPowerPopout.qml @@ -181,8 +181,7 @@ Column { } ] transitions: Transition { - AnchorAnim { - } + AnchorAnim {} } } @@ -246,7 +245,7 @@ Column { anchors.centerIn: parent color: profiles.current === text ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface fill: profiles.current === text ? 1 : 0 - font.pointSize: Tokens.font.size.large * 2 + fontStyle: Tokens.font.icon.extraLarge grade: Colors.light ? 0 : (text === "balance" ? -25 : 0) text: parent.icon diff --git a/Modules/Bar/Popouts/UpdatesPopout.qml b/Modules/Bar/Popouts/UpdatesPopout.qml index 8a143f3..6de1f39 100644 --- a/Modules/Bar/Popouts/UpdatesPopout.qml +++ b/Modules/Bar/Popouts/UpdatesPopout.qml @@ -39,7 +39,7 @@ CustomClippingRect { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top color: Colors.tPalette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.extraLarge * 3 + fontStyle: Tokens.font.icon.builders.large.size(48).weight(Font.DemiBold).build() horizontalAlignment: Text.AlignHCenter text: "check" } @@ -89,7 +89,7 @@ CustomClippingRect { anchors.rightMargin: Tokens.padding.small MaterialIcon { - font.pointSize: Tokens.font.size.large * 2 + fontStyle: Tokens.font.icon.extraLarge text: "package_2" } @@ -100,7 +100,7 @@ CustomClippingRect { Layout.fillWidth: true Layout.preferredHeight: 25 elide: Text.ElideRight - font.pointSize: Tokens.font.size.large + font: Tokens.font.title.medium text: update.sections[0] } @@ -122,7 +122,7 @@ CustomClippingRect { Layout.preferredWidth: 125 animate: true color: Colors.palette.m3tertiary - font.pointSize: Tokens.font.size.large + font: Tokens.font.title.medium horizontalAlignment: Text.AlignHCenter marqueeEnabled: true pauseMs: 4000 @@ -133,7 +133,7 @@ CustomClippingRect { MaterialIcon { Layout.fillHeight: true color: Colors.palette.m3secondary - font.pointSize: Tokens.font.size.extraLarge + fontStyle: Tokens.font.icon.large horizontalAlignment: Text.AlignHCenter text: "arrow_right_alt" verticalAlignment: Text.AlignVCenter @@ -146,7 +146,7 @@ CustomClippingRect { Layout.preferredWidth: 120 animate: true color: Colors.palette.m3primary - font.pointSize: Tokens.font.size.large + font: Tokens.font.title.medium horizontalAlignment: Text.AlignHCenter marqueeEnabled: true pauseMs: 4000 diff --git a/Modules/Clipboard/Content.qml b/Modules/Clipboard/Content.qml index dd5d6a3..f4683c6 100644 --- a/Modules/Clipboard/Content.qml +++ b/Modules/Clipboard/Content.qml @@ -66,8 +66,7 @@ Item { radius: 25 Behavior on implicitWidth { - Anim { - } + Anim {} } Column { @@ -104,7 +103,6 @@ Item { anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.small text: lineRow.modelData.line } } @@ -252,7 +250,7 @@ Item { anchors.left: parent.left anchors.margins: Tokens.padding.small anchors.verticalCenter: parent.verticalCenter - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.large text: clipItem.isImage ? "image" : "text_fields" } diff --git a/Modules/Dashboard/Dash/DateTime.qml b/Modules/Dashboard/Dash/DateTime.qml deleted file mode 100644 index 3a76d5c..0000000 --- a/Modules/Dashboard/Dash/DateTime.qml +++ /dev/null @@ -1,51 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import QtQuick.Layouts -import qs.Components -import ZShell.Config -import qs.Helpers -import qs.Services - -Item { - id: root - - anchors.bottom: parent.bottom - anchors.top: parent.top - implicitWidth: 110 - - ColumnLayout { - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: 0 - - CustomText { - Layout.alignment: Qt.AlignHCenter - Layout.bottomMargin: -(font.pointSize * 0.4) - color: Colors.palette.m3secondary - font.family: "Rubik" - font.pointSize: 18 - font.weight: 600 - text: Time.hourStr - } - - CustomText { - Layout.alignment: Qt.AlignHCenter - color: Colors.palette.m3primary - font.family: "Rubik" - font.pointSize: 18 * 0.9 - text: "•••" - } - - CustomText { - Layout.alignment: Qt.AlignHCenter - Layout.topMargin: -(font.pointSize * 0.4) - color: Colors.palette.m3secondary - font.family: "Rubik" - font.pointSize: 18 - font.weight: 600 - text: Time.minuteStr - } - } -} diff --git a/Modules/Dashboard/Dash/User.qml b/Modules/Dashboard/Dash/User.qml index 1d37230..264ae5f 100644 --- a/Modules/Dashboard/Dash/User.qml +++ b/Modules/Dashboard/Dash/User.qml @@ -23,8 +23,7 @@ Row { MaterialIcon { anchors.centerIn: parent fill: 1 - font.pointSize: Math.floor(info.implicitHeight / 2) || 1 - grade: 200 + fontStyle: Tokens.font.icon.large text: "person" } @@ -65,7 +64,6 @@ Row { anchors.leftMargin: icon.anchors.leftMargin anchors.verticalCenter: icon.verticalCenter elide: Text.ElideRight - font.pointSize: 13 text: `: ${SystemInfo.osPrettyName || SystemInfo.osName}` width: Config.dashboard.sizes.infoWidth } @@ -103,7 +101,7 @@ Row { anchors.leftMargin: (Config.dashboard.sizes.infoIconSize - implicitWidth) / 2 color: line.colour fill: 1 - font.pointSize: 13 + fontStyle: Tokens.font.icon.small text: line.icon } @@ -114,7 +112,6 @@ Row { anchors.leftMargin: icon.anchors.leftMargin anchors.verticalCenter: icon.verticalCenter elide: Text.ElideNone - font.pointSize: 13 text: `: ${line.text}` width: Config.dashboard.sizes.infoWidth } diff --git a/Modules/Dashboard/Dash/Weather.qml b/Modules/Dashboard/Dash/Weather.qml index c951fb7..906ac93 100644 --- a/Modules/Dashboard/Dash/Weather.qml +++ b/Modules/Dashboard/Dash/Weather.qml @@ -19,7 +19,7 @@ Item { anchors.verticalCenter: parent.verticalCenter animate: true color: Colors.palette.m3secondary - font.pointSize: 54 + fontStyle: Tokens.font.icon.extraLarge text: Weather.icon } @@ -35,8 +35,7 @@ Item { anchors.horizontalCenter: parent.horizontalCenter animate: true color: Colors.palette.m3primary - font.pointSize: Tokens.font.size.extraLarge - font.weight: 500 + font: Tokens.font.body.large text: Weather.temp } diff --git a/Modules/Dashboard/Media.qml b/Modules/Dashboard/Media.qml index f1f98ee..297e996 100644 --- a/Modules/Dashboard/Media.qml +++ b/Modules/Dashboard/Media.qml @@ -108,7 +108,7 @@ Item { anchors.centerIn: parent text: "queue_music" - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.large color: Colors.palette.m3onPrimaryContainer } } @@ -116,13 +116,13 @@ Item { CustomText { Layout.alignment: Qt.AlignHCenter text: qsTr("Nothing playing") - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.medium } CustomText { text: qsTr("Play something for it to show up here!") color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.large + font: Tokens.font.body.large } } } diff --git a/Modules/Dashboard/Media/Details.qml b/Modules/Dashboard/Media/Details.qml index 39ba295..2d6c6c9 100644 --- a/Modules/Dashboard/Media/Details.qml +++ b/Modules/Dashboard/Media/Details.qml @@ -38,7 +38,7 @@ ColumnLayout { CustomText { Layout.fillWidth: true text: Players.active?.trackTitle ?? "" - font.pointSize: Tokens.font.size.large + font: Tokens.font.title.large elide: Text.ElideRight animate: true } @@ -47,7 +47,7 @@ ColumnLayout { Layout.fillWidth: true text: Players.active?.trackArtist || qsTr("Unknown artist") color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.normal + font: Tokens.font.title.medium elide: Text.ElideRight animate: true } @@ -56,7 +56,7 @@ ColumnLayout { Layout.fillWidth: true text: Players.active?.trackAlbum || qsTr("Unknown album") color: Colors.palette.m3secondary - font.pointSize: Tokens.font.size.normal + font: Tokens.font.title.medium elide: Text.ElideRight animate: true } @@ -70,7 +70,7 @@ ColumnLayout { id: timeMetrics text: Players.active ? root.lengthStr(Math.max(Players.active.position, root.hasUnknownLength ? 0 : Players.active.length)).replace(/[1-9]/g, "0") : "00:00" - font.pointSize: Tokens.font.size.normal + font: Tokens.font.label.medium } CustomText { @@ -128,7 +128,7 @@ ColumnLayout { isRound: true shapeMorph: true checked: Players.active?.shuffle ?? false - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.builders.medium.weight(Font.Medium).build() enabled: Players.active?.shuffleSupported onClicked: Players.active.shuffle = !Players.active?.shuffle implicitWidth: Math.round(implicitHeight * 0.9) @@ -141,7 +141,7 @@ ColumnLayout { icon: "skip_previous" isRound: true shapeMorph: true - font.pointSize: Tokens.font.size.extraLarge + font: Tokens.font.icon.large enabled: Players.active?.canGoPrevious onClicked: Players.active?.previous() } @@ -154,7 +154,7 @@ ColumnLayout { shapeMorph: true fillWidth: true checked: Players.active?.isPlaying ?? false - font.pointSize: Tokens.font.size.extraLarge + font: Tokens.font.icon.large enabled: Players.active?.canTogglePlaying onClicked: Players.active?.togglePlaying() } @@ -166,7 +166,7 @@ ColumnLayout { icon: "skip_next" isRound: true shapeMorph: true - font.pointSize: Tokens.font.size.extraLarge + font: Tokens.font.icon.large enabled: Players.active?.canGoNext onClicked: Players.active?.next() } @@ -177,7 +177,7 @@ ColumnLayout { isRound: true shapeMorph: true checked: Players.active?.loopState === MprisLoopState.Track || Players.active?.loopState === MprisLoopState.Playlist - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.builders.medium.weight(Font.Medium).build() enabled: Players.active?.loopSupported onClicked: { const state = Players.active.loopState; diff --git a/Modules/Dashboard/Media/LyricList.qml b/Modules/Dashboard/Media/LyricList.qml index a90aaa2..69ce845 100644 --- a/Modules/Dashboard/Media/LyricList.qml +++ b/Modules/Dashboard/Media/LyricList.qml @@ -179,7 +179,7 @@ Item { CustomText { text: qsTr("Loading lyrics...") color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.normal } } @@ -204,14 +204,14 @@ Item { MaterialIcon { Layout.alignment: Qt.AlignHCenter text: "sentiment_sad" - font.pointSize: Tokens.font.size.extraLarge + fontStyle: Tokens.font.icon.extraLarge color: Colors.palette.m3outline } CustomText { text: qsTr("No lyrics found") color: Colors.palette.m3outline - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.medium } } } @@ -258,7 +258,7 @@ Item { text: modelData || ". . ." color: ListView.isCurrentItem ? Colors.palette.m3primary : mouse.containsMouse ? Colors.palette.m3onSurface : Colors.palette.m3outline - font.pointSize: Tokens.font.size.medium + font: Tokens.font.body.medium wrapMode: Text.WrapAtWordBoundaryOrAnywhere layer.enabled: effectScale > 0 diff --git a/Modules/Dashboard/Media/LyricsAndSelector.qml b/Modules/Dashboard/Media/LyricsAndSelector.qml index 453ed2c..328cc5b 100644 --- a/Modules/Dashboard/Media/LyricsAndSelector.qml +++ b/Modules/Dashboard/Media/LyricsAndSelector.qml @@ -23,13 +23,13 @@ Item { MaterialIcon { Layout.topMargin: Math.round(fontInfo.pointSize * 0.12) text: "lyrics" - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.large } CustomText { Layout.fillWidth: true text: qsTr("Lyrics") - font.pointSize: Tokens.font.size.large + font: Tokens.font.body.large } LyricsInfo {} diff --git a/Modules/Dashboard/Media/LyricsInfo.qml b/Modules/Dashboard/Media/LyricsInfo.qml index 2e4437c..cc15f41 100644 --- a/Modules/Dashboard/Media/LyricsInfo.qml +++ b/Modules/Dashboard/Media/LyricsInfo.qml @@ -184,7 +184,7 @@ Item { text: Lyrics.loading ? qsTr("Loading...") : qsTr("No lyrics found") color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.medium animate: true } } @@ -206,7 +206,7 @@ Item { anchors.centerIn: parent text: "more_vert" - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.medium } } } diff --git a/Modules/Dashboard/Tabs.qml b/Modules/Dashboard/Tabs.qml index ce04b93..56234fa 100644 --- a/Modules/Dashboard/Tabs.qml +++ b/Modules/Dashboard/Tabs.qml @@ -162,7 +162,7 @@ Item { text: tab.iconName color: tab.current ? Colors.palette.m3primary : Colors.palette.m3onSurfaceVariant fill: tab.current ? 1 : 0 - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.medium Behavior on fill { Anim { diff --git a/Modules/Dashboard/Weather/Graphs.qml b/Modules/Dashboard/Weather/Graphs.qml index ff0e0df..f0ac43d 100644 --- a/Modules/Dashboard/Weather/Graphs.qml +++ b/Modules/Dashboard/Weather/Graphs.qml @@ -48,7 +48,7 @@ RowLayout { MaterialIcon { text: "device_thermostat" - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.medium color: Colors.palette.m3secondary } @@ -99,7 +99,7 @@ RowLayout { MaterialIcon { text: "water_drop" - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.medium color: Colors.palette.m3tertiary } diff --git a/Modules/Dashboard/WeatherTab.qml b/Modules/Dashboard/WeatherTab.qml index fbd44bc..24538a2 100644 --- a/Modules/Dashboard/WeatherTab.qml +++ b/Modules/Dashboard/WeatherTab.qml @@ -31,13 +31,13 @@ Item { CustomText { text: Weather.city || qsTr("Loading...") - font.pointSize: Tokens.font.size.large + font: Tokens.font.body.builders.large.size(24).weight(Font.DemiBold).build() color: Colors.palette.m3onSurface } CustomText { text: new Date().toLocaleDateString(Qt.locale("en_US"), "dddd, MMMM d") - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small color: Colors.palette.m3onSurfaceVariant } } @@ -114,7 +114,7 @@ Item { Layout.leftMargin: Tokens.padding.medium visible: forecastRepeater.count > 0 text: qsTr("7-day forecast") - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.builders.medium.weight(Font.DemiBold).build() color: Colors.palette.m3onSurface } @@ -148,7 +148,7 @@ Item { CustomText { Layout.alignment: Qt.AlignHCenter text: forecastItem.index === 0 ? qsTr("Today", "forecast column") : new Date(forecastItem.modelData.date).toLocaleDateString(Qt.locale("en_US"), "ddd") - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.builders.medium.weight(Font.DemiBold).build() color: Colors.palette.m3primary } @@ -156,7 +156,7 @@ Item { Layout.topMargin: -Tokens.spacing.extraSmall Layout.alignment: Qt.AlignHCenter text: new Date(forecastItem.modelData.date).toLocaleDateString(Qt.locale("en_US"), "MMM d") - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small opacity: 0.7 color: Colors.palette.m3onSurfaceVariant } @@ -164,7 +164,7 @@ Item { MaterialIcon { Layout.alignment: Qt.AlignHCenter text: forecastItem.modelData.icon - font.pointSize: Tokens.font.size.extraLarge + fontStyle: Tokens.font.icon.extraLarge color: Colors.palette.m3secondary } @@ -175,7 +175,7 @@ Item { const max = Weather.formatTemp(forecastItem.modelData.maxTempC, true); return qsTr("%1 / %2", "min/max temperature").arg(min).arg(max); } - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.builders.small.weight(Font.DemiBold).build() color: Colors.palette.m3tertiary } } @@ -204,7 +204,7 @@ Item { MaterialIcon { text: detailRoot.icon color: detailRoot.colour - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.large anchors.verticalCenter: parent.verticalCenter } @@ -214,20 +214,20 @@ Item { CustomText { text: detailRoot.label - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small opacity: 0.7 horizontalAlignment: Text.AlignLeft } CustomText { text: detailRoot.value - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.builders.small.weight(Font.DemiBold).build() horizontalAlignment: Text.AlignLeft } } } } - component WeatherStat: Row { + component WeatherStat: RowLayout { id: weatherStat property string icon @@ -239,19 +239,20 @@ Item { MaterialIcon { text: weatherStat.icon - font.pointSize: Tokens.font.size.extraLarge + fontStyle: Tokens.font.icon.extraLarge color: weatherStat.colour } Column { + Layout.alignment: Qt.AlignVCenter CustomText { text: weatherStat.label - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small color: Colors.palette.m3onSurfaceVariant } CustomText { text: weatherStat.value - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.builders.small.weight(Font.DemiBold).build() color: Colors.palette.m3onSurface } } diff --git a/Modules/DesktopIcons/BackgroundContextMenu.qml b/Modules/DesktopIcons/BackgroundContextMenu.qml index 24f0217..98050f3 100644 --- a/Modules/DesktopIcons/BackgroundContextMenu.qml +++ b/Modules/DesktopIcons/BackgroundContextMenu.qml @@ -11,175 +11,195 @@ import qs.Services import qs.Services Item { - id: root + id: root - anchors.fill: parent - z: 998 - visible: false + anchors.fill: parent + z: 998 + visible: false - property real menuX: 0 - property real menuY: 0 + property real menuX: 0 + property real menuY: 0 - MouseArea { - anchors.fill: parent - onClicked: root.close() - } + MouseArea { + anchors.fill: parent + onClicked: root.close() + } - CustomClippingRect { - id: popupBackground - readonly property real padding: 4 + CustomClippingRect { + id: popupBackground + readonly property real padding: 4 - x: root.menuX - y: root.menuY + x: root.menuX + y: root.menuY - color: Colors.tPalette.m3surface - radius: Tokens.rounding.medium + color: Colors.tPalette.m3surface + radius: Tokens.rounding.medium - implicitWidth: menuLayout.implicitWidth + padding * 2 - implicitHeight: menuLayout.implicitHeight + padding * 2 + implicitWidth: menuLayout.implicitWidth + padding * 2 + implicitHeight: menuLayout.implicitHeight + padding * 2 - Behavior on opacity { Anim {} } - opacity: root.visible ? 1 : 0 + Behavior on opacity { + Anim {} + } + opacity: root.visible ? 1 : 0 - ColumnLayout { - id: menuLayout - anchors.centerIn: parent - spacing: 0 + ColumnLayout { + id: menuLayout + anchors.centerIn: parent + spacing: 0 - CustomRect { - Layout.preferredWidth: 200 - radius: popupBackground.radius - popupBackground.padding - implicitHeight: openTerminalRow.implicitHeight + Tokens.padding.extraSmall * 2 + CustomRect { + Layout.preferredWidth: 200 + radius: popupBackground.radius - popupBackground.padding + implicitHeight: openTerminalRow.implicitHeight + Tokens.padding.extraSmall * 2 - RowLayout { - id: openTerminalRow - spacing: 8 - anchors.fill: parent - anchors.leftMargin: Tokens.padding.small + RowLayout { + id: openTerminalRow + spacing: 8 + anchors.fill: parent + anchors.leftMargin: Tokens.padding.small - MaterialIcon { text: "terminal"; font.pointSize: 20 } - CustomText { text: "Open terminal"; Layout.fillWidth: true } - } + MaterialIcon { + text: "terminal" + fontStyle: Tokens.font.icon.medium + } + CustomText { + text: "Open terminal" + Layout.fillWidth: true + } + } - StateLayer { - anchors.fill: parent + StateLayer { + anchors.fill: parent - onClicked: { - Quickshell.execDetached([Config.general.apps.terminal, "--working-directory", FileUtils.trimFileProtocol(Paths.desktop)]) - root.close() - } - } - } + onClicked: { + Quickshell.execDetached([Config.general.apps.terminal, "--working-directory", FileUtils.trimFileProtocol(Paths.desktop)]); + root.close(); + } + } + } - CustomRect { - Layout.fillWidth: true - implicitHeight: 1 - color: Colors.palette.m3outlineVariant - Layout.topMargin: 4 - Layout.bottomMargin: 4 - } + CustomRect { + Layout.fillWidth: true + implicitHeight: 1 + color: Colors.palette.m3outlineVariant + Layout.topMargin: 4 + Layout.bottomMargin: 4 + } - CustomRect { - Layout.fillWidth: true - radius: popupBackground.radius - popupBackground.padding - implicitHeight: settingsRow.implicitHeight + Tokens.padding.extraSmall * 2 + CustomRect { + Layout.fillWidth: true + radius: popupBackground.radius - popupBackground.padding + implicitHeight: settingsRow.implicitHeight + Tokens.padding.extraSmall * 2 - RowLayout { - id: settingsRow - spacing: 8 - anchors.fill: parent - anchors.leftMargin: Tokens.padding.small + RowLayout { + id: settingsRow + spacing: 8 + anchors.fill: parent + anchors.leftMargin: Tokens.padding.small - MaterialIcon { text: "settings"; font.pointSize: 20 } - CustomText { text: "ZShell settings"; Layout.fillWidth: true } - } + MaterialIcon { + text: "settings" + fontStyle: Tokens.font.icon.medium + } + CustomText { + text: "ZShell settings" + Layout.fillWidth: true + } + } - StateLayer { - anchors.fill: parent + StateLayer { + anchors.fill: parent - onClicked: { - const state = ShellState.forActive(); + onClicked: { + const state = ShellState.forActive(); state.settings = true; - root.close() - } - } - } + root.close(); + } + } + } - CustomRect { - Layout.fillWidth: true - implicitHeight: 1 - color: Colors.palette.m3outlineVariant - Layout.topMargin: 4 - Layout.bottomMargin: 4 - } + CustomRect { + Layout.fillWidth: true + implicitHeight: 1 + color: Colors.palette.m3outlineVariant + Layout.topMargin: 4 + Layout.bottomMargin: 4 + } - CustomRect { - Layout.fillWidth: true - radius: popupBackground.radius - popupBackground.padding - implicitHeight: logoutRow.implicitHeight + Tokens.padding.extraSmall * 2 + CustomRect { + Layout.fillWidth: true + radius: popupBackground.radius - popupBackground.padding + implicitHeight: logoutRow.implicitHeight + Tokens.padding.extraSmall * 2 - RowLayout { - id: logoutRow - spacing: 8 - anchors.fill: parent - anchors.leftMargin: Tokens.padding.small + RowLayout { + id: logoutRow + spacing: 8 + anchors.fill: parent + anchors.leftMargin: Tokens.padding.small - MaterialIcon { text: "logout"; font.pointSize: 20 } - CustomText { text: "Logout"; Layout.fillWidth: true } - } + MaterialIcon { + text: "logout" + fontStyle: Tokens.font.icon.medium + } + CustomText { + text: "Logout" + Layout.fillWidth: true + } + } - StateLayer { - anchors.fill: parent + StateLayer { + anchors.fill: parent - onClicked: { - Hyprland.dispatch("global quickshell:sessionOpen") - root.close() - } - } - } + onClicked: { + Hyprland.dispatch("global quickshell:sessionOpen"); + root.close(); + } + } + } - // CustomRect { - // Layout.fillWidth: true - // implicitHeight: 1 - // color: Colors.palette.m3outlineVariant - // Layout.topMargin: 4 - // Layout.bottomMargin: 4 - // } - // - // CustomRect { - // Layout.fillWidth: true - // radius: popupBackground.radius - popupBackground.padding - // implicitHeight: desktopIconsRow.implicitHeight + Tokens.padding.extraSmall * 2 - // - // RowLayout { - // id: desktopIconsRow - // spacing: 8 - // anchors.fill: parent - // anchors.leftMargin: Tokens.padding.small - // - // MaterialIcon { text: Config.options.background.showDesktopIcons ? "visibility_off" : "visibility"; font.pointSize: 20 } - // CustomText { text: Config.options.background.showDesktopIcons ? "Hide icons" : "Show icons"; Layout.fillWidth: true } - // } - // - // StateLayer { - // anchors.fill: parent - // - // onClicked: { - // Config.options.background.showDesktopIcons = !Config.options.background.showDesktopIcons - // root.close() - // } - // } - // } - } - } + // CustomRect { + // Layout.fillWidth: true + // implicitHeight: 1 + // color: Colors.palette.m3outlineVariant + // Layout.topMargin: 4 + // Layout.bottomMargin: 4 + // } + // + // CustomRect { + // Layout.fillWidth: true + // radius: popupBackground.radius - popupBackground.padding + // implicitHeight: desktopIconsRow.implicitHeight + Tokens.padding.extraSmall * 2 + // + // RowLayout { + // id: desktopIconsRow + // spacing: 8 + // anchors.fill: parent + // anchors.leftMargin: Tokens.padding.small + // + // MaterialIcon { text: Config.options.background.showDesktopIcons ? "visibility_off" : "visibility"; font.pointSize: 20 } + // CustomText { text: Config.options.background.showDesktopIcons ? "Hide icons" : "Show icons"; Layout.fillWidth: true } + // } + // + // StateLayer { + // anchors.fill: parent + // + // onClicked: { + // Config.options.background.showDesktopIcons = !Config.options.background.showDesktopIcons + // root.close() + // } + // } + // } + } + } - function openAt(mouseX, mouseY, parentW, parentH) { - menuX = Math.floor(Math.min(mouseX, parentW - popupBackground.implicitWidth)) - menuY = Math.floor(Math.min(mouseY, parentH - popupBackground.implicitHeight)) - visible = true - } + function openAt(mouseX, mouseY, parentW, parentH) { + menuX = Math.floor(Math.min(mouseX, parentW - popupBackground.implicitWidth)); + menuY = Math.floor(Math.min(mouseY, parentH - popupBackground.implicitHeight)); + visible = true; + } - function close() { - visible = false - } + function close() { + visible = false; + } } diff --git a/Modules/DesktopIcons/DesktopIconContextMenu.qml b/Modules/DesktopIcons/DesktopIconContextMenu.qml index 4b9b570..349d0cb 100644 --- a/Modules/DesktopIcons/DesktopIconContextMenu.qml +++ b/Modules/DesktopIcons/DesktopIconContextMenu.qml @@ -54,8 +54,7 @@ Item { y: contextMenu.menuY Behavior on opacity { - Anim { - } + Anim {} } ColumnLayout { @@ -77,7 +76,7 @@ Item { spacing: 8 MaterialIcon { - font.pointSize: 20 + fontStyle: Tokens.font.icon.medium text: "open_in_new" } @@ -120,7 +119,7 @@ Item { spacing: 8 MaterialIcon { - font.pointSize: 20 + fontStyle: Tokens.font.icon.medium text: contextMenu.targetIsDir ? "terminal" : "apps" } @@ -165,7 +164,7 @@ Item { spacing: 8 MaterialIcon { - font.pointSize: 20 + fontStyle: Tokens.font.icon.medium text: "content_copy" } @@ -199,7 +198,7 @@ Item { spacing: 8 MaterialIcon { - font.pointSize: 20 + fontStyle: Tokens.font.icon.medium text: "edit" } @@ -241,7 +240,7 @@ Item { MaterialIcon { color: deleteButton.hovered ? Colors.palette.m3onError : Colors.palette.m3error - font.pointSize: 20 + fontStyle: Tokens.font.icon.medium text: "delete" } diff --git a/Modules/Drawing/Content.qml b/Modules/Drawing/Content.qml index c689836..a580337 100644 --- a/Modules/Drawing/Content.qml +++ b/Modules/Drawing/Content.qml @@ -145,7 +145,6 @@ Item { IconTextButton { fillWidth: true - font.pointSize: Tokens.font.size.normal icon: "close" inactiveColor: Colors.palette.m3error inactiveOnColor: Colors.palette.m3onError @@ -158,7 +157,6 @@ Item { IconTextButton { fillWidth: true - font.pointSize: Tokens.font.size.normal icon: "ink_eraser" inactiveColor: Colors.layer(Colors.palette.m3surfaceContainerHighest, 2) inactiveOnColor: Colors.palette.m3onSurfaceVariant @@ -193,7 +191,7 @@ Item { required property ButtonRow row fillWidth: false - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.medium icon: "" implicitHeight: buttonSize implicitWidth: buttonSize diff --git a/Modules/Drawing/Wrapper.qml b/Modules/Drawing/Wrapper.qml index e7835d1..654950e 100644 --- a/Modules/Drawing/Wrapper.qml +++ b/Modules/Drawing/Wrapper.qml @@ -74,11 +74,10 @@ Item { opacity: root.expanded ? 0 : 1 Behavior on opacity { - Anim { - } + Anim {} } sourceComponent: MaterialIcon { - font.pointSize: Tokens.font.size.larger + fontStyle: Tokens.font.icon.medium text: "arrow_forward_ios" } } @@ -93,8 +92,7 @@ Item { opacity: root.expanded ? 1 : 0 Behavior on opacity { - Anim { - } + Anim {} } sourceComponent: Content { drawing: root.drawing diff --git a/Modules/Launcher/ContentList.qml b/Modules/Launcher/ContentList.qml index 76bfeed..54093de 100644 --- a/Modules/Launcher/ContentList.qml +++ b/Modules/Launcher/ContentList.qml @@ -53,8 +53,7 @@ Item { to: 0 } - PropertyAction { - } + PropertyAction {} Anim { duration: Tokens.anim.durations.small @@ -130,18 +129,16 @@ Item { spacing: Tokens.spacing.medium Behavior on opacity { - Anim { - } + Anim {} } Behavior on scale { - Anim { - } + Anim {} } MaterialIcon { anchors.verticalCenter: parent.verticalCenter color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.extraLarge + fontStyle: Tokens.font.icon.extraLarge text: root.state === "wallpapers" ? "wallpaper_slideshow" : "manage_search" } @@ -150,14 +147,13 @@ Item { CustomText { color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.larger - font.weight: 500 + font: Tokens.font.body.builders.large.weight(Font.Medium).build() text: root.state === "wallpapers" ? qsTr("No wallpapers found") : qsTr("No results") } CustomText { color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.medium text: root.state === "wallpapers" && Wallpapers.list.length === 0 ? qsTr("Try putting some wallpapers in %1").arg(Paths.shortenHome(Paths.wallsdir)) : qsTr("Try searching for something else") } } diff --git a/Modules/Launcher/Items/ActionItem.qml b/Modules/Launcher/Items/ActionItem.qml index 6ccd88b..30f0004 100644 --- a/Modules/Launcher/Items/ActionItem.qml +++ b/Modules/Launcher/Items/ActionItem.qml @@ -33,7 +33,7 @@ Item { id: icon anchors.verticalCenter: parent.verticalCenter - font.pointSize: Tokens.font.size.extraLarge + fontStyle: Tokens.font.icon.large text: root.modelData?.icon ?? "" } @@ -47,7 +47,6 @@ Item { CustomText { id: name - font.pointSize: Tokens.font.size.normal text: root.modelData?.name ?? "" } @@ -57,7 +56,7 @@ Item { anchors.top: name.bottom color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small text: root.modelData?.desc ?? "" width: root.width - icon.width - Tokens.rounding.medium * 2 } diff --git a/Modules/Launcher/Items/AppItem.qml b/Modules/Launcher/Items/AppItem.qml index fc8ed82..c93a8e5 100644 --- a/Modules/Launcher/Items/AppItem.qml +++ b/Modules/Launcher/Items/AppItem.qml @@ -51,7 +51,6 @@ Item { CustomText { id: name - font.pointSize: Tokens.font.size.normal text: root.modelData?.name ?? "" } @@ -61,7 +60,7 @@ Item { anchors.top: name.bottom color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small text: (root.modelData?.comment || root.modelData?.genericName || root.modelData?.name) ?? "" width: root.width - icon.width - Tokens.rounding.medium - Tokens.padding.medium * 2 } diff --git a/Modules/Launcher/Items/CalcItem.qml b/Modules/Launcher/Items/CalcItem.qml index 63a9ef0..c52d71a 100644 --- a/Modules/Launcher/Items/CalcItem.qml +++ b/Modules/Launcher/Items/CalcItem.qml @@ -40,7 +40,7 @@ Item { MaterialIcon { Layout.alignment: Qt.AlignVCenter - font.pointSize: Tokens.font.size.extraLarge + fontStyle: Tokens.font.icon.large text: "function" } @@ -92,7 +92,7 @@ Item { anchors.rightMargin: Tokens.spacing.small anchors.verticalCenter: parent.verticalCenter color: Colors.palette.m3onTertiary - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.medium opacity: stateLayer.containsMouse ? 1 : 0 text: qsTr("Open in calculator") @@ -108,7 +108,7 @@ Item { anchors.rightMargin: Tokens.padding.small anchors.verticalCenter: parent.verticalCenter color: Colors.palette.m3onTertiary - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.medium text: "open_in_new" } } diff --git a/Modules/Launcher/Items/FilesItem.qml b/Modules/Launcher/Items/FilesItem.qml index ab3b3ba..b878e6e 100644 --- a/Modules/Launcher/Items/FilesItem.qml +++ b/Modules/Launcher/Items/FilesItem.qml @@ -120,7 +120,7 @@ Item { CustomText { id: name - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.medium text: root.modelData?.name ?? "" elide: Text.ElideRight width: root.width - icon.width - openLocation.implicitWidth - openLocation.anchors.rightMargin - Tokens.spacing.medium - Tokens.rounding.medium * 2 @@ -132,7 +132,7 @@ Item { anchors.top: name.bottom color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small text: root.modelData?.path ?? "" width: root.width - icon.width - openLocation.implicitWidth - openLocation.anchors.rightMargin - Tokens.spacing.medium - Tokens.rounding.medium * 2 } diff --git a/Modules/Launcher/Items/VariantItem.qml b/Modules/Launcher/Items/VariantItem.qml index cb37cd3..18aedce 100644 --- a/Modules/Launcher/Items/VariantItem.qml +++ b/Modules/Launcher/Items/VariantItem.qml @@ -32,7 +32,7 @@ Item { id: icon anchors.verticalCenter: parent.verticalCenter - font.pointSize: Tokens.font.size.extraLarge + fontStyle: Tokens.font.icon.large text: root.modelData?.icon ?? "" } @@ -44,7 +44,6 @@ Item { width: parent.width - icon.width - anchors.leftMargin - (current.active ? current.width + Tokens.spacing.medium : 0) CustomText { - font.pointSize: Tokens.font.size.normal text: root.modelData?.name ?? "" } @@ -53,7 +52,7 @@ Item { anchors.right: parent.right color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small text: root.modelData?.description ?? "" } } @@ -67,7 +66,7 @@ Item { sourceComponent: MaterialIcon { color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.large text: "check" } } diff --git a/Modules/Launcher/Items/WallpaperTile.qml b/Modules/Launcher/Items/WallpaperTile.qml index b4a1091..293c48c 100755 --- a/Modules/Launcher/Items/WallpaperTile.qml +++ b/Modules/Launcher/Items/WallpaperTile.qml @@ -32,8 +32,7 @@ Item { MaterialIcon { anchors.centerIn: parent color: Colors.tPalette.m3outline - font.pointSize: Tokens.font.size.extraLarge * 2 - font.weight: 600 + fontStyle: Tokens.font.icon.builders.extraLarge.scale(2).weight(Font.DemiBold).build() text: "image" } diff --git a/Modules/Lock/Center.qml b/Modules/Lock/Center.qml index 06ad24b..481d757 100644 --- a/Modules/Lock/Center.qml +++ b/Modules/Lock/Center.qml @@ -28,27 +28,21 @@ ColumnLayout { CustomText { Layout.alignment: Qt.AlignVCenter color: Colors.palette.m3secondary - font.bold: true - font.family: Config.appearance.font.family.clock - font.pointSize: Math.floor(Tokens.font.size.extraLarge * 3 * root.centerScale) + font: Tokens.font.headline.builders.large.scale(3 * root.centerScale).weight(Font.Bold).width(30).build() text: Time.hourStr } CustomText { Layout.alignment: Qt.AlignVCenter color: Colors.palette.m3primary - font.bold: true - font.family: Config.appearance.font.family.clock - font.pointSize: Math.floor(Tokens.font.size.extraLarge * 3 * root.centerScale) + font: Tokens.font.headline.builders.large.scale(3 * root.centerScale).weight(Font.Bold).width(30).build() text: ":" } CustomText { Layout.alignment: Qt.AlignVCenter color: Colors.palette.m3secondary - font.bold: true - font.family: Config.appearance.font.family.clock - font.pointSize: Math.floor(Tokens.font.size.extraLarge * 3 * root.centerScale) + font: Tokens.font.headline.builders.large.scale(3 * root.centerScale).weight(Font.Bold).width(30).build() text: Time.minuteStr } } @@ -57,9 +51,7 @@ ColumnLayout { Layout.alignment: Qt.AlignHCenter Layout.topMargin: -Tokens.padding.large * 2 color: Colors.palette.m3tertiary - font.bold: true - font.family: Config.appearance.font.family.mono - font.pointSize: Math.floor(Tokens.font.size.extraLarge * root.centerScale) + font: Tokens.font.title.builders.medium.weight(Font.DemiBold).build() text: Time.format("dddd, d MMMM yyyy") } @@ -74,7 +66,7 @@ ColumnLayout { MaterialIcon { anchors.centerIn: parent color: Colors.palette.m3onSurfaceVariant - font.pointSize: Math.floor(root.centerWidth / 4) + fontStyle: Tokens.font.icon.size(root.centerWidth / 4).build() text: "person" } @@ -144,8 +136,7 @@ ColumnLayout { } Behavior on opacity { - Anim { - } + Anim {} } } @@ -159,6 +150,7 @@ ColumnLayout { id: inputField pam: root.lock.pam + centerScale: root.centerScale } CustomRect { @@ -180,7 +172,6 @@ ColumnLayout { anchors.centerIn: parent color: root.lock.pam.buffer ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface - font.weight: 500 text: "arrow_forward" } } @@ -193,8 +184,7 @@ ColumnLayout { implicitHeight: Math.max(message.implicitHeight, stateMessage.implicitHeight) Behavior on implicitHeight { - Anim { - } + Anim {} } CustomText { @@ -226,7 +216,7 @@ ColumnLayout { anchors.right: parent.right animateProp: "opacity" color: Colors.palette.m3onSurfaceVariant - font.family: Config.appearance.font.family.mono + font: Tokens.font.body.small horizontalAlignment: Qt.AlignHCenter lineHeight: 1.2 opacity: shouldBeVisible && !message.msg ? 1 : 0 @@ -234,12 +224,10 @@ ColumnLayout { wrapMode: Text.WrapAtWordBoundaryOrAnywhere Behavior on opacity { - Anim { - } + Anim {} } Behavior on scale { - Anim { - } + Anim {} } onMsgChanged: { @@ -295,8 +283,7 @@ ColumnLayout { anchors.left: parent.left anchors.right: parent.right color: Colors.palette.m3error - font.family: Config.appearance.font.family.mono - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small horizontalAlignment: Qt.AlignHCenter opacity: 0 scale: 0.7 diff --git a/Modules/Lock/InputField.qml b/Modules/Lock/InputField.qml index 67511c3..b2ca56c 100644 --- a/Modules/Lock/InputField.qml +++ b/Modules/Lock/InputField.qml @@ -14,6 +14,7 @@ Item { property string buffer required property Pam pam + required property real centerScale readonly property alias placeholder: placeholder Layout.fillHeight: true @@ -41,8 +42,7 @@ Item { anchors.centerIn: parent animate: true color: root.pam.passwd.active ? Colors.palette.m3secondary : Colors.palette.m3outline - font.family: Config.appearance.font.family.mono - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.builders.medium.scale(root.centerScale).width(110).build() opacity: root.buffer ? 0 : 1 text: { if (root.pam.passwd.active) @@ -53,8 +53,7 @@ Item { } Behavior on opacity { - Anim { - } + Anim {} } } @@ -84,12 +83,11 @@ Item { implicitHeight: charList.implicitHeight implicitWidth: implicitHeight opacity: 0 - radius: Tokens.rounding.small / 2 + radius: Tokens.rounding.full scale: 0 Behavior on opacity { - Anim { - } + Anim {} } Behavior on scale { Anim { @@ -137,8 +135,7 @@ Item { Behavior on implicitWidth { id: imWidthBehavior - Anim { - } + Anim {} } model: ScriptModel { values: root.buffer.split("") diff --git a/Modules/Lock/LockSurface.qml b/Modules/Lock/LockSurface.qml index 6086d68..540e704 100644 --- a/Modules/Lock/LockSurface.qml +++ b/Modules/Lock/LockSurface.qml @@ -236,8 +236,7 @@ WlSessionLockSurface { id: lockIcon anchors.centerIn: parent - font.bold: true - font.pointSize: Tokens.font.size.extraLarge * 4 + fontStyle: Tokens.font.icon.builders.extraLarge.scale(4).weight(Font.Bold).build() text: "lock" } diff --git a/Modules/Lock/Media.qml b/Modules/Lock/Media.qml index d292965..326f5ba 100644 --- a/Modules/Lock/Media.qml +++ b/Modules/Lock/Media.qml @@ -57,7 +57,7 @@ CustomClippingRect { animate: true color: Colors.palette.m3primary elide: Text.ElideRight - font.pointSize: Tokens.font.size.normal + font: Tokens.font.title.large horizontalAlignment: Text.AlignHCenter text: (Players.active?.trackTitle ?? qsTr("Nothing playing")) || qsTr("Unknown track") } @@ -67,7 +67,6 @@ CustomClippingRect { animate: true color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight - font.pointSize: Tokens.font.size.small horizontalAlignment: Text.AlignHCenter text: (Players.active?.trackArtist ?? qsTr("Try playing some music!")) || qsTr("Unknown artist") } diff --git a/Modules/Lock/NotifDock.qml b/Modules/Lock/NotifDock.qml index 3b468a9..c441ff9 100644 --- a/Modules/Lock/NotifDock.qml +++ b/Modules/Lock/NotifDock.qml @@ -66,9 +66,7 @@ ColumnLayout { CustomText { Layout.alignment: Qt.AlignHCenter color: Colors.palette.m3outlineVariant - font.family: Config.appearance.font.family.mono - font.pointSize: Tokens.font.size.large - font.weight: 500 + font: Tokens.font.headline.builders.small.width(90).build() text: qsTr("No Notifications") } } @@ -94,8 +92,7 @@ ColumnLayout { to: 1 } } - delegate: NotifGroup { - } + delegate: NotifGroup {} displaced: Transition { Anim { properties: "opacity,scale" diff --git a/Modules/Lock/NotifGroup.qml b/Modules/Lock/NotifGroup.qml index 09bf5d5..0d6d6ad 100644 --- a/Modules/Lock/NotifGroup.qml +++ b/Modules/Lock/NotifGroup.qml @@ -80,7 +80,7 @@ CustomRect { MaterialIcon { color: root.urgency === "critical" ? Colors.palette.m3onError : root.urgency === "low" ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.large text: Icons.getNotifIcon(root.notifs[0]?.summary, root.urgency) } } @@ -133,14 +133,14 @@ CustomRect { Layout.fillWidth: true color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small text: root.modelData } CustomText { animate: true color: Colors.palette.m3outline - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small text: root.notifs[0]?.timeStr ?? "" } @@ -153,12 +153,10 @@ CustomRect { radius: Tokens.rounding.full Behavior on Layout.preferredWidth { - Anim { - } + Anim {} } Behavior on opacity { - Anim { - } + Anim {} } StateLayer { @@ -181,7 +179,7 @@ CustomRect { Layout.leftMargin: Tokens.padding.extraSmall / 2 animate: true color: root.urgency === "critical" ? Colors.palette.m3onError : Colors.palette.m3onSurface - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small text: root.notifs.length } @@ -261,8 +259,7 @@ CustomRect { opacity: root.expanded ? 1 : 0 Behavior on opacity { - Anim { - } + Anim {} } sourceComponent: ColumnLayout { Repeater { @@ -270,8 +267,7 @@ CustomRect { values: root.notifs.slice(Config.notifs.groupPreviewNum) } - NotifLine { - } + NotifLine {} } } } diff --git a/Modules/Lock/Resources.qml b/Modules/Lock/Resources.qml index e06fff7..7ce6c90 100644 --- a/Modules/Lock/Resources.qml +++ b/Modules/Lock/Resources.qml @@ -70,14 +70,13 @@ CustomRect { implicitSize: width Behavior on clampedVal { - Anim { - } + Anim {} } MaterialIcon { anchors.centerIn: parent color: res.fgColor - font.pointSize: Tokens.font.size.extraLarge + fontStyle: Tokens.font.icon.extraLarge text: res.icon } } diff --git a/Modules/Lock/Weather/BriefInfo.qml b/Modules/Lock/Weather/BriefInfo.qml index fc6a820..cd92521 100644 --- a/Modules/Lock/Weather/BriefInfo.qml +++ b/Modules/Lock/Weather/BriefInfo.qml @@ -16,7 +16,7 @@ ColumnLayout { Layout.alignment: Qt.AlignHCenter animate: true color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.large + font: Tokens.font.title.large text: Weather.description } @@ -29,7 +29,7 @@ ColumnLayout { animate: true color: Colors.palette.m3primary - font.pointSize: Tokens.font.size.large + font: Tokens.font.body.large text: Weather.temp } @@ -44,7 +44,7 @@ ColumnLayout { Layout.alignment: Qt.AlignHCenter animate: true color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.large + font: Tokens.font.body.large text: qsTr("Feels like %1").arg(Weather.temp) visible: root.rootHeight > 550 } @@ -53,7 +53,7 @@ ColumnLayout { Layout.alignment: Qt.AlignHCenter animate: true color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.normal text: { const today = Weather.forecast[0]; return qsTr("High %1 • Low %2").arg(Weather.formatTemp(today?.maxTempC)).arg(Weather.formatTemp(today?.minTempC)); diff --git a/Modules/Lock/Weather/Forecast.qml b/Modules/Lock/Weather/Forecast.qml index 467879b..dd8cf82 100644 --- a/Modules/Lock/Weather/Forecast.qml +++ b/Modules/Lock/Weather/Forecast.qml @@ -24,14 +24,14 @@ CustomRect { MaterialIcon { Layout.topMargin: Math.round(fontInfo.pointSize * 0.12) - font.pointSize: Tokens.font.size.normal + fontStyle: Tokens.font.icon.medium text: "schedule" } CustomText { id: title - font.pointSize: Tokens.font.size.normal + font: Tokens.font.title.medium text: qsTr("Hourly forecast") } } @@ -65,8 +65,7 @@ CustomRect { shape: MaterialShape.Cookie4Sided Behavior on color { - CAnim { - } + CAnim {} } CustomText { @@ -74,7 +73,7 @@ CustomRect { anchors.centerIn: parent color: hour.index === Weather.currentHourIndex ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.medium text: Weather.formatTemp(hour.cond.tempC).slice(0, -1) // Remove C/F } } @@ -82,7 +81,7 @@ CustomRect { MaterialIcon { Layout.alignment: Qt.AlignHCenter color: Colors.palette.m3secondary - font.pointSize: Tokens.font.size.extraLarge + fontStyle: Tokens.font.icon.extraLarge text: hour.cond.icon } @@ -96,7 +95,7 @@ CustomRect { Layout.alignment: Qt.AlignHCenter Layout.topMargin: Tokens.spacing.extraSmall color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small text: hour.index === 0 ? qsTr("Now") : Qt.formatDateTime(new Date(hour.cond.timestamp.replace("T", " ")), Config.services.useTwelveHourClock ? "ha" : "hh:00") } } diff --git a/Modules/Notifications/Notification.qml b/Modules/Notifications/Notification.qml index 46e2bc4..0cf7d74 100644 --- a/Modules/Notifications/Notification.qml +++ b/Modules/Notifications/Notification.qml @@ -94,8 +94,7 @@ CustomRect { implicitHeight: root.nonAnimHeight Behavior on implicitHeight { - Anim { - } + Anim {} } Loader { @@ -171,6 +170,7 @@ CustomRect { sourceComponent: MaterialIcon { color: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3onError : root.modelData.urgency === NotificationUrgency.Low ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer text: Icons.getNotifIcon(root.modelData.summary, root.modelData.urgency) + fontStyle: Tokens.font.icon.medium } } } @@ -222,6 +222,7 @@ CustomRect { maximumLineCount: 1 opacity: root.expanded ? 1 : 0 text: appNameMetrics.elidedText + font: Tokens.font.label.medium Behavior on opacity { Anim { @@ -246,14 +247,12 @@ CustomRect { anchors.leftMargin: Tokens.spacing.small anchors.top: parent.top animate: true - font.pointSize: Tokens.font.size.small height: implicitHeight maximumLineCount: 1 text: summaryMetrics.elidedText Behavior on height { - Anim { - } + Anim {} } states: State { name: "expanded" @@ -281,8 +280,7 @@ CustomRect { property: "topMargin" } - AnchorAnim { - } + AnchorAnim {} } } @@ -303,6 +301,7 @@ CustomRect { anchors.top: parent.top color: Colors.palette.m3onSurfaceVariant text: "•" + font: Tokens.font.body.small states: State { name: "expanded" @@ -314,8 +313,7 @@ CustomRect { } } transitions: Transition { - AnchorAnim { - } + AnchorAnim {} } } @@ -327,7 +325,7 @@ CustomRect { anchors.top: parent.top animate: true color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small horizontalAlignment: Text.AlignLeft text: root.modelData.timeStr } @@ -355,14 +353,13 @@ CustomRect { anchors.verticalCenterOffset: root.expanded ? -1 : 1 rotation: root.expanded ? 180 : 0 text: "expand_more" + fontStyle: Tokens.font.icon.medium Behavior on anchors.verticalCenterOffset { - Anim { - } + Anim {} } Behavior on rotation { - Anim { - } + Anim {} } } } @@ -376,7 +373,7 @@ CustomRect { anchors.top: summary.bottom animate: true color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small opacity: root.expanded ? 0 : 1 text: bodyPreviewMetrics.elidedText textFormat: Text.MarkdownText @@ -407,6 +404,7 @@ CustomRect { animate: true color: Colors.palette.m3onSurfaceVariant height: text ? implicitHeight : 0 + font: Tokens.font.body.medium opacity: root.expanded ? 1 : 0 text: root.modelData.body textFormat: Text.MarkdownText @@ -447,6 +445,7 @@ CustomRect { enabled: root.expanded fillWidth: root.modelData.actions.length === 0 icon: "close" + font: Tokens.font.icon.builders.small.size(14).build() inactiveColor: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3secondary : Colors.layer(Colors.palette.m3surfaceContainerHighest, 2) inactiveOnColor: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3onSecondary : Colors.palette.m3onSurfaceVariant isRound: true @@ -464,7 +463,6 @@ CustomRect { enabled: root.expanded fillWidth: true - font.pointSize: Tokens.font.size.small implicitWidth: label.implicitWidth inactiveColor: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3secondary : Colors.layer(Colors.palette.m3surfaceContainerHighest, 2) inactiveOnColor: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3onSecondary : Colors.palette.m3onSurfaceVariant @@ -493,6 +491,7 @@ CustomRect { label.animate: true padding: Tokens.padding.extraSmall shapeMorph: true + font: Tokens.font.icon.builders.small.size(14).build() onClicked: { Quickshell.clipboardText = root.modelData.body; diff --git a/Modules/Notifications/Sidebar/Chat/ChatContent.qml b/Modules/Notifications/Sidebar/Chat/ChatContent.qml index 88a4c2d..66cbf63 100644 --- a/Modules/Notifications/Sidebar/Chat/ChatContent.qml +++ b/Modules/Notifications/Sidebar/Chat/ChatContent.qml @@ -170,7 +170,7 @@ Item { Layout.fillWidth: ChatState.isWindow ? false : true Layout.alignment: ChatState.isWindow ? Qt.AlignCenter : Qt.AlignLeft | Qt.AlignVCenter elide: Text.ElideRight - font.pointSize: Tokens.font.size.larger + font: Tokens.font.title.medium text: qsTr(root.chatData.title) } } @@ -346,7 +346,7 @@ Item { id: scrollToBottom anchors.centerIn: parent - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.large icon: "arrow_downward" isRound: true padding: Tokens.padding.extraSmall @@ -455,7 +455,7 @@ Item { MaterialIcon { anchors.centerIn: parent - font.pointSize: Tokens.font.size.extraLarge + fontStyle: Tokens.font.icon.large text: thumb.fileIcon(thumb.modelData?.mimeType ?? "") visible: !thumb.modelData?.isImage ?? false } @@ -537,13 +537,15 @@ Item { anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right + anchors.margins: Tokens.padding.medium bg.border.color: Colors.palette.m3outlineVariant bg.color: Colors.tPalette.m3surfaceContainerLowest - font.pointSize: Tokens.font.size.normal + fastGlow: Chat.busy + font: Tokens.font.body.small implicitHeight: Math.min(root.height / 5, contentHeight + topPadding + bottomPadding) focus: true placeholderText: qsTr("Send a message") - sendIcon.font.pointSize: Tokens.font.size.large + sendIcon.font: Tokens.font.icon.medium sendIcon.icon: "arrow_upward" sendIcon.padding: Tokens.padding.extraSmall diff --git a/Modules/Notifications/Sidebar/Chat/ChatDelegate.qml b/Modules/Notifications/Sidebar/Chat/ChatDelegate.qml index 5a2613f..75e5c21 100644 --- a/Modules/Notifications/Sidebar/Chat/ChatDelegate.qml +++ b/Modules/Notifications/Sidebar/Chat/ChatDelegate.qml @@ -67,7 +67,7 @@ CustomClippingRect { anchors.leftMargin: Tokens.padding.large anchors.top: parent.top anchors.topMargin: Tokens.padding.large - font.pointSize: Tokens.font.size.extraLarge + fontStyle: Tokens.font.icon.extraLarge text: root.modelData.icon || "check" color: Colors.palette.m3onSurface } @@ -134,7 +134,7 @@ CustomClippingRect { anchors.leftMargin: readOnly ? 0 : Tokens.padding.large anchors.top: parent.top anchors.topMargin: readOnly ? Tokens.padding.small : Tokens.padding.extraSmall * 2 - font.pointSize: Tokens.font.size.normal + font: Tokens.font.title.medium text: root.modelData.title || qsTr("New chat") readOnly: true color: Colors.palette.m3onSurface @@ -192,7 +192,6 @@ CustomClippingRect { anchors.topMargin: Tokens.spacing.extraSmall anchors.left: parent.left anchors.right: parent.right - font.pointSize: Tokens.font.size.small color: Colors.palette.m3onSurfaceVariant text: qsTr("Created on: %1").arg(root.modelData.createdAt.toLocaleString(Qt.locale("en_US"), "MMM d, yyyy - h:mm AP")) opacity: root.expanded ? 1 : 0 @@ -208,7 +207,6 @@ CustomClippingRect { anchors.top: created.bottom anchors.topMargin: Tokens.spacing.small anchors.left: parent.left - font.pointSize: Tokens.font.size.small color: Colors.palette.m3onSurfaceVariant text: qsTr("Updated on: ") opacity: root.expanded ? 1 : 0 @@ -225,7 +223,6 @@ CustomClippingRect { anchors.top: title.bottom anchors.topMargin: Tokens.spacing.extraSmall color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.small text: root.modelData.updatedAt.toLocaleString(Qt.locale("en_US"), "MMM d, yyyy - h:mm AP") states: State { @@ -256,7 +253,6 @@ CustomClippingRect { y: infoContainer.implicitHeight + topMargin elide: Text.ElideRight color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.small maximumLineCount: 1 opacity: !root.expanded && !root.slim ? 1 : 0 text: root.modelData.messagesModel.lastMessage?.activeGeneration.content.replace(/\s+/g, " ").trim() ?? qsTr("No messages yet") @@ -323,7 +319,7 @@ CustomClippingRect { fillWidth: true shapeMorph: true isRound: true - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.medium inactiveColor: Colors.layer(Colors.palette.m3surfaceContainerHighest, 3) inactiveOnColor: Colors.palette.m3onSurfaceVariant @@ -336,7 +332,7 @@ CustomClippingRect { isToggle: true fillWidth: true shapeMorph: true - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.medium isRound: true inactiveColor: Colors.layer(Colors.palette.m3surfaceContainerHighest, 3) inactiveOnColor: Colors.palette.m3onSurfaceVariant diff --git a/Modules/Notifications/Sidebar/Chat/ChatInput.qml b/Modules/Notifications/Sidebar/Chat/ChatInput.qml index 058ac31..34d2275 100644 --- a/Modules/Notifications/Sidebar/Chat/ChatInput.qml +++ b/Modules/Notifications/Sidebar/Chat/ChatInput.qml @@ -9,6 +9,8 @@ TextAreaBase { readonly property alias bg: bg readonly property alias sendIcon: sendIcon + property bool fastGlow: false + signal sendPressed bottomPadding: Tokens.padding.large @@ -17,6 +19,16 @@ TextAreaBase { topPadding: Tokens.padding.large wrapMode: TextAreaBase.Wrap + onFastGlowChanged: { + if (fastGlow) { + resetAnim.stop(); + boostAnim.restart(); + } else { + boostAnim.stop(); + resetAnim.restart(); + } + } + background: CustomRect { id: bg @@ -24,6 +36,47 @@ TextAreaBase { color: Colors.tPalette.m3surfaceContainer radius: Tokens.rounding.extraLarge + GeminiGlow { + id: glow + glowSize: 32 + + opacity: root.activeFocus ? 1 : 0 + visible: opacity > 0 + + Behavior on opacity { + Anim {} + } + + SequentialAnimation { + id: boostAnim + + NumberAnimation { + target: glow + property: "speed" + to: 4.0 + duration: 250 + easing.type: Easing.OutCubic + } + NumberAnimation { + target: glow + property: "speed" + to: 2.25 + duration: 1500 + easing.type: Easing.InOutQuad + } + } + + // Ease back down to normal once fastGlow is false + NumberAnimation { + id: resetAnim + target: glow + property: "speed" + to: 1.0 + duration: 800 + easing.type: Easing.InOutQuad + } + } + StateLayer { id: stateLayer diff --git a/Modules/Notifications/Sidebar/Chat/ChatList.qml b/Modules/Notifications/Sidebar/Chat/ChatList.qml index d9a17fe..0ff81ca 100644 --- a/Modules/Notifications/Sidebar/Chat/ChatList.qml +++ b/Modules/Notifications/Sidebar/Chat/ChatList.qml @@ -29,9 +29,7 @@ Item { anchors.right: parent.right anchors.top: parent.top color: Colors.palette.m3outline - font.family: "CaskaydiaCove NF" - font.pointSize: 13 - font.weight: 500 + font: Tokens.font.label.large text: qsTr("%1 Chat%2").arg(list.count).arg(list.count > 1 ? "s" : "") } @@ -156,7 +154,7 @@ Item { anchors.verticalCenter: parent.verticalCenter text: modelsContainer.expanded ? "unfold_less" : "unfold_more" animate: true - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.medium visible: modelsList.count > 0 } @@ -229,7 +227,7 @@ Item { Layout.alignment: Qt.AlignRight visible: model.selected color: Colors.palette.m3onTertiaryContainer - font.pointSize: Tokens.font.size.normal + fontStyle: Tokens.font.icon.medium opacity: model.selected ? 1 : 0 text: "check" @@ -259,7 +257,7 @@ Item { anchors.right: parent.right anchors.margins: Tokens.padding.small padding: 8 - font.pointSize: Math.round(18 * 1.2) + font: Tokens.font.icon.large icon: root.slim ? "left_panel_open" : "add" isRound: ChatState.fabExpanded // opacity: root.slim ? 0 : 1 @@ -405,7 +403,7 @@ Item { MaterialIcon { text: fabMenuItem.modelData.icon color: Colors.palette.m3onPrimaryContainer - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.medium fill: 1 } diff --git a/Modules/Notifications/Sidebar/Chat/Content/Actions.qml b/Modules/Notifications/Sidebar/Chat/Content/Actions.qml index 1d4efdf..43227ab 100644 --- a/Modules/Notifications/Sidebar/Chat/Content/Actions.qml +++ b/Modules/Notifications/Sidebar/Chat/Content/Actions.qml @@ -40,8 +40,7 @@ Item { IconButton { enabled: false icon: `${root.message.activeGenerationIndex + 1}` - label.font.family: Config.appearance.font.family.sans - label.font.pointSize: Tokens.font.size.small + label.font: Tokens.font.label.small type: IconButton.Text } diff --git a/Modules/Notifications/Sidebar/Chat/Content/BubbleEdit.qml b/Modules/Notifications/Sidebar/Chat/Content/BubbleEdit.qml index 4b96374..a3666f3 100644 --- a/Modules/Notifications/Sidebar/Chat/Content/BubbleEdit.qml +++ b/Modules/Notifications/Sidebar/Chat/Content/BubbleEdit.qml @@ -10,7 +10,7 @@ TextEditBase { color: Colors.palette.m3onSurface readOnly: true textFormat: Text.MarkdownText - font.pointSize: Tokens.font.size.smaller + font: Tokens.font.body.small wrapMode: Text.WrapAtWordBoundaryOrAnywhere onLinkActivated: link => { diff --git a/Modules/Notifications/Sidebar/Chat/Content/CodeBlockView.qml b/Modules/Notifications/Sidebar/Chat/Content/CodeBlockView.qml index d199797..993c5e8 100644 --- a/Modules/Notifications/Sidebar/Chat/Content/CodeBlockView.qml +++ b/Modules/Notifications/Sidebar/Chat/Content/CodeBlockView.qml @@ -32,8 +32,7 @@ CustomRect { function onHighlightSpans(token, spans) { if (token !== root.highlightToken) return; - if (root.code !== root.requestedCode || - root.language !== root.requestedLanguage) + if (root.code !== root.requestedCode || root.language !== root.requestedLanguage) return; html = spans.length ? root.highlightedHtml(root.code, spans) : ""; colored = root.visible && html.length > 0; @@ -84,15 +83,13 @@ CustomRect { // whitespace kept, mid-line runs collapsed, tabs as single spaces) so the // plain and colored layouts are identical. function plainForDisplay(code): string { - return code.split("\n") - .map(line => { - const i = line.search(/\S/); - if (i < 0) - return ""; - const lead = line.slice(0, i).replace(/\t/g, " "); - return lead + line.slice(i).replace(/\s+/g, " ").replace(/\s+$/, ""); - }) - .join("\n"); + return code.split("\n").map(line => { + const i = line.search(/\S/); + if (i < 0) + return ""; + const lead = line.slice(0, i).replace(/\t/g, " "); + return lead + line.slice(i).replace(/\s+/g, " ").replace(/\s+$/, ""); + }).join("\n"); } function highlightedHtml(code, spans): string { @@ -136,7 +133,7 @@ CustomRect { refreshTimer.restart(); } onVisibleChanged: if (root.visible) - refreshTimer.restart(); + refreshTimer.restart() Timer { id: refreshTimer @@ -223,7 +220,7 @@ CustomRect { Layout.alignment: Qt.AlignVCenter color: root.codeHeaderColor - font.pointSize: Tokens.font.size.small + font: Tokens.font.label.small text: CodeIcons.name(root.language) visible: root.language.length > 0 } @@ -289,8 +286,7 @@ CustomRect { color: CodeColors.active.normal layer.enabled: true clip: false - font.family: Config.appearance.font.family.mono - font.pointSize: Tokens.font.size.small + font: Tokens.font.mono.small textFormat: root.colored ? Text.RichText : Text.PlainText text: root.colored ? root.html : root.plainForDisplay(root.code) readOnly: true diff --git a/Modules/Notifications/Sidebar/Chat/Content/ContentBubble.qml b/Modules/Notifications/Sidebar/Chat/Content/ContentBubble.qml index 86581c4..1c4669c 100644 --- a/Modules/Notifications/Sidebar/Chat/Content/ContentBubble.qml +++ b/Modules/Notifications/Sidebar/Chat/Content/ContentBubble.qml @@ -85,7 +85,7 @@ Item { animateCursor: false color: root.isUser ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface cursor.color: root.isUser ? Colors.palette.m3onPrimary : Colors.palette.m3primary - font.pointSize: Tokens.font.size.smaller + font: Tokens.font.body.small readOnly: true selectionColor: Qt.alpha((root.isUser ? Colors.palette.m3onPrimary : Colors.palette.m3primary), 0.4) text: root.isUser ? root.segment.text : "" diff --git a/Modules/Notifications/Sidebar/Chat/Content/EmptyBackground.qml b/Modules/Notifications/Sidebar/Chat/Content/EmptyBackground.qml index d3370e7..dd251a0 100644 --- a/Modules/Notifications/Sidebar/Chat/Content/EmptyBackground.qml +++ b/Modules/Notifications/Sidebar/Chat/Content/EmptyBackground.qml @@ -5,28 +5,28 @@ import qs.Components import qs.Services ColumnLayout { - id: root + id: root - spacing: Tokens.spacing.small + spacing: Tokens.spacing.small - Item { - Layout.fillHeight: true - } + Item { + Layout.fillHeight: true + } - MaterialIcon { - Layout.alignment: Qt.AlignHCenter - color: Colors.tPalette.m3outlineVariant - font.pointSize: 36 - text: "chat" - } + MaterialIcon { + Layout.alignment: Qt.AlignHCenter + color: Colors.tPalette.m3outlineVariant + fontStyle: Tokens.font.icon.large + text: "chat" + } - CustomText { - Layout.alignment: Qt.AlignHCenter - color: Colors.tPalette.m3onSurfaceVariant - text: qsTr("Send a message to get started") - } + CustomText { + Layout.alignment: Qt.AlignHCenter + color: Colors.tPalette.m3onSurfaceVariant + text: qsTr("Send a message to get started") + } - Item { - Layout.fillHeight: true - } + Item { + Layout.fillHeight: true + } } diff --git a/Modules/Notifications/Sidebar/Chat/Content/ErrorBubble.qml b/Modules/Notifications/Sidebar/Chat/Content/ErrorBubble.qml index 503df55..728b5a9 100644 --- a/Modules/Notifications/Sidebar/Chat/Content/ErrorBubble.qml +++ b/Modules/Notifications/Sidebar/Chat/Content/ErrorBubble.qml @@ -93,7 +93,7 @@ Item { Layout.fillWidth: true - font.pointSize: Tokens.font.size.large + font: Tokens.font.title.large elide: CustomText.ElideRight color: Colors.palette.m3onErrorContainer @@ -120,7 +120,7 @@ Item { isRound: true icon: "close" type: IconButton.Text - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.medium onClicked: exitAnim.start() } diff --git a/Modules/Notifications/Sidebar/Chat/Content/MarkdownBlocks.qml b/Modules/Notifications/Sidebar/Chat/Content/MarkdownBlocks.qml index 32377ad..a81d824 100644 --- a/Modules/Notifications/Sidebar/Chat/Content/MarkdownBlocks.qml +++ b/Modules/Notifications/Sidebar/Chat/Content/MarkdownBlocks.qml @@ -62,13 +62,12 @@ Column { text: modelData.text textFormat: Text.MarkdownText readOnly: true - font.bold: true - font.pointSize: { + font: { if (modelData.level <= 1) - return Tokens.font.size.large; + return Tokens.font.headline.builders.small.weight(Font.Bold).build(); if (modelData.level === 2) - return Tokens.font.size.normal; - return Tokens.font.size.smaller; + return Tokens.font.headline.builders.small.size(18).weight(Font.DemiBold).build(); + return Tokens.font.body.medium; } wrapMode: Text.WrapAtWordBoundaryOrAnywhere } diff --git a/Modules/Notifications/Sidebar/Chat/Content/MathBlockView.qml b/Modules/Notifications/Sidebar/Chat/Content/MathBlockView.qml index b07d49f..73f5b40 100644 --- a/Modules/Notifications/Sidebar/Chat/Content/MathBlockView.qml +++ b/Modules/Notifications/Sidebar/Chat/Content/MathBlockView.qml @@ -39,8 +39,7 @@ Item { anchors.centerIn: parent color: root.mathColor - font.family: Config.appearance.font.family.mono - font.pointSize: Tokens.font.size.small + font: Tokens.font.mono.small text: root.latex wrapMode: Text.WrapAtWordBoundaryOrAnywhere visible: !math.ok diff --git a/Modules/Notifications/Sidebar/Chat/Content/MessageDelegate.qml b/Modules/Notifications/Sidebar/Chat/Content/MessageDelegate.qml index af362f7..dd1d131 100644 --- a/Modules/Notifications/Sidebar/Chat/Content/MessageDelegate.qml +++ b/Modules/Notifications/Sidebar/Chat/Content/MessageDelegate.qml @@ -231,7 +231,7 @@ MouseArea { MaterialIcon { anchors.centerIn: parent - font.pointSize: Tokens.font.size.extraLarge + fontStyle: Tokens.font.icon.large text: thumb.fileIcon(thumb.modelData?.mimeType ?? "") visible: !thumb.modelData?.isImage ?? false } diff --git a/Modules/Notifications/Sidebar/Chat/Content/ProcessBlock.qml b/Modules/Notifications/Sidebar/Chat/Content/ProcessBlock.qml index 70bff51..45bdbc2 100644 --- a/Modules/Notifications/Sidebar/Chat/Content/ProcessBlock.qml +++ b/Modules/Notifications/Sidebar/Chat/Content/ProcessBlock.qml @@ -70,7 +70,7 @@ Item { IconButton { id: expandBtn - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.medium icon: "keyboard_arrow_down" inactiveOnColor: hovered ? Colors.palette.m3onSurface : Colors.palette.m3outline anchors.centerIn: parent @@ -91,7 +91,6 @@ Item { id: collapsedText color: Colors.palette.m3outline - font.pointSize: Tokens.font.size.small Layout.fillWidth: true Layout.leftMargin: Tokens.spacing.medium text: { @@ -139,7 +138,7 @@ Item { CustomText { id: requestHeader text: qsTr("Tool call request") - font.pointSize: Tokens.font.size.large + font: Tokens.font.headline.medium color: Colors.palette.m3onSurface } @@ -420,7 +419,7 @@ Item { IconButton { id: toolExpandBtn - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.medium icon: "keyboard_arrow_down" inactiveOnColor: hovered ? Colors.palette.m3onSurface : Colors.palette.m3outline rotation: toolCall.expanded ? 180 : 0 @@ -609,7 +608,6 @@ Item { anchors.topMargin: Tokens.spacing.small anchors.right: parent.right color: Colors.palette.m3outline - font.pointSize: Tokens.font.size.small wrapMode: CustomText.WrapAtWordBoundaryOrAnywhere text: segment.modelData.type === LlmSegment.Type.Reasoning ? segment.modelData.text : qsTr("%1 %2").arg(content.prettyTool(segment.modelData)).arg(content.toolTarget(segment.modelData)) } diff --git a/Modules/Notifications/Sidebar/Chat/SidebarView.qml b/Modules/Notifications/Sidebar/Chat/SidebarView.qml index 499b669..4458e33 100644 --- a/Modules/Notifications/Sidebar/Chat/SidebarView.qml +++ b/Modules/Notifications/Sidebar/Chat/SidebarView.qml @@ -174,7 +174,7 @@ Item { MaterialIcon { Layout.alignment: Qt.AlignCenter text: "chat_bubble_off" - font.pointSize: Tokens.font.size.extraLarge + fontStyle: Tokens.font.icon.extraLarge color: Colors.tPalette.m3onSurfaceVariant } diff --git a/Modules/Notifications/Sidebar/NotifDock.qml b/Modules/Notifications/Sidebar/NotifDock.qml index 6792807..e0cbdf0 100644 --- a/Modules/Notifications/Sidebar/NotifDock.qml +++ b/Modules/Notifications/Sidebar/NotifDock.qml @@ -37,19 +37,15 @@ Item { anchors.leftMargin: root.notifCount > 0 ? 0 : -width - titleText.anchors.leftMargin anchors.verticalCenter: parent.verticalCenter color: Colors.palette.m3outline - font.family: "CaskaydiaCove NF" - font.pointSize: 13 - font.weight: 500 + font: Tokens.font.label.large opacity: root.notifCount > 0 ? 1 : 0 text: root.notifCount Behavior on anchors.leftMargin { - Anim { - } + Anim {} } Behavior on opacity { - Anim { - } + Anim {} } } @@ -62,9 +58,7 @@ Item { anchors.verticalCenter: parent.verticalCenter color: Colors.palette.m3outline elide: Text.ElideRight - font.family: "CaskaydiaCove NF" - font.pointSize: 13 - font.weight: 500 + font: Tokens.font.label.large text: root.notifCount > 0 ? qsTr("notification%1").arg(root.notifCount === 1 ? "" : "s") : qsTr("Notifications") } } @@ -86,8 +80,7 @@ Item { opacity: root.notifCount > 0 ? 0 : 1 Behavior on opacity { - Anim { - } + Anim {} } sourceComponent: ColumnLayout { spacing: 20 @@ -95,9 +88,7 @@ Item { CustomText { Layout.alignment: Qt.AlignHCenter color: Colors.palette.m3outlineVariant - font.family: "CaskaydiaCove NF" - font.pointSize: 18 - font.weight: 500 + font: Tokens.font.headline.builders.small.width(90).build() text: qsTr("No Notifications") } } @@ -160,20 +151,17 @@ Item { scale: root.notifCount > 0 ? 1 : 0.5 Behavior on opacity { - Anim { - } + Anim {} } Behavior on scale { - Anim { - } + Anim {} } sourceComponent: IconButton { id: clearBtn - font.pointSize: Math.round(18 * 1.2) + font: Tokens.font.icon.large icon: "clear_all" - padding: 8 - radius: Tokens.rounding.full + isRound: true onClicked: clearTimer.start() diff --git a/Modules/Notifications/Sidebar/Tabs.qml b/Modules/Notifications/Sidebar/Tabs.qml index 09b6f77..5cfa192 100644 --- a/Modules/Notifications/Sidebar/Tabs.qml +++ b/Modules/Notifications/Sidebar/Tabs.qml @@ -62,12 +62,10 @@ Item { } Behavior on implicitWidth { - Anim { - } + Anim {} } Behavior on x { - Anim { - } + Anim {} } CustomRect { @@ -120,12 +118,11 @@ Item { anchors.horizontalCenter: parent.horizontalCenter color: tab.current ? Colors.palette.m3primary : Colors.palette.m3onSurfaceVariant fill: tab.current ? 1 : 0 - font.pointSize: 18 + fontStyle: Tokens.font.icon.medium text: tab.iconName Behavior on fill { - Anim { - } + Anim {} } } diff --git a/Modules/Notifications/Sidebar/Utils/Cards/Record.qml b/Modules/Notifications/Sidebar/Utils/Cards/Record.qml index 0f90322..5094d86 100644 --- a/Modules/Notifications/Sidebar/Utils/Cards/Record.qml +++ b/Modules/Notifications/Sidebar/Utils/Cards/Record.qml @@ -13,7 +13,6 @@ CustomRect { required property ScreenState screenState - Layout.fillWidth: true color: Colors.tPalette.m3surfaceContainer implicitHeight: layout.implicitHeight + layout.anchors.margins * 2 @@ -46,7 +45,7 @@ CustomRect { anchors.horizontalCenterOffset: -0.5 anchors.verticalCenterOffset: 1.5 color: Recorder.running ? Colors.palette.m3onSecondary : Colors.palette.m3onSecondaryContainer - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.large text: "screen_record" } } @@ -58,7 +57,7 @@ CustomRect { CustomText { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.medium text: qsTr("Screen Recorder") } @@ -66,7 +65,7 @@ CustomRect { Layout.fillWidth: true color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small text: Recorder.paused ? qsTr("Recording paused") : Recorder.running ? qsTr("Recording running") : qsTr("Recording off") } } @@ -126,8 +125,7 @@ CustomRect { enabled: false - Anim { - } + Anim {} } Behavior on running { SequentialAnimation { @@ -155,8 +153,7 @@ CustomRect { value: true } - PropertyAction { - } + PropertyAction {} PropertyAction { property: "enabled" @@ -207,8 +204,7 @@ CustomRect { radius: Tokens.rounding.full Behavior on implicitWidth { - Anim { - } + Anim {} } SequentialAnimation on opacity { alwaysRunToEnd: true @@ -236,13 +232,13 @@ CustomRect { anchors.centerIn: parent animate: true color: Recorder.paused ? Colors.palette.m3onTertiary : Colors.palette.m3onError - font.family: Config.appearance.font.family.mono + font: Tokens.font.mono.small text: Recorder.paused ? "PAUSED" : "REC" } } CustomText { - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.medium text: { const elapsed = Recorder.elapsed; @@ -266,8 +262,9 @@ CustomRect { IconButton { checked: Recorder.paused - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.medium icon: Recorder.paused ? "play_arrow" : "pause" + isRound: true isToggle: true label.animate: true type: IconButton.Tonal @@ -279,8 +276,9 @@ CustomRect { } IconButton { - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.medium icon: "stop" + isRound: true inactiveColor: Colors.palette.m3error inactiveOnColor: Colors.palette.m3onError diff --git a/Modules/Notifications/Sidebar/Utils/Cards/RecordingList.qml b/Modules/Notifications/Sidebar/Utils/Cards/RecordingList.qml index 4222414..31fb5cf 100644 --- a/Modules/Notifications/Sidebar/Utils/Cards/RecordingList.qml +++ b/Modules/Notifications/Sidebar/Utils/Cards/RecordingList.qml @@ -16,7 +16,6 @@ ColumnLayout { required property ScreenState screenState - spacing: 0 WrapperMouseArea { @@ -30,14 +29,14 @@ ColumnLayout { MaterialIcon { Layout.alignment: Qt.AlignVCenter - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.large text: "list" } CustomText { Layout.alignment: Qt.AlignVCenter Layout.fillWidth: true - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.medium text: qsTr("Recordings") } @@ -176,7 +175,7 @@ ColumnLayout { Layout.alignment: Qt.AlignHCenter Layout.preferredHeight: root.screenState.recordingListExpanded ? implicitHeight : 0 color: Colors.palette.m3outline - font.pointSize: Tokens.font.size.extraLarge + fontStyle: Tokens.font.icon.extraLarge opacity: root.screenState.recordingListExpanded ? 1 : 0 scale: root.screenState.recordingListExpanded ? 1 : 0 text: "scan_delete" diff --git a/Modules/Notifications/Sidebar/Utils/Cards/Toggles.qml b/Modules/Notifications/Sidebar/Utils/Cards/Toggles.qml index 60c24a9..fe80745 100644 --- a/Modules/Notifications/Sidebar/Utils/Cards/Toggles.qml +++ b/Modules/Notifications/Sidebar/Utils/Cards/Toggles.qml @@ -53,7 +53,7 @@ CustomRect { spacing: Tokens.spacing.medium CustomText { - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.medium text: qsTr("Quick Toggles") } diff --git a/Modules/Notifications/Sidebar/Utils/IdleInhibit.qml b/Modules/Notifications/Sidebar/Utils/IdleInhibit.qml index ae190e1..7cb4b6e 100644 --- a/Modules/Notifications/Sidebar/Utils/IdleInhibit.qml +++ b/Modules/Notifications/Sidebar/Utils/IdleInhibit.qml @@ -15,8 +15,7 @@ CustomRect { radius: Tokens.rounding.small Behavior on implicitHeight { - Anim { - } + Anim {} } RowLayout { @@ -39,7 +38,7 @@ CustomRect { anchors.centerIn: parent color: IdleInhibitor.enabled ? Colors.palette.m3onSecondary : Colors.palette.m3onSecondaryContainer - font.pointSize: 18 + fontStyle: Tokens.font.icon.large text: "coffee" } } @@ -51,7 +50,7 @@ CustomRect { CustomText { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: 13 + font: Tokens.font.body.medium text: qsTr("Keep Awake") } @@ -59,7 +58,7 @@ CustomRect { Layout.fillWidth: true color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight - font.pointSize: 11 + font: Tokens.font.body.small text: IdleInhibitor.enabled ? qsTr("Preventing sleep mode") : qsTr("Normal power management") } } @@ -83,16 +82,13 @@ CustomRect { scale: IdleInhibitor.enabled ? 1 : 0.5 Behavior on anchors.bottomMargin { - Anim { - } + Anim {} } Behavior on opacity { - Anim { - } + Anim {} } Behavior on scale { - Anim { - } + Anim {} } sourceComponent: CustomRect { color: Colors.palette.m3primary @@ -105,7 +101,7 @@ CustomRect { anchors.centerIn: parent color: Colors.palette.m3onPrimary - font.pointSize: Math.round(11 * 0.9) + font: Tokens.font.body.builders.small.size(Math.round(Tokens.font.body.small.pointSize * 0.9)).build() text: qsTr("Active since %1").arg(Qt.formatTime(IdleInhibitor.enabledSince, Config.services.useTwelveHourClock ? "hh:mm a" : "hh:mm")) } } diff --git a/Modules/Polkit/Polkit.qml b/Modules/Polkit/Polkit.qml index 7bff94e..c598cd5 100644 --- a/Modules/Polkit/Polkit.qml +++ b/Modules/Polkit/Polkit.qml @@ -112,7 +112,7 @@ Scope { MaterialIcon { anchors.fill: parent - font.pointSize: 64 + fontStyle: Tokens.font.icon.size(64).build() horizontalAlignment: Text.AlignHCenter text: "security" verticalAlignment: Text.AlignVCenter @@ -129,8 +129,7 @@ Scope { CustomText { Layout.alignment: Qt.AlignLeft Layout.preferredWidth: Math.min(600, contentWidth) - font.bold: true - font.pointSize: 16 + font: Tokens.font.title.builders.medium.weight(Font.Bold).build() text: polkitAgent.flow?.message ?? "" wrapMode: Text.WordWrap } @@ -139,8 +138,7 @@ Scope { Layout.alignment: Qt.AlignLeft Layout.preferredWidth: Math.min(600, contentWidth) color: Colors.tPalette.m3onSurfaceVariant - font.bold: true - font.pointSize: 12 + font: Tokens.font.title.builders.small.weight(Font.Bold).build() text: polkitAgent.flow?.supplementaryMessage || "No Additional Information" wrapMode: Text.WordWrap } @@ -155,6 +153,7 @@ Scope { placeholderText: polkitAgent.flow?.failed ? " Incorrect Password" : " Input Password" placeholderTextColor: polkitAgent.flow?.failed ? Colors.palette.m3onError : Colors.tPalette.m3onSurfaceVariant selectByMouse: true + font: Tokens.font.body.small background: CustomRect { color: (polkitAgent.flow?.failed && passInput.text === "") ? Colors.palette.m3error : Colors.tPalette.m3surfaceVariant @@ -342,8 +341,7 @@ Scope { visible: panelWindow.visible Behavior on color { - CAnim { - } + CAnim {} } anchors { diff --git a/Modules/Resources/Cards/HeroCard.qml b/Modules/Resources/Cards/HeroCard.qml index 668a329..2b488de 100644 --- a/Modules/Resources/Cards/HeroCard.qml +++ b/Modules/Resources/Cards/HeroCard.qml @@ -27,8 +27,7 @@ CustomClippingRect { implicitWidth: parent.width * root.usage Behavior on implicitWidth { - Anim { - } + Anim {} } } @@ -45,8 +44,7 @@ CustomClippingRect { value: root.usage Behavior on clampedVal { - Anim { - } + Anim {} } MaterialIcon { @@ -54,7 +52,7 @@ CustomClippingRect { anchors.centerIn: parent color: root.accent - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.large text: root.icon } } @@ -125,15 +123,14 @@ CustomClippingRect { anchors.right: parent.right color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.medium text: qsTr("Usage") } CustomText { anchors.right: parent.right color: root.accent - font.pointSize: Tokens.font.size.extraLarge - font.weight: Font.Medium + font: Tokens.font.headline.builders.small.width(50).build() text: isNaN(root.usage) ? "...%" : Math.round(root.usage * 100) + "%" } } diff --git a/Modules/Resources/Cards/MemoryCard.qml b/Modules/Resources/Cards/MemoryCard.qml index 168663d..bb56af0 100644 --- a/Modules/Resources/Cards/MemoryCard.qml +++ b/Modules/Resources/Cards/MemoryCard.qml @@ -51,8 +51,7 @@ CustomRect { value: Memory.percentage Behavior on clampedVal { - Anim { - } + Anim {} } ColumnLayout { @@ -65,7 +64,7 @@ CustomRect { CustomText { Layout.alignment: Qt.AlignHCenter color: root.accent - font.pointSize: Tokens.font.size.large + font: Tokens.font.body.large text: Math.round(Memory.percentage * 100) + "%" } diff --git a/Modules/Resources/Cards/StorageCard.qml b/Modules/Resources/Cards/StorageCard.qml index 238bed7..83b4ecc 100644 --- a/Modules/Resources/Cards/StorageCard.qml +++ b/Modules/Resources/Cards/StorageCard.qml @@ -43,8 +43,7 @@ CustomRect { value: root.percentage Behavior on clampedVal { - Anim { - } + Anim {} } ColumnLayout { @@ -56,14 +55,14 @@ CustomRect { MaterialIcon { Layout.alignment: Qt.AlignHCenter color: root.accent - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.large text: "hard_drive" } CustomText { Layout.alignment: Qt.AlignHCenter color: root.accent - font.pointSize: Tokens.font.size.large + font: Tokens.font.body.large text: Math.round(root.percentage * 100) + "%" } @@ -112,8 +111,7 @@ CustomRect { model: Storage.disks - DiskItem { - } + DiskItem {} } } } diff --git a/Modules/Resources/Cards/VramCard.qml b/Modules/Resources/Cards/VramCard.qml index 789bc39..034f00f 100644 --- a/Modules/Resources/Cards/VramCard.qml +++ b/Modules/Resources/Cards/VramCard.qml @@ -53,8 +53,7 @@ CustomRect { value: Gpu.memoryUsed / Gpu.memoryTotal Behavior on clampedVal { - Anim { - } + Anim {} } ColumnLayout { @@ -67,7 +66,7 @@ CustomRect { CustomText { Layout.alignment: Qt.AlignHCenter color: root.accent - font.pointSize: Tokens.font.size.large + font: Tokens.font.body.large text: Math.round(circularIndicator.value * 100) + "%" } diff --git a/Modules/Settings/Common/AudioDeviceList.qml b/Modules/Settings/Common/AudioDeviceList.qml index febdd2a..d0d21bb 100644 --- a/Modules/Settings/Common/AudioDeviceList.qml +++ b/Modules/Settings/Common/AudioDeviceList.qml @@ -60,12 +60,11 @@ ItemList { anchors.centerIn: parent color: device.active ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondaryContainer fill: device.active ? 1 : 0 - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.medium text: root.iconName Behavior on fill { - Anim { - } + Anim {} } } } @@ -73,13 +72,13 @@ ItemList { CustomText { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Tokens.font.size.smaller + font: Tokens.font.body.small text: device.modelData?.description || device.modelData?.name || qsTr("Unknown") } MaterialIcon { color: Colors.palette.m3primary - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.medium opacity: device.active ? 1 : 0 text: "check" diff --git a/Modules/Settings/Common/BlobPopup.qml b/Modules/Settings/Common/BlobPopup.qml index 1978d10..bad56b1 100644 --- a/Modules/Settings/Common/BlobPopup.qml +++ b/Modules/Settings/Common/BlobPopup.qml @@ -35,8 +35,7 @@ Item { smoothing: Tokens.rounding.largeIncreased Behavior on color { - CAnim { - } + CAnim {} } } @@ -49,8 +48,7 @@ Item { radius: root.open ? Tokens.rounding.largeIncreased : Tokens.rounding.largeIncreased Behavior on anchors.margins { - Anim { - } + Anim {} } Behavior on radius { Anim { @@ -122,7 +120,7 @@ Item { anchors.centerIn: parent color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.normal + fontStyle: Tokens.font.icon.medium text: "view_apps" } } diff --git a/Modules/Settings/Common/DialogRowButton.qml b/Modules/Settings/Common/DialogRowButton.qml index 805682c..dba32d1 100644 --- a/Modules/Settings/Common/DialogRowButton.qml +++ b/Modules/Settings/Common/DialogRowButton.qml @@ -186,7 +186,7 @@ Item { spacing: 0 CustomText { - font.pointSize: Tokens.font.size.large + font: Tokens.font.title.builders.large.weight(Font.Normal).build() text: root.header } diff --git a/Modules/Settings/Common/DialogSelectButton.qml b/Modules/Settings/Common/DialogSelectButton.qml index d8cb270..b10de33 100644 --- a/Modules/Settings/Common/DialogSelectButton.qml +++ b/Modules/Settings/Common/DialogSelectButton.qml @@ -66,7 +66,6 @@ DialogRowButton { anchors.verticalCenter: parent.verticalCenter color: item.selected ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurface elide: Text.ElideRight - font.pointSize: Tokens.font.size.smaller text: root.labelFor(item.modelData) } @@ -77,7 +76,7 @@ DialogRowButton { anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter color: Colors.palette.m3onTertiaryContainer - font.pointSize: Tokens.font.size.normal + fontStyle: Tokens.font.icon.medium opacity: item.selected ? 1 : 0 text: "check" diff --git a/Modules/Settings/Common/InfoRow.qml b/Modules/Settings/Common/InfoRow.qml index 0cec60b..63f510d 100644 --- a/Modules/Settings/Common/InfoRow.qml +++ b/Modules/Settings/Common/InfoRow.qml @@ -24,7 +24,7 @@ ConnectedRect { MaterialIcon { color: root.iconColor - font.pointSize: Tokens.font.size.small + fontStyle: Tokens.font.icon.small text: root.icon } } @@ -53,14 +53,14 @@ ConnectedRect { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small } CustomText { Layout.fillWidth: true color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.label.small text: root.subtext visible: root.subtext } @@ -72,7 +72,7 @@ ConnectedRect { Layout.maximumWidth: root.width / 2 color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small horizontalAlignment: Text.AlignRight } } diff --git a/Modules/Settings/Common/ItemList.qml b/Modules/Settings/Common/ItemList.qml index b5fcd41..d32f678 100644 --- a/Modules/Settings/Common/ItemList.qml +++ b/Modules/Settings/Common/ItemList.qml @@ -23,8 +23,7 @@ ConnectedRect { implicitHeight: (showList && list.count > 0 ? list.contentHeight : placeholder.implicitHeight + Tokens.padding.extraLarge * 2) + extraHeight Behavior on implicitHeight { - Anim { - } + Anim {} } Loader { @@ -46,7 +45,7 @@ ConnectedRect { Layout.alignment: Qt.AlignHCenter animate: true color: Colors.palette.m3outline - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.large text: root.placeholderIcon } @@ -54,7 +53,7 @@ ConnectedRect { Layout.alignment: Qt.AlignHCenter animate: true color: Colors.palette.m3outline - font.pointSize: Tokens.font.size.large + font: Tokens.font.body.large text: root.placeholderText } } diff --git a/Modules/Settings/Common/ListEditor.qml b/Modules/Settings/Common/ListEditor.qml index e9e7705..9685068 100644 --- a/Modules/Settings/Common/ListEditor.qml +++ b/Modules/Settings/Common/ListEditor.qml @@ -54,14 +54,12 @@ ListView { } } Behavior on implicitHeight { - Anim { - } + Anim {} } model: DelegateModel { id: visualModel - delegate: ListRow { - } + delegate: ListRow {} model: ScriptModel { id: valuesModel } @@ -280,7 +278,7 @@ ListView { id: dragIcon color: Qt.alpha(Colors.palette.m3onSurfaceVariant, enabledSwitch.checked ? 1 : 0.5) - font.pointSize: Tokens.font.size.normal + fontStyle: Tokens.font.icon.medium text: "drag_indicator" } @@ -290,7 +288,6 @@ ListView { Layout.fillWidth: true color: Qt.alpha(Colors.palette.m3onSurface, enabledSwitch.checked ? 1 : 0.5) elide: Text.ElideRight - font.pointSize: Tokens.font.size.smaller text: root.labelFor(item.modelData) } @@ -298,13 +295,13 @@ ListView { id: enabledSwitch checked: root.toggledFor(item.modelData) - font.pointSize: Tokens.font.size.normal + font: Tokens.font.icon.medium onToggled: root.itemToggled(item.DelegateModel.itemsIndex, checked) } IconButton { - font.pointSize: Tokens.font.size.large + font: Tokens.font.icon.medium icon: "delete" inactiveOnColor: Colors.palette.m3error isRound: true diff --git a/Modules/Settings/Common/NavRow.qml b/Modules/Settings/Common/NavRow.qml index a496c53..7d0ca3a 100644 --- a/Modules/Settings/Common/NavRow.qml +++ b/Modules/Settings/Common/NavRow.qml @@ -1,71 +1,8 @@ pragma ComponentBehavior: Bound import QtQuick -import QtQuick.Layouts -import qs.Components -import ZShell.Config -import qs.Services -ConnectedRect { - id: root - - property alias icon: icon.text - property alias status: status.text - property alias text: label.text - - signal clicked - - Layout.fillWidth: true - implicitHeight: navLayout.implicitHeight + navLayout.anchors.margins * 2 - - StateLayer { - onClicked: root.clicked() - } - - RowLayout { - id: navLayout - - anchors.fill: parent - anchors.leftMargin: Tokens.padding.largeIncreased - anchors.margins: Tokens.padding.small - anchors.rightMargin: Tokens.padding.largeIncreased - spacing: Tokens.spacing.medium - - MaterialIcon { - id: icon - - color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.large - } - - ColumnLayout { - Layout.fillWidth: true - spacing: 0 - - CustomText { - id: label - - Layout.fillWidth: true - elide: Text.ElideRight - font.pointSize: Tokens.font.size.small - } - - CustomText { - id: status - - Layout.fillWidth: true - animate: true - color: Colors.palette.m3outline - elide: Text.ElideRight - font.pointSize: Tokens.font.size.small - visible: text - } - } - - MaterialIcon { - color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.normal - text: "chevron_right" - } - } +RowButton { + trailingIcon: "chevron_right" + subLabel.animate: true } diff --git a/Modules/Settings/Common/PageBase.qml b/Modules/Settings/Common/PageBase.qml index 6fec5f8..991fde1 100644 --- a/Modules/Settings/Common/PageBase.qml +++ b/Modules/Settings/Common/PageBase.qml @@ -134,6 +134,7 @@ ColumnLayout { inactiveOnColor: Colors.palette.m3onSurfaceVariant isRound: true type: IconButton.Tonal + font: Tokens.font.icon.medium onClicked: root.sState.closeSubPage() } @@ -142,7 +143,7 @@ ColumnLayout { CustomText { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Tokens.font.size.large + font: Tokens.font.title.large text: root.title } } diff --git a/Modules/Settings/Common/PopupRow.qml b/Modules/Settings/Common/PopupRow.qml index 3e7394f..0b3a22a 100644 --- a/Modules/Settings/Common/PopupRow.qml +++ b/Modules/Settings/Common/PopupRow.qml @@ -40,7 +40,7 @@ ConnectedRect { id: icon color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.larger + fontStyle: Tokens.font.icon.medium } ColumnLayout { @@ -52,7 +52,7 @@ ConnectedRect { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small } CustomText { @@ -62,7 +62,7 @@ ConnectedRect { animate: true color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.label.small visible: text } } diff --git a/Modules/Settings/Common/RowButton.qml b/Modules/Settings/Common/RowButton.qml index 50d1c3d..419fae8 100644 --- a/Modules/Settings/Common/RowButton.qml +++ b/Modules/Settings/Common/RowButton.qml @@ -51,7 +51,7 @@ ConnectedRect { visible: root.icon !== "" fill: 1 text: root.icon - font.pointSize: Tokens.font.size.normal + fontStyle: Tokens.font.icon.medium } Column { @@ -66,7 +66,6 @@ ConnectedRect { anchors.left: parent.left anchors.right: parent.right elide: Text.ElideRight - font.pointSize: Tokens.font.size.small } CustomText { @@ -76,7 +75,7 @@ ConnectedRect { anchors.right: parent.right color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.label.small visible: text } } @@ -108,7 +107,7 @@ ConnectedRect { sourceComponent: MaterialIcon { color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.normal + fontStyle: Tokens.font.icon.medium text: root.trailingIcon } } diff --git a/Modules/Settings/Common/SearchPopup.qml b/Modules/Settings/Common/SearchPopup.qml index 193fd1a..4bfc086 100644 --- a/Modules/Settings/Common/SearchPopup.qml +++ b/Modules/Settings/Common/SearchPopup.qml @@ -70,7 +70,6 @@ DialogRowButton { anchors.verticalCenter: parent.verticalCenter color: item.selected ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurface elide: Text.ElideRight - font.pointSize: Tokens.font.size.smaller text: item.modelData } @@ -81,7 +80,7 @@ DialogRowButton { anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter color: Colors.palette.m3onTertiaryContainer - font.pointSize: Tokens.font.size.normal + fontStyle: Tokens.font.icon.medium opacity: item.selected ? 1 : 0 text: "check" @@ -100,12 +99,12 @@ DialogRowButton { Layout.fillWidth: true bg.border.color: Colors.palette.m3outlineVariant bg.color: Colors.tPalette.m3surfaceContainerLowest - clearIcon.font.pointSize: Tokens.font.size.large + clearIcon.font: Tokens.font.icon.medium clearIcon.padding: Tokens.padding.extraSmall - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small placeholderText: qsTr("Search...") searchIcon.anchors.leftMargin: Tokens.padding.large - searchIcon.font.pointSize: Tokens.font.size.large + searchIcon.fontStyle: Tokens.font.icon.medium Behavior on bg.border.color { CAnim {} diff --git a/Modules/Settings/Common/SectionHeader.qml b/Modules/Settings/Common/SectionHeader.qml index 0433f65..b826399 100644 --- a/Modules/Settings/Common/SectionHeader.qml +++ b/Modules/Settings/Common/SectionHeader.qml @@ -13,5 +13,5 @@ CustomText { Layout.topMargin: first ? 0 : Tokens.spacing.largeIncreased - ((parent as ColumnLayout).spacing ?? 0) color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight - font.pointSize: Tokens.font.size.normal + font: Tokens.font.label.medium } diff --git a/Modules/Settings/Common/SelectRow.qml b/Modules/Settings/Common/SelectRow.qml index 0689182..ce97cad 100644 --- a/Modules/Settings/Common/SelectRow.qml +++ b/Modules/Settings/Common/SelectRow.qml @@ -40,14 +40,14 @@ ConnectedRect { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Tokens.font.size.smaller + font: Tokens.font.body.small } CustomText { Layout.fillWidth: true color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.label.small text: root.subtext visible: root.subtext } diff --git a/Modules/Settings/Common/SliderRow.qml b/Modules/Settings/Common/SliderRow.qml index d4669ea..10c69b1 100644 --- a/Modules/Settings/Common/SliderRow.qml +++ b/Modules/Settings/Common/SliderRow.qml @@ -40,14 +40,14 @@ ConnectedRect { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small } CustomText { id: valueLabel color: Colors.palette.m3outline - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small } } diff --git a/Modules/Settings/Common/SpinRow.qml b/Modules/Settings/Common/SpinRow.qml index 93c9d13..429d4d1 100644 --- a/Modules/Settings/Common/SpinRow.qml +++ b/Modules/Settings/Common/SpinRow.qml @@ -39,14 +39,14 @@ ConnectedRect { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Tokens.font.size.smaller + font: Tokens.font.body.small } CustomText { Layout.fillWidth: true color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.label.small text: root.subtext visible: root.subtext } diff --git a/Modules/Settings/Common/TextFieldRow.qml b/Modules/Settings/Common/TextFieldRow.qml index 38dd9a8..32ec8a4 100644 --- a/Modules/Settings/Common/TextFieldRow.qml +++ b/Modules/Settings/Common/TextFieldRow.qml @@ -62,7 +62,6 @@ ConnectedRect { visible: root.subtext text: input.isError && root.errorText ? root.errorText : root.subtext color: input.isError && root.errorText ? Colors.palette.m3error : Colors.palette.m3outline - font.pointSize: Tokens.font.size.small elide: Text.ElideRight animate: root.errorText } diff --git a/Modules/Settings/Common/TimeDialogRow.qml b/Modules/Settings/Common/TimeDialogRow.qml index 79d6035..96b2115 100644 --- a/Modules/Settings/Common/TimeDialogRow.qml +++ b/Modules/Settings/Common/TimeDialogRow.qml @@ -190,7 +190,7 @@ Item { spacing: 0 CustomText { - font.pointSize: Tokens.font.size.large + font: Tokens.font.title.builders.large.weight(Font.Normal).build() text: root.header } diff --git a/Modules/Settings/Common/TimeDialogToggle.qml b/Modules/Settings/Common/TimeDialogToggle.qml index 0cd1555..98eab9d 100644 --- a/Modules/Settings/Common/TimeDialogToggle.qml +++ b/Modules/Settings/Common/TimeDialogToggle.qml @@ -34,14 +34,14 @@ ConnectedRect { CustomText { id: text - font.pointSize: Tokens.font.size.smaller + font: Tokens.font.body.small } CustomText { id: subtext color: Colors.palette.m3outline - font.pointSize: Tokens.font.size.small + font: Tokens.font.label.small wrapMode: Text.WordWrap } } diff --git a/Modules/Settings/Common/TimeInput.qml b/Modules/Settings/Common/TimeInput.qml index c8bfd2b..f01100f 100644 --- a/Modules/Settings/Common/TimeInput.qml +++ b/Modules/Settings/Common/TimeInput.qml @@ -137,7 +137,7 @@ ColumnLayout { CustomText { id: startSeparator - font.pointSize: Tokens.font.size.extraLarge + font: Tokens.font.body.builders.large.size(28).weight(Font.DemiBold).build() text: ":" } @@ -360,7 +360,7 @@ ColumnLayout { CustomText { id: endSeparator - font.pointSize: Tokens.font.size.extraLarge + font: Tokens.font.body.builders.large.size(28).weight(Font.DemiBold).build() text: ":" } diff --git a/Modules/Settings/Common/ToggleRow.qml b/Modules/Settings/Common/ToggleRow.qml index 36fb583..2eea3f5 100644 --- a/Modules/Settings/Common/ToggleRow.qml +++ b/Modules/Settings/Common/ToggleRow.qml @@ -20,6 +20,7 @@ CustomSwitch { Layout.fillWidth: true cLayer: 2 + font: Tokens.font.body.small horizontalPadding: Tokens.padding.largeIncreased implicitHeight: Math.max(implicitContentHeight, implicitIndicatorHeight) + verticalPadding * 2 implicitWidth: implicitContentWidth + implicitIndicatorWidth + horizontalPadding * 2 @@ -59,7 +60,7 @@ CustomSwitch { anchors.left: parent.left anchors.right: parent.right elide: Text.ElideRight - font.pointSize: Tokens.font.size.smaller + font: root.font opacity: root.enabled ? 1 : 0.5 text: root.text @@ -75,7 +76,7 @@ CustomSwitch { anchors.right: parent.right color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.label.small opacity: root.enabled ? 1 : 0.5 text: root.subtext visible: root.subtext diff --git a/Modules/Settings/NavPane.qml b/Modules/Settings/NavPane.qml index e802071..820e3e3 100644 --- a/Modules/Settings/NavPane.qml +++ b/Modules/Settings/NavPane.qml @@ -18,16 +18,15 @@ ColumnLayout { Layout.fillWidth: true bg.border.color: Colors.palette.m3outlineVariant bg.color: Colors.tPalette.m3surfaceContainerLowest - clearIcon.font.pointSize: Tokens.font.size.large + clearIcon.font: Tokens.font.icon.medium clearIcon.padding: Tokens.padding.extraSmall - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.large placeholderText: qsTr("Search settings") searchIcon.anchors.leftMargin: Tokens.padding.largeIncreased - searchIcon.font.pointSize: Tokens.font.size.large + searchIcon.fontStyle: Tokens.font.icon.medium Behavior on bg.border.color { - CAnim { - } + CAnim {} } Binding { diff --git a/Modules/Settings/NavPane/NavLocations.qml b/Modules/Settings/NavPane/NavLocations.qml index ed50d33..a73378d 100644 --- a/Modules/Settings/NavPane/NavLocations.qml +++ b/Modules/Settings/NavPane/NavLocations.qml @@ -103,7 +103,7 @@ VerticalFadeFlickable { anchors.fill: parent anchors.margins: Tokens.padding.large - spacing: Tokens.spacing.small + spacing: Tokens.spacing.medium CustomRect { Layout.bottomMargin: -1 @@ -118,7 +118,7 @@ VerticalFadeFlickable { anchors.verticalCenterOffset: 1 color: item.isCurrentPage ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondaryContainer fill: item.modelData.noFill ? 0 : 1 - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.builders.medium.weight(Font.Medium).build() grade: 25 text: item.modelData.icon } @@ -131,6 +131,7 @@ VerticalFadeFlickable { CustomText { Layout.fillWidth: true elide: Text.ElideRight + font: Tokens.font.body.medium text: item.modelData.name } @@ -138,6 +139,7 @@ VerticalFadeFlickable { Layout.fillWidth: true color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight + font: Tokens.font.label.small text: item.modelData.description } } @@ -194,7 +196,7 @@ VerticalFadeFlickable { MaterialIcon { color: Colors.palette.m3primary fill: 1 - font.pointSize: Tokens.font.size.large + fontStyle: Tokens.font.icon.builders.medium.weight(Font.Medium).build() text: group.modelData.icon } @@ -202,7 +204,7 @@ VerticalFadeFlickable { Layout.fillWidth: true color: Colors.palette.m3secondary elide: Text.ElideRight - font.pointSize: Tokens.font.size.large + font: Tokens.font.body.large text: group.modelData.page } } @@ -275,7 +277,7 @@ VerticalFadeFlickable { Layout.fillWidth: true color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.label.small text: { const labels = result.modelData.crumbLabels.slice(1); const section = result.modelData.section; @@ -289,7 +291,6 @@ VerticalFadeFlickable { Layout.fillWidth: true color: Colors.palette.m3onSurface elide: Text.ElideRight - font.pointSize: Tokens.font.size.normal text: SettingsSearcher.highlight(result.modelData.title, root.search, Colors.palette.m3primary) textFormat: text.includes(" 0 @@ -310,10 +311,10 @@ VerticalFadeFlickable { z: 1 - onClicked: { - const target = result.modelData.targetSubPath; - root.sState.jumpToSetting(result.modelData.pageIdx, target.length > 0 ? target : result.modelData.subPath, target.length > 0 ? "" : result.modelData.anchor); - } + onClicked: { + const target = result.modelData.targetSubPath; + root.sState.jumpToSetting(result.modelData.pageIdx, target.length > 0 ? target : result.modelData.subPath, target.length > 0 ? "" : result.modelData.anchor); + } } CustomSwitch { @@ -342,7 +343,6 @@ VerticalFadeFlickable { Layout.fillWidth: true Layout.topMargin: Tokens.padding.large color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.normal horizontalAlignment: Text.AlignHCenter text: qsTr("No matching settings") visible: root.searching && root.results.length === 0 diff --git a/Modules/Settings/PageCompRegistry.qml b/Modules/Settings/PageCompRegistry.qml index ee45aba..591e7e1 100644 --- a/Modules/Settings/PageCompRegistry.qml +++ b/Modules/Settings/PageCompRegistry.qml @@ -165,7 +165,7 @@ QtObject { MaterialIcon { Layout.alignment: Qt.AlignHCenter color: Colors.palette.m3outlineVariant - font.pointSize: Tokens.font.size.extraLarge + fontStyle: Tokens.font.icon.extraLarge text: "handyman" } diff --git a/Modules/Settings/Pages/AboutPage.qml b/Modules/Settings/Pages/AboutPage.qml index 1fae077..53bc19e 100644 --- a/Modules/Settings/Pages/AboutPage.qml +++ b/Modules/Settings/Pages/AboutPage.qml @@ -56,14 +56,14 @@ PageBase { CustomText { Layout.alignment: Qt.AlignHCenter Layout.topMargin: Tokens.spacing.small - font.pointSize: Tokens.font.size.large + font: Tokens.font.headline.large text: "ZShell" } CustomText { Layout.alignment: Qt.AlignHCenter color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.medium text: ZUtils.version ? `v${ZUtils.version}` : "…" } } diff --git a/Modules/Settings/Pages/Apps/AllApps.qml b/Modules/Settings/Pages/Apps/AllApps.qml index dc05f73..0dde289 100644 --- a/Modules/Settings/Pages/Apps/AllApps.qml +++ b/Modules/Settings/Pages/Apps/AllApps.qml @@ -67,7 +67,7 @@ PageBase { CustomText { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small text: appItem.modelData.name } @@ -75,7 +75,7 @@ PageBase { Layout.fillWidth: true color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.label.small text: (appItem.modelData.comment || appItem.modelData.genericName) ?? "" visible: text } @@ -84,14 +84,14 @@ PageBase { MaterialIcon { color: Colors.palette.m3primary fill: 1 - font.pointSize: Tokens.font.size.small + fontStyle: Tokens.font.icon.small text: "favorite" visible: Strings.testRegexList(Config.launcher.favoriteApps, appItem.modelData.id) } MaterialIcon { color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.normal + fontStyle: Tokens.font.icon.medium text: "chevron_right" } } diff --git a/Modules/Settings/Pages/Apps/AppInfo.qml b/Modules/Settings/Pages/Apps/AppInfo.qml index b3273f4..333a880 100644 --- a/Modules/Settings/Pages/Apps/AppInfo.qml +++ b/Modules/Settings/Pages/Apps/AppInfo.qml @@ -57,7 +57,7 @@ PageBase { CustomText { Layout.fillWidth: true - font.pointSize: Tokens.font.size.normal + font: Tokens.font.body.medium text: root.app?.name ?? "" wrapMode: Text.WordWrap } @@ -65,7 +65,7 @@ PageBase { CustomText { Layout.fillWidth: true color: Colors.palette.m3outline - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small text: (root.app?.comment || root.app?.genericName) ?? "" visible: text wrapMode: Text.WordWrap @@ -152,7 +152,7 @@ PageBase { id: label Layout.alignment: Qt.AlignTop - font.pointSize: Tokens.font.size.small + font: Tokens.font.label.small } Item { @@ -165,7 +165,6 @@ PageBase { Layout.fillWidth: true Layout.maximumWidth: implicitWidth + 1 // Whyyyyyyyyy color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.small wrapMode: Text.WrapAtWordBoundaryOrAnywhere } } diff --git a/Modules/Settings/Pages/AppsPage.qml b/Modules/Settings/Pages/AppsPage.qml index a9ff2f7..43cf99f 100644 --- a/Modules/Settings/Pages/AppsPage.qml +++ b/Modules/Settings/Pages/AppsPage.qml @@ -76,7 +76,7 @@ PageBase { icon: "apps" last: true settingAnchor: "apps-all-apps" - status: qsTr("Browse installed apps, set favorites and hidden") + subtext: qsTr("Browse installed apps, set favorites and hidden") text: qsTr("All apps") onClicked: root.sState.openSubPage(1) @@ -154,7 +154,7 @@ PageBase { CustomText { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small text: appItem.modelData.name } @@ -162,7 +162,7 @@ PageBase { Layout.fillWidth: true color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small text: (appItem.modelData.comment || appItem.modelData.genericName) ?? "" visible: text } @@ -171,7 +171,7 @@ PageBase { MaterialIcon { color: Colors.palette.m3primary fill: 1 - font.pointSize: Tokens.font.size.small + fontStyle: Tokens.font.icon.small text: "favorite" visible: Strings.testRegexList(Config.launcher.favoriteApps, appItem.modelData.id) } diff --git a/Modules/Settings/Pages/Audio/AppVolumes.qml b/Modules/Settings/Pages/Audio/AppVolumes.qml index 59d634b..9d59da6 100644 --- a/Modules/Settings/Pages/Audio/AppVolumes.qml +++ b/Modules/Settings/Pages/Audio/AppVolumes.qml @@ -28,7 +28,6 @@ PageBase { Layout.fillWidth: true Layout.leftMargin: Tokens.padding.extraSmall color: Colors.palette.m3outline - font.pointSize: Tokens.font.size.small text: qsTr("Adjust the volume of individual apps currently playing audio.") wrapMode: Text.WordWrap } diff --git a/Modules/Settings/Pages/AudioPage.qml b/Modules/Settings/Pages/AudioPage.qml index fa8f225..7c6e0f7 100644 --- a/Modules/Settings/Pages/AudioPage.qml +++ b/Modules/Settings/Pages/AudioPage.qml @@ -103,7 +103,7 @@ PageBase { spacing: Tokens.spacing.small MaterialIcon { - font.pointSize: Tokens.font.size.normal + fontStyle: Tokens.font.icon.medium text: "tune" } @@ -114,7 +114,7 @@ PageBase { CustomText { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small text: qsTr("App volumes") } @@ -123,14 +123,14 @@ PageBase { animate: true color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Tokens.font.size.small + font: Tokens.font.body.small text: Audio.streams.length === 0 ? qsTr("No apps playing audio") : Audio.streams.length === 1 ? qsTr("1 app playing audio") : qsTr("%1 apps playing audio").arg(Audio.streams.length) } } MaterialIcon { color: Colors.palette.m3onSurfaceVariant - font.pointSize: Tokens.font.size.normal + fontStyle: Tokens.font.icon.medium text: "chevron_right" } } diff --git a/Modules/Settings/Pages/Panels/BarPanel.qml b/Modules/Settings/Pages/Panels/BarPanel.qml index c14f3bd..8f6ddb6 100644 --- a/Modules/Settings/Pages/Panels/BarPanel.qml +++ b/Modules/Settings/Pages/Panels/BarPanel.qml @@ -91,7 +91,7 @@ PageBase { first: true icon: "widgets" settingAnchor: "bar-tray" - status: qsTr("System tray icons") + subtext: qsTr("System tray icons") text: qsTr("Tray") onClicked: root.sState.openSubPage(6) @@ -100,7 +100,7 @@ PageBase { NavRow { icon: "signal_cellular_alt" settingAnchor: "bar-statusicons" - status: qsTr("Visible indicators") + subtext: qsTr("Visible indicators") text: qsTr("Status icons") onClicked: root.sState.openSubPage(7) @@ -110,7 +110,7 @@ PageBase { icon: "schedule" last: true settingAnchor: "bar-clock" - status: qsTr("Date, icon, background") + subtext: qsTr("Date, icon, background") text: qsTr("Clock") onClicked: root.sState.openSubPage(8) diff --git a/Modules/Settings/Pages/Panels/Sidebar/SidebarLlm.qml b/Modules/Settings/Pages/Panels/Sidebar/SidebarLlm.qml index 2538aac..8046e5c 100644 --- a/Modules/Settings/Pages/Panels/Sidebar/SidebarLlm.qml +++ b/Modules/Settings/Pages/Panels/Sidebar/SidebarLlm.qml @@ -95,7 +95,7 @@ PageBase { first: true last: true icon: "format_paint" - iconLabel.font.pointSize: Tokens.font.size.large + iconLabel.fontStyle: Tokens.font.icon.large rowButton.trailingIcon: "open_in_new" onOpenChanged: { root.sState.dimmed = open; diff --git a/Modules/Settings/Pages/PanelsPage.qml b/Modules/Settings/Pages/PanelsPage.qml index eeb33ba..6a16a5b 100644 --- a/Modules/Settings/Pages/PanelsPage.qml +++ b/Modules/Settings/Pages/PanelsPage.qml @@ -17,7 +17,7 @@ PageBase { first: true icon: "dock_to_bottom" settingAnchor: "panels-bar" - status: !Config.bar.autoHide ? qsTr("Always visible") : qsTr("Reveal on hover") + subtext: !Config.bar.autoHide ? qsTr("Always visible") : qsTr("Reveal on hover") text: qsTr("Bar") onClicked: root.sState.openSubPage(1) @@ -26,7 +26,7 @@ PageBase { NavRow { icon: "dashboard" settingAnchor: "panels-dashboard" - status: Config.dashboard.enabled ? qsTr("Enabled") : qsTr("Disabled") + subtext: Config.dashboard.enabled ? qsTr("Enabled") : qsTr("Disabled") text: qsTr("Dashboard") onClicked: root.sState.openSubPage(2) @@ -35,7 +35,7 @@ PageBase { NavRow { icon: "insert_chart" settingAnchor: "panels-resources" - status: Config.dashboard.performance.enabled ? qsTr("Enabled") : qsTr("Disabled") + subtext: Config.dashboard.performance.enabled ? qsTr("Enabled") : qsTr("Disabled") text: qsTr("Resources") onClicked: root.sState.openSubPage(3) @@ -44,7 +44,7 @@ PageBase { NavRow { icon: "apps" settingAnchor: "panels-launcher" - status: Config.launcher.enabled ? qsTr("Enabled") : qsTr("Disabled") + subtext: Config.launcher.enabled ? qsTr("Enabled") : qsTr("Disabled") text: qsTr("Launcher") onClicked: root.sState.openSubPage(4) @@ -54,7 +54,7 @@ PageBase { icon: "dock_to_right" last: true settingAnchor: "panels-sidebar" - status: Config.sidebar.enabled ? qsTr("Enabled") : qsTr("Disabled") + subtext: Config.sidebar.enabled ? qsTr("Enabled") : qsTr("Disabled") text: qsTr("Sidebar") onClicked: root.sState.openSubPage(5) diff --git a/Modules/Settings/Pages/ServicesPage.qml b/Modules/Settings/Pages/ServicesPage.qml index 8a7ffb7..fe827bf 100644 --- a/Modules/Settings/Pages/ServicesPage.qml +++ b/Modules/Settings/Pages/ServicesPage.qml @@ -72,7 +72,7 @@ PageBase { icon: "notifications" last: true settingAnchor: "services-notifications" - status: qsTr("Notifications, toasts, timeouts") + subtext: qsTr("Notifications, toasts, timeouts") text: qsTr("Notifications") onClicked: root.sState.openSubPage(1) diff --git a/Modules/Settings/Pages/Wallpaper/WallpaperSelect.qml b/Modules/Settings/Pages/Wallpaper/WallpaperSelect.qml index 18016d2..a4d4906 100644 --- a/Modules/Settings/Pages/Wallpaper/WallpaperSelect.qml +++ b/Modules/Settings/Pages/Wallpaper/WallpaperSelect.qml @@ -25,7 +25,7 @@ PageBase { CustomText { Layout.topMargin: Tokens.spacing.largeIncreased - font.pointSize: Tokens.font.size.large + font: Tokens.font.title.small text: qsTr("Wallpapers") } diff --git a/Plugins/ZShell/Config/CMakeLists.txt b/Plugins/ZShell/Config/CMakeLists.txt index ae992f3..b8b6527 100644 --- a/Plugins/ZShell/Config/CMakeLists.txt +++ b/Plugins/ZShell/Config/CMakeLists.txt @@ -8,6 +8,8 @@ qml_module(ZShell-config config.hpp config.cpp migration.hpp migration.cpp anim.hpp anim.cpp + fontbuilder.hpp fontbuilder.cpp + font.hpp font.cpp tokens.hpp appearance.hpp background.hpp @@ -28,4 +30,6 @@ qml_module(ZShell-config services.hpp sidebar.hpp utilities.hpp + LIBRARIES + Qt::Gui ) diff --git a/Plugins/ZShell/Config/appearance.hpp b/Plugins/ZShell/Config/appearance.hpp index b4b0e5a..5181423 100644 --- a/Plugins/ZShell/Config/appearance.hpp +++ b/Plugins/ZShell/Config/appearance.hpp @@ -1,19 +1,78 @@ #pragma once #include "configobject.hpp" +#include +#include +#include #include namespace ZShell::config { +class AnimDurations : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(qreal, scale, 1) + + Q_PROPERTY(int extraLarge READ extraLarge NOTIFY scaleChanged) + Q_PROPERTY( + int expressiveDefaultEffects READ expressiveDefaultEffects NOTIFY + scaleChanged) + Q_PROPERTY( + int expressiveDefaultSpatial READ expressiveDefaultSpatial NOTIFY + scaleChanged) + Q_PROPERTY( + int expressiveFastEffects READ expressiveFastEffects NOTIFY scaleChanged) + Q_PROPERTY( + int expressiveFastSpatial READ expressiveFastSpatial NOTIFY scaleChanged) + Q_PROPERTY( + int expressiveSlowEffects READ expressiveSlowEffects NOTIFY scaleChanged) + Q_PROPERTY( + int expressiveSlowSpatial READ expressiveSlowSpatial NOTIFY scaleChanged) + Q_PROPERTY(int large READ large NOTIFY scaleChanged) + Q_PROPERTY(int normal READ normal NOTIFY scaleChanged) + Q_PROPERTY(int small READ small NOTIFY scaleChanged) + + public: + explicit AnimDurations(QObject* parent = nullptr) : ConfigObject(parent) {} + + [[nodiscard]] int small() const { return static_cast(200 * scale()); } + [[nodiscard]] int normal() const { return static_cast(400 * scale()); } + [[nodiscard]] int large() const { return static_cast(600 * scale()); } + [[nodiscard]] int extraLarge() const { + return static_cast(1000 * scale()); + } + [[nodiscard]] int expressiveFastSpatial() const { + return static_cast(350 * scale()); + } + [[nodiscard]] int expressiveDefaultSpatial() const { + return static_cast(500 * scale()); + } + [[nodiscard]] int expressiveSlowSpatial() const { + return static_cast(650 * scale()); + } + [[nodiscard]] int expressiveFastEffects() const { + return static_cast(150 * scale()); + } + [[nodiscard]] int expressiveDefaultEffects() const { + return static_cast(200 * scale()); + } + [[nodiscard]] int expressiveSlowEffects() const { + return static_cast(300 * scale()); + } +}; + class Anim : public ConfigObject { Q_OBJECT QML_ANONYMOUS CFG_PROPERTY(int, mediaGifSpeedAdjustment, 300) CFG_PROPERTY(qreal, sessionGifSpeed, 0.7) + CONFIG_SUBOBJECT(AnimDurations, durations) public: - explicit Anim(QObject* parent = nullptr) : ConfigObject(parent) {} + explicit Anim(QObject* parent = nullptr) + : ConfigObject(parent), m_durations(new AnimDurations(this)) {} }; class Deform : public ConfigObject { @@ -39,15 +98,161 @@ class FontFamily : public ConfigObject { explicit FontFamily(QObject* parent = nullptr) : ConfigObject(parent) {} }; -class Font : public ConfigObject { +namespace detail { + +struct FontConfig { + QString family = {}; + int size; + int weight = QFont::Normal; + bool italic = false; + QVariantMap vaxes = {{QStringLiteral("ROND"), 25}}; +}; + +} // namespace detail + +class FontSizeNode : public ConfigObject { + public: + explicit FontSizeNode(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class FontStyleNode : public ConfigObject { + public: + explicit FontStyleNode(QObject* parent = nullptr) : ConfigObject(parent) {} + + virtual FontSizeNode* largeNode() const = 0; + virtual FontSizeNode* mediumNode() const = 0; + virtual FontSizeNode* smallNode() const = 0; + virtual FontSizeNode* extraLargeNode() const { return nullptr; } +}; + +#define ARG(...) __VA_ARGS__ +#define FONT(...) ZShell::config::detail::FontConfig __VA_ARGS__ +#define FONT_CONFIG(Style, Size, props) \ + class FontConfig##Style##Size : public FontSizeNode { \ + Q_OBJECT QML_ANONYMOUS \ + \ + CFG_PROPERTY(QString, family, ARG(props).family) \ + CFG_PROPERTY(int, size, ARG(props).size) \ + CFG_PROPERTY(int, weight, ARG(props).weight) \ + CFG_PROPERTY(bool, italic, ARG(props).italic) \ + CFG_PROPERTY(QVariantMap, vaxes, ARG(props).vaxes) \ + \ + public \ + : explicit FontConfig##Style##Size(QObject* parent = nullptr) \ + : FontSizeNode(parent) {} \ + }; +#define FONT_STYLE(Style, family_, large_, medium_, small_) \ + FONT_CONFIG(Style, Large, ARG(large_)) \ + FONT_CONFIG(Style, Medium, ARG(medium_)) \ + FONT_CONFIG(Style, Small, ARG(small_)) \ + \ + class FontStyle##Style : public FontStyleNode { \ + Q_OBJECT QML_ANONYMOUS \ + \ + CFG_PROPERTY(QString, family, family_) \ + CONFIG_SUBOBJECT(FontConfig##Style##Large, large) \ + CONFIG_SUBOBJECT(FontConfig##Style##Medium, medium) \ + CONFIG_SUBOBJECT(FontConfig##Style##Small, small) \ + \ + public \ + : explicit FontStyle##Style(QObject* parent = nullptr) \ + : FontStyleNode(parent) \ + , m_large(new FontConfig##Style##Large(this)) \ + , m_medium(new FontConfig##Style##Medium(this)) \ + , m_small(new FontConfig##Style##Small(this)) {} \ + \ + FontSizeNode* largeNode() const override { return m_large; } \ + FontSizeNode* mediumNode() const override { return m_medium; } \ + FontSizeNode* smallNode() const override { return m_small; } \ + }; + +// clang-format off +FONT_STYLE(Headline, QStringLiteral("GoogleSansFlex"), + FONT({ .size = 32, .weight = QFont::Medium }), + FONT({ .size = 28, .weight = QFont::Medium }), + FONT({ .size = 24, .weight = QFont::Medium }) +) +FONT_STYLE(Title, QStringLiteral("GoogleSansFlex"), + FONT({ .size = 22, .weight = QFont::Medium }), + FONT({ .size = 16, .weight = QFont::Medium }), + FONT({ .size = 14, .weight = QFont::Medium }) +) +FONT_STYLE(Body, QStringLiteral("GoogleSansFlex"), + FONT({ .size = 16 }), + FONT({ .size = 14 }), + FONT({ .size = 12 }) +) +FONT_STYLE(Label, QStringLiteral("GoogleSansFlex"), + FONT({ .size = 14, .weight = QFont::Medium }), + FONT({ .size = 12, .weight = QFont::Medium }), + FONT({ .size = 11 }) +) +FONT_STYLE(Mono, QStringLiteral("CaskaydiaCove NF"), + FONT({ .size = 16, .vaxes = {} }), + FONT({ .size = 14, .vaxes = {} }), + FONT({ .size = 12, .vaxes = {} }) +) +// clang-format on + +FONT_CONFIG(Icon, ExtraLarge, FONT({.size = static_cast(48 / 1.33)})) +FONT_CONFIG(Icon, Large, FONT({.size = static_cast(32 / 1.33)})) +FONT_CONFIG(Icon, Medium, FONT({.size = static_cast(24 / 1.33)})) +FONT_CONFIG(Icon, Small, FONT({.size = static_cast(20 / 1.33)})) + +class FontStyleIcon : public FontStyleNode { Q_OBJECT QML_ANONYMOUS - CONFIG_SUBOBJECT(FontFamily, family) + CFG_PROPERTY(QString, family, QStringLiteral("Material Symbols Rounded")) + CONFIG_SUBOBJECT(FontConfigIconExtraLarge, extraLarge) + CONFIG_SUBOBJECT(FontConfigIconLarge, large) + CONFIG_SUBOBJECT(FontConfigIconMedium, medium) + CONFIG_SUBOBJECT(FontConfigIconSmall, small) public: - explicit Font(QObject* parent = nullptr) - : ConfigObject(parent), m_family(new FontFamily(this)) {} + explicit FontStyleIcon(QObject* parent = nullptr) + : FontStyleNode(parent) + , m_extraLarge(new FontConfigIconExtraLarge(this)) + , m_large(new FontConfigIconLarge(this)) + , m_medium(new FontConfigIconMedium(this)) + , m_small(new FontConfigIconSmall(this)) {} + + FontSizeNode* extraLargeNode() const override { return m_extraLarge; } + FontSizeNode* largeNode() const override { return m_large; } + FontSizeNode* mediumNode() const override { return m_medium; } + FontSizeNode* smallNode() const override { return m_small; } +}; + +#undef ARG +#undef FONT +#undef FONT_CONFIG +#undef FONT_STYLE + +class AppearanceFont : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(qreal, scale, 1) + CONFIG_SUBOBJECT(FontFamily, family) + CONFIG_SUBOBJECT(FontStyleHeadline, headline) + CONFIG_SUBOBJECT(FontStyleTitle, title) + CONFIG_SUBOBJECT(FontStyleBody, body) + CONFIG_SUBOBJECT(FontStyleLabel, label) + CONFIG_SUBOBJECT(FontStyleMono, mono) + CONFIG_SUBOBJECT(FontStyleIcon, icon) + CFG_PROPERTY(QString, clock, QStringLiteral("Rubik")) + CFG_PROPERTY(QString, workspaces, QStringLiteral("Rubik")) + + public: + explicit AppearanceFont(QObject* parent = nullptr) + : ConfigObject(parent) + , m_family(new FontFamily(this)) + , m_headline(new FontStyleHeadline(this)) + , m_title(new FontStyleTitle(this)) + , m_body(new FontStyleBody(this)) + , m_label(new FontStyleLabel(this)) + , m_mono(new FontStyleMono(this)) + , m_icon(new FontStyleIcon(this)) {} }; class Transparency : public ConfigObject { @@ -62,13 +267,140 @@ class Transparency : public ConfigObject { explicit Transparency(QObject* parent = nullptr) : ConfigObject(parent) {} }; +class AppearanceRounding : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(qreal, scale, 1) + + Q_PROPERTY(int extraSmall READ extraSmall NOTIFY scaleChanged) + Q_PROPERTY(int small READ small NOTIFY scaleChanged) + Q_PROPERTY(int medium READ medium NOTIFY scaleChanged) + Q_PROPERTY(int large READ large NOTIFY scaleChanged) + Q_PROPERTY(int largeIncreased READ largeIncreased NOTIFY scaleChanged) + Q_PROPERTY(int extraLarge READ extraLarge NOTIFY scaleChanged) + Q_PROPERTY( + int extraLargeIncreased READ extraLargeIncreased NOTIFY scaleChanged) + Q_PROPERTY(int extraExtraLarge READ extraExtraLarge NOTIFY scaleChanged) + Q_PROPERTY(int full READ full CONSTANT) + + public: + explicit AppearanceRounding(QObject* parent = nullptr) + : ConfigObject(parent) {} + + [[nodiscard]] int extraSmall() const { + return static_cast(4 * scale()); + } + [[nodiscard]] int small() const { return static_cast(8 * scale()); } + [[nodiscard]] int medium() const { return static_cast(12 * scale()); } + [[nodiscard]] int large() const { return static_cast(16 * scale()); } + [[nodiscard]] int largeIncreased() const { + return static_cast(20 * scale()); + } + [[nodiscard]] int extraLarge() const { + return static_cast(28 * scale()); + } + [[nodiscard]] int extraLargeIncreased() const { + return static_cast(32 * scale()); + } + [[nodiscard]] int extraExtraLarge() const { + return static_cast(48 * scale()); + } + [[nodiscard]] int full() const { return std::numeric_limits::max(); } +}; + +class AppearanceSpacing : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(qreal, scale, 1) + + Q_PROPERTY(int extraSmall READ extraSmall NOTIFY scaleChanged) + Q_PROPERTY(int small READ small NOTIFY scaleChanged) + Q_PROPERTY(int medium READ medium NOTIFY scaleChanged) + Q_PROPERTY(int large READ large NOTIFY scaleChanged) + Q_PROPERTY(int largeIncreased READ largeIncreased NOTIFY scaleChanged) + Q_PROPERTY(int extraLarge READ extraLarge NOTIFY scaleChanged) + Q_PROPERTY( + int extraLargeIncreased READ extraLargeIncreased NOTIFY scaleChanged) + Q_PROPERTY(int extraExtraLarge READ extraExtraLarge NOTIFY scaleChanged) + + public: + explicit AppearanceSpacing(QObject* parent = nullptr) + : ConfigObject(parent) {} + + [[nodiscard]] int extraSmall() const { + return static_cast(4 * scale()); + } + [[nodiscard]] int small() const { return static_cast(8 * scale()); } + [[nodiscard]] int medium() const { return static_cast(12 * scale()); } + [[nodiscard]] int large() const { return static_cast(16 * scale()); } + [[nodiscard]] int largeIncreased() const { + return static_cast(20 * scale()); + } + [[nodiscard]] int extraLarge() const { + return static_cast(28 * scale()); + } + [[nodiscard]] int extraLargeIncreased() const { + return static_cast(32 * scale()); + } + [[nodiscard]] int extraExtraLarge() const { + return static_cast(48 * scale()); + } +}; + +class AppearancePadding : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(qreal, scale, 1) + + Q_PROPERTY(int extraSmall READ extraSmall NOTIFY scaleChanged) + Q_PROPERTY(int smaller READ smaller NOTIFY scaleChanged) + Q_PROPERTY(int small READ small NOTIFY scaleChanged) + Q_PROPERTY(int medium READ medium NOTIFY scaleChanged) + Q_PROPERTY(int large READ large NOTIFY scaleChanged) + Q_PROPERTY(int largeIncreased READ largeIncreased NOTIFY scaleChanged) + Q_PROPERTY(int extraLarge READ extraLarge NOTIFY scaleChanged) + Q_PROPERTY( + int extraLargeIncreased READ extraLargeIncreased NOTIFY scaleChanged) + Q_PROPERTY(int extraExtraLarge READ extraExtraLarge NOTIFY scaleChanged) + + public: + explicit AppearancePadding(QObject* parent = nullptr) + : ConfigObject(parent) {} + + [[nodiscard]] int extraSmall() const { + return static_cast(4 * scale()); + } + [[nodiscard]] int smaller() const { return static_cast(5 * scale()); } + [[nodiscard]] int small() const { return static_cast(8 * scale()); } + [[nodiscard]] int medium() const { return static_cast(12 * scale()); } + [[nodiscard]] int large() const { return static_cast(16 * scale()); } + [[nodiscard]] int largeIncreased() const { + return static_cast(20 * scale()); + } + [[nodiscard]] int extraLarge() const { + return static_cast(28 * scale()); + } + [[nodiscard]] int extraLargeIncreased() const { + return static_cast(32 * scale()); + } + [[nodiscard]] int extraExtraLarge() const { + return static_cast(48 * scale()); + } +}; + class Appearance : public ConfigObject { Q_OBJECT QML_ANONYMOUS CONFIG_SUBOBJECT(Anim, anim) CONFIG_SUBOBJECT(Deform, deform) - CONFIG_SUBOBJECT(Font, font) + CONFIG_SUBOBJECT(AppearanceFont, font) + CONFIG_SUBOBJECT(AppearanceRounding, rounding) + CONFIG_SUBOBJECT(AppearanceSpacing, spacing) + CONFIG_SUBOBJECT(AppearancePadding, padding) CONFIG_SUBOBJECT(Transparency, transparency) public: @@ -76,8 +408,11 @@ class Appearance : public ConfigObject { : ConfigObject(parent) , m_anim(new Anim(this)) , m_deform(new Deform(this)) - , m_font(new Font(this)) - , m_transparency(new Transparency(this)) {} + , m_font(new AppearanceFont(this)) + , m_rounding(new AppearanceRounding(this)) + , m_spacing(new AppearanceSpacing(this)) + , m_padding(new AppearancePadding(this)) + , m_transparency(new Transparency(this)) {}; }; } // namespace ZShell::config diff --git a/Plugins/ZShell/Config/configobject.cpp b/Plugins/ZShell/Config/configobject.cpp index 9ee0517..1b0d01d 100644 --- a/Plugins/ZShell/Config/configobject.cpp +++ b/Plugins/ZShell/Config/configobject.cpp @@ -65,13 +65,12 @@ void ConfigObject::loadFromJson(const QJsonValue& json) { auto prop = meta->property(i); const auto key = QString::fromUtf8(prop.name()); - known.insert(key); - if (!obj.contains(key)) continue; const auto jsonVal = obj.value(key); if (prop.metaType().flags().testFlag(QMetaType::PointerToQObject)) { + known.insert(key); if (auto* const node = prop.read(this).value()) { node->loadFromJson(jsonVal); continue; @@ -80,6 +79,8 @@ void ConfigObject::loadFromJson(const QJsonValue& json) { if (!prop.isWritable()) continue; + known.insert(key); + if (!jsonValueMatchesType(jsonVal, prop.metaType())) { qWarning() << "Config: type mismatch for" << key << "in" << meta->className() << "- expected" @@ -218,18 +219,9 @@ void ConfigObject::materializeDefaults() { for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) { const auto prop = meta->property(i); - const auto key = QString::fromUtf8(prop.name()); - if (auto* const node = prop.read(this).value()) { + if (auto* const node = prop.read(this).value()) node->materializeDefaults(); - continue; - } - - if (!prop.isWritable()) continue; - - if (m_global) continue; - - m_loadedKeys.insert(key); } } diff --git a/Plugins/ZShell/Config/font.cpp b/Plugins/ZShell/Config/font.cpp new file mode 100644 index 0000000..57038f5 --- /dev/null +++ b/Plugins/ZShell/Config/font.cpp @@ -0,0 +1,290 @@ +#include "font.hpp" + +#include "appearance.hpp" +#include "config.hpp" + +namespace ZShell::config { + +FontStyleBase::FontStyleBase(QObject* parent) : QObject(parent) {} + +QFont FontStyleBase::large() const { + return m_large; +} + +QFont FontStyleBase::medium() const { + return m_medium; +} + +QFont FontStyleBase::small() const { + return m_small; +} + +QFont FontStyleBase::buildFont( + const FontSizeNode* cfg, const QString& fallbackFamily, qreal scale) { + const auto family = cfg->property("family").toString(); + const auto size = cfg->property("size").toInt(); + const auto weight = cfg->property("weight").value(); + const auto italic = cfg->property("italic").toBool(); + const auto vaxes = cfg->property("vaxes").toMap(); + + QFont font; + font.setFamily(family.isEmpty() ? fallbackFamily : family); + const int scaledSize = static_cast(size * scale); + const int cappedSize = scaledSize > 0 ? scaledSize : 1; + font.setPointSize(cappedSize); + font.setVariableAxis("opsz", static_cast(cappedSize)); + font.setWeight(weight); + font.setVariableAxis("wght", static_cast(weight)); + font.setItalic(italic); + + for (auto it = vaxes.constBegin(); it != vaxes.constEnd(); ++it) { + if (auto tag = QFont::Tag::fromString(it.key())) + font.setVariableAxis(*tag, it.value().toFloat()); + } + + return font; +} + +void FontStyleBase::bind(FontStyleNode* cfg) { + if (m_cfg == cfg) return; + + if (m_cfg) { + disconnect(m_cfg, nullptr, this, nullptr); + disconnect(m_cfg->largeNode(), nullptr, this, nullptr); + disconnect(m_cfg->mediumNode(), nullptr, this, nullptr); + disconnect(m_cfg->smallNode(), nullptr, this, nullptr); + } + + m_cfg = cfg; + + if (cfg) { + connect( + cfg, &ConfigNode::propertiesChanged, this, &FontStyleBase::rebuild); + connect( + cfg->largeNode(), + &ConfigNode::propertiesChanged, + this, + &FontStyleBase::rebuild); + connect( + cfg->mediumNode(), + &ConfigNode::propertiesChanged, + this, + &FontStyleBase::rebuild); + connect( + cfg->smallNode(), + &ConfigNode::propertiesChanged, + this, + &FontStyleBase::rebuild); + } + + rebuild(); +} + +void FontStyleBase::rebuild() { + if (m_cfg) { + const auto family = m_cfg->property("family").toString(); + m_large = buildFont(m_cfg->largeNode(), family, m_scale); + m_medium = buildFont(m_cfg->mediumNode(), family, m_scale); + m_small = buildFont(m_cfg->smallNode(), family, m_scale); + } else { + m_large = QFont(); + m_medium = QFont(); + m_small = QFont(); + } + emit fontsChanged(); +} + +void FontStyleBase::setScale(qreal scale) { + if (qFuzzyCompare(m_scale + 1.0, scale + 1.0)) return; + m_scale = scale; + rebuild(); +} + +FontStyle::FontStyle(QObject* parent) + : FontStyleBase(parent), m_builders(new FontBuilders(this, this)) {} + +FontBuilders* FontStyle::builders() const { + return m_builders; +} + +IconFontStyle::IconFontStyle(QObject* parent) + : FontStyleBase(parent), m_builders(new IconFontBuilders(this, this)) {} + +FontBuilder IconFontStyle::size(int pointSize) { + return FontBuilder(m_small).size(pointSize); +} + +FontBuilder IconFontStyle::pixelSize(int pixelSize) { + return FontBuilder(m_small).pixelSize(pixelSize); +} + +void IconFontStyle::bind(FontStyleNode* cfg) { + if (m_cfg == cfg) return; + + if (m_cfg) disconnect(m_cfg->extraLargeNode(), nullptr, this, nullptr); + + FontStyleBase::bind(cfg); + + if (cfg) + connect( + cfg->extraLargeNode(), + &ConfigNode::propertiesChanged, + this, + &IconFontStyle::rebuild); +} + +QFont IconFontStyle::extraLarge() const { + return m_extraLarge; +} + +IconFontBuilders* IconFontStyle::builders() const { + return m_builders; +} + +void IconFontStyle::rebuild() { + if (m_cfg) { + const auto family = m_cfg->property("family").toString(); + m_extraLarge = buildFont(m_cfg->extraLargeNode(), family, m_scale); + } else { + m_extraLarge = QFont(); + } + FontStyleBase::rebuild(); +} + +FontBuilders::FontBuilders(const FontStyleBase* style, QObject* parent) + : QObject(parent), m_style(style) { + connect( + style, + &FontStyleBase::fontsChanged, + this, + &FontBuilders::buildersChanged); +} + +FontBuilder FontBuilders::large() const { + return FontBuilder(m_style->large()); +} + +FontBuilder FontBuilders::medium() const { + return FontBuilder(m_style->medium()); +} + +FontBuilder FontBuilders::small() const { + return FontBuilder(m_style->small()); +} + +IconFontBuilders::IconFontBuilders(const IconFontStyle* style, QObject* parent) + : FontBuilders(style, parent) {} + +FontBuilder IconFontBuilders::extraLarge() const { + return FontBuilder( + static_cast(m_style)->extraLarge()); +} + +FontTokens::FontTokens(QObject* parent) + : ConfigObject(parent) + , m_size(new FontSizeTokens(this)) + , m_headline(new FontStyle(this)) + , m_title(new FontStyle(this)) + , m_body(new FontStyle(this)) + , m_label(new FontStyle(this)) + , m_mono(new FontStyle(this)) + , m_icon(new IconFontStyle(this)) { + if (!Config::instance()) new Config(); + bindFont(Config::instance()->appearance()->font()); +} + +FontStyle* FontTokens::headline() const { + return m_headline; +} + +FontStyle* FontTokens::title() const { + return m_title; +} + +FontStyle* FontTokens::body() const { + return m_body; +} + +FontStyle* FontTokens::label() const { + return m_label; +} + +FontStyle* FontTokens::mono() const { + return m_mono; +} + +IconFontStyle* FontTokens::icon() const { + return m_icon; +} + +FontBuilder FontTokens::clock() const { + return FontBuilder(m_clock); +} + +QString FontTokens::workspaces() const { + return m_font ? m_font->workspaces() : QString(); +} + +void FontTokens::bindFont(AppearanceFont* font) { + if (m_font == font) return; + + if (m_font) disconnect(m_font, nullptr, this, nullptr); + + m_font = font; + + if (font) { + rebuildScale(); + m_headline->bind(font->headline()); + m_title->bind(font->title()); + m_body->bind(font->body()); + m_label->bind(font->label()); + m_mono->bind(font->mono()); + m_icon->bind(font->icon()); + + connect( + font, + &AppearanceFont::clockChanged, + this, + &FontTokens::rebuildClock); + connect( + font, + &AppearanceFont::scaleChanged, + this, + &FontTokens::rebuildScale); + connect( + font, + &AppearanceFont::workspacesChanged, + this, + &FontTokens::workspacesChanged); + } else { + rebuildScale(); + m_headline->bind(nullptr); + m_title->bind(nullptr); + m_body->bind(nullptr); + m_label->bind(nullptr); + m_mono->bind(nullptr); + m_icon->bind(nullptr); + } + + rebuildClock(); + emit workspacesChanged(); +} + +void FontTokens::rebuildScale() { + const qreal s = m_font ? m_font->scale() : 1; + m_headline->setScale(s); + m_title->setScale(s); + m_body->setScale(s); + m_label->setScale(s); + m_mono->setScale(s); + m_icon->setScale(s); +} + +void FontTokens::rebuildClock() { + QFont f; + if (m_font) f.setFamily(m_font->clock()); + m_clock = f; + emit clockChanged(); +} + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/font.hpp b/Plugins/ZShell/Config/font.hpp new file mode 100644 index 0000000..9625457 --- /dev/null +++ b/Plugins/ZShell/Config/font.hpp @@ -0,0 +1,200 @@ +#pragma once + +#include "configobject.hpp" +#include "fontbuilder.hpp" + +#include +#include +#include +#include + +namespace ZShell::config { + +class AppearanceFont; +class FontBuilders; +class FontStyleBase; +class FontSizeNode; +class FontStyleNode; +class IconFontStyle; + +class FontSizeTokens : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(int, small, 11) + CFG_PROPERTY(int, smaller, 12) + CFG_PROPERTY(int, normal, 13) + CFG_PROPERTY(int, larger, 15) + CFG_PROPERTY(int, large, 18) + CFG_PROPERTY(int, extraLarge, 28) + + public: + explicit FontSizeTokens(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class FontBuilders : public QObject { + Q_OBJECT + QML_ANONYMOUS + + Q_PROPERTY( + ZShell::config::FontBuilder large READ large NOTIFY buildersChanged + FINAL) + Q_PROPERTY( + ZShell::config::FontBuilder medium READ medium NOTIFY buildersChanged + FINAL) + Q_PROPERTY( + ZShell::config::FontBuilder small READ small NOTIFY buildersChanged + FINAL) + + public: + explicit FontBuilders(const FontStyleBase* style, QObject* parent = nullptr); + + [[nodiscard]] FontBuilder large() const; + [[nodiscard]] FontBuilder medium() const; + [[nodiscard]] FontBuilder small() const; + + signals: + void buildersChanged(); + + protected: + const FontStyleBase* m_style; +}; + +class IconFontBuilders : public FontBuilders { + Q_OBJECT + QML_ANONYMOUS + + Q_PROPERTY( + ZShell::config::FontBuilder extraLarge READ extraLarge NOTIFY + buildersChanged FINAL) + + public: + explicit IconFontBuilders( + const IconFontStyle* style, QObject* parent = nullptr); + + [[nodiscard]] FontBuilder extraLarge() const; +}; + +class FontStyleBase : public QObject { + Q_OBJECT + + Q_PROPERTY(QFont large READ large NOTIFY fontsChanged FINAL) + Q_PROPERTY(QFont medium READ medium NOTIFY fontsChanged FINAL) + Q_PROPERTY(QFont small READ small NOTIFY fontsChanged FINAL) + + public: + explicit FontStyleBase(QObject* parent = nullptr); + + virtual void bind(FontStyleNode* cfg); + void setScale(qreal scale); + + [[nodiscard]] QFont large() const; + [[nodiscard]] QFont medium() const; + [[nodiscard]] QFont small() const; + + signals: + void fontsChanged(); + + protected: + virtual void rebuild(); + + static QFont buildFont( + const FontSizeNode* cfg, const QString& fallbackFamily, qreal scale); + + FontStyleNode* m_cfg = nullptr; + qreal m_scale = 1; + QFont m_large; + QFont m_medium; + QFont m_small; +}; + +class FontStyle : public FontStyleBase { + Q_OBJECT + QML_ANONYMOUS + + Q_PROPERTY(FontBuilders* builders READ builders CONSTANT FINAL) + + public: + explicit FontStyle(QObject* parent = nullptr); + + [[nodiscard]] FontBuilders* builders() const; + + private: + FontBuilders* m_builders; +}; + +class IconFontStyle : public FontStyleBase { + Q_OBJECT + QML_ANONYMOUS + + Q_PROPERTY(QFont extraLarge READ extraLarge NOTIFY fontsChanged FINAL) + Q_PROPERTY(IconFontBuilders* builders READ builders CONSTANT FINAL) + + public: + explicit IconFontStyle(QObject* parent = nullptr); + + Q_INVOKABLE FontBuilder size(int pointSize); + Q_INVOKABLE FontBuilder pixelSize(int pixelSize); + + void bind(FontStyleNode* cfg) override; + + [[nodiscard]] QFont extraLarge() const; + [[nodiscard]] IconFontBuilders* builders() const; + + protected: + void rebuild() override; + + private: + QFont m_extraLarge; + IconFontBuilders* m_builders; +}; + +class FontTokens : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CONFIG_SUBOBJECT(FontSizeTokens, size) + + Q_PROPERTY(FontStyle* headline READ headline CONSTANT FINAL) + Q_PROPERTY(FontStyle* title READ title CONSTANT FINAL) + Q_PROPERTY(FontStyle* body READ body CONSTANT FINAL) + Q_PROPERTY(FontStyle* label READ label CONSTANT FINAL) + Q_PROPERTY(FontStyle* mono READ mono CONSTANT FINAL) + Q_PROPERTY(IconFontStyle* icon READ icon CONSTANT FINAL) + Q_PROPERTY( + ZShell::config::FontBuilder clock READ clock NOTIFY clockChanged FINAL) + Q_PROPERTY(QString workspaces READ workspaces NOTIFY workspacesChanged FINAL) + + public: + explicit FontTokens(QObject* parent = nullptr); + + void bindFont(AppearanceFont* font); + + [[nodiscard]] FontStyle* headline() const; + [[nodiscard]] FontStyle* title() const; + [[nodiscard]] FontStyle* body() const; + [[nodiscard]] FontStyle* label() const; + [[nodiscard]] FontStyle* mono() const; + [[nodiscard]] IconFontStyle* icon() const; + [[nodiscard]] FontBuilder clock() const; + [[nodiscard]] QString workspaces() const; + + signals: + void clockChanged(); + void workspacesChanged(); + + private: + void rebuildClock(); + void rebuildScale(); + + AppearanceFont* m_font = nullptr; + FontStyle* m_headline; + FontStyle* m_title; + FontStyle* m_body; + FontStyle* m_label; + FontStyle* m_mono; + IconFontStyle* m_icon; + QFont m_clock; +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/fontbuilder.cpp b/Plugins/ZShell/Config/fontbuilder.cpp new file mode 100644 index 0000000..3726711 --- /dev/null +++ b/Plugins/ZShell/Config/fontbuilder.cpp @@ -0,0 +1,105 @@ +#include "fontbuilder.hpp" + +#include + +namespace { + +Q_LOGGING_CATEGORY(lcFontBuilder, "zshell.fontbuilder", QtInfoMsg) + +} // namespace + +namespace ZShell::config { + +FontBuilder::FontBuilder(const QFont& font) : m_font(font) {} + +FontBuilder FontBuilder::family(const QString& family) { + m_font.setFamily(family); + return *this; +} + +FontBuilder FontBuilder::size(int pointSize) { + if (pointSize <= 0) pointSize = 1; + m_font.setPointSize(pointSize); + m_font.setVariableAxis("opsz", static_cast(pointSize)); + return *this; +} + +FontBuilder FontBuilder::pixelSize(int pixelSize) { + if (pixelSize <= 0) pixelSize = 1; + m_font.setPixelSize(pixelSize); + return *this; +} + +FontBuilder FontBuilder::weight(QFont::Weight weight) { + m_font.setWeight(weight); + m_font.setVariableAxis("wght", static_cast(weight)); + return *this; +} + +FontBuilder FontBuilder::italic(bool on) { + m_font.setItalic(on); + return *this; +} + +FontBuilder FontBuilder::stretch(int stretch) { + m_font.setStretch(stretch); + return *this; +} + +FontBuilder FontBuilder::letterSpacing(qreal spacing, bool absolute) { + m_font.setLetterSpacing( + absolute ? QFont::AbsoluteSpacing : QFont::PercentageSpacing, spacing); + return *this; +} + +FontBuilder FontBuilder::capitalisation(QFont::Capitalization cap) { + m_font.setCapitalization(cap); + return *this; +} + +FontBuilder FontBuilder::vaxis(const QString& tag, float value) { + if (auto t = QFont::Tag::fromString(tag)) + m_font.setVariableAxis(*t, value); + else + qCWarning(lcFontBuilder) + << "Unable to convert tag" << tag << "to QFont::Tag"; + return *this; +} + +FontBuilder FontBuilder::vaxes(const QVariantMap& axes) { + for (auto it = axes.constBegin(); it != axes.constEnd(); ++it) { + if (it.value().canConvert()) { + if (auto tag = QFont::Tag::fromString(it.key())) + m_font.setVariableAxis(*tag, it.value().toFloat()); + else + qCWarning(lcFontBuilder) + << "Unable to convert tag" << it.key() << "to QFont::Tag"; + } else { + qCWarning(lcFontBuilder) + << "Unable to convert value" << it.value() << "to float"; + } + } + return *this; +} + +QFont FontBuilder::build() const { + return m_font; +} + +FontBuilder FontBuilder::fill(float value) { + return vaxis(QStringLiteral("FILL"), value); +} + +FontBuilder FontBuilder::grade(float value) { + return vaxis(QStringLiteral("GRAD"), value); +} + +FontBuilder FontBuilder::width(float value) { + return vaxis(QStringLiteral("wdth"), value); +} + +FontBuilder FontBuilder::scale(qreal factor) { + return size(static_cast(m_font.pointSize() * factor)); +} + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/fontbuilder.hpp b/Plugins/ZShell/Config/fontbuilder.hpp new file mode 100644 index 0000000..d474f92 --- /dev/null +++ b/Plugins/ZShell/Config/fontbuilder.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include + +namespace ZShell::config { + +class FontBuilder { + Q_GADGET + QML_ANONYMOUS + + public: + FontBuilder() = default; + explicit FontBuilder(const QFont& font); + + [[nodiscard]] Q_INVOKABLE FontBuilder family(const QString& family); + [[nodiscard]] Q_INVOKABLE FontBuilder size(int pointSize); + [[nodiscard]] Q_INVOKABLE FontBuilder pixelSize(int pixelSize); + [[nodiscard]] Q_INVOKABLE FontBuilder weight(QFont::Weight weight); + [[nodiscard]] Q_INVOKABLE FontBuilder italic(bool on = true); + [[nodiscard]] Q_INVOKABLE FontBuilder stretch(int stretch); + [[nodiscard]] Q_INVOKABLE FontBuilder + letterSpacing(qreal spacing, bool absolute = true); + [[nodiscard]] Q_INVOKABLE FontBuilder + capitalisation(QFont::Capitalization cap); + [[nodiscard]] Q_INVOKABLE FontBuilder vaxis(const QString& tag, float value); + [[nodiscard]] Q_INVOKABLE FontBuilder vaxes(const QVariantMap& axes); + [[nodiscard]] Q_INVOKABLE QFont build() const; + + [[nodiscard]] Q_INVOKABLE FontBuilder fill(float value); + [[nodiscard]] Q_INVOKABLE FontBuilder grade(float value); + [[nodiscard]] Q_INVOKABLE FontBuilder width(float value); + + [[nodiscard]] Q_INVOKABLE FontBuilder scale(qreal factor); + + private: + QFont m_font; +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/tokens.hpp b/Plugins/ZShell/Config/tokens.hpp index b58d8ea..07dd953 100644 --- a/Plugins/ZShell/Config/tokens.hpp +++ b/Plugins/ZShell/Config/tokens.hpp @@ -2,6 +2,9 @@ #include "configobject.hpp" #include "anim.hpp" +#include "appearance.hpp" +#include "config.hpp" +#include "font.hpp" #include #include @@ -13,89 +16,6 @@ namespace ZShell::config { -class AppearanceRounding : public ConfigObject { - Q_OBJECT - QML_ANONYMOUS - - CFG_PROPERTY(qreal, extraSmall, 4) - CFG_PROPERTY(qreal, full, std::numeric_limits::max()) - CFG_PROPERTY(qreal, large, 16) - CFG_PROPERTY(qreal, largeIncreased, 20) - CFG_PROPERTY(qreal, extraLarge, 28) - CFG_PROPERTY(qreal, extraLargeIncreased, 32) - CFG_PROPERTY(qreal, extraExtraLarge, 48) - CFG_PROPERTY(qreal, medium, 12) - CFG_PROPERTY(qreal, scale, 1) - CFG_PROPERTY(qreal, small, 8) - - public: - explicit AppearanceRounding(QObject* parent = nullptr) - : ConfigObject(parent) {} -}; - -class AppearancePadding : public ConfigObject { - Q_OBJECT - QML_ANONYMOUS - - CFG_PROPERTY(int, extraSmall, 4) - CFG_PROPERTY(int, smaller, 5) - CFG_PROPERTY(int, small, 8) - CFG_PROPERTY(int, medium, 12) - CFG_PROPERTY(int, large, 16) - CFG_PROPERTY(int, largeIncreased, 20) - CFG_PROPERTY(int, extraLarge, 28) - CFG_PROPERTY(int, extraLargeIncreased, 32) - CFG_PROPERTY(int, extraExtraLarge, 48) - - public: - explicit AppearancePadding(QObject* parent = nullptr) - : ConfigObject(parent) {} -}; - -class AppearanceSpacing : public ConfigObject { - Q_OBJECT - QML_ANONYMOUS - - CFG_PROPERTY(int, extraSmall, 4) - CFG_PROPERTY(int, small, 8) - CFG_PROPERTY(int, medium, 12) - CFG_PROPERTY(int, large, 16) - CFG_PROPERTY(int, largeIncreased, 20) - CFG_PROPERTY(int, extraLarge, 28) - CFG_PROPERTY(int, extraLargeIncreased, 32) - CFG_PROPERTY(int, extraExtraLarge, 48) - - public: - explicit AppearanceSpacing(QObject* parent = nullptr) - : ConfigObject(parent) {} -}; - -class FontSizeTokens : public ConfigObject { - Q_OBJECT - QML_ANONYMOUS - - CFG_PROPERTY(int, small, 11) - CFG_PROPERTY(int, smaller, 12) - CFG_PROPERTY(int, normal, 13) - CFG_PROPERTY(int, larger, 15) - CFG_PROPERTY(int, large, 18) - CFG_PROPERTY(int, extraLarge, 28) - - public: - explicit FontSizeTokens(QObject* parent = nullptr) : ConfigObject(parent) {} -}; - -class FontTokens : public ConfigObject { - Q_OBJECT - QML_ANONYMOUS - - CONFIG_SUBOBJECT(FontSizeTokens, size) - - public: - explicit FontTokens(QObject* parent = nullptr) - : ConfigObject(parent), m_size(new FontSizeTokens(this)) {} -}; - class AnimCurves : public ConfigObject { Q_OBJECT QML_ANONYMOUS @@ -142,31 +62,11 @@ class AnimCurves : public ConfigObject { , m_expressiveSlowEffects({0.34, 0.88, 0.34, 1, 1, 1}) {} }; -class AnimDurations : public ConfigObject { - Q_OBJECT - QML_ANONYMOUS - - CFG_PROPERTY(int, small, 200) - CFG_PROPERTY(int, scale, 1) - CFG_PROPERTY(int, normal, 400) - CFG_PROPERTY(int, large, 600) - CFG_PROPERTY(int, extraLarge, 1000) - CFG_PROPERTY(int, expressiveFastSpatial, 350) - CFG_PROPERTY(int, expressiveDefaultSpatial, 500) - CFG_PROPERTY(int, expressiveSlowSpatial, 650) - CFG_PROPERTY(int, expressiveFastEffects, 150) - CFG_PROPERTY(int, expressiveDefaultEffects, 200) - CFG_PROPERTY(int, expressiveSlowEffects, 300) - - public: - explicit AnimDurations(QObject* parent = nullptr) : ConfigObject(parent) {} -}; - class AnimTokens : public ConfigObject { Q_OBJECT QML_ANONYMOUS - CONFIG_SUBOBJECT(AnimDurations, durations) + Q_PROPERTY(ZShell::config::AnimDurations* durations READ durations CONSTANT) Q_PROPERTY(QEasingCurve emphasized READ emphasized NOTIFY curvesChanged) Q_PROPERTY( @@ -201,7 +101,6 @@ class AnimTokens : public ConfigObject { explicit AnimTokens(QObject* parent = nullptr) : ConfigObject(parent) , m_curves(new AnimCurves(this)) - , m_durations(new AnimDurations(this)) , m_easing(new AnimEasing(this)) { connect( m_easing, @@ -211,6 +110,10 @@ class AnimTokens : public ConfigObject { m_easing->bindCurves(m_curves); } + [[nodiscard]] AnimDurations* durations() const { + return Config::instance()->appearance()->anim()->durations(); + } + [[nodiscard]] QEasingCurve emphasized() const { return m_easing->emphasized(); } @@ -269,9 +172,10 @@ class Tokens : public ConfigObject { QML_ELEMENT QML_SINGLETON - CONFIG_SUBOBJECT(AppearanceRounding, rounding) - CONFIG_SUBOBJECT(AppearancePadding, padding) - CONFIG_SUBOBJECT(AppearanceSpacing, spacing) + Q_PROPERTY( + ZShell::config::AppearanceRounding* rounding READ rounding CONSTANT) + Q_PROPERTY(ZShell::config::AppearancePadding* padding READ padding CONSTANT) + Q_PROPERTY(ZShell::config::AppearanceSpacing* spacing READ spacing CONSTANT) CONFIG_SUBOBJECT(FontTokens, font) CONFIG_SUBOBJECT(AnimTokens, anim) CONFIG_SUBOBJECT(BarTokens, bar) @@ -279,12 +183,21 @@ class Tokens : public ConfigObject { public: explicit Tokens(QObject* parent = nullptr) : ConfigObject(parent) - , m_rounding(new AppearanceRounding(this)) - , m_padding(new AppearancePadding(this)) - , m_spacing(new AppearanceSpacing(this)) , m_font(new FontTokens(this)) , m_anim(new AnimTokens(this)) - , m_bar(new BarTokens(this)) {} + , m_bar(new BarTokens(this)) { + if (!Config::instance()) new Config(); + } + + [[nodiscard]] AppearanceRounding* rounding() const { + return Config::instance()->appearance()->rounding(); + } + [[nodiscard]] AppearancePadding* padding() const { + return Config::instance()->appearance()->padding(); + } + [[nodiscard]] AppearanceSpacing* spacing() const { + return Config::instance()->appearance()->spacing(); + } static Tokens* create(QQmlEngine*, QJSEngine*) { return new Tokens(); } }; diff --git a/assets/shaders/geminiglow.frag b/assets/shaders/geminiglow.frag new file mode 100755 index 0000000..ad9de36 --- /dev/null +++ b/assets/shaders/geminiglow.frag @@ -0,0 +1,93 @@ +#version 440 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +// NOTE: std140 layout. Order/types must match the ShaderEffect properties by name. +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + vec2 itemSize; // full ShaderEffect size in px (rect + glow padding) + vec2 rectSize; // size of the target rectangle in px + float radius; // corner radius of the target rectangle in px + float glowSize; // how far the glow extends outside the rectangle (px) + float innerGlow; // how far the glow bleeds inside (px), 0 = none + float lineWidth; // width of the bright edge line (px), 0 = none + float phase; // 0..1, loops seamlessly + float intensity; // overall brightness + vec4 color1; + vec4 color2; + vec4 color3; + vec4 color4; +}; + +const float TAU = 6.28318530718; + +// Signed distance to a rounded box centred at the origin. <0 inside, >0 outside. +float sdRoundBox(vec2 p, vec2 halfSize, float r) +{ + vec2 q = abs(p) - (halfSize - r); + return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - r; +} + +// Cyclic 4-colour gradient, t is wrapped to [0,1) +vec3 palette(float t) +{ + t = fract(t) * 4.0; + float f = smoothstep(0.0, 1.0, fract(t)); + if (t < 1.0) return mix(color1.rgb, color2.rgb, f); + if (t < 2.0) return mix(color2.rgb, color3.rgb, f); + if (t < 3.0) return mix(color3.rgb, color4.rgb, f); + return mix(color4.rgb, color1.rgb, f); +} + +// Cheap hash for dithering (avoids banding in soft gradients) +float hash(vec2 p) +{ + return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453); +} + +void main() +{ + // Pixel position relative to the centre of the item + vec2 p = (qt_TexCoord0 - 0.5) * itemSize; + + float r = clamp(radius, 0.0, min(rectSize.x, rectSize.y) * 0.5); + float d = sdRoundBox(p, rectSize * 0.5, r); + + // ---- colour: rotates around the rectangle, slightly wobbling ---- + float ang = atan(p.y, p.x); + float a2 = phase * TAU; + float u = ang / TAU + 0.5 + phase; + u += 0.07 * sin(ang * 2.0 + a2) + 0.04 * sin(ang * 3.0 - a2 * 2.0); + vec3 col = palette(u); + + // ---- intensity falloff ---- + float g = 0.0; + if (d > 0.0) { + float t = clamp(d / max(glowSize, 0.001), 0.0, 1.0); + g = pow(1.0 - t, 3.0); + } else if (innerGlow > 0.0) { + g = exp(d / innerGlow * 3.0); + } + + // Slow "breathing" so the glow feels alive + float pulse = 0.9 + 0.1 * sin(a2 * 2.0 + ang); + g *= pulse; + + // Crisp bright line along the edge + float line = 0.0; + if (lineWidth > 0.0) + line = 1.0 - smoothstep(0.0, lineWidth, abs(d)); + + float a = clamp(g * intensity + line * 0.9, 0.0, 1.0); + + // Brighten the colour a bit where the line is + col = mix(col, vec3(1.0), line * 0.25); + + a += (hash(gl_FragCoord.xy) - 0.5) / 255.0; + a = clamp(a, 0.0, 1.0); + + // Premultiplied alpha output + fragColor = vec4(col * a, a) * qt_Opacity; +} diff --git a/assets/shaders/geminiglow.frag.qsb b/assets/shaders/geminiglow.frag.qsb new file mode 100644 index 0000000000000000000000000000000000000000..233240e6fd7552d50ef537e097b4a5c3c2609215 GIT binary patch literal 3721 zcmV;44tDVX06lSdob6e8lv`yLzi-wyEl^5XTBUp~D9JQUU$&XVA#_vf0=8IXk>c<= zNoJy%Bu(D5GiZ-RP&vn?xTB)tj^e%|F1X?bE{H4c;I6oX8|b;;``ygVW1<{AoZ}zK zIj{5X?=IiH_q*SH_q`I)QX(24B8P}hpnc@i1U;TgG)LR1PIYQhkz69`BO>}IezeGs z4XmUxHOZqXt6a6}f%*TaIz)SEmdf^Sg2wEc?@}^HTJwQ_XOTxfHK{^#M6?VNTa@$) zxmg93ozx(YCaFR`&11H)!itq>hIUhhE~XOVeC7L8Zq_C@-!g8CY zB2{RXT5#vQ?(R(4Tpm!?Sz%8%g_TsH8r7&oP1*s~K;@$DDpjjgqI0Q2Me=DHD#dOp z5o*vhdDLn7Urc1Oe17Oi z>Q{>_v4;7Y@hUaOpGQRN9imMRN7Qe5!)%B8>EZ37AF%iQ8?^Lbn;u3cG&Eq$15`HXvoIO_e*dsg`E|^d7X7MKu2S*mx4Z4>206^doOVvO9S*! z_(b3{eQJmvL4An+sO28oB6L2WH?N{TIvsv(!@67>C(r!T=Ml&q+ZhLa1~86m2jUXHcc6|V(0>$Uw<-Qvs2_>zoFENbgnuDwN%;I2B-+yE z&!Db^e+lR28#}iO{R|>H^T1Wx;xuUEy%aKxi_Ei#=(%@}>|h_C3;%}^Bh$|d?Zx51 z$Iary3sp_M2=}Zn{422s%zrufLyCVDYDwt#hid0KBD(FU&$svf6GRl-bGRV%=QzjT zJh{O3zovSR*!ux`gUJ7wi0UgZeVFinsr=!;cXOW0<;_C>g@|sx>866n4>+Cit#pFg zkJFG{_d!ljpK^(v6K!ukbUORF&Ixk54S8mo&$rHV)XG17JIg1WAV(t4G@pN+w;c3G zY0&0a9u_R~7wWS)U|r7bbJQNQ?=K6{Z%{PLUlXF=8j`;@M86|Mzb`~zuV~)0TSNS> zhv;vG=n}zRc%icO z65!8--b_ZlTPqU5dy zZ#fNH`n5RI4}p!V;V<)E2R_HXoR(PZ_3a)I__iK$9M8+Zmz=y&`5-xY6Y%FFCvOIJ zSjoHvb;&lb0nPVsg}lV_HqsM4 z*!wK{`i;uo=R<3L0a#hdd=YDk%uT?~!MSDZX6W9e{P>dc<7TD*Wjs&5q~iDr{QI(6 z_p9h(B6AC{uc-XpqU65;dFFi`be;z7^WvL!ehYdY^KS*l_us-<6Fc8VZ@!)e?cDPn zU@UVt_0xCJ^Z!NzmUkNw{Q~{}Hf87gup>3{L)6F*l+2HSORe9IoJGO=v8u&8VDom> zGk&6a#vSl6kGQ@EzO40A^mN&?pF#GgYW<(X-Wu@BDo4!wEA`pkq&sSAT@wA5`7_33yr6=${eqgTR+q z|BP70pWlXJ|E^m5uc7ntH(>hQ{vGE`YWW|K`@8bx9(7*+q3qp@`RE>{|4+vQqCyVP-s1#mN}& ztN6B5t$Q?bCcYj6Uso!bRZf6QUXOJGy;Vx)IG!Pu%<)cu-L3ZX1SilvUd6MzJ*x(M zeYSblT8%ZhzpZhC`A*h+aA?i7PJr=zybCk*N&IfBE?$>$gLM`L!ULO8Dlw-w=DEo7&6X1u{IgU92&U3oNHp1UaoQ2$N zZ~}~FB{v(Cd>rzU*NrN#@kR2wQRUSQik{Il;dPGEy^j*s7G7`ulY%8_H=W9->M zFXs2?G3vMT`!aRE9QRAnpZKgCrDlDe&Gf9l2KszvhtXf<%&t*#4~A{=|3uiAcZ9XT zPE_v*CqZwm!VK169>=*Fn5@I!fL1HJ{EcWmE`Ihgc8YrTu7iy99G>CjUGfw)zeZtK z&#y7yBC`Q9dJc{Qm*?(AwRQ}A;U(02#76imwZ92?LfLkaLpfJT$T5B|^;uf>eg)>D z;Ctr69{ z+suJ4HVd$M9iC5{f#vah+Nx%c&G>D{}bn}A=tAj|u{8}V&bcApT+)49OT zL7vW6c{&&0g3pJY^HhvaTqMQ|fJ=;ffL+ifPfvo43zdxt;9}z?vLHRD+Ef zWup#UY&3w?yX0wKC{Imba!H-zC1MhT?k~Fu5eYgDSoQu=_N`$2|RvJih&Xec`!y9CC1ide$5Q{$l7|2JBMR zYQt$Y6Xec(#XACE*@esgxxH+yHxk*7wCF=oc|GiIMZahB&dD|6!(vlbZK z+3+SS{(OM$FHNRQ#V^h5u3TJFP_s1YFF=8A(<@eHTN;_F)(?cGDz#dvxuaS?puuXT zRywy*^rto0nD$yBRlihgY2PwtvRlVKng2GU_5GaflO9*NA>D&=}}hI3;k#@z8p zWWU#(uhgc3F!%Wrk1x$_uh*MJ<^^uFijS+$){5Keb5SeQhzG*cUbW28#w8yyq&qNW z3dY;piZ)_qqlt>F*=V`ZW-JzX*ev<8&6FGVZ0`m7I^d~wM)1ygQ%lYZ2XnGuso zxH{2gQ!uTWdflIH`K1Og95+e+M^xZ!rEH?UIgNQS3k1eh95a=<=){X0qvIZq!X@liAT!Hg3jpiBvl6y2&v&m(OL=V_B}6 z5yN-6L^d;;8_Na@@2^*ihTBcFqf#5DV4}M6rAXaG)>`6dI(q^N-W1Ga)thP9_=9#} zOEYdu)`I98T)7?eJR9Z(RFi3VO>f2&Oe2g1Ok3H=W9*NAt;yI~vyHQ^NhqOTkP`YF?)~Z3Y&5HPIi<>@HYJ-oWkw3YD&ePec!${c_S1Xu-GW+>&G2KTLqBexkj2inic{9! z>?qe|kTQ$|wy5nYBi&PS->nX6klXcSy^5a9T->$|rn2IY>OdJ&FjLiuGn(F%ZIX#O zOeJ1$I&C|LD4!sElsB1FHrrl*AtdiUzQOdvJ>R>)z0efw8d z&iT=atNHPa_WYQ3T~liHM#u+jgsjvSn;xs)e0|oBR_l|V&)ZNiZp`p#W-XR&Ayw8k?S#2SO_&!fOqi+Og!zDeq+E2C?2Vnh nubaKEo4v1_y|0_SubaKEo4v1_)&JYCoBz|;+5Y_tl5~t>$k>?V literal 0 HcmV?d00001