Improve panes system and add battery pane
This commit is contained in:
157
Panes/Battery.qml
Normal file
157
Panes/Battery.qml
Normal file
@@ -0,0 +1,157 @@
|
||||
import QtQuick
|
||||
import QtQuick.Shapes
|
||||
import Quickshell.Services.UPower
|
||||
|
||||
Column {
|
||||
anchors {
|
||||
top: parent.top
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
width: childrenRect.width
|
||||
height: childrenRect.height
|
||||
anchors.topMargin: 6
|
||||
Rectangle {
|
||||
radius: 12
|
||||
height: 40
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.margins: 6
|
||||
color: "#181818"
|
||||
Rectangle {
|
||||
color: "white"
|
||||
width: parent.width/3 - anchors.margins
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: 4
|
||||
x: PowerProfiles.profile * (width + anchors.margins) + anchors.margins
|
||||
Behavior on x {NumberAnimation {duration: 300; easing.type: Easing.OutQuint}}
|
||||
radius: 8
|
||||
}
|
||||
Row {
|
||||
id: profilesRow
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
component Profile: Rectangle {
|
||||
id: profile
|
||||
color: "transparent"
|
||||
required property var powerProfile
|
||||
width: parent.width/3
|
||||
height: 40
|
||||
Text {
|
||||
parent: profile
|
||||
anchors.centerIn: parent
|
||||
text: PowerProfile.toString(powerProfile)
|
||||
color: PowerProfiles.profile === powerProfile ? "black" : "white"
|
||||
Behavior on color { ColorAnimation {duration: 50}}
|
||||
}
|
||||
TapHandler {onTapped: PowerProfiles.profile = powerProfile}
|
||||
}
|
||||
Profile {powerProfile: PowerProfile.PowerSaver}
|
||||
Profile {powerProfile: PowerProfile.Balanced}
|
||||
Profile {powerProfile: PowerProfile.Performance}
|
||||
}
|
||||
}
|
||||
Repeater {
|
||||
model: UPower.devices.values.filter(dev => dev.model)
|
||||
delegate: Row {
|
||||
spacing: 6
|
||||
Shape {
|
||||
id: meter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 120
|
||||
height: 120
|
||||
preferredRendererType: Shape.CurveRenderer
|
||||
ShapePath {
|
||||
fillColor: "transparent"
|
||||
strokeColor: "#444"
|
||||
strokeWidth: 6
|
||||
capStyle: ShapePath.RoundCap
|
||||
PathAngleArc {
|
||||
centerX: meter.width/2
|
||||
centerY: meter.height/2
|
||||
moveToStart: true
|
||||
radiusX: meter.width/2 - 12
|
||||
radiusY: meter.height/2 - 12
|
||||
startAngle: 90
|
||||
sweepAngle: 270
|
||||
}
|
||||
}
|
||||
ShapePath {
|
||||
fillColor: "transparent"
|
||||
strokeColor: "white"
|
||||
strokeWidth: 6
|
||||
capStyle: ShapePath.RoundCap
|
||||
PathAngleArc {
|
||||
centerX: meter.width/2
|
||||
centerY: meter.height/2
|
||||
moveToStart: true
|
||||
radiusX: meter.width/2 - 12
|
||||
radiusY: meter.height/2 - 12
|
||||
startAngle: 90
|
||||
sweepAngle: modelData.percentage * 270
|
||||
}
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
font.pixelSize: 20
|
||||
color: "white"
|
||||
text: Math.round(modelData.percentage * 100) + "%"
|
||||
}
|
||||
}
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: 6
|
||||
Text {
|
||||
x: 4
|
||||
text: UPowerDeviceType.toString(modelData.type)
|
||||
font.pixelSize: 20
|
||||
color: "white"
|
||||
}
|
||||
Row {
|
||||
spacing: 6
|
||||
component InfoCard: Rectangle {
|
||||
id: card
|
||||
required property var data
|
||||
required property var label
|
||||
color: "#181818"
|
||||
height: 60
|
||||
width: 100
|
||||
radius: 12
|
||||
Column {
|
||||
parent: card
|
||||
anchors.centerIn: parent
|
||||
Text {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: "white"
|
||||
font.pixelSize: 16
|
||||
text: card.data
|
||||
}
|
||||
Text {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: "#aaa"
|
||||
text: card.label
|
||||
font.pixelSize: 12
|
||||
}
|
||||
}
|
||||
}
|
||||
InfoCard {
|
||||
data: modelData.changeRate + "W"
|
||||
label: UPowerDeviceState.toString(modelData.state)
|
||||
}
|
||||
InfoCard {
|
||||
property int time: (modelData.timeToEmpty ? modelData.timeToEmpty : modelData.timeToFull)
|
||||
data: `${Math.floor(time / 60 / 60)}H ${Math.floor((time / 60) % 60)}M`
|
||||
label: modelData.timeToEmpty ? "to empty" : "to full"
|
||||
}
|
||||
InfoCard {
|
||||
data: Math.round(modelData.healthPercentage) + "%"
|
||||
label: "healthy"
|
||||
}
|
||||
Item {width: 6; height: 1}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Item {width: 1; height: 6}
|
||||
}
|
||||
174
Panes/Launcher.qml
Normal file
174
Panes/Launcher.qml
Normal file
@@ -0,0 +1,174 @@
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
import QtQuick
|
||||
import QtQuick.Effects
|
||||
import "../emojis.mjs" as Emojis
|
||||
|
||||
Item {
|
||||
height: currentItems.length ? 180 : 60
|
||||
width: 700
|
||||
property var show: input.text.length
|
||||
property var currentItems: {
|
||||
if (input.text.length === 0 || input.text === ":") {
|
||||
return []
|
||||
}
|
||||
const searchEmojis = (input.text[0] === ':')
|
||||
const items = searchEmojis
|
||||
? Emojis.emojis.emojis
|
||||
: Array.from(DesktopEntries.applications.values)
|
||||
for (let item of items) {
|
||||
item.searchPos = item.name.toLowerCase().search(input.text.slice(searchEmojis))
|
||||
}
|
||||
return items
|
||||
.filter(item => item.searchPos !== -1)
|
||||
.sort((a, b) => a.searchPos - b.searchPos)
|
||||
}
|
||||
function clear() { input.text = "" }
|
||||
anchors {
|
||||
top: parent.top
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: 6
|
||||
}
|
||||
height: 48
|
||||
color: "#181818"
|
||||
radius: 10
|
||||
TextInput {
|
||||
id: input
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
x: parent.width/2 - this.width/2
|
||||
Behavior on x {NumberAnimation {duration: 300; easing.type: Easing.OutQuint}}
|
||||
focus: true
|
||||
font.pixelSize: 20
|
||||
color: "white"
|
||||
cursorDelegate: Item {}
|
||||
onCursorPositionChanged: cursorPosition = text.length
|
||||
Keys.onPressed: (event) => { switch (event.key) {
|
||||
case Qt.Key_Escape:
|
||||
root.close();
|
||||
break;
|
||||
case Qt.Key_Return:
|
||||
list.currentItem.execute();
|
||||
root.close();
|
||||
break;
|
||||
case Qt.Key_Right:
|
||||
list.incrementCurrentIndex();
|
||||
break;
|
||||
case Qt.Key_Left:
|
||||
list.decrementCurrentIndex();
|
||||
break;
|
||||
}}
|
||||
}
|
||||
}
|
||||
ListView {
|
||||
id: list
|
||||
anchors {
|
||||
top: input.parent.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: 6
|
||||
}
|
||||
height: 114
|
||||
highlightFollowsCurrentItem: true
|
||||
onCurrentIndexChanged: background.indexChanged()
|
||||
orientation: ListView.Horizontal
|
||||
spacing: 6
|
||||
|
||||
add: Transition { NumberAnimation {
|
||||
property: "opacity"
|
||||
from: 0
|
||||
to: 1
|
||||
duration: 150
|
||||
}}
|
||||
remove: Transition { NumberAnimation {
|
||||
property: "opacity"
|
||||
from: 1
|
||||
to: 0
|
||||
duration: 150
|
||||
}}
|
||||
displaced: Transition {
|
||||
NumberAnimation {
|
||||
property: "x"
|
||||
duration: 300
|
||||
easing.type: Easing.OutQuint
|
||||
onStarted: console.log("displaced")
|
||||
}
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
to: 1
|
||||
duration: 150
|
||||
}
|
||||
}
|
||||
|
||||
model: ScriptModel {values: currentItems.slice(0, 5)}
|
||||
delegate: Rectangle {
|
||||
id: item
|
||||
anchors {
|
||||
top: parent?.top
|
||||
bottom: parent?.bottom
|
||||
}
|
||||
width: (700 - 6*6)/5
|
||||
color: "#20181818"
|
||||
ListView.onIsCurrentItemChanged: ListView.isCurrentItem ? selectAnim.start() : deselectAnim.start()
|
||||
property var selectAnim: ColorAnimation {
|
||||
target: item
|
||||
property: "color"
|
||||
to: "#10ffffff"
|
||||
duration: 200
|
||||
easing.type: Easing.OutQuint
|
||||
}
|
||||
property var deselectAnim: ColorAnimation {
|
||||
target: item
|
||||
onStarted: selectAnim.stop()
|
||||
property: "color"
|
||||
to: "#00181818"
|
||||
duration: 200
|
||||
easing.type: Easing.InQuint
|
||||
}
|
||||
radius: 10
|
||||
function execute() {
|
||||
modelData.emoji
|
||||
? Quickshell.clipboardText = modelData.emoji
|
||||
: modelData.execute()
|
||||
}
|
||||
Column {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
Image {
|
||||
visible: !modelData.emoji
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 64
|
||||
height: width
|
||||
source: Quickshell.iconPath(modelData.icon)
|
||||
}
|
||||
Text {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
font.pixelSize: 64
|
||||
text: modelData.emoji ?? ""
|
||||
}
|
||||
Text {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
width: parent.width - 12
|
||||
text: modelData.name
|
||||
color: "white"
|
||||
font.pixelSize: 16
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
43
Panes/Status.qml
Normal file
43
Panes/Status.qml
Normal file
@@ -0,0 +1,43 @@
|
||||
import Quickshell
|
||||
import QtQuick
|
||||
import "../Widgets" as Widgets
|
||||
|
||||
Item {
|
||||
width: 800
|
||||
height: 42
|
||||
anchors {
|
||||
top: parent.top
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
Row {
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
leftMargin: 0
|
||||
}
|
||||
Widgets.Battery {}
|
||||
}
|
||||
Widgets.Workspaces {
|
||||
height: parent.height
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
}
|
||||
Row {
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
rightMargin: 12
|
||||
}
|
||||
Text {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
property var clock: SystemClock {}
|
||||
color: "white"
|
||||
text: Qt.formatDateTime(clock.date, "ddd MMM dd · hh:mm")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user