feat: add wallpaper & style nexus page
This commit is contained in:
parent
69fe7c1251
commit
c31cb2a7f6
5 changed files with 345 additions and 2 deletions
|
|
@ -9,6 +9,7 @@ MouseArea {
|
|||
|
||||
property bool disabled
|
||||
property bool showHoverBackground: true
|
||||
property bool manualPressOverride
|
||||
readonly property alias rect: base
|
||||
|
||||
property bool shapeMorph
|
||||
|
|
@ -60,12 +61,17 @@ MouseArea {
|
|||
onPressed: e => press(e.x, e.y)
|
||||
|
||||
onPressedChanged: {
|
||||
if (!pressed && !rippleAnim.running && circle.opacity > 0)
|
||||
if (!(pressed || manualPressOverride) && !rippleAnim.running && circle.opacity > 0)
|
||||
fadeAnim.start();
|
||||
}
|
||||
|
||||
onManualPressOverrideChanged: {
|
||||
if (!(pressed || manualPressOverride) && circleRadius > endRadiusAtPress * 0.99 && !fadeAnim.running)
|
||||
fadeAnim.start();
|
||||
}
|
||||
|
||||
onCircleRadiusChanged: {
|
||||
if (!pressed && circleRadius > endRadiusAtPress * 0.99 && !fadeAnim.running)
|
||||
if (!(pressed || manualPressOverride) && circleRadius > endRadiusAtPress * 0.99 && !fadeAnim.running)
|
||||
fadeAnim.start();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,4 +89,15 @@ Item {
|
|||
nState: nState
|
||||
width: Math.min(Tokens.sizes.nexus.maxNavWidth, Math.round(root.width / 3))
|
||||
}
|
||||
|
||||
Pages {
|
||||
anchors.left: navPane.right
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.leftMargin: navPane.anchors.margins + anchors.margins
|
||||
anchors.margins: Tokens.padding.extraLarge
|
||||
|
||||
nState: nState
|
||||
}
|
||||
}
|
||||
|
|
|
|||
111
modules/nexus/Pages.qml
Normal file
111
modules/nexus/Pages.qml
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import "pages"
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Caelestia.Config
|
||||
import qs.components
|
||||
import qs.services
|
||||
import qs.modules.nexus
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
required property NexusState nState
|
||||
|
||||
readonly property list<Component> pageComps: [
|
||||
Component {
|
||||
WallpaperAndStyle {
|
||||
nState: root.nState
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
property int lastPageIdx
|
||||
property int animOff
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
|
||||
anchors.fill: parent
|
||||
layer.enabled: opacity < 1
|
||||
Component.onCompleted: sourceComponent = root.pageComps[root.nState.currentPageIdx] ?? placeholderComp
|
||||
}
|
||||
|
||||
Connections {
|
||||
function onCurrentPageIdxChanged(): void {
|
||||
switchAnim.complete();
|
||||
root.animOff = root.Tokens.padding.extraLarge * (root.nState.currentPageIdx > root.lastPageIdx ? -1 : 1);
|
||||
switchAnim.start();
|
||||
root.lastPageIdx = root.nState.currentPageIdx;
|
||||
}
|
||||
|
||||
target: root.nState
|
||||
}
|
||||
|
||||
SequentialAnimation {
|
||||
id: switchAnim
|
||||
|
||||
Anim {
|
||||
target: loader
|
||||
property: "opacity"
|
||||
to: 0
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
PropertyAction {
|
||||
target: loader
|
||||
property: "sourceComponent"
|
||||
value: root.pageComps[root.nState.currentPageIdx] ?? placeholderComp
|
||||
}
|
||||
PropertyAction {
|
||||
target: loader.anchors
|
||||
property: "topMargin"
|
||||
value: root.animOff
|
||||
}
|
||||
PropertyAction {
|
||||
target: loader.anchors
|
||||
property: "bottomMargin"
|
||||
value: -root.animOff
|
||||
}
|
||||
ParallelAnimation {
|
||||
Anim {
|
||||
target: loader
|
||||
property: "opacity"
|
||||
from: 0
|
||||
to: 1
|
||||
type: Anim.SlowEffects
|
||||
}
|
||||
Anim {
|
||||
target: loader.anchors
|
||||
properties: "topMargin,bottomMargin"
|
||||
to: 0
|
||||
type: Anim.SlowEffects
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: placeholderComp
|
||||
|
||||
Item {
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: Tokens.padding.extraSmall
|
||||
|
||||
MaterialIcon {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: "handyman"
|
||||
color: Colours.palette.m3outlineVariant
|
||||
font: Tokens.font.icon.extraLarge
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("Page under construction")
|
||||
color: Colours.palette.m3outlineVariant
|
||||
font: Tokens.font.title.large
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
55
modules/nexus/common/ToggleRow.qml
Normal file
55
modules/nexus/common/ToggleRow.qml
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import QtQuick
|
||||
import Caelestia.Config
|
||||
import qs.components
|
||||
import qs.components.controls
|
||||
import qs.services
|
||||
|
||||
StyledSwitch {
|
||||
id: root
|
||||
|
||||
property bool first
|
||||
property bool last
|
||||
|
||||
implicitWidth: implicitContentWidth + implicitIndicatorWidth + Tokens.padding.largeIncreased * 2
|
||||
implicitHeight: Math.max(implicitContentHeight, implicitIndicatorHeight) + Tokens.padding.medium * 2
|
||||
cLayer: 2
|
||||
|
||||
indicator.anchors.verticalCenter: verticalCenter
|
||||
indicator.anchors.right: right
|
||||
indicator.anchors.rightMargin: Tokens.padding.large
|
||||
|
||||
onPressed: stateLayer.press(stateLayer.mouseX, stateLayer.mouseY)
|
||||
|
||||
background: StyledRect {
|
||||
color: Colours.tPalette.m3surfaceContainer
|
||||
topLeftRadius: root.first ? Tokens.rounding.extraLarge : Tokens.rounding.extraSmall
|
||||
topRightRadius: root.first ? Tokens.rounding.extraLarge : Tokens.rounding.extraSmall
|
||||
bottomLeftRadius: root.last ? Tokens.rounding.extraLarge : Tokens.rounding.extraSmall
|
||||
bottomRightRadius: root.last ? Tokens.rounding.extraLarge : Tokens.rounding.extraSmall
|
||||
|
||||
StateLayer {
|
||||
id: stateLayer
|
||||
|
||||
manualPressOverride: root.pressed
|
||||
|
||||
topLeftRadius: parent.topLeftRadius
|
||||
topRightRadius: parent.topRightRadius
|
||||
bottomLeftRadius: parent.bottomLeftRadius
|
||||
bottomRightRadius: parent.bottomRightRadius
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: StyledText {
|
||||
id: label
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: root.indicator.left
|
||||
anchors.leftMargin: Tokens.padding.large
|
||||
anchors.rightMargin: Tokens.spacing.medium
|
||||
|
||||
text: root.text
|
||||
font: Tokens.font.body.small
|
||||
elide: Text.ElideRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
160
modules/nexus/pages/WallpaperAndStyle.qml
Normal file
160
modules/nexus/pages/WallpaperAndStyle.qml
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Caelestia.Components
|
||||
import Caelestia.Config
|
||||
import qs.components
|
||||
import qs.components.controls
|
||||
import qs.services
|
||||
import qs.modules.nexus
|
||||
import qs.modules.nexus.common
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
required property NexusState nState
|
||||
readonly property int cappedWidth: Math.min(800, width)
|
||||
|
||||
spacing: Tokens.spacing.large
|
||||
|
||||
StyledText {
|
||||
text: qsTr("Wallpaper & style")
|
||||
font: Tokens.font.title.large
|
||||
}
|
||||
|
||||
StyledClippingRect {
|
||||
id: wallWrapper
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: Tokens.spacing.extraLarge
|
||||
implicitWidth: {
|
||||
const screen = root.nState.screen;
|
||||
return implicitHeight / screen.height * screen.width;
|
||||
}
|
||||
implicitHeight: {
|
||||
const screen = root.nState.screen;
|
||||
const cWidth = root.cappedWidth;
|
||||
return Math.min(Math.round(cWidth * 0.4), cWidth / screen.width * screen.height);
|
||||
}
|
||||
|
||||
color: Colours.palette.m3surfaceContainer
|
||||
radius: Tokens.rounding.large
|
||||
|
||||
Loader {
|
||||
anchors.centerIn: parent
|
||||
|
||||
opacity: wallImg.status === Image.Ready ? 0 : 1
|
||||
active: opacity > 0
|
||||
|
||||
sourceComponent: StyledRect {
|
||||
implicitWidth: wallLoadingIndicator.implicitSize + Tokens.padding.largeIncreased * 2
|
||||
implicitHeight: wallLoadingIndicator.implicitSize + Tokens.padding.largeIncreased * 2
|
||||
|
||||
color: Colours.palette.m3primaryContainer
|
||||
radius: Tokens.rounding.full
|
||||
|
||||
LoadingIndicator {
|
||||
id: wallLoadingIndicator
|
||||
|
||||
anchors.centerIn: parent
|
||||
containsIcon: true
|
||||
implicitSize: wallWrapper.implicitHeight * 0.4
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
Anim {
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: wallImg
|
||||
|
||||
anchors.fill: parent
|
||||
source: Wallpapers.current
|
||||
asynchronous: true
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
sourceSize: {
|
||||
const dpr = (QsWindow.window as QsWindow)?.devicePixelRatio ?? 1;
|
||||
return Qt.size(width * dpr, height * dpr);
|
||||
}
|
||||
|
||||
retainWhileLoading: true
|
||||
opacity: status === Image.Ready ? 1 : 0
|
||||
|
||||
Behavior on opacity {
|
||||
Anim {
|
||||
type: Anim.SlowEffects
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ButtonRow {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Tokens.spacing.small
|
||||
|
||||
IconTextButton {
|
||||
icon: "wallpaper"
|
||||
text: qsTr("Wallpapers")
|
||||
font: Tokens.font.body.large
|
||||
isRound: true
|
||||
shapeMorph: true
|
||||
type: IconTextButton.Tonal
|
||||
horizontalPadding: Tokens.padding.extraLarge
|
||||
verticalPadding: Tokens.padding.medium
|
||||
onClicked: ; // TODO
|
||||
}
|
||||
|
||||
IconTextButton {
|
||||
icon: "palette"
|
||||
text: qsTr("Colours")
|
||||
font: Tokens.font.body.large
|
||||
isRound: true
|
||||
shapeMorph: true
|
||||
type: IconTextButton.Tonal
|
||||
horizontalPadding: Tokens.padding.extraLarge
|
||||
verticalPadding: Tokens.padding.medium
|
||||
onClicked: ; // TODO
|
||||
}
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
implicitWidth: root.cappedWidth
|
||||
|
||||
first: true
|
||||
text: qsTr("Display wallpaper")
|
||||
checked: Config.background.wallpaperEnabled
|
||||
onToggled: GlobalConfig.background.wallpaperEnabled = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
Layout.topMargin: Tokens.spacing.extraSmall / 2 - parent.spacing
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
implicitWidth: root.cappedWidth
|
||||
|
||||
text: qsTr("Dark theme")
|
||||
checked: !Colours.light
|
||||
onToggled: Colours.setMode(checked ? "dark" : "light")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
Layout.topMargin: Tokens.spacing.extraSmall / 2 - parent.spacing
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
implicitWidth: root.cappedWidth
|
||||
|
||||
last: true
|
||||
text: qsTr("Transparency")
|
||||
checked: Colours.transparency.enabled
|
||||
onToggled: GlobalConfig.appearance.transparency.enabled = checked
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue