forked from Shinonome/dots-hyprland
action center: toggle pages
This commit is contained in:
@@ -581,7 +581,7 @@ Singleton {
|
||||
property bool leftAlignApps: false
|
||||
}
|
||||
property JsonObject actionCenter: JsonObject {
|
||||
property list<string> toggles: [ "network", "bluetooth", "easyEffects", "powerProfile", "idleInhibitor", "antiFlashbang", "nightLight", "darkMode", "cloudflareWarp", "mic", "audio", "musicRecognition", "notifications", "onScreenKeyboard", "gameMode", "screenSnip", "colorPicker" ]
|
||||
property list<string> toggles: [ "network", "bluetooth", "easyEffects", "powerProfile", "idleInhibitor", "nightLight", "darkMode", "antiFlashbang", "cloudflareWarp", "mic", "audio", "musicRecognition", "notifications", "onScreenKeyboard", "gameMode", "screenSnip", "colorPicker" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ Rectangle {
|
||||
ActionCenterBodyToggles {
|
||||
id: togglesContainer
|
||||
Layout.fillWidth: true
|
||||
Layout.bottomMargin: -12
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
||||
+63
-27
@@ -7,39 +7,75 @@ import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.waffle.looks
|
||||
|
||||
RowLayout {
|
||||
spacing: 4
|
||||
ColumnLayout {
|
||||
id: root
|
||||
property var screen: root.QsWindow.window?.screen
|
||||
property var brightnessMonitor: Brightness.getMonitorForScreen(screen)
|
||||
spacing: 12
|
||||
|
||||
WPanelIconButton {
|
||||
iconName: WIcons.volumeIcon
|
||||
onClicked: Audio.toggleMute();
|
||||
}
|
||||
|
||||
WSlider {
|
||||
Layout.fillWidth: true
|
||||
value: Audio.sink.audio.volume
|
||||
onMoved: {
|
||||
Audio.sink.audio.volume = value;
|
||||
RowLayout {
|
||||
spacing: 4
|
||||
|
||||
WPanelIconButton {
|
||||
color: colBackground
|
||||
property real animationValue: root.brightnessMonitor.brightness
|
||||
rotation: animationValue * 180
|
||||
scale: 0.8 + animationValue * 0.2
|
||||
iconName: "weather-sunny"
|
||||
|
||||
Behavior on animationValue {
|
||||
animation: Looks.transition.longMovement.createObject(this)
|
||||
}
|
||||
}
|
||||
|
||||
WSlider {
|
||||
Layout.fillWidth: true
|
||||
value: root.brightnessMonitor.brightness
|
||||
onMoved: {
|
||||
root.brightnessMonitor.setBrightness(value)
|
||||
}
|
||||
}
|
||||
|
||||
WPanelIconButton {
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 4
|
||||
|
||||
WPanelIconButton {
|
||||
contentItem: Item {
|
||||
anchors.centerIn: parent
|
||||
Row {
|
||||
WPanelIconButton {
|
||||
iconName: WIcons.volumeIcon
|
||||
onClicked: Audio.toggleMute();
|
||||
}
|
||||
|
||||
WSlider {
|
||||
Layout.fillWidth: true
|
||||
value: Audio.sink.audio.volume
|
||||
onMoved: {
|
||||
Audio.sink.audio.volume = value;
|
||||
}
|
||||
}
|
||||
|
||||
WPanelIconButton {
|
||||
contentItem: Item {
|
||||
anchors.centerIn: parent
|
||||
spacing: -1
|
||||
FluentIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
implicitSize: 18
|
||||
icon: "options"
|
||||
}
|
||||
FluentIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
implicitSize: 12
|
||||
icon: "chevron-right"
|
||||
Row {
|
||||
anchors.centerIn: parent
|
||||
spacing: -1
|
||||
FluentIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
implicitSize: 18
|
||||
icon: "options"
|
||||
}
|
||||
FluentIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
implicitSize: 12
|
||||
icon: "chevron-right"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+113
-23
@@ -1,10 +1,13 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import Qt.labs.synchronizer
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.common.models.quickToggles
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.waffle.looks
|
||||
@@ -13,37 +16,124 @@ import qs.modules.waffle.actionCenter.toggles
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property int columns: 3
|
||||
property int rows: 2
|
||||
property int currentPage: 0
|
||||
property alias columns: grid.columns
|
||||
property alias rows: grid.rows
|
||||
readonly property int itemsPerPage: columns * rows
|
||||
readonly property int pages: Math.ceil(toggles.length / itemsPerPage)
|
||||
property list<string> toggles: Config.options.waffles.actionCenter.toggles
|
||||
property list<string> togglesInCurrentPage: toggles.slice(currentPage * itemsPerPage, (currentPage + 1) * itemsPerPage)
|
||||
|
||||
property real padding: 22
|
||||
implicitHeight: grid.implicitHeight + padding * 2
|
||||
property real reducedBottomPadding: 12
|
||||
implicitHeight: swipeView.implicitHeight + (padding - swipeView.padding) * 2 - reducedBottomPadding
|
||||
|
||||
GridLayout {
|
||||
id: grid
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: parent.padding
|
||||
}
|
||||
function togglesInPage(index) {
|
||||
var start = index * root.itemsPerPage;
|
||||
var end = start + root.itemsPerPage;
|
||||
return root.toggles.slice(start, end);
|
||||
}
|
||||
|
||||
columns: 3
|
||||
rows: 2
|
||||
rowSpacing: 12
|
||||
columnSpacing: 12
|
||||
uniformCellHeights: true
|
||||
uniformCellWidths: true
|
||||
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
values: root.togglesInCurrentPage
|
||||
}
|
||||
delegate: ActionCenterTogglesDelegateChooser {}
|
||||
function decreasePage() {
|
||||
if (root.currentPage > 0) {
|
||||
root.currentPage -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: pages indicator on the right
|
||||
function increasePage() {
|
||||
if (root.currentPage < (root.pages - 1)) {
|
||||
root.currentPage += 1;
|
||||
}
|
||||
}
|
||||
|
||||
clip: true
|
||||
SwipeView {
|
||||
id: swipeView
|
||||
anchors {
|
||||
fill: parent
|
||||
topMargin: root.padding - swipeView.padding
|
||||
bottomMargin: root.padding - swipeView.padding - root.reducedBottomPadding
|
||||
}
|
||||
padding: 4
|
||||
leftPadding: root.padding
|
||||
rightPadding: root.padding
|
||||
spacing: padding
|
||||
|
||||
orientation: Qt.Vertical
|
||||
clip: true
|
||||
Synchronizer on currentIndex {
|
||||
property alias source: root.currentPage
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: root.pages
|
||||
delegate: GridLayout {
|
||||
id: grid
|
||||
required property int index
|
||||
// width: SwipeView.view.width - root.padding * 2
|
||||
// height: SwipeView.view.height - root.padding * 2
|
||||
|
||||
columns: root.columns
|
||||
rows: root.rows
|
||||
rowSpacing: 12
|
||||
columnSpacing: 12
|
||||
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
values: root.togglesInPage(grid.index)
|
||||
}
|
||||
delegate: ActionCenterTogglesDelegateChooser {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 6
|
||||
spacing: 6
|
||||
|
||||
FluentIcon {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
implicitSize: 12
|
||||
icon: "caret-up"
|
||||
color: Looks.colors.controlBg
|
||||
filled: true
|
||||
opacity: root.currentPage > 0 ? 1 : 0
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: root.pages
|
||||
delegate: Item {
|
||||
required property int index
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
implicitWidth: 6
|
||||
implicitHeight: 6
|
||||
|
||||
Circle {
|
||||
anchors.centerIn: parent
|
||||
diameter: index === root.currentPage ? 6 : 4
|
||||
color: Looks.colors.controlBg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluentIcon {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
implicitSize: 12
|
||||
icon: "caret-down"
|
||||
color: Looks.colors.controlBg
|
||||
filled: true
|
||||
opacity: root.currentPage < (root.pages - 1) ? 1 : 0
|
||||
}
|
||||
}
|
||||
|
||||
FocusedScrollMouseArea {
|
||||
z: 999
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
hoverEnabled: false
|
||||
onScrollUp: decreasePage();
|
||||
onScrollDown: increasePage();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,7 @@ WBarAttachedPanelContent {
|
||||
anchors.centerIn: parent
|
||||
spacing: 0
|
||||
|
||||
ActionCenterBody {
|
||||
topLeftRadius: root.border.radius - root.border.border.width
|
||||
topRightRadius: topLeftRadius
|
||||
}
|
||||
ActionCenterBody {}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillHeight: false
|
||||
@@ -26,9 +23,6 @@ WBarAttachedPanelContent {
|
||||
implicitHeight: 1
|
||||
}
|
||||
|
||||
ActionCenterFooter {
|
||||
bottomLeftRadius: root.border.radius - root.border.border.width
|
||||
bottomRightRadius: bottomLeftRadius
|
||||
}
|
||||
ActionCenterFooter {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,11 @@ Rectangle {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 12
|
||||
|
||||
onClicked: {
|
||||
GlobalStates.sidebarLeftOpen = false;
|
||||
Quickshell.execDetached(["qs", "-p", Quickshell.shellPath("settings.qml")]);
|
||||
}
|
||||
|
||||
contentItem: FluentIcon {
|
||||
icon: "settings"
|
||||
}
|
||||
|
||||
@@ -56,6 +56,13 @@ Scope {
|
||||
id: content
|
||||
anchors.centerIn: parent
|
||||
|
||||
focus: true
|
||||
Keys.onPressed: event => { // Esc to close
|
||||
if (event.key === Qt.Key_Escape) {
|
||||
content.close()
|
||||
}
|
||||
}
|
||||
|
||||
onClosed: {
|
||||
barLoader.active = false;
|
||||
GlobalStates.sidebarLeftOpen = false;
|
||||
|
||||
+5
-5
@@ -32,18 +32,18 @@ ColumnLayout {
|
||||
property color colBorder: toggled ? Looks.colors.accentHover : Looks.colors.bg0Border
|
||||
property color colForeground: toggled ? Looks.colors.accentFg : Looks.colors.fg1
|
||||
|
||||
spacing: 0
|
||||
property real wholeToggleWidth: 96
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
implicitWidth: 96
|
||||
implicitWidth: root.wholeToggleWidth
|
||||
implicitHeight: 48
|
||||
color: root.colBackground
|
||||
border.color: root.colBorder
|
||||
border.width: 1
|
||||
radius: Looks.radius.medium
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
uniformCellSizes: true
|
||||
spacing: 0
|
||||
|
||||
WButton {
|
||||
@@ -102,8 +102,8 @@ ColumnLayout {
|
||||
|
||||
Item {
|
||||
id: toggleNameWidget
|
||||
implicitWidth: root.wholeToggleWidth
|
||||
implicitHeight: 36
|
||||
Layout.fillWidth: true
|
||||
WText {
|
||||
id: toggleNameText
|
||||
anchors {
|
||||
|
||||
+5
-2
@@ -32,6 +32,7 @@ DelegateChooser {
|
||||
roleValue: "bluetooth"
|
||||
ActionCenterToggleButton {
|
||||
toggleModel: BluetoothToggle {}
|
||||
name: toggleModel.statusText
|
||||
icon: WIcons.bluetoothIcon
|
||||
}
|
||||
}
|
||||
@@ -39,7 +40,7 @@ DelegateChooser {
|
||||
roleValue: "cloudflareWarp"
|
||||
ActionCenterToggleButton {
|
||||
toggleModel: CloudflareWarpToggle {}
|
||||
icon: "globe-shield"
|
||||
icon: "cloudflare"
|
||||
}
|
||||
}
|
||||
DelegateChoice {
|
||||
@@ -53,7 +54,7 @@ DelegateChooser {
|
||||
roleValue: "darkMode"
|
||||
ActionCenterToggleButton {
|
||||
toggleModel: DarkModeToggle {}
|
||||
icon: "dark-theme*"
|
||||
icon: "dark-theme"
|
||||
}
|
||||
}
|
||||
DelegateChoice {
|
||||
@@ -95,6 +96,7 @@ DelegateChooser {
|
||||
roleValue: "network"
|
||||
ActionCenterToggleButton {
|
||||
toggleModel: NetworkToggle {}
|
||||
name: toggleModel.statusText
|
||||
icon: WIcons.internetIcon
|
||||
}
|
||||
}
|
||||
@@ -124,6 +126,7 @@ DelegateChooser {
|
||||
ActionCenterToggleButton {
|
||||
toggleModel: PowerProfilesToggle {}
|
||||
icon: WIcons.powerProfileIcon
|
||||
name: toggleModel.statusText
|
||||
}
|
||||
}
|
||||
DelegateChoice {
|
||||
|
||||
@@ -18,18 +18,29 @@ BarButton {
|
||||
|
||||
contentItem: Item {
|
||||
anchors.centerIn: root.background
|
||||
implicitHeight: column.implicitHeight
|
||||
implicitWidth: column.implicitWidth
|
||||
Column {
|
||||
id: column
|
||||
implicitHeight: contentLayout.implicitHeight
|
||||
implicitWidth: contentLayout.implicitWidth
|
||||
Row {
|
||||
id: contentLayout
|
||||
anchors.centerIn: parent
|
||||
WText {
|
||||
anchors.right: parent.right
|
||||
text: DateTime.time
|
||||
spacing: 7
|
||||
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
WText {
|
||||
anchors.right: parent.right
|
||||
text: DateTime.time
|
||||
}
|
||||
WText {
|
||||
anchors.right: parent.right
|
||||
text: DateTime.date
|
||||
}
|
||||
}
|
||||
WText {
|
||||
anchors.right: parent.right
|
||||
text: DateTime.date
|
||||
FluentIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
icon: "alert-snooze"
|
||||
implicitSize: 18
|
||||
filled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,5 +148,13 @@ Singleton {
|
||||
easing.bezierCurve: transition.easing.bezierCurve.easeIn
|
||||
}
|
||||
}
|
||||
|
||||
property Component longMovement: Component {
|
||||
NumberAnimation {
|
||||
duration: 1000
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: transition.easing.bezierCurve.easeIn
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell
|
||||
import qs
|
||||
import qs.services
|
||||
@@ -9,10 +10,10 @@ import qs.modules.waffle.looks
|
||||
Item {
|
||||
id: root
|
||||
|
||||
signal closed()
|
||||
signal closed
|
||||
|
||||
property alias border: borderRect
|
||||
required default property Item contentItem
|
||||
default required property Item contentItem
|
||||
property real visualMargin: 12
|
||||
|
||||
function close() {
|
||||
@@ -26,6 +27,7 @@ Item {
|
||||
|
||||
Rectangle {
|
||||
id: borderRect
|
||||
z: 1
|
||||
|
||||
color: "transparent"
|
||||
radius: Looks.radius.large
|
||||
@@ -33,7 +35,6 @@ Item {
|
||||
border.width: 1
|
||||
implicitWidth: contentItem.implicitWidth + border.width * 2
|
||||
implicitHeight: contentItem.implicitHeight + border.width * 2
|
||||
children: [root.contentItem]
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
@@ -76,4 +77,20 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentArea
|
||||
z: 0
|
||||
anchors.fill: borderRect
|
||||
anchors.margins: borderRect.border.width
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: Rectangle {
|
||||
width: contentArea.width
|
||||
height: contentArea.height
|
||||
radius: borderRect.radius - borderRect.border.width
|
||||
}
|
||||
}
|
||||
children: [root.contentItem]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,24 @@ Button {
|
||||
property color colBackgroundToggledHover: Looks.colors.accentHover
|
||||
property color colBackgroundToggledActive: Looks.colors.accentActive
|
||||
property alias backgroundOpacity: backgroundRect.opacity
|
||||
property color color: {
|
||||
if (root.checked) {
|
||||
if (root.down) {
|
||||
return root.colBackgroundToggledActive;
|
||||
} else if (root.hovered && !root.down) {
|
||||
return root.colBackgroundToggledHover;
|
||||
} else {
|
||||
return root.colBackgroundToggled;
|
||||
}
|
||||
}
|
||||
if (root.down) {
|
||||
return root.colBackgroundActive;
|
||||
} else if (root.hovered && !root.down) {
|
||||
return root.colBackgroundHover;
|
||||
} else {
|
||||
return root.colBackground;
|
||||
}
|
||||
}
|
||||
|
||||
property alias monochromeIcon: buttonIcon.monochrome
|
||||
property bool forceShowIcon: false
|
||||
@@ -42,24 +60,7 @@ Button {
|
||||
background: Rectangle {
|
||||
id: backgroundRect
|
||||
radius: Looks.radius.medium
|
||||
color: {
|
||||
if (root.checked) {
|
||||
if (root.down) {
|
||||
return root.colBackgroundToggledActive;
|
||||
} else if (root.hovered && !root.down) {
|
||||
return root.colBackgroundToggledHover;
|
||||
} else {
|
||||
return root.colBackgroundToggled;
|
||||
}
|
||||
}
|
||||
if (root.down) {
|
||||
return root.colBackgroundActive;
|
||||
} else if (root.hovered && !root.down) {
|
||||
return root.colBackgroundHover;
|
||||
} else {
|
||||
return root.colBackground;
|
||||
}
|
||||
}
|
||||
color: root.color
|
||||
Behavior on color {
|
||||
animation: Looks.transition.color.createObject(this)
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ Singleton {
|
||||
property string powerProfileIcon: {
|
||||
switch(PowerProfiles.profile) {
|
||||
case PowerProfile.PowerSaver: return "leaf-two";
|
||||
case PowerProfile.Balanced: return "settings-cog-multiple";
|
||||
case PowerProfile.Balanced: return "flash-on";
|
||||
case PowerProfile.Performance: return "fire";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +46,8 @@ Slider {
|
||||
right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
topLeftRadius: root.trackWidth / 2
|
||||
bottomLeftRadius: root.trackWidth / 2
|
||||
topRightRadius: root.trackWidth / 2
|
||||
bottomRightRadius: root.trackWidth / 2
|
||||
color: Looks.colors.controlBg
|
||||
implicitHeight: root.trackWidth
|
||||
width: background.width * (1 - root.visualPosition)
|
||||
|
||||
Reference in New Issue
Block a user