Files

145 lines
4.4 KiB
QML

import QtQuick
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
import Quickshell
import Quickshell.Wayland
import Quickshell.Hyprland
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
import qs.modules.waffle.looks
WMouseAreaButton {
id: root
required property int workspace
property bool newWorkspace: false
property bool droppable: false
readonly property bool isActiveWorkspace: HyprlandData.activeWorkspace?.id === root.workspace
readonly property real screenWidth: QsWindow.window?.width ?? 0
readonly property real screenHeight: QsWindow.window?.height ?? 0
readonly property real screenAspectRatio: screenWidth / screenHeight
readonly property real windowScale: wallpaperHeight / screenHeight
property real wallpaperHeight: 124
height: ListView.view?.height ?? 100
implicitWidth: 244 // for now
colBackground: ColorUtils.transparentize(Looks.colors.bg2, (isActiveWorkspace || droppable) ? 0 : 1)
Behavior on color {
animation: Looks.transition.color.createObject(this)
}
scale: root.containsPress ? 0.95 : 1
Behavior on scale {
NumberAnimation {
id: scaleAnim
duration: 300
easing.type: Easing.OutExpo
}
}
// Content
ColumnLayout {
id: contentItem
anchors {
fill: parent
leftMargin: 12
rightMargin: 12
topMargin: 9
bottomMargin: 8
}
spacing: 8
WText {
Layout.fillWidth: true
Layout.fillHeight: false
horizontalAlignment: Text.AlignLeft
elide: Text.ElideRight
text: root.newWorkspace ? Translation.tr("New desktop") : Translation.tr("Desktop %1").arg(root.workspace)
}
Rectangle {
id: wsBg
height: root.wallpaperHeight
Layout.fillHeight: true
Layout.fillWidth: true
color: Looks.colors.bg1
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Rectangle {
width: wsBg.width
height: wsBg.height
radius: Looks.radius.medium
}
}
// Workspace content
Loader {
anchors.fill: parent
active: !root.newWorkspace
sourceComponent: StyledImage {
cache: true
source: Config.options.background.wallpaperPath
fillMode: Image.PreserveAspectCrop
Repeater {
model: ScriptModel {
values: HyprlandData.toplevelsForWorkspace(root.workspace)
}
delegate: ScreencopyView {
required property var modelData
readonly property var hyprlandWindowData: HyprlandData.windowByAddress[`0x${modelData.HyprlandToplevel?.address}`]
captureSource: modelData
live: true
width: hyprlandWindowData?.size[0] * root.windowScale
height: hyprlandWindowData?.size[1] * root.windowScale
x: hyprlandWindowData?.at[0] * root.windowScale
y: hyprlandWindowData?.at[1] * root.windowScale
}
}
}
}
// New plus icon
Loader {
anchors.centerIn: parent
active: root.newWorkspace
sourceComponent: FluentIcon {
icon: "add"
}
}
Rectangle {
z: 2
visible: root.droppable && !root.newWorkspace
anchors.fill: parent
color: Looks.colors.accent
opacity: 0.2
}
}
}
// Active indicator
WFadeLoader {
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
}
shown: root.isActiveWorkspace
sourceComponent: Rectangle {
id: activeIndicator
implicitWidth: 32
implicitHeight: 3
color: Looks.colors.accent
radius: height / 2
}
}
}