updated pi, quickshell, and ollama
This commit is contained in:
531
home/hypr/quickshell/components/SidePanel.qml
Normal file
531
home/hypr/quickshell/components/SidePanel.qml
Normal file
@@ -0,0 +1,531 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Hyprland
|
||||
import Quickshell.Wayland
|
||||
import "../theme"
|
||||
import ".."
|
||||
|
||||
PanelWindow {
|
||||
id: root
|
||||
property var screen
|
||||
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.namespace: "quickshell-sidepanel"
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||
|
||||
anchors {
|
||||
top: true
|
||||
bottom: true
|
||||
left: true
|
||||
right: false
|
||||
}
|
||||
|
||||
exclusiveZone: Theme.sidebarWidth
|
||||
implicitWidth: Theme.sidebarWidth
|
||||
color: Theme.bgPrimary
|
||||
|
||||
// Right edge hairline border
|
||||
Rectangle {
|
||||
width: 1
|
||||
color: Theme.glassBorder
|
||||
anchors {
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
||||
component Separator: Rectangle {
|
||||
width: 36
|
||||
height: 1
|
||||
color: Theme.glassBorder
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
component DockIcon: Item {
|
||||
id: dockIconRoot
|
||||
width: 36
|
||||
height: 36
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
property string appClass: ""
|
||||
property string execCmd: ""
|
||||
property string iconSource: ""
|
||||
property string tooltipText: ""
|
||||
|
||||
property bool isRunning: (appClass !== "" && GlobalState.activeWindowClass === appClass) || (GlobalState.runningApps && GlobalState.runningApps.indexOf(appClass) !== -1)
|
||||
|
||||
Image {
|
||||
id: img
|
||||
anchors.centerIn: parent
|
||||
width: 24
|
||||
height: 24
|
||||
source: iconSource ? Qt.resolvedUrl("../assets/" + iconSource) : ""
|
||||
sourceSize: Qt.size(24, 24)
|
||||
fillMode: Image.PreserveAspectFit
|
||||
opacity: mouseArea.containsMouse ? 1.0 : 0.8
|
||||
|
||||
scale: mouseArea.containsMouse ? 1.15 : 1.0
|
||||
Behavior on scale {
|
||||
NumberAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic }
|
||||
}
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic }
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: runningDot
|
||||
width: 4
|
||||
height: 4
|
||||
radius: 2
|
||||
color: Theme.accentVolt
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
visible: isRunning
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
if (execCmd !== "") {
|
||||
GlobalState.launchApp(execCmd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tooltip
|
||||
Rectangle {
|
||||
id: tooltip
|
||||
visible: mouseArea.containsMouse && tooltipText !== ""
|
||||
color: Theme.glassBg
|
||||
radius: 4
|
||||
width: tooltipLabel.implicitWidth + 16
|
||||
height: tooltipLabel.implicitHeight + 8
|
||||
|
||||
anchors.left: parent.right
|
||||
anchors.leftMargin: 24
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Text {
|
||||
id: tooltipLabel
|
||||
anchors.centerIn: parent
|
||||
text: tooltipText
|
||||
color: Theme.textPrimary
|
||||
font.family: Theme.fontSans
|
||||
font.pixelSize: 11
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 8
|
||||
|
||||
// Top spacer
|
||||
Item { height: 4; Layout.fillWidth: true }
|
||||
|
||||
// 1. AG Logo Button
|
||||
Rectangle {
|
||||
width: 36
|
||||
height: 36
|
||||
radius: 4
|
||||
color: logoMouse.containsMouse ? Qt.rgba(1,1,1,0.05) : "transparent"
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic }
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "AG"
|
||||
font.family: Theme.fontSerif
|
||||
font.italic: true
|
||||
font.pixelSize: 16
|
||||
color: Theme.accentVolt
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: logoMouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: GlobalState.appleMenuVisible = !GlobalState.appleMenuVisible
|
||||
}
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
// 3. Workspace Indicators
|
||||
Column {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: 2
|
||||
|
||||
Repeater {
|
||||
model: GlobalState.workspaceList
|
||||
delegate: Rectangle {
|
||||
width: 52
|
||||
height: 36
|
||||
color: wsMouse.containsMouse ? Qt.rgba(1,1,1,0.04) : "transparent"
|
||||
|
||||
property bool isActive: GlobalState.activeWorkspace === modelData
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic }
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 2
|
||||
height: 20
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: Theme.accentVolt
|
||||
visible: isActive
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
spacing: 2
|
||||
|
||||
Text {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: (modelData < 10 ? "0" : "") + modelData
|
||||
color: isActive ? Theme.accentVolt : Theme.textMuted
|
||||
font.family: Theme.fontMono
|
||||
font.pixelSize: 12
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic }
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: (GlobalState.workspaceNames && GlobalState.workspaceNames[modelData]) ? GlobalState.workspaceNames[modelData] : ""
|
||||
color: Theme.textMuted
|
||||
font.family: Theme.fontSans
|
||||
font.pixelSize: 8
|
||||
opacity: 0.7
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: wsMouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: GlobalState.switchWorkspace(modelData)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
// 5. Spotlight trigger
|
||||
Item {
|
||||
width: 36
|
||||
height: 36
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "⌕"
|
||||
font.pixelSize: 20
|
||||
color: spotlightMouse.containsMouse ? Theme.accentVolt : Theme.textMuted
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic }
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: spotlightMouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: GlobalState.toggleSpotlight()
|
||||
}
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
// 7. Pinned Apps
|
||||
Column {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: 8
|
||||
|
||||
DockIcon {
|
||||
appClass: ""
|
||||
execCmd: "nautilus"
|
||||
iconSource: "finder.svg"
|
||||
tooltipText: "Finder"
|
||||
}
|
||||
DockIcon {
|
||||
appClass: "brave-browser"
|
||||
execCmd: "brave"
|
||||
iconSource: "browser.svg"
|
||||
tooltipText: "Brave Browser"
|
||||
}
|
||||
DockIcon {
|
||||
appClass: "foot"
|
||||
execCmd: "foot"
|
||||
iconSource: "terminal.svg"
|
||||
tooltipText: "Terminal"
|
||||
}
|
||||
DockIcon {
|
||||
appClass: "nvim"
|
||||
execCmd: "foot -e nvim"
|
||||
iconSource: "code.svg"
|
||||
tooltipText: "Code"
|
||||
}
|
||||
DockIcon {
|
||||
appClass: "pavucontrol"
|
||||
execCmd: "pavucontrol"
|
||||
iconSource: "preferences.svg"
|
||||
tooltipText: "Settings"
|
||||
}
|
||||
DockIcon {
|
||||
appClass: ""
|
||||
execCmd: "spotify"
|
||||
iconSource: "music.svg"
|
||||
tooltipText: "Music"
|
||||
}
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
// 9. Running Apps (non-pinned)
|
||||
Column {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: 8
|
||||
|
||||
Repeater {
|
||||
model: {
|
||||
var pinned = ["foot", "brave-browser", "pavucontrol", "nvim", "nautilus", "spotify", ""]
|
||||
var running = []
|
||||
var seen = {}
|
||||
if (GlobalState.runningApps) {
|
||||
for (var i = 0; i < GlobalState.runningApps.length; i++) {
|
||||
var cls = GlobalState.runningApps[i]
|
||||
if (cls && pinned.indexOf(cls) === -1 && !seen[cls]) {
|
||||
seen[cls] = true
|
||||
running.push(cls)
|
||||
}
|
||||
}
|
||||
}
|
||||
return running
|
||||
}
|
||||
|
||||
delegate: Item {
|
||||
width: 36
|
||||
height: 36
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: 24
|
||||
height: 24
|
||||
radius: 12
|
||||
color: Qt.rgba(1, 1, 1, 0.1)
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: modelData.charAt(0).toUpperCase()
|
||||
color: Theme.textPrimary
|
||||
font.family: Theme.fontSans
|
||||
font.pixelSize: 12
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 4
|
||||
height: 4
|
||||
radius: 2
|
||||
color: Theme.accentVolt
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
// Focus app logic here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 10. Flexible spacer
|
||||
Item { Layout.fillHeight: true }
|
||||
|
||||
Separator {}
|
||||
|
||||
// 12. Telemetry mini-readouts
|
||||
Column {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: 2
|
||||
|
||||
Text {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: "CPU" + (GlobalState.cpuPercent !== undefined ? GlobalState.cpuPercent : "0") + "%"
|
||||
font.family: Theme.fontMono
|
||||
font.pixelSize: 11
|
||||
color: (GlobalState.cpuPercent !== undefined && GlobalState.cpuPercent > 80) ? Theme.accentCoral : Theme.textMuted
|
||||
Behavior on color { ColorAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic } }
|
||||
}
|
||||
Text {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: "RAM" + (GlobalState.memUsedGb !== undefined ? GlobalState.memUsedGb : "0") + "G"
|
||||
font.family: Theme.fontMono
|
||||
font.pixelSize: 11
|
||||
color: (GlobalState.memPercent !== undefined && GlobalState.memPercent > 85) ? Theme.accentCoral : Theme.textMuted
|
||||
Behavior on color { ColorAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic } }
|
||||
}
|
||||
Text {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: "VRM" + (GlobalState.gpuVramUsed !== undefined ? GlobalState.gpuVramUsed : "0") + "G"
|
||||
font.family: Theme.fontMono
|
||||
font.pixelSize: 11
|
||||
color: Theme.textMuted
|
||||
}
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
// 14. System tray icons
|
||||
Column {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: 8
|
||||
|
||||
// Volume
|
||||
Item {
|
||||
width: 36
|
||||
height: 36
|
||||
Image {
|
||||
anchors.centerIn: parent
|
||||
width: 16
|
||||
height: 16
|
||||
source: Qt.resolvedUrl("../assets/volume.svg")
|
||||
sourceSize: Qt.size(16, 16)
|
||||
opacity: volMouse.containsMouse ? 1.0 : 0.7
|
||||
Behavior on opacity { NumberAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic } }
|
||||
}
|
||||
MouseArea {
|
||||
id: volMouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
GlobalState.systemHudActiveSection = "volume"
|
||||
GlobalState.systemHudVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WiFi
|
||||
Item {
|
||||
width: 36
|
||||
height: 36
|
||||
Image {
|
||||
anchors.centerIn: parent
|
||||
width: 16
|
||||
height: 16
|
||||
source: Qt.resolvedUrl("../assets/wifi.svg")
|
||||
sourceSize: Qt.size(16, 16)
|
||||
opacity: GlobalState.wifiConnected ? 0.7 : 0.3
|
||||
Behavior on opacity { NumberAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic } }
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
GlobalState.systemHudActiveSection = "network"
|
||||
GlobalState.systemHudVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Battery
|
||||
Item {
|
||||
width: 36
|
||||
height: 44
|
||||
visible: GlobalState.batteryPresent !== undefined ? GlobalState.batteryPresent : false
|
||||
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
spacing: 2
|
||||
|
||||
Image {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 16
|
||||
height: 16
|
||||
source: Qt.resolvedUrl("../assets/battery.svg")
|
||||
sourceSize: Qt.size(16, 16)
|
||||
opacity: (GlobalState.batteryPercent !== undefined && GlobalState.batteryPercent < 20) ? 1.0 : 0.7
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: (GlobalState.batteryPercent !== undefined ? GlobalState.batteryPercent : "100") + "%"
|
||||
font.family: Theme.fontMono
|
||||
font.pixelSize: 9
|
||||
color: (GlobalState.batteryPercent !== undefined && GlobalState.batteryPercent < 20) ? Theme.accentCoral : Theme.textSecondary
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
GlobalState.systemHudActiveSection = "battery"
|
||||
GlobalState.systemHudVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
// 16. Clock
|
||||
Item {
|
||||
width: 36
|
||||
height: 44
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
spacing: 2
|
||||
|
||||
Text {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: GlobalState.timeString !== undefined ? GlobalState.timeString : "00:00"
|
||||
font.family: Theme.fontMono
|
||||
font.pixelSize: 12
|
||||
color: Theme.textPrimary
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: GlobalState.dateString !== undefined ? GlobalState.dateString : "Jan 01"
|
||||
font.family: Theme.fontMono
|
||||
font.pixelSize: 9
|
||||
color: Theme.textMuted
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
GlobalState.systemHudActiveSection = "calendar"
|
||||
GlobalState.systemHudVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom spacer
|
||||
Item { height: 4; Layout.fillWidth: true }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user