mirror of
https://github.com/belsabbagh/dotfiles.git
synced 2026-04-11 09:36:46 +00:00
quickshell and hyprland additions
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
import qs.components
|
||||
import qs.components.controls
|
||||
import qs.services
|
||||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
StyledRect {
|
||||
id: root
|
||||
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: layout.implicitHeight + (IdleInhibitor.enabled ? activeChip.implicitHeight + activeChip.anchors.topMargin : 0) + Appearance.padding.large * 2
|
||||
|
||||
radius: Appearance.rounding.normal
|
||||
color: Colours.tPalette.m3surfaceContainer
|
||||
clip: true
|
||||
|
||||
RowLayout {
|
||||
id: layout
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.margins: Appearance.padding.large
|
||||
spacing: Appearance.spacing.normal
|
||||
|
||||
StyledRect {
|
||||
implicitWidth: implicitHeight
|
||||
implicitHeight: icon.implicitHeight + Appearance.padding.smaller * 2
|
||||
|
||||
radius: Appearance.rounding.full
|
||||
color: IdleInhibitor.enabled ? Colours.palette.m3secondary : Colours.palette.m3secondaryContainer
|
||||
|
||||
MaterialIcon {
|
||||
id: icon
|
||||
|
||||
anchors.centerIn: parent
|
||||
text: "coffee"
|
||||
color: IdleInhibitor.enabled ? Colours.palette.m3onSecondary : Colours.palette.m3onSecondaryContainer
|
||||
font.pointSize: Appearance.font.size.large
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 0
|
||||
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Keep Awake")
|
||||
font.pointSize: Appearance.font.size.normal
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
text: IdleInhibitor.enabled ? qsTr("Preventing sleep mode") : qsTr("Normal power management")
|
||||
color: Colours.palette.m3onSurfaceVariant
|
||||
font.pointSize: Appearance.font.size.small
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
StyledSwitch {
|
||||
checked: IdleInhibitor.enabled
|
||||
onToggled: IdleInhibitor.enabled = checked
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: activeChip
|
||||
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.topMargin: Appearance.spacing.larger
|
||||
anchors.bottomMargin: IdleInhibitor.enabled ? Appearance.padding.large : -implicitHeight
|
||||
anchors.leftMargin: Appearance.padding.large
|
||||
|
||||
opacity: IdleInhibitor.enabled ? 1 : 0
|
||||
scale: IdleInhibitor.enabled ? 1 : 0.5
|
||||
|
||||
Component.onCompleted: active = Qt.binding(() => opacity > 0)
|
||||
|
||||
sourceComponent: StyledRect {
|
||||
implicitWidth: activeText.implicitWidth + Appearance.padding.normal * 2
|
||||
implicitHeight: activeText.implicitHeight + Appearance.padding.small * 2
|
||||
|
||||
radius: Appearance.rounding.full
|
||||
color: Colours.palette.m3primary
|
||||
|
||||
StyledText {
|
||||
id: activeText
|
||||
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("Active since %1").arg(Qt.formatTime(IdleInhibitor.enabledSince, Config.services.useTwelveHourClock ? "hh:mm a" : "hh:mm"))
|
||||
color: Colours.palette.m3onPrimary
|
||||
font.pointSize: Math.round(Appearance.font.size.small * 0.9)
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on anchors.bottomMargin {
|
||||
Anim {
|
||||
duration: Appearance.anim.durations.expressiveDefaultSpatial
|
||||
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
Anim {
|
||||
duration: Appearance.anim.durations.small
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on scale {
|
||||
Anim {}
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on implicitHeight {
|
||||
Anim {
|
||||
duration: Appearance.anim.durations.expressiveDefaultSpatial
|
||||
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
|
||||
}
|
||||
}
|
||||
}
|
||||
277
.config/quickshell/caelestia/modules/utilities/cards/Record.qml
Normal file
277
.config/quickshell/caelestia/modules/utilities/cards/Record.qml
Normal file
@@ -0,0 +1,277 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.components
|
||||
import qs.components.controls
|
||||
import qs.services
|
||||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
StyledRect {
|
||||
id: root
|
||||
|
||||
required property var props
|
||||
required property var visibilities
|
||||
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: layout.implicitHeight + layout.anchors.margins * 2
|
||||
|
||||
radius: Appearance.rounding.normal
|
||||
color: Colours.tPalette.m3surfaceContainer
|
||||
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: Appearance.padding.large
|
||||
spacing: Appearance.spacing.normal
|
||||
|
||||
RowLayout {
|
||||
spacing: Appearance.spacing.normal
|
||||
z: 1
|
||||
|
||||
StyledRect {
|
||||
implicitWidth: implicitHeight
|
||||
implicitHeight: {
|
||||
const h = icon.implicitHeight + Appearance.padding.smaller * 2;
|
||||
return h - (h % 2);
|
||||
}
|
||||
|
||||
radius: Appearance.rounding.full
|
||||
color: Recorder.running ? Colours.palette.m3secondary : Colours.palette.m3secondaryContainer
|
||||
|
||||
MaterialIcon {
|
||||
id: icon
|
||||
|
||||
anchors.centerIn: parent
|
||||
anchors.horizontalCenterOffset: -0.5
|
||||
anchors.verticalCenterOffset: 1.5
|
||||
text: "screen_record"
|
||||
color: Recorder.running ? Colours.palette.m3onSecondary : Colours.palette.m3onSecondaryContainer
|
||||
font.pointSize: Appearance.font.size.large
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 0
|
||||
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Screen Recorder")
|
||||
font.pointSize: Appearance.font.size.normal
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
text: Recorder.paused ? qsTr("Recording paused") : Recorder.running ? qsTr("Recording running") : qsTr("Recording off")
|
||||
color: Colours.palette.m3onSurfaceVariant
|
||||
font.pointSize: Appearance.font.size.small
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
SplitButton {
|
||||
disabled: Recorder.running
|
||||
active: menuItems.find(m => root.props.recordingMode === m.icon + m.text) ?? menuItems[0]
|
||||
menu.onItemSelected: item => root.props.recordingMode = item.icon + item.text
|
||||
|
||||
menuItems: [
|
||||
MenuItem {
|
||||
icon: "fullscreen"
|
||||
text: qsTr("Record fullscreen")
|
||||
activeText: qsTr("Fullscreen")
|
||||
onClicked: Recorder.start()
|
||||
},
|
||||
MenuItem {
|
||||
icon: "screenshot_region"
|
||||
text: qsTr("Record region")
|
||||
activeText: qsTr("Region")
|
||||
onClicked: Recorder.start(["-r"])
|
||||
},
|
||||
MenuItem {
|
||||
icon: "select_to_speak"
|
||||
text: qsTr("Record fullscreen with sound")
|
||||
activeText: qsTr("Fullscreen")
|
||||
onClicked: Recorder.start(["-s"])
|
||||
},
|
||||
MenuItem {
|
||||
icon: "volume_up"
|
||||
text: qsTr("Record region with sound")
|
||||
activeText: qsTr("Region")
|
||||
onClicked: Recorder.start(["-sr"])
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: listOrControls
|
||||
|
||||
property bool running: Recorder.running
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: implicitHeight
|
||||
sourceComponent: running ? recordingControls : recordingList
|
||||
|
||||
Behavior on Layout.preferredHeight {
|
||||
id: locHeightAnim
|
||||
|
||||
enabled: false
|
||||
|
||||
Anim {}
|
||||
}
|
||||
|
||||
Behavior on running {
|
||||
SequentialAnimation {
|
||||
ParallelAnimation {
|
||||
Anim {
|
||||
target: listOrControls
|
||||
property: "scale"
|
||||
to: 0.7
|
||||
duration: Appearance.anim.durations.small
|
||||
easing.bezierCurve: Appearance.anim.curves.standardAccel
|
||||
}
|
||||
Anim {
|
||||
target: listOrControls
|
||||
property: "opacity"
|
||||
to: 0
|
||||
duration: Appearance.anim.durations.small
|
||||
easing.bezierCurve: Appearance.anim.curves.standardAccel
|
||||
}
|
||||
}
|
||||
PropertyAction {
|
||||
target: locHeightAnim
|
||||
property: "enabled"
|
||||
value: true
|
||||
}
|
||||
PropertyAction {}
|
||||
PropertyAction {
|
||||
target: locHeightAnim
|
||||
property: "enabled"
|
||||
value: false
|
||||
}
|
||||
ParallelAnimation {
|
||||
Anim {
|
||||
target: listOrControls
|
||||
property: "scale"
|
||||
to: 1
|
||||
duration: Appearance.anim.durations.small
|
||||
easing.bezierCurve: Appearance.anim.curves.standardDecel
|
||||
}
|
||||
Anim {
|
||||
target: listOrControls
|
||||
property: "opacity"
|
||||
to: 1
|
||||
duration: Appearance.anim.durations.small
|
||||
easing.bezierCurve: Appearance.anim.curves.standardDecel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: recordingList
|
||||
|
||||
RecordingList {
|
||||
props: root.props
|
||||
visibilities: root.visibilities
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: recordingControls
|
||||
|
||||
RowLayout {
|
||||
spacing: Appearance.spacing.normal
|
||||
|
||||
StyledRect {
|
||||
radius: Appearance.rounding.full
|
||||
color: Recorder.paused ? Colours.palette.m3tertiary : Colours.palette.m3error
|
||||
|
||||
implicitWidth: recText.implicitWidth + Appearance.padding.normal * 2
|
||||
implicitHeight: recText.implicitHeight + Appearance.padding.smaller * 2
|
||||
|
||||
StyledText {
|
||||
id: recText
|
||||
|
||||
anchors.centerIn: parent
|
||||
animate: true
|
||||
text: Recorder.paused ? "PAUSED" : "REC"
|
||||
color: Recorder.paused ? Colours.palette.m3onTertiary : Colours.palette.m3onError
|
||||
font.family: Appearance.font.family.mono
|
||||
}
|
||||
|
||||
Behavior on implicitWidth {
|
||||
Anim {}
|
||||
}
|
||||
|
||||
SequentialAnimation on opacity {
|
||||
running: !Recorder.paused
|
||||
alwaysRunToEnd: true
|
||||
loops: Animation.Infinite
|
||||
|
||||
Anim {
|
||||
from: 1
|
||||
to: 0
|
||||
duration: Appearance.anim.durations.large
|
||||
easing.bezierCurve: Appearance.anim.curves.emphasizedAccel
|
||||
}
|
||||
Anim {
|
||||
from: 0
|
||||
to: 1
|
||||
duration: Appearance.anim.durations.extraLarge
|
||||
easing.bezierCurve: Appearance.anim.curves.emphasizedDecel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: {
|
||||
const elapsed = Recorder.elapsed;
|
||||
|
||||
const hours = Math.floor(elapsed / 3600);
|
||||
const mins = Math.floor((elapsed % 3600) / 60);
|
||||
const secs = Math.floor(elapsed % 60).toString().padStart(2, "0");
|
||||
|
||||
let time;
|
||||
if (hours > 0)
|
||||
time = `${hours}:${mins.toString().padStart(2, "0")}:${secs}`;
|
||||
else
|
||||
time = `${mins}:${secs}`;
|
||||
|
||||
return qsTr("Recording for %1").arg(time);
|
||||
}
|
||||
font.pointSize: Appearance.font.size.normal
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
IconButton {
|
||||
label.animate: true
|
||||
icon: Recorder.paused ? "play_arrow" : "pause"
|
||||
toggle: true
|
||||
checked: Recorder.paused
|
||||
type: IconButton.Tonal
|
||||
font.pointSize: Appearance.font.size.large
|
||||
onClicked: {
|
||||
Recorder.togglePause();
|
||||
internalChecked = Recorder.paused;
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
icon: "stop"
|
||||
inactiveColour: Colours.palette.m3error
|
||||
inactiveOnColour: Colours.palette.m3onError
|
||||
font.pointSize: Appearance.font.size.large
|
||||
onClicked: Recorder.stop()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.components
|
||||
import qs.components.controls
|
||||
import qs.components.containers
|
||||
import qs.services
|
||||
import qs.config
|
||||
import qs.utils
|
||||
import Caelestia
|
||||
import Caelestia.Models
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
required property var props
|
||||
required property var visibilities
|
||||
|
||||
spacing: 0
|
||||
|
||||
WrapperMouseArea {
|
||||
Layout.fillWidth: true
|
||||
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: root.props.recordingListExpanded = !root.props.recordingListExpanded
|
||||
|
||||
RowLayout {
|
||||
spacing: Appearance.spacing.smaller
|
||||
|
||||
MaterialIcon {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: "list"
|
||||
font.pointSize: Appearance.font.size.large
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Recordings")
|
||||
font.pointSize: Appearance.font.size.normal
|
||||
}
|
||||
|
||||
IconButton {
|
||||
icon: root.props.recordingListExpanded ? "unfold_less" : "unfold_more"
|
||||
type: IconButton.Text
|
||||
label.animate: true
|
||||
onClicked: root.props.recordingListExpanded = !root.props.recordingListExpanded
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledListView {
|
||||
id: list
|
||||
|
||||
model: FileSystemModel {
|
||||
path: Paths.recsdir
|
||||
nameFilters: ["recording_*.mp4"]
|
||||
sortReverse: true
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.rightMargin: -Appearance.spacing.small
|
||||
implicitHeight: (Appearance.font.size.larger + Appearance.padding.small) * (root.props.recordingListExpanded ? 10 : 3)
|
||||
clip: true
|
||||
|
||||
StyledScrollBar.vertical: StyledScrollBar {
|
||||
flickable: list
|
||||
}
|
||||
|
||||
delegate: RowLayout {
|
||||
id: recording
|
||||
|
||||
required property FileSystemEntry modelData
|
||||
property string baseName
|
||||
|
||||
anchors.left: list.contentItem.left
|
||||
anchors.right: list.contentItem.right
|
||||
anchors.rightMargin: Appearance.spacing.small
|
||||
spacing: Appearance.spacing.small / 2
|
||||
|
||||
Component.onCompleted: baseName = modelData.baseName
|
||||
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
Layout.rightMargin: Appearance.spacing.small / 2
|
||||
text: {
|
||||
const time = recording.baseName;
|
||||
const matches = time.match(/^recording_(\d{4})(\d{2})(\d{2})_(\d{2})-(\d{2})-(\d{2})/);
|
||||
if (!matches)
|
||||
return time;
|
||||
const date = new Date(...matches.slice(1));
|
||||
date.setMonth(date.getMonth() - 1); // Woe (months start from 0)
|
||||
return qsTr("Recording at %1").arg(Qt.formatDateTime(date, Qt.locale()));
|
||||
}
|
||||
color: Colours.palette.m3onSurfaceVariant
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
IconButton {
|
||||
icon: "play_arrow"
|
||||
type: IconButton.Text
|
||||
onClicked: {
|
||||
root.visibilities.utilities = false;
|
||||
root.visibilities.sidebar = false;
|
||||
Quickshell.execDetached(["app2unit", "--", ...Config.general.apps.playback, recording.modelData.path]);
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
icon: "folder"
|
||||
type: IconButton.Text
|
||||
onClicked: {
|
||||
root.visibilities.utilities = false;
|
||||
root.visibilities.sidebar = false;
|
||||
Quickshell.execDetached(["app2unit", "--", ...Config.general.apps.explorer, recording.modelData.path]);
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
icon: "delete_forever"
|
||||
type: IconButton.Text
|
||||
label.color: Colours.palette.m3error
|
||||
stateLayer.color: Colours.palette.m3error
|
||||
onClicked: root.props.recordingConfirmDelete = recording.modelData.path
|
||||
}
|
||||
}
|
||||
|
||||
add: Transition {
|
||||
Anim {
|
||||
property: "opacity"
|
||||
from: 0
|
||||
to: 1
|
||||
}
|
||||
Anim {
|
||||
property: "scale"
|
||||
from: 0.5
|
||||
to: 1
|
||||
}
|
||||
}
|
||||
|
||||
remove: Transition {
|
||||
Anim {
|
||||
property: "opacity"
|
||||
to: 0
|
||||
}
|
||||
Anim {
|
||||
property: "scale"
|
||||
to: 0.5
|
||||
}
|
||||
}
|
||||
|
||||
displaced: Transition {
|
||||
Anim {
|
||||
properties: "opacity,scale"
|
||||
to: 1
|
||||
}
|
||||
Anim {
|
||||
property: "y"
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
anchors.centerIn: parent
|
||||
|
||||
opacity: list.count === 0 ? 1 : 0
|
||||
active: opacity > 0
|
||||
|
||||
sourceComponent: ColumnLayout {
|
||||
spacing: Appearance.spacing.small
|
||||
|
||||
MaterialIcon {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: "scan_delete"
|
||||
color: Colours.palette.m3outline
|
||||
font.pointSize: Appearance.font.size.extraLarge
|
||||
|
||||
opacity: root.props.recordingListExpanded ? 1 : 0
|
||||
scale: root.props.recordingListExpanded ? 1 : 0
|
||||
Layout.preferredHeight: root.props.recordingListExpanded ? implicitHeight : 0
|
||||
|
||||
Behavior on opacity {
|
||||
Anim {}
|
||||
}
|
||||
|
||||
Behavior on scale {
|
||||
Anim {}
|
||||
}
|
||||
|
||||
Behavior on Layout.preferredHeight {
|
||||
Anim {}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: Appearance.spacing.smaller
|
||||
|
||||
MaterialIcon {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: "scan_delete"
|
||||
color: Colours.palette.m3outline
|
||||
|
||||
opacity: !root.props.recordingListExpanded ? 1 : 0
|
||||
scale: !root.props.recordingListExpanded ? 1 : 0
|
||||
Layout.preferredWidth: !root.props.recordingListExpanded ? implicitWidth : 0
|
||||
|
||||
Behavior on opacity {
|
||||
Anim {}
|
||||
}
|
||||
|
||||
Behavior on scale {
|
||||
Anim {}
|
||||
}
|
||||
|
||||
Behavior on Layout.preferredWidth {
|
||||
Anim {}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: qsTr("No recordings found")
|
||||
color: Colours.palette.m3outline
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
Anim {}
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on implicitHeight {
|
||||
Anim {
|
||||
duration: Appearance.anim.durations.expressiveDefaultSpatial
|
||||
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
113
.config/quickshell/caelestia/modules/utilities/cards/Toggles.qml
Normal file
113
.config/quickshell/caelestia/modules/utilities/cards/Toggles.qml
Normal file
@@ -0,0 +1,113 @@
|
||||
import qs.components
|
||||
import qs.components.controls
|
||||
import qs.services
|
||||
import qs.config
|
||||
import qs.modules.controlcenter
|
||||
import Quickshell
|
||||
import Quickshell.Bluetooth
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
StyledRect {
|
||||
id: root
|
||||
|
||||
required property var visibilities
|
||||
required property Item popouts
|
||||
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: layout.implicitHeight + Appearance.padding.large * 2
|
||||
|
||||
radius: Appearance.rounding.normal
|
||||
color: Colours.tPalette.m3surfaceContainer
|
||||
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: Appearance.padding.large
|
||||
spacing: Appearance.spacing.normal
|
||||
|
||||
StyledText {
|
||||
text: qsTr("Quick Toggles")
|
||||
font.pointSize: Appearance.font.size.normal
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Appearance.spacing.small
|
||||
|
||||
Toggle {
|
||||
icon: "wifi"
|
||||
checked: Nmcli.wifiEnabled
|
||||
onClicked: Nmcli.toggleWifi()
|
||||
}
|
||||
|
||||
Toggle {
|
||||
icon: "bluetooth"
|
||||
checked: Bluetooth.defaultAdapter?.enabled ?? false
|
||||
onClicked: {
|
||||
const adapter = Bluetooth.defaultAdapter;
|
||||
if (adapter)
|
||||
adapter.enabled = !adapter.enabled;
|
||||
}
|
||||
}
|
||||
|
||||
Toggle {
|
||||
icon: "mic"
|
||||
checked: !Audio.sourceMuted
|
||||
onClicked: {
|
||||
const audio = Audio.source?.audio;
|
||||
if (audio)
|
||||
audio.muted = !audio.muted;
|
||||
}
|
||||
}
|
||||
|
||||
Toggle {
|
||||
icon: "settings"
|
||||
inactiveOnColour: Colours.palette.m3onSurfaceVariant
|
||||
toggle: false
|
||||
onClicked: {
|
||||
root.visibilities.utilities = false;
|
||||
root.popouts.detach("network");
|
||||
}
|
||||
}
|
||||
|
||||
Toggle {
|
||||
icon: "gamepad"
|
||||
checked: GameMode.enabled
|
||||
onClicked: GameMode.enabled = !GameMode.enabled
|
||||
}
|
||||
|
||||
Toggle {
|
||||
icon: "notifications_off"
|
||||
checked: Notifs.dnd
|
||||
onClicked: Notifs.dnd = !Notifs.dnd
|
||||
}
|
||||
|
||||
Toggle {
|
||||
icon: "vpn_key"
|
||||
checked: VPN.connected
|
||||
enabled: !VPN.connecting
|
||||
visible: Config.utilities.vpn.provider.some(p => typeof p === "object" ? (p.enabled === true) : false)
|
||||
onClicked: VPN.toggle()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component Toggle: IconButton {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: implicitWidth + (stateLayer.pressed ? Appearance.padding.large : internalChecked ? Appearance.padding.smaller : 0)
|
||||
radius: stateLayer.pressed ? Appearance.rounding.small / 2 : internalChecked ? Appearance.rounding.small : Appearance.rounding.normal
|
||||
inactiveColour: Colours.layer(Colours.palette.m3surfaceContainerHighest, 2)
|
||||
toggle: true
|
||||
radiusAnim.duration: Appearance.anim.durations.expressiveFastSpatial
|
||||
radiusAnim.easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial
|
||||
|
||||
Behavior on Layout.preferredWidth {
|
||||
Anim {
|
||||
duration: Appearance.anim.durations.expressiveFastSpatial
|
||||
easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user