Redesign Quickshell control center
This commit is contained in:
@@ -15,10 +15,12 @@ Scope {
|
||||
|
||||
property bool open: false
|
||||
property bool panelVisible: false
|
||||
property bool contentReady: false
|
||||
property bool mediaOpen: false
|
||||
property bool notificationsOpen: false
|
||||
property bool osdOpen: false
|
||||
property string osdKind: "volume"
|
||||
property int pageIndex: 0
|
||||
property int brightness: 0
|
||||
property var pendingNetwork: null
|
||||
property string wifiPassword: ""
|
||||
@@ -29,9 +31,8 @@ Scope {
|
||||
property alias cpuTemperature: statusBar.temperature
|
||||
property alias gpuTemperature: statusBar.gpuTemperature
|
||||
|
||||
Settings {
|
||||
id: statusSettings
|
||||
}
|
||||
Settings { id: statusSettings }
|
||||
UiTokens { id: uiTheme }
|
||||
|
||||
Bar {
|
||||
id: statusBar
|
||||
@@ -50,6 +51,7 @@ Scope {
|
||||
|
||||
Notifications {
|
||||
id: notificationCenter
|
||||
settings: root.settings
|
||||
open: root.notificationsOpen
|
||||
onDismissed: root.notificationsOpen = false
|
||||
}
|
||||
@@ -74,7 +76,6 @@ Scope {
|
||||
network.connect();
|
||||
return;
|
||||
}
|
||||
|
||||
root.pendingNetwork = network;
|
||||
root.wifiPassword = "";
|
||||
}
|
||||
@@ -102,20 +103,23 @@ Scope {
|
||||
function temperatureColor(value) {
|
||||
const match = String(value).match(/(\d+)C\s*$/);
|
||||
const temperature = match ? Number(match[1]) : -1;
|
||||
if (temperature < 0) return "#806d95";
|
||||
if (temperature >= root.settings.temperatureCritical) return "#c94f6d";
|
||||
if (temperature >= root.settings.temperatureWarning) return "#996315";
|
||||
return "#4d7c38";
|
||||
if (temperature < 0) return uiTheme.mutedText;
|
||||
if (temperature >= root.settings.temperatureCritical) return uiTheme.critical;
|
||||
if (temperature >= root.settings.temperatureWarning) return uiTheme.warning;
|
||||
return uiTheme.success;
|
||||
}
|
||||
|
||||
function openPanel() {
|
||||
closePanelTimer.stop();
|
||||
root.panelVisible = true;
|
||||
root.contentReady = false;
|
||||
openPanelTimer.restart();
|
||||
}
|
||||
|
||||
function closePanel() {
|
||||
openPanelTimer.stop();
|
||||
contentReadyTimer.stop();
|
||||
root.contentReady = false;
|
||||
root.open = false;
|
||||
closePanelTimer.restart();
|
||||
}
|
||||
@@ -129,9 +133,17 @@ Scope {
|
||||
id: openPanelTimer
|
||||
interval: 1
|
||||
repeat: false
|
||||
onTriggered: root.open = true
|
||||
onTriggered: {
|
||||
root.open = true;
|
||||
contentReadyTimer.restart();
|
||||
}
|
||||
}
|
||||
Timer {
|
||||
id: contentReadyTimer
|
||||
interval: 220
|
||||
repeat: false
|
||||
onTriggered: root.contentReady = true
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: closePanelTimer
|
||||
interval: 240
|
||||
@@ -141,62 +153,22 @@ Scope {
|
||||
|
||||
IpcHandler {
|
||||
target: "controlcenter"
|
||||
|
||||
function toggle() {
|
||||
root.togglePanel();
|
||||
}
|
||||
|
||||
function open() {
|
||||
root.openPanel();
|
||||
}
|
||||
|
||||
function close() {
|
||||
root.closePanel();
|
||||
}
|
||||
function toggle() { root.togglePanel(); }
|
||||
function open() { root.openPanel(); }
|
||||
function close() { root.closePanel(); }
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
target: "osd"
|
||||
|
||||
function volume_up() {
|
||||
Quickshell.execDetached(["wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "5%+"]);
|
||||
root.showOsd("volume");
|
||||
}
|
||||
|
||||
function volume_down() {
|
||||
Quickshell.execDetached(["wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "5%-"]);
|
||||
root.showOsd("volume");
|
||||
}
|
||||
|
||||
function volume_mute() {
|
||||
Quickshell.execDetached(["wpctl", "set-mute", "@DEFAULT_AUDIO_SINK@", "toggle"]);
|
||||
root.showOsd("volume");
|
||||
}
|
||||
|
||||
function mic_mute() {
|
||||
Quickshell.execDetached(["wpctl", "set-mute", "@DEFAULT_AUDIO_SOURCE@", "toggle"]);
|
||||
root.showOsd("mic");
|
||||
}
|
||||
|
||||
function brightness_up() {
|
||||
root.adjustBrightness(5);
|
||||
}
|
||||
|
||||
function brightness_down() {
|
||||
root.adjustBrightness(-5);
|
||||
}
|
||||
function volume_up() { Quickshell.execDetached(["wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "5%+"]); root.showOsd("volume"); }
|
||||
function volume_down() { Quickshell.execDetached(["wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "5%-"]); root.showOsd("volume"); }
|
||||
function volume_mute() { Quickshell.execDetached(["wpctl", "set-mute", "@DEFAULT_AUDIO_SINK@", "toggle"]); root.showOsd("volume"); }
|
||||
function mic_mute() { Quickshell.execDetached(["wpctl", "set-mute", "@DEFAULT_AUDIO_SOURCE@", "toggle"]); root.showOsd("mic"); }
|
||||
function brightness_up() { root.adjustBrightness(5); }
|
||||
function brightness_down() { root.adjustBrightness(-5); }
|
||||
}
|
||||
Timer { id: osdTimer; interval: 1400; repeat: false; onTriggered: root.osdOpen = false }
|
||||
|
||||
Timer {
|
||||
id: osdTimer
|
||||
interval: 1400
|
||||
repeat: false
|
||||
onTriggered: root.osdOpen = false
|
||||
}
|
||||
|
||||
PwObjectTracker {
|
||||
objects: [root.audioSink]
|
||||
}
|
||||
PwObjectTracker { objects: [root.audioSink] }
|
||||
|
||||
Process {
|
||||
id: brightnessReader
|
||||
@@ -208,26 +180,18 @@ Scope {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: brightnessPoll
|
||||
interval: 3000
|
||||
repeat: true
|
||||
running: root.open
|
||||
onTriggered: {
|
||||
if (!brightnessReader.running) brightnessReader.running = true;
|
||||
}
|
||||
onTriggered: if (!brightnessReader.running) brightnessReader.running = true
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
visible: root.panelVisible
|
||||
color: "transparent"
|
||||
anchors {
|
||||
top: true
|
||||
bottom: true
|
||||
left: true
|
||||
right: true
|
||||
}
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
WlrLayershell.keyboardFocus: root.panelVisible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
||||
@@ -240,509 +204,133 @@ Scope {
|
||||
|
||||
Rectangle {
|
||||
id: card
|
||||
width: Math.min(470, parent.width - 32)
|
||||
width: Math.min(root.settings.panelWidth, parent.width - 24)
|
||||
height: parent.height
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 0
|
||||
x: root.open ? parent.width - width - 16 : parent.width + 24
|
||||
radius: 20
|
||||
color: "#f5f2ea"
|
||||
border.color: "#d8d0c2"
|
||||
radius: root.settings.panelRadius
|
||||
color: Qt.rgba(uiTheme.background.r, uiTheme.background.g, uiTheme.background.b, root.settings.panelOpacity)
|
||||
border.color: uiTheme.border
|
||||
border.width: 1
|
||||
z: 1
|
||||
|
||||
Behavior on x {
|
||||
NumberAnimation {
|
||||
duration: 220
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
NumberAnimation { duration: 220; easing.type: Easing.OutCubic }
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: mouse.accepted = true
|
||||
}
|
||||
MouseArea { anchors.fill: parent; onClicked: mouse.accepted = true }
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 18
|
||||
anchors.margins: 12
|
||||
spacing: 12
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 0
|
||||
|
||||
Label {
|
||||
text: "Control center"
|
||||
color: "#252321"
|
||||
font.pixelSize: 22
|
||||
font.bold: true
|
||||
}
|
||||
Label {
|
||||
text: "Niri / QuickShell"
|
||||
color: "#7c756c"
|
||||
font.pixelSize: 12
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "✕"
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.text: "Close"
|
||||
onClicked: root.closePanel()
|
||||
}
|
||||
NavigationRail {
|
||||
id: navigation
|
||||
theme: uiTheme
|
||||
currentIndex: root.pageIndex
|
||||
Layout.fillHeight: true
|
||||
onSelected: root.pageIndex = index
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
Rectangle {
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredWidth: 1
|
||||
color: uiTheme.border
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
spacing: 10
|
||||
|
||||
ColumnLayout {
|
||||
width: parent.width
|
||||
spacing: 10
|
||||
|
||||
Rectangle {
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: wifiColumn.implicitHeight + 24
|
||||
radius: 14
|
||||
color: "#e5f0ef"
|
||||
|
||||
ColumnLayout {
|
||||
id: wifiColumn
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
spacing: 8
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Label {
|
||||
text: "Wi-Fi"
|
||||
color: "#1c666d"
|
||||
font.pixelSize: 16
|
||||
font.bold: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Label {
|
||||
text: root.wifiDevice ? (root.wifiDevice.name || "Available") : "Unavailable"
|
||||
color: "#52777a"
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
Switch {
|
||||
checked: Networking.wifiEnabled
|
||||
enabled: Networking.wifiHardwareEnabled
|
||||
onToggled: Networking.wifiEnabled = checked
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: root.wifiDevice !== null
|
||||
Layout.fillWidth: true
|
||||
Label {
|
||||
text: root.wifiDevice && root.wifiDevice.networks.values.find(network => network.connected)
|
||||
? root.wifiDevice.networks.values.find(network => network.connected).name
|
||||
: "Not connected"
|
||||
color: "#252321"
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Button {
|
||||
text: "Scan"
|
||||
onClicked: {
|
||||
if (root.wifiDevice) root.wifiDevice.scannerEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: root.wifiDevice ? root.wifiDevice.networks : null
|
||||
delegate: RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 8
|
||||
|
||||
Label {
|
||||
text: modelData.name
|
||||
color: "#252321"
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Label {
|
||||
text: modelData.connected ? "Connected" : Math.round(modelData.signalStrength) + "%"
|
||||
color: modelData.connected ? "#1c666d" : "#7c756c"
|
||||
}
|
||||
Button {
|
||||
text: modelData.connected ? "Disconnect" : "Connect"
|
||||
enabled: !modelData.stateChanging
|
||||
onClicked: modelData.connected ? modelData.disconnect() : root.connectWifi(modelData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: root.pendingNetwork !== null
|
||||
Layout.fillWidth: true
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
placeholderText: "Password for " + (root.pendingNetwork ? root.pendingNetwork.name : "network")
|
||||
echoMode: TextInput.Password
|
||||
text: root.wifiPassword
|
||||
onTextChanged: root.wifiPassword = text
|
||||
onAccepted: root.submitWifiPassword()
|
||||
}
|
||||
Button {
|
||||
text: "Join"
|
||||
enabled: root.wifiPassword.length > 0
|
||||
onClicked: root.submitWifiPassword()
|
||||
}
|
||||
}
|
||||
spacing: 0
|
||||
Label {
|
||||
text: navigation.names[root.pageIndex]
|
||||
color: uiTheme.text
|
||||
font.pixelSize: 22
|
||||
font.bold: true
|
||||
}
|
||||
Label {
|
||||
text: "Control center / Niri"
|
||||
color: uiTheme.mutedText
|
||||
font.pixelSize: 11
|
||||
}
|
||||
}
|
||||
CCButton { theme: uiTheme; text: "Close"; onClicked: root.closePanel() }
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: bluetoothColumn.implicitHeight + 24
|
||||
radius: 14
|
||||
color: "#eceafd"
|
||||
ScrollView {
|
||||
id: pageScroll
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
contentWidth: availableWidth
|
||||
|
||||
ColumnLayout {
|
||||
id: bluetoothColumn
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
spacing: 8
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Label {
|
||||
text: "Bluetooth"
|
||||
color: "#55499c"
|
||||
font.pixelSize: 16
|
||||
font.bold: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Switch {
|
||||
checked: root.bluetoothAdapter ? root.bluetoothAdapter.enabled : false
|
||||
enabled: root.bluetoothAdapter !== null
|
||||
onToggled: {
|
||||
if (root.bluetoothAdapter) root.bluetoothAdapter.enabled = checked;
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: root.bluetoothAdapter && root.bluetoothAdapter.discovering ? "Stop scan" : "Scan"
|
||||
enabled: root.bluetoothAdapter && root.bluetoothAdapter.enabled
|
||||
onClicked: {
|
||||
if (root.bluetoothAdapter) root.bluetoothAdapter.discovering = !root.bluetoothAdapter.discovering;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: root.bluetoothAdapter ? root.bluetoothAdapter.devices : null
|
||||
delegate: RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 8
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 0
|
||||
Label {
|
||||
text: modelData.name || modelData.deviceName || "Unknown device"
|
||||
color: "#252321"
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Label {
|
||||
text: modelData.connected ? "Connected" : (modelData.paired ? "Paired" : "Not paired")
|
||||
color: "#7c756c"
|
||||
font.pixelSize: 11
|
||||
}
|
||||
}
|
||||
Label {
|
||||
visible: modelData.batteryAvailable
|
||||
text: Math.round(modelData.battery * 100) + "%"
|
||||
color: "#7c756c"
|
||||
}
|
||||
Button {
|
||||
text: modelData.connected ? "Disconnect" : (modelData.paired ? "Connect" : "Pair")
|
||||
onClicked: {
|
||||
if (modelData.connected) modelData.disconnect();
|
||||
else if (modelData.paired) modelData.connect();
|
||||
else modelData.pair();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: audioColumn.implicitHeight + 24
|
||||
radius: 14
|
||||
color: "#fff1d7"
|
||||
|
||||
ColumnLayout {
|
||||
id: audioColumn
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
spacing: 8
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Label {
|
||||
text: "Audio"
|
||||
color: "#996315"
|
||||
font.pixelSize: 16
|
||||
font.bold: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Label {
|
||||
text: root.audioSink ? (root.audioSink.description || "Default output") : "Unavailable"
|
||||
color: "#806a48"
|
||||
elide: Text.ElideRight
|
||||
Layout.maximumWidth: 230
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Button {
|
||||
text: root.audioSink && root.audioSink.audio && root.audioSink.audio.muted ? "Unmute" : "Mute"
|
||||
enabled: root.audioSink && root.audioSink.audio
|
||||
onClicked: {
|
||||
if (root.audioSink && root.audioSink.audio) root.audioSink.audio.muted = !root.audioSink.audio.muted;
|
||||
}
|
||||
}
|
||||
Slider {
|
||||
Layout.fillWidth: true
|
||||
from: 0
|
||||
to: 1
|
||||
value: root.audioSink && root.audioSink.audio ? root.audioSink.audio.volume : 0
|
||||
enabled: root.audioSink && root.audioSink.audio
|
||||
onMoved: {
|
||||
if (root.audioSink && root.audioSink.audio) root.audioSink.audio.volume = value;
|
||||
}
|
||||
}
|
||||
Label {
|
||||
text: root.audioSink && root.audioSink.audio ? Math.round(root.audioSink.audio.volume * 100) + "%" : "--"
|
||||
color: "#806a48"
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Pipewire.nodes
|
||||
delegate: RowLayout {
|
||||
visible: modelData.isSink && !modelData.isStream
|
||||
Layout.fillWidth: true
|
||||
Label {
|
||||
text: modelData.description || modelData.name
|
||||
color: "#252321"
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Button {
|
||||
text: modelData === root.audioSink ? "Default" : "Use"
|
||||
enabled: modelData !== root.audioSink
|
||||
onClicked: Pipewire.preferredDefaultAudioSink = modelData
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: displayColumn.implicitHeight + 24
|
||||
radius: 14
|
||||
color: "#f8e4dc"
|
||||
|
||||
ColumnLayout {
|
||||
id: displayColumn
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
spacing: 8
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Label {
|
||||
text: "Display brightness"
|
||||
color: "#9e4d39"
|
||||
font.pixelSize: 16
|
||||
font.bold: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Label {
|
||||
text: root.brightness > 0 ? root.brightness + "%" : "Unavailable"
|
||||
color: "#8b665b"
|
||||
}
|
||||
}
|
||||
Slider {
|
||||
Layout.fillWidth: true
|
||||
from: 1
|
||||
to: 100
|
||||
value: root.brightness
|
||||
enabled: root.brightness > 0
|
||||
onPressedChanged: {
|
||||
if (!pressed) root.setBrightness(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: statusColumn.implicitHeight + 24
|
||||
radius: 14
|
||||
color: "#eee8f7"
|
||||
|
||||
ColumnLayout {
|
||||
id: statusColumn
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
spacing: 8
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Label {
|
||||
text: "Status bar"
|
||||
color: "#684b8f"
|
||||
font.pixelSize: 16
|
||||
font.bold: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Label {
|
||||
text: "Temperature"
|
||||
color: "#806d95"
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Label {
|
||||
text: "CPU temperature"
|
||||
color: "#252321"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Label {
|
||||
text: root.cpuTemperature
|
||||
color: root.temperatureColor(root.cpuTemperature)
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Label {
|
||||
text: "GPU temperature"
|
||||
color: "#252321"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Label {
|
||||
text: root.gpuTemperature
|
||||
color: root.temperatureColor(root.gpuTemperature)
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Label {
|
||||
text: "Refresh interval"
|
||||
color: "#252321"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
ComboBox {
|
||||
model: ["1 second", "2 seconds", "5 seconds"]
|
||||
currentIndex: [1000, 2000, 5000].indexOf(root.settings.temperatureInterval)
|
||||
onActivated: root.settings.temperatureInterval = [1000, 2000, 5000][currentIndex]
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Label {
|
||||
text: "Warning / critical"
|
||||
color: "#252321"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
SpinBox {
|
||||
from: 40
|
||||
to: 99
|
||||
value: root.settings.temperatureWarning
|
||||
editable: true
|
||||
onValueModified: root.settings.setTemperatureWarning(value)
|
||||
}
|
||||
Label {
|
||||
text: "/"
|
||||
color: "#7c756c"
|
||||
}
|
||||
SpinBox {
|
||||
from: 41
|
||||
to: 110
|
||||
value: root.settings.temperatureCritical
|
||||
editable: true
|
||||
onValueModified: root.settings.setTemperatureCritical(value)
|
||||
}
|
||||
Label {
|
||||
text: "°C"
|
||||
color: "#7c756c"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: powerColumn.implicitHeight + 24
|
||||
radius: 14
|
||||
color: "#e8f1df"
|
||||
|
||||
ColumnLayout {
|
||||
id: powerColumn
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
spacing: 8
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Label {
|
||||
text: "Power profile"
|
||||
color: "#4d7c38"
|
||||
font.pixelSize: 16
|
||||
font.bold: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Label {
|
||||
text: PowerProfile.toString(PowerProfiles.profile)
|
||||
color: "#66825a"
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Button {
|
||||
text: "Saver"
|
||||
Layout.fillWidth: true
|
||||
onClicked: PowerProfiles.profile = PowerProfile.PowerSaver
|
||||
}
|
||||
Button {
|
||||
text: "Balanced"
|
||||
Layout.fillWidth: true
|
||||
onClicked: PowerProfiles.profile = PowerProfile.Balanced
|
||||
}
|
||||
Button {
|
||||
text: "Performance"
|
||||
enabled: PowerProfiles.hasPerformanceProfile
|
||||
Layout.fillWidth: true
|
||||
onClicked: PowerProfiles.profile = PowerProfile.Performance
|
||||
}
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
id: pageLoader
|
||||
width: pageScroll.availableWidth
|
||||
active: root.contentReady
|
||||
sourceComponent: [quickPage, barPage, panelPage, notificationsPage, statusPage][root.pageIndex]
|
||||
opacity: root.contentReady ? 1 : 0
|
||||
Behavior on opacity { NumberAnimation { duration: 140 } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
visible: root.settings.panelOpenOnCorner && !root.panelVisible
|
||||
implicitWidth: 30
|
||||
implicitHeight: 30
|
||||
anchors { top: true; right: true }
|
||||
color: "transparent"
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||
WlrLayershell.namespace: "quickshell-control-center-hot-corner"
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 4
|
||||
radius: 8
|
||||
color: uiTheme.primary
|
||||
opacity: 0.35
|
||||
MouseArea { anchors.fill: parent; onClicked: root.openPanel() }
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: quickPage
|
||||
QuickPage { width: pageLoader.width; controlCenter: root; settings: root.settings; theme: uiTheme }
|
||||
}
|
||||
Component {
|
||||
id: barPage
|
||||
BarPage { width: pageLoader.width; settings: root.settings; theme: uiTheme; availableModules: root.settings.defaultBarModules }
|
||||
}
|
||||
Component {
|
||||
id: panelPage
|
||||
PanelPage { width: pageLoader.width; settings: root.settings; theme: uiTheme }
|
||||
}
|
||||
Component {
|
||||
id: notificationsPage
|
||||
NotificationsPage { width: pageLoader.width; settings: root.settings; theme: uiTheme; notificationCenter: notificationCenter }
|
||||
}
|
||||
Component {
|
||||
id: statusPage
|
||||
StatusPage {
|
||||
width: pageLoader.width
|
||||
settings: root.settings
|
||||
theme: uiTheme
|
||||
cpuTemperature: root.cpuTemperature
|
||||
gpuTemperature: root.gpuTemperature
|
||||
temperatureColorCpu: root.temperatureColor(root.cpuTemperature)
|
||||
temperatureColorGpu: root.temperatureColor(root.gpuTemperature)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user