Horizontal media widget #16
@@ -0,0 +1,135 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import qs.Config
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
default property alias content: contentColumn.data
|
||||||
|
property string description: ""
|
||||||
|
property bool expanded: false
|
||||||
|
property bool nested: false
|
||||||
|
property bool showBackground: false
|
||||||
|
required property string title
|
||||||
|
|
||||||
|
signal toggleRequested
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: Appearance.spacing.small
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: sectionHeaderItem
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: Math.max(titleRow.implicitHeight + Appearance.padding.normal * 2, 48)
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: titleRow
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Appearance.padding.normal
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Appearance.padding.normal
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Appearance.spacing.normal
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
font.pointSize: Appearance.font.size.larger
|
||||||
|
font.weight: 500
|
||||||
|
text: root.title
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
color: DynamicColors.palette.m3onSurfaceVariant
|
||||||
|
font.pointSize: Appearance.font.size.normal
|
||||||
|
rotation: root.expanded ? 180 : 0
|
||||||
|
text: "expand_more"
|
||||||
|
|
||||||
|
Behavior on rotation {
|
||||||
|
Anim {
|
||||||
|
duration: Appearance.anim.durations.small
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.standard
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StateLayer {
|
||||||
|
function onClicked(): void {
|
||||||
|
root.toggleRequested();
|
||||||
|
root.expanded = !root.expanded;
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
color: DynamicColors.palette.m3onSurface
|
||||||
|
radius: Appearance.rounding.normal
|
||||||
|
showHoverBackground: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: contentWrapper
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: root.expanded ? (contentColumn.implicitHeight + Appearance.spacing.small * 2) : 0
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Behavior on Layout.preferredHeight {
|
||||||
|
Anim {
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.standard
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
id: backgroundRect
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
color: DynamicColors.transparency.enabled ? DynamicColors.layer(DynamicColors.palette.m3surfaceContainer, root.nested ? 3 : 2) : (root.nested ? DynamicColors.palette.m3surfaceContainerHigh : DynamicColors.palette.m3surfaceContainer)
|
||||||
|
opacity: root.showBackground && root.expanded ? 1.0 : 0.0
|
||||||
|
radius: Appearance.rounding.normal
|
||||||
|
visible: root.showBackground
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.standard
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: contentColumn
|
||||||
|
|
||||||
|
anchors.bottomMargin: Appearance.spacing.small
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Appearance.padding.normal
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Appearance.padding.normal
|
||||||
|
opacity: root.expanded ? 1.0 : 0.0
|
||||||
|
spacing: Appearance.spacing.small
|
||||||
|
y: Appearance.spacing.small
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.standard
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: descriptionText
|
||||||
|
|
||||||
|
Layout.bottomMargin: root.description !== "" ? Appearance.spacing.small : 0
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: root.description !== "" ? Appearance.spacing.smaller : 0
|
||||||
|
color: DynamicColors.palette.m3onSurfaceVariant
|
||||||
|
font.pointSize: Appearance.font.size.small
|
||||||
|
text: root.description
|
||||||
|
visible: root.description !== ""
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import qs.Config
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string displayText: root.value.toString()
|
||||||
|
property bool isEditing: false
|
||||||
|
property real max: Infinity
|
||||||
|
property real min: -Infinity
|
||||||
|
property alias repeatRate: timer.interval
|
||||||
|
property real step: 1
|
||||||
|
property real value
|
||||||
|
|
||||||
|
signal valueModified(value: real)
|
||||||
|
|
||||||
|
spacing: Appearance.spacing.small
|
||||||
|
|
||||||
|
onValueChanged: {
|
||||||
|
if (!root.isEditing) {
|
||||||
|
root.displayText = root.value.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomTextField {
|
||||||
|
id: textField
|
||||||
|
|
||||||
|
inputMethodHints: Qt.ImhFormattedNumbersOnly
|
||||||
|
leftPadding: Appearance.padding.normal
|
||||||
|
padding: Appearance.padding.small
|
||||||
|
rightPadding: Appearance.padding.normal
|
||||||
|
text: root.isEditing ? text : root.displayText
|
||||||
|
|
||||||
|
background: CustomRect {
|
||||||
|
color: DynamicColors.tPalette.m3surfaceContainerHigh
|
||||||
|
implicitWidth: 100
|
||||||
|
radius: Appearance.rounding.small
|
||||||
|
}
|
||||||
|
validator: DoubleValidator {
|
||||||
|
bottom: root.min
|
||||||
|
decimals: root.step < 1 ? Math.max(1, Math.ceil(-Math.log10(root.step))) : 0
|
||||||
|
top: root.max
|
||||||
|
}
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
const numValue = parseFloat(text);
|
||||||
|
if (!isNaN(numValue)) {
|
||||||
|
const clampedValue = Math.max(root.min, Math.min(root.max, numValue));
|
||||||
|
root.value = clampedValue;
|
||||||
|
root.displayText = clampedValue.toString();
|
||||||
|
root.valueModified(clampedValue);
|
||||||
|
} else {
|
||||||
|
text = root.displayText;
|
||||||
|
}
|
||||||
|
root.isEditing = false;
|
||||||
|
}
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
root.isEditing = true;
|
||||||
|
} else {
|
||||||
|
root.isEditing = false;
|
||||||
|
root.displayText = root.value.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onEditingFinished: {
|
||||||
|
if (text !== root.displayText) {
|
||||||
|
const numValue = parseFloat(text);
|
||||||
|
if (!isNaN(numValue)) {
|
||||||
|
const clampedValue = Math.max(root.min, Math.min(root.max, numValue));
|
||||||
|
root.value = clampedValue;
|
||||||
|
root.displayText = clampedValue.toString();
|
||||||
|
root.valueModified(clampedValue);
|
||||||
|
} else {
|
||||||
|
text = root.displayText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
root.isEditing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
color: DynamicColors.palette.m3primary
|
||||||
|
implicitHeight: upIcon.implicitHeight + Appearance.padding.small * 2
|
||||||
|
implicitWidth: implicitHeight
|
||||||
|
radius: Appearance.rounding.small
|
||||||
|
|
||||||
|
StateLayer {
|
||||||
|
id: upState
|
||||||
|
|
||||||
|
function onClicked(): void {
|
||||||
|
let newValue = Math.min(root.max, root.value + root.step);
|
||||||
|
// Round to avoid floating point precision errors
|
||||||
|
const decimals = root.step < 1 ? Math.max(1, Math.ceil(-Math.log10(root.step))) : 0;
|
||||||
|
newValue = Math.round(newValue * Math.pow(10, decimals)) / Math.pow(10, decimals);
|
||||||
|
root.value = newValue;
|
||||||
|
root.displayText = newValue.toString();
|
||||||
|
root.valueModified(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
color: DynamicColors.palette.m3onPrimary
|
||||||
|
|
||||||
|
onPressAndHold: timer.start()
|
||||||
|
onReleased: timer.stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
id: upIcon
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: DynamicColors.palette.m3onPrimary
|
||||||
|
text: "keyboard_arrow_up"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
color: DynamicColors.palette.m3primary
|
||||||
|
implicitHeight: downIcon.implicitHeight + Appearance.padding.small * 2
|
||||||
|
implicitWidth: implicitHeight
|
||||||
|
radius: Appearance.rounding.small
|
||||||
|
|
||||||
|
StateLayer {
|
||||||
|
id: downState
|
||||||
|
|
||||||
|
function onClicked(): void {
|
||||||
|
let newValue = Math.max(root.min, root.value - root.step);
|
||||||
|
// Round to avoid floating point precision errors
|
||||||
|
const decimals = root.step < 1 ? Math.max(1, Math.ceil(-Math.log10(root.step))) : 0;
|
||||||
|
newValue = Math.round(newValue * Math.pow(10, decimals)) / Math.pow(10, decimals);
|
||||||
|
root.value = newValue;
|
||||||
|
root.displayText = newValue.toString();
|
||||||
|
root.valueModified(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
color: DynamicColors.palette.m3onPrimary
|
||||||
|
|
||||||
|
onPressAndHold: timer.start()
|
||||||
|
onReleased: timer.stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
id: downIcon
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: DynamicColors.palette.m3onPrimary
|
||||||
|
text: "keyboard_arrow_down"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: timer
|
||||||
|
|
||||||
|
interval: 100
|
||||||
|
repeat: true
|
||||||
|
triggeredOnStart: true
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
if (upState.pressed)
|
||||||
|
upState.onClicked();
|
||||||
|
else if (downState.pressed)
|
||||||
|
downState.onClicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,200 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Effects
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property color color: DynamicColors.palette.m3onSurface
|
||||||
|
property int fadeStrengthAnimMs: 180
|
||||||
|
property real fadeStrengthIdle: 0.0
|
||||||
|
property real fadeStrengthMoving: 1.0
|
||||||
|
property alias font: elideText.font
|
||||||
|
property int gap: 40
|
||||||
|
property alias horizontalAlignment: elideText.horizontalAlignment
|
||||||
|
property bool leftFadeEnabled: false
|
||||||
|
property real leftFadeStrength: overflowing && leftFadeEnabled ? fadeStrengthMoving : fadeStrengthIdle
|
||||||
|
property int leftFadeWidth: 28
|
||||||
|
property bool marqueeEnabled: true
|
||||||
|
readonly property bool overflowing: metrics.width > root.width
|
||||||
|
property int pauseMs: 1200
|
||||||
|
property real pixelsPerSecond: 40
|
||||||
|
property real rightFadeStrength: overflowing ? fadeStrengthMoving : fadeStrengthIdle
|
||||||
|
property int rightFadeWidth: 28
|
||||||
|
property bool sliding: false
|
||||||
|
property alias text: elideText.text
|
||||||
|
|
||||||
|
function durationForDistance(px): int {
|
||||||
|
return Math.max(1, Math.round(Math.abs(px) / root.pixelsPerSecond * 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
implicitHeight: elideText.implicitHeight
|
||||||
|
|
||||||
|
Behavior on leftFadeStrength {
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on rightFadeStrength {
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onTextChanged: strip.x = 0
|
||||||
|
onVisibleChanged: if (!visible)
|
||||||
|
strip.x = 0
|
||||||
|
onWidthChanged: strip.x = 0
|
||||||
|
|
||||||
|
TextMetrics {
|
||||||
|
id: metrics
|
||||||
|
|
||||||
|
font: elideText.font
|
||||||
|
text: elideText.text
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: elideText
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: root.color
|
||||||
|
elide: Text.ElideRight
|
||||||
|
visible: !root.overflowing
|
||||||
|
width: root.width
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: marqueeViewport
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
clip: true
|
||||||
|
layer.enabled: true
|
||||||
|
visible: root.overflowing
|
||||||
|
|
||||||
|
layer.effect: OpacityMask {
|
||||||
|
maskSource: rightFadeMask
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: strip
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
height: t1.implicitHeight
|
||||||
|
width: t1.width + root.gap + t2.width
|
||||||
|
x: 0
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: t1
|
||||||
|
|
||||||
|
color: root.color
|
||||||
|
text: elideText.text
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: t2
|
||||||
|
|
||||||
|
color: root.color
|
||||||
|
text: t1.text
|
||||||
|
x: t1.width + root.gap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SequentialAnimation {
|
||||||
|
id: marqueeAnim
|
||||||
|
|
||||||
|
loops: Animation.Infinite
|
||||||
|
running: root.marqueeEnabled && root.overflowing && root.visible
|
||||||
|
|
||||||
|
ScriptAction {
|
||||||
|
script: {
|
||||||
|
strip.x = 0;
|
||||||
|
root.sliding = false;
|
||||||
|
root.leftFadeEnabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PauseAnimation {
|
||||||
|
duration: root.pauseMs
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptAction {
|
||||||
|
script: {
|
||||||
|
root.sliding = true;
|
||||||
|
root.leftFadeEnabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
duration: root.durationForDistance(t1.width)
|
||||||
|
easing.bezierCurve: Easing.Linear
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
from: 0
|
||||||
|
property: "x"
|
||||||
|
target: strip
|
||||||
|
to: -t1.width
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptAction {
|
||||||
|
script: {
|
||||||
|
root.leftFadeEnabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
duration: root.durationForDistance(root.gap)
|
||||||
|
easing.bezierCurve: Easing.Linear
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
from: -t1.width
|
||||||
|
property: "x"
|
||||||
|
target: strip
|
||||||
|
to: -(t1.width + root.gap)
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptAction {
|
||||||
|
script: {
|
||||||
|
root.sliding = false;
|
||||||
|
strip.x = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rightFadeMask
|
||||||
|
|
||||||
|
readonly property real fadeStartPos: {
|
||||||
|
const w = Math.max(1, width);
|
||||||
|
return Math.max(0, Math.min(1, (w - root.rightFadeWidth) / w));
|
||||||
|
}
|
||||||
|
readonly property real leftFadeEndPos: {
|
||||||
|
const w = Math.max(1, width);
|
||||||
|
return Math.max(0, Math.min(1, root.leftFadeWidth / w));
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors.fill: marqueeViewport
|
||||||
|
layer.enabled: true
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
gradient: Gradient {
|
||||||
|
orientation: Gradient.Horizontal
|
||||||
|
|
||||||
|
GradientStop {
|
||||||
|
color: Qt.rgba(1, 1, 1, 1.0 - root.leftFadeStrength)
|
||||||
|
position: 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
GradientStop {
|
||||||
|
color: Qt.rgba(1, 1, 1, 1.0)
|
||||||
|
position: rightFadeMask.leftFadeEndPos
|
||||||
|
}
|
||||||
|
|
||||||
|
GradientStop {
|
||||||
|
color: Qt.rgba(1, 1, 1, 1.0)
|
||||||
|
position: rightFadeMask.fadeStartPos
|
||||||
|
}
|
||||||
|
|
||||||
|
GradientStop {
|
||||||
|
color: Qt.rgba(1, 1, 1, 1.0 - root.rightFadeStrength)
|
||||||
|
position: 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import qs.Config
|
||||||
|
|
||||||
|
Elevation {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property MenuItem active: items[0] ?? null
|
||||||
|
property bool expanded
|
||||||
|
property list<MenuItem> items
|
||||||
|
|
||||||
|
signal itemSelected(item: MenuItem)
|
||||||
|
|
||||||
|
implicitHeight: root.expanded ? column.implicitHeight : 0
|
||||||
|
implicitWidth: Math.max(200, column.implicitWidth)
|
||||||
|
level: 2
|
||||||
|
opacity: root.expanded ? 1 : 0
|
||||||
|
radius: Appearance.rounding.small / 2
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
Anim {
|
||||||
|
duration: Appearance.anim.durations.expressiveDefaultSpatial
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {
|
||||||
|
duration: Appearance.anim.durations.expressiveDefaultSpatial
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomClippingRect {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: DynamicColors.palette.m3surfaceContainer
|
||||||
|
radius: parent.radius
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: column
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.items
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
id: item
|
||||||
|
|
||||||
|
readonly property bool active: modelData === root.active
|
||||||
|
required property int index
|
||||||
|
required property MenuItem modelData
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: Qt.alpha(DynamicColors.palette.m3secondaryContainer, active ? 1 : 0)
|
||||||
|
implicitHeight: menuOptionRow.implicitHeight + Appearance.padding.normal * 2
|
||||||
|
implicitWidth: menuOptionRow.implicitWidth + Appearance.padding.normal * 2
|
||||||
|
|
||||||
|
StateLayer {
|
||||||
|
function onClicked(): void {
|
||||||
|
root.itemSelected(item.modelData);
|
||||||
|
root.active = item.modelData;
|
||||||
|
root.expanded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
color: item.active ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurface
|
||||||
|
disabled: !root.expanded
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: menuOptionRow
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Appearance.padding.normal
|
||||||
|
spacing: Appearance.spacing.small
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
color: item.active ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurfaceVariant
|
||||||
|
text: item.modelData.icon
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: item.active ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurface
|
||||||
|
text: item.modelData.text
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
active: item.modelData.trailingIcon.length > 0
|
||||||
|
visible: active
|
||||||
|
|
||||||
|
sourceComponent: MaterialIcon {
|
||||||
|
color: item.active ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurface
|
||||||
|
text: item.modelData.trailingIcon
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import QtQuick
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
property string activeIcon: icon
|
||||||
|
property string activeText: text
|
||||||
|
property string icon
|
||||||
|
required property string text
|
||||||
|
property string trailingIcon
|
||||||
|
property var value
|
||||||
|
|
||||||
|
signal clicked
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import qs.Config
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property string label
|
||||||
|
required property real max
|
||||||
|
required property real min
|
||||||
|
property var onValueModified: function (value) {}
|
||||||
|
property real step: 1
|
||||||
|
required property real value
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: DynamicColors.layer(DynamicColors.palette.m3surfaceContainer, 2)
|
||||||
|
implicitHeight: row.implicitHeight + Appearance.padding.large * 2
|
||||||
|
radius: Appearance.rounding.normal
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: row
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.margins: Appearance.padding.large
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Appearance.spacing.normal
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: root.label
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomSpinBox {
|
||||||
|
max: root.max
|
||||||
|
min: root.min
|
||||||
|
step: root.step
|
||||||
|
value: root.value
|
||||||
|
|
||||||
|
onValueModified: value => {
|
||||||
|
root.onValueModified(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-4
@@ -28,7 +28,7 @@ Variants {
|
|||||||
property bool trayMenuVisible: false
|
property bool trayMenuVisible: false
|
||||||
|
|
||||||
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
||||||
WlrLayershell.keyboardFocus: visibilities.launcher || visibilities.sidebar || visibilities.dashboard ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
WlrLayershell.keyboardFocus: visibilities.launcher || visibilities.sidebar || visibilities.dashboard || visibilities.settings ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||||
WlrLayershell.namespace: "ZShell-Bar"
|
WlrLayershell.namespace: "ZShell-Bar"
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
contentItem.focus: true
|
contentItem.focus: true
|
||||||
@@ -37,8 +37,6 @@ Variants {
|
|||||||
mask: Region {
|
mask: Region {
|
||||||
id: region
|
id: region
|
||||||
|
|
||||||
property list<Region> nullRegions: []
|
|
||||||
|
|
||||||
height: bar.screen.height - backgroundRect.implicitHeight
|
height: bar.screen.height - backgroundRect.implicitHeight
|
||||||
intersection: Intersection.Xor
|
intersection: Intersection.Xor
|
||||||
regions: popoutRegions.instances
|
regions: popoutRegions.instances
|
||||||
@@ -53,6 +51,7 @@ Variants {
|
|||||||
visibilities.sidebar = false;
|
visibilities.sidebar = false;
|
||||||
visibilities.dashboard = false;
|
visibilities.dashboard = false;
|
||||||
visibilities.osd = false;
|
visibilities.osd = false;
|
||||||
|
visibilities.settings = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
@@ -98,7 +97,7 @@ Variants {
|
|||||||
HyprlandFocusGrab {
|
HyprlandFocusGrab {
|
||||||
id: focusGrab
|
id: focusGrab
|
||||||
|
|
||||||
active: visibilities.launcher || visibilities.sidebar || visibilities.dashboard || (panels.popouts.hasCurrent && panels.popouts.currentName.startsWith("traymenu"))
|
active: visibilities.launcher || visibilities.sidebar || visibilities.dashboard || visibilities.settings || (panels.popouts.hasCurrent && panels.popouts.currentName.startsWith("traymenu"))
|
||||||
windows: [bar]
|
windows: [bar]
|
||||||
|
|
||||||
onCleared: {
|
onCleared: {
|
||||||
@@ -106,6 +105,7 @@ Variants {
|
|||||||
visibilities.sidebar = false;
|
visibilities.sidebar = false;
|
||||||
visibilities.dashboard = false;
|
visibilities.dashboard = false;
|
||||||
visibilities.osd = false;
|
visibilities.osd = false;
|
||||||
|
visibilities.settings = false;
|
||||||
panels.popouts.hasCurrent = false;
|
panels.popouts.hasCurrent = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import QtQuick
|
|||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import qs.Helpers
|
import qs.Helpers
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import qs.Paths
|
|
||||||
import qs.Modules
|
import qs.Modules
|
||||||
import qs.Config
|
import qs.Config
|
||||||
import qs.Modules.Dashboard.Dash
|
import qs.Modules.Dashboard.Dash
|
||||||
@@ -86,18 +85,6 @@ GridLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rect {
|
|
||||||
// Layout.row: 1
|
|
||||||
// Layout.preferredWidth: dateTime.implicitWidth
|
|
||||||
// Layout.fillHeight: true
|
|
||||||
//
|
|
||||||
// radius: root.radius
|
|
||||||
//
|
|
||||||
// DateTime {
|
|
||||||
// id: dateTime
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
Rect {
|
Rect {
|
||||||
Layout.column: 0
|
Layout.column: 0
|
||||||
Layout.columnSpan: 3
|
Layout.columnSpan: 3
|
||||||
@@ -128,11 +115,11 @@ GridLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Rect {
|
Rect {
|
||||||
Layout.column: 5
|
Layout.column: 0
|
||||||
Layout.fillHeight: true
|
Layout.columnSpan: 5
|
||||||
Layout.preferredWidth: media.implicitWidth
|
Layout.fillWidth: true
|
||||||
Layout.row: 0
|
Layout.preferredHeight: media.implicitHeight
|
||||||
Layout.rowSpan: 2
|
Layout.row: 2
|
||||||
radius: root.radius
|
radius: root.radius
|
||||||
|
|
||||||
Media {
|
Media {
|
||||||
|
|||||||
+108
-103
@@ -1,12 +1,10 @@
|
|||||||
import ZShell.Services
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
import QtQuick.Shapes
|
import QtQuick.Shapes
|
||||||
import qs.Daemons
|
import qs.Daemons
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import qs.Config
|
import qs.Config
|
||||||
import qs.Helpers
|
import qs.Helpers
|
||||||
import qs.Modules
|
|
||||||
import qs.Paths
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
@@ -15,10 +13,11 @@ Item {
|
|||||||
const active = Players.active;
|
const active = Players.active;
|
||||||
return active?.length ? active.position / active.length : 0;
|
return active?.length ? active.position / active.length : 0;
|
||||||
}
|
}
|
||||||
|
property int rowHeight: Appearance.padding.large + Config.dashboard.sizes.mediaProgressThickness + Appearance.spacing.small
|
||||||
|
|
||||||
anchors.bottom: parent.bottom
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.right: parent.right
|
||||||
implicitWidth: Config.dashboard.sizes.mediaWidth
|
implicitHeight: cover.height + rowHeight * 2
|
||||||
|
|
||||||
Behavior on playerProgress {
|
Behavior on playerProgress {
|
||||||
Anim {
|
Anim {
|
||||||
@@ -35,10 +34,6 @@ Item {
|
|||||||
onTriggered: Players.active?.positionChanged()
|
onTriggered: Players.active?.positionChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceRef {
|
|
||||||
service: Audio.beatTracker
|
|
||||||
}
|
|
||||||
|
|
||||||
Shape {
|
Shape {
|
||||||
preferredRendererType: Shape.CurveRenderer
|
preferredRendererType: Shape.CurveRenderer
|
||||||
|
|
||||||
@@ -85,114 +80,124 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomClippingRect {
|
RowLayout {
|
||||||
id: cover
|
id: layout
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.margins: Appearance.padding.large + Config.dashboard.sizes.mediaProgressThickness + Appearance.spacing.small
|
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
implicitHeight: root.implicitHeight
|
||||||
color: DynamicColors.tPalette.m3surfaceContainerHigh
|
|
||||||
implicitHeight: width
|
|
||||||
radius: Infinity
|
|
||||||
|
|
||||||
MaterialIcon {
|
CustomClippingRect {
|
||||||
anchors.centerIn: parent
|
id: cover
|
||||||
color: DynamicColors.palette.m3onSurfaceVariant
|
|
||||||
font.pointSize: (parent.width * 0.4) || 1
|
|
||||||
grade: 200
|
|
||||||
text: "art_track"
|
|
||||||
}
|
|
||||||
|
|
||||||
Image {
|
Layout.alignment: Qt.AlignLeft
|
||||||
id: image
|
Layout.bottomMargin: Appearance.padding.large + Config.dashboard.sizes.mediaProgressThickness + Appearance.spacing.small
|
||||||
|
Layout.leftMargin: Appearance.padding.large + Config.dashboard.sizes.mediaProgressThickness + Appearance.spacing.small
|
||||||
|
Layout.preferredHeight: Config.dashboard.sizes.mediaCoverArtSize
|
||||||
|
Layout.preferredWidth: Config.dashboard.sizes.mediaCoverArtSize
|
||||||
|
Layout.topMargin: Appearance.padding.large + Config.dashboard.sizes.mediaProgressThickness + Appearance.spacing.small
|
||||||
|
color: DynamicColors.tPalette.m3surfaceContainerHigh
|
||||||
|
radius: Infinity
|
||||||
|
|
||||||
anchors.fill: parent
|
MaterialIcon {
|
||||||
asynchronous: true
|
anchors.centerIn: parent
|
||||||
fillMode: Image.PreserveAspectCrop
|
color: DynamicColors.palette.m3onSurfaceVariant
|
||||||
source: Players.active?.trackArtUrl ?? ""
|
font.pointSize: (parent.width * 0.4) || 1
|
||||||
sourceSize.height: height
|
grade: 200
|
||||||
sourceSize.width: width
|
text: "art_track"
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomText {
|
|
||||||
id: title
|
|
||||||
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.top: cover.bottom
|
|
||||||
anchors.topMargin: Appearance.spacing.normal
|
|
||||||
animate: true
|
|
||||||
color: DynamicColors.palette.m3primary
|
|
||||||
elide: Text.ElideRight
|
|
||||||
font.pointSize: Appearance.font.size.normal
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: (Players.active?.trackTitle ?? qsTr("No media")) || qsTr("Unknown title")
|
|
||||||
width: parent.implicitWidth - Appearance.padding.large * 2
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomText {
|
|
||||||
id: album
|
|
||||||
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.top: title.bottom
|
|
||||||
anchors.topMargin: Appearance.spacing.small
|
|
||||||
animate: true
|
|
||||||
color: DynamicColors.palette.m3outline
|
|
||||||
elide: Text.ElideRight
|
|
||||||
font.pointSize: Appearance.font.size.small
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: (Players.active?.trackAlbum ?? qsTr("No media")) || qsTr("Unknown album")
|
|
||||||
width: parent.implicitWidth - Appearance.padding.large * 2
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomText {
|
|
||||||
id: artist
|
|
||||||
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.top: album.bottom
|
|
||||||
anchors.topMargin: Appearance.spacing.small
|
|
||||||
animate: true
|
|
||||||
color: DynamicColors.palette.m3secondary
|
|
||||||
elide: Text.ElideRight
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: (Players.active?.trackArtist ?? qsTr("No media")) || qsTr("Unknown artist")
|
|
||||||
width: parent.implicitWidth - Appearance.padding.large * 2
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: controls
|
|
||||||
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.top: artist.bottom
|
|
||||||
anchors.topMargin: Appearance.spacing.smaller
|
|
||||||
spacing: Appearance.spacing.small
|
|
||||||
|
|
||||||
Control {
|
|
||||||
function onClicked(): void {
|
|
||||||
Players.active?.previous();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canUse: Players.active?.canGoPrevious ?? false
|
Image {
|
||||||
icon: "skip_previous"
|
id: image
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
asynchronous: true
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
source: Players.active?.trackArtUrl ?? ""
|
||||||
|
sourceSize.height: Math.floor(height)
|
||||||
|
sourceSize.width: Math.floor(width)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Control {
|
CustomRect {
|
||||||
function onClicked(): void {
|
Layout.fillWidth: true
|
||||||
Players.active?.togglePlaying();
|
Layout.preferredHeight: childrenRect.height
|
||||||
|
|
||||||
|
MarqueeText {
|
||||||
|
id: title
|
||||||
|
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.top: parent.top
|
||||||
|
color: DynamicColors.palette.m3primary
|
||||||
|
font.pointSize: Appearance.font.size.normal
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
pauseMs: 4000
|
||||||
|
text: (Players.active?.trackTitle ?? qsTr("No media")) || qsTr("Unknown title")
|
||||||
|
width: parent.width - Appearance.padding.large * 4
|
||||||
}
|
}
|
||||||
|
|
||||||
canUse: Players.active?.canTogglePlaying ?? false
|
CustomText {
|
||||||
icon: Players.active?.isPlaying ? "pause" : "play_arrow"
|
id: album
|
||||||
}
|
|
||||||
|
|
||||||
Control {
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
function onClicked(): void {
|
anchors.top: title.bottom
|
||||||
Players.active?.next();
|
anchors.topMargin: Appearance.spacing.small
|
||||||
|
animate: true
|
||||||
|
color: DynamicColors.palette.m3outline
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font.pointSize: Appearance.font.size.small
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: (Players.active?.trackAlbum ?? qsTr("No media")) || qsTr("Unknown album")
|
||||||
}
|
}
|
||||||
|
|
||||||
canUse: Players.active?.canGoNext ?? false
|
CustomText {
|
||||||
icon: "skip_next"
|
id: artist
|
||||||
|
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.top: album.bottom
|
||||||
|
anchors.topMargin: Appearance.spacing.small
|
||||||
|
animate: true
|
||||||
|
color: DynamicColors.palette.m3secondary
|
||||||
|
elide: Text.ElideRight
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: (Players.active?.trackArtist ?? qsTr("No media")) || qsTr("Unknown artist")
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: controls
|
||||||
|
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.top: artist.bottom
|
||||||
|
anchors.topMargin: Appearance.spacing.smaller
|
||||||
|
spacing: Appearance.spacing.small
|
||||||
|
|
||||||
|
Control {
|
||||||
|
function onClicked(): void {
|
||||||
|
Players.active?.previous();
|
||||||
|
}
|
||||||
|
|
||||||
|
canUse: Players.active?.canGoPrevious ?? false
|
||||||
|
icon: "skip_previous"
|
||||||
|
}
|
||||||
|
|
||||||
|
Control {
|
||||||
|
function onClicked(): void {
|
||||||
|
Players.active?.togglePlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
canUse: Players.active?.canTogglePlaying ?? false
|
||||||
|
icon: Players.active?.isPlaying ? "pause" : "play_arrow"
|
||||||
|
}
|
||||||
|
|
||||||
|
Control {
|
||||||
|
function onClicked(): void {
|
||||||
|
Players.active?.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
canUse: Players.active?.canGoNext ?? false
|
||||||
|
icon: "skip_next"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Shapes
|
|
||||||
import qs.Components
|
|
||||||
import qs.Config
|
|
||||||
|
|
||||||
ShapePath {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
readonly property bool flatten: wrapper.height < rounding * 2
|
|
||||||
readonly property real rounding: 8
|
|
||||||
readonly property real roundingY: flatten ? wrapper.height / 2 : rounding
|
|
||||||
required property Wrapper wrapper
|
|
||||||
|
|
||||||
fillColor: DynamicColors.palette.m3surface
|
|
||||||
strokeWidth: -1
|
|
||||||
|
|
||||||
Behavior on fillColor {
|
|
||||||
CAnim {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PathArc {
|
|
||||||
radiusX: root.rounding
|
|
||||||
radiusY: Math.min(root.roundingY, root.wrapper.height)
|
|
||||||
relativeX: root.rounding
|
|
||||||
relativeY: root.roundingY
|
|
||||||
}
|
|
||||||
|
|
||||||
PathLine {
|
|
||||||
relativeX: 0
|
|
||||||
relativeY: root.wrapper.height - root.roundingY * 2
|
|
||||||
}
|
|
||||||
|
|
||||||
PathArc {
|
|
||||||
direction: PathArc.Counterclockwise
|
|
||||||
radiusX: root.rounding
|
|
||||||
radiusY: Math.min(root.rounding, root.wrapper.height)
|
|
||||||
relativeX: root.rounding
|
|
||||||
relativeY: root.roundingY
|
|
||||||
}
|
|
||||||
|
|
||||||
PathLine {
|
|
||||||
relativeX: root.wrapper.width - root.rounding * 2
|
|
||||||
relativeY: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
PathArc {
|
|
||||||
direction: PathArc.Counterclockwise
|
|
||||||
radiusX: root.rounding
|
|
||||||
radiusY: Math.min(root.rounding, root.wrapper.height)
|
|
||||||
relativeX: root.rounding
|
|
||||||
relativeY: -root.roundingY
|
|
||||||
}
|
|
||||||
|
|
||||||
PathLine {
|
|
||||||
relativeX: 0
|
|
||||||
relativeY: -(root.wrapper.height - root.roundingY * 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
PathArc {
|
|
||||||
radiusX: root.rounding
|
|
||||||
radiusY: Math.min(root.rounding, root.wrapper.height)
|
|
||||||
relativeX: root.rounding
|
|
||||||
relativeY: -root.roundingY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,178 +0,0 @@
|
|||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Widgets
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import qs.Components
|
|
||||||
import qs.Modules as Modules
|
|
||||||
import qs.Config
|
|
||||||
import qs.Helpers
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property Item content
|
|
||||||
|
|
||||||
implicitHeight: clayout.contentHeight + Appearance.padding.smaller * 2
|
|
||||||
implicitWidth: clayout.contentWidth + Appearance.padding.smaller * 2
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: listModel
|
|
||||||
|
|
||||||
ListElement {
|
|
||||||
icon: "settings"
|
|
||||||
name: "General"
|
|
||||||
}
|
|
||||||
|
|
||||||
ListElement {
|
|
||||||
icon: "wallpaper"
|
|
||||||
name: "Wallpaper"
|
|
||||||
}
|
|
||||||
|
|
||||||
ListElement {
|
|
||||||
icon: "settop_component"
|
|
||||||
name: "Bar"
|
|
||||||
}
|
|
||||||
|
|
||||||
ListElement {
|
|
||||||
icon: "lock"
|
|
||||||
name: "Lockscreen"
|
|
||||||
}
|
|
||||||
|
|
||||||
ListElement {
|
|
||||||
icon: "build_circle"
|
|
||||||
name: "Services"
|
|
||||||
}
|
|
||||||
|
|
||||||
ListElement {
|
|
||||||
icon: "notifications"
|
|
||||||
name: "Notifications"
|
|
||||||
}
|
|
||||||
|
|
||||||
ListElement {
|
|
||||||
icon: "view_sidebar"
|
|
||||||
name: "Sidebar"
|
|
||||||
}
|
|
||||||
|
|
||||||
ListElement {
|
|
||||||
icon: "handyman"
|
|
||||||
name: "Utilities"
|
|
||||||
}
|
|
||||||
|
|
||||||
ListElement {
|
|
||||||
icon: "dashboard"
|
|
||||||
name: "Dashboard"
|
|
||||||
}
|
|
||||||
|
|
||||||
ListElement {
|
|
||||||
icon: "colors"
|
|
||||||
name: "Appearance"
|
|
||||||
}
|
|
||||||
|
|
||||||
ListElement {
|
|
||||||
icon: "display_settings"
|
|
||||||
name: "On screen display"
|
|
||||||
}
|
|
||||||
|
|
||||||
ListElement {
|
|
||||||
icon: "rocket_launch"
|
|
||||||
name: "Launcher"
|
|
||||||
}
|
|
||||||
|
|
||||||
ListElement {
|
|
||||||
icon: "colors"
|
|
||||||
name: "Colors"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: DynamicColors.tPalette.m3surfaceContainer
|
|
||||||
radius: 4
|
|
||||||
|
|
||||||
CustomListView {
|
|
||||||
id: clayout
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
contentHeight: contentItem.childrenRect.height
|
|
||||||
contentWidth: contentItem.childrenRect.width
|
|
||||||
highlightFollowsCurrentItem: false
|
|
||||||
implicitHeight: contentItem.childrenRect.height
|
|
||||||
implicitWidth: contentItem.childrenRect.width
|
|
||||||
model: listModel
|
|
||||||
spacing: 5
|
|
||||||
|
|
||||||
delegate: Category {
|
|
||||||
}
|
|
||||||
highlight: CustomRect {
|
|
||||||
color: DynamicColors.palette.m3primary
|
|
||||||
implicitHeight: clayout.currentItem?.implicitHeight ?? 0
|
|
||||||
implicitWidth: clayout.width
|
|
||||||
radius: 4
|
|
||||||
y: clayout.currentItem?.y ?? 0
|
|
||||||
|
|
||||||
Behavior on y {
|
|
||||||
Anim {
|
|
||||||
duration: Appearance.anim.durations.small
|
|
||||||
easing.bezierCurve: Appearance.anim.curves.expressiveEffects
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
component Category: CustomRect {
|
|
||||||
id: categoryItem
|
|
||||||
|
|
||||||
required property string icon
|
|
||||||
required property int index
|
|
||||||
required property string name
|
|
||||||
|
|
||||||
implicitHeight: 42
|
|
||||||
implicitWidth: 200
|
|
||||||
radius: 4
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: layout
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.margins: Appearance.padding.smaller
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
id: icon
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.preferredWidth: icon.contentWidth
|
|
||||||
color: categoryItem.index === clayout.currentIndex ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface
|
|
||||||
font.pointSize: 22
|
|
||||||
text: categoryItem.icon
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomText {
|
|
||||||
id: text
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: Appearance.spacing.normal
|
|
||||||
color: categoryItem.index === clayout.currentIndex ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface
|
|
||||||
text: categoryItem.name
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StateLayer {
|
|
||||||
id: layer
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
root.content.currentCategory = categoryItem.name.toLowerCase();
|
|
||||||
clayout.currentIndex = categoryItem.index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
import Quickshell
|
|
||||||
import Quickshell.Widgets
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import qs.Components
|
|
||||||
import qs.Modules as Modules
|
|
||||||
import qs.Modules.Settings.Controls
|
|
||||||
import qs.Config
|
|
||||||
import qs.Helpers
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: clayout
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: colorLayout.implicitHeight
|
|
||||||
color: DynamicColors.tPalette.m3surfaceContainer
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: colorLayout
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.margins: Appearance.padding.large
|
|
||||||
anchors.right: parent.right
|
|
||||||
|
|
||||||
Settings {
|
|
||||||
name: "smth"
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingSwitch {
|
|
||||||
name: "wallust"
|
|
||||||
object: Config.general.color
|
|
||||||
setting: "wallust"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
component Settings: CustomRect {
|
|
||||||
id: settingsItem
|
|
||||||
|
|
||||||
required property string name
|
|
||||||
|
|
||||||
Layout.preferredHeight: 42
|
|
||||||
Layout.preferredWidth: 200
|
|
||||||
radius: 4
|
|
||||||
|
|
||||||
CustomText {
|
|
||||||
id: text
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.margins: Appearance.padding.smaller
|
|
||||||
anchors.right: parent.right
|
|
||||||
font.bold: true
|
|
||||||
font.pointSize: 32
|
|
||||||
text: settingsItem.name
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import Quickshell
|
|
||||||
import Quickshell.Widgets
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import qs.Components
|
|
||||||
import qs.Modules as Modules
|
|
||||||
import qs.Config
|
|
||||||
import qs.Helpers
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
import Quickshell
|
|
||||||
import Quickshell.Widgets
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import qs.Components
|
|
||||||
import qs.Modules as Modules
|
|
||||||
import qs.Config
|
|
||||||
import qs.Helpers
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: clayout
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
Settings {
|
|
||||||
name: "apps"
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
component Settings: CustomRect {
|
|
||||||
id: settingsItem
|
|
||||||
|
|
||||||
required property string name
|
|
||||||
|
|
||||||
implicitHeight: 42
|
|
||||||
implicitWidth: 200
|
|
||||||
radius: 4
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: layout
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.margins: Appearance.padding.smaller
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
CustomText {
|
|
||||||
id: text
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: Appearance.spacing.normal
|
|
||||||
text: settingsItem.name
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
import Quickshell
|
|
||||||
import Quickshell.Widgets
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import qs.Components
|
|
||||||
import qs.Modules as Modules
|
|
||||||
import qs.Modules.Settings.Categories as Cat
|
|
||||||
import qs.Config
|
|
||||||
import qs.Helpers
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property string currentCategory: "general"
|
|
||||||
readonly property real nonAnimHeight: view.implicitHeight + viewWrapper.anchors.margins * 2
|
|
||||||
readonly property real nonAnimWidth: view.implicitWidth + 500 + viewWrapper.anchors.margins * 2
|
|
||||||
required property PersistentProperties visibilities
|
|
||||||
|
|
||||||
implicitHeight: nonAnimHeight
|
|
||||||
implicitWidth: nonAnimWidth
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
function onCurrentCategoryChanged() {
|
|
||||||
stack.pop();
|
|
||||||
if (currentCategory === "general") {
|
|
||||||
stack.push(general);
|
|
||||||
} else if (currentCategory === "wallpaper") {
|
|
||||||
stack.push(background);
|
|
||||||
} else if (currentCategory === "appearance") {
|
|
||||||
stack.push(appearance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
target: root
|
|
||||||
}
|
|
||||||
|
|
||||||
ClippingRectangle {
|
|
||||||
id: viewWrapper
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.padding.smaller
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: view
|
|
||||||
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.top: parent.top
|
|
||||||
implicitHeight: layout.implicitHeight
|
|
||||||
implicitWidth: layout.implicitWidth
|
|
||||||
|
|
||||||
Categories {
|
|
||||||
id: layout
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
content: root
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomClippingRect {
|
|
||||||
id: categoryContent
|
|
||||||
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: view.right
|
|
||||||
anchors.leftMargin: Appearance.spacing.smaller
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
color: DynamicColors.tPalette.m3surfaceContainer
|
|
||||||
radius: 4
|
|
||||||
|
|
||||||
StackView {
|
|
||||||
id: stack
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.padding.smaller
|
|
||||||
initialItem: general
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: general
|
|
||||||
|
|
||||||
Cat.General {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: background
|
|
||||||
|
|
||||||
Cat.Background {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: appearance
|
|
||||||
|
|
||||||
Cat.Appearance {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import qs.Components
|
|
||||||
import qs.Config
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property string name
|
|
||||||
required property var object
|
|
||||||
required property string setting
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 42
|
|
||||||
|
|
||||||
CustomText {
|
|
||||||
id: text
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignLeft
|
|
||||||
Layout.fillWidth: true
|
|
||||||
font.pointSize: 16
|
|
||||||
text: root.name
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomSwitch {
|
|
||||||
id: cswitch
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignRight
|
|
||||||
checked: root.object[root.setting]
|
|
||||||
|
|
||||||
onToggled: {
|
|
||||||
root.object[root.setting] = checked;
|
|
||||||
Config.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import Quickshell
|
|
||||||
import Quickshell.Widgets
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import qs.Components
|
|
||||||
import qs.Modules as Modules
|
|
||||||
import qs.Config
|
|
||||||
import qs.Helpers
|
|
||||||
|
|
||||||
Item {
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
import Quickshell
|
|
||||||
import QtQuick
|
|
||||||
import qs.Components
|
|
||||||
import qs.Config
|
|
||||||
import qs.Helpers
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property var panels
|
|
||||||
required property PersistentProperties visibilities
|
|
||||||
|
|
||||||
implicitHeight: 0
|
|
||||||
implicitWidth: content.implicitWidth
|
|
||||||
visible: height > 0
|
|
||||||
|
|
||||||
states: State {
|
|
||||||
name: "visible"
|
|
||||||
when: root.visibilities.settings
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
root.implicitHeight: content.implicitHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
transitions: [
|
|
||||||
Transition {
|
|
||||||
from: ""
|
|
||||||
to: "visible"
|
|
||||||
|
|
||||||
Anim {
|
|
||||||
duration: MaterialEasing.expressiveEffectsTime
|
|
||||||
easing.bezierCurve: MaterialEasing.expressiveEffects
|
|
||||||
property: "implicitHeight"
|
|
||||||
target: root
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Transition {
|
|
||||||
from: "visible"
|
|
||||||
to: ""
|
|
||||||
|
|
||||||
Anim {
|
|
||||||
easing.bezierCurve: MaterialEasing.expressiveEffects
|
|
||||||
property: "implicitHeight"
|
|
||||||
target: root
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: content
|
|
||||||
|
|
||||||
active: true
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
visible: true
|
|
||||||
|
|
||||||
sourceComponent: Content {
|
|
||||||
visibilities: root.visibilities
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
Reference in New Issue
Block a user