Files

107 lines
3.6 KiB
QML

pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import qs.Common
import qs.Services
// Page-control style workspace strip: a dot per workspace, the focused one stretched into a pill.
Item {
id: root
required property var model
property bool vertical: false
property real dotSize: Theme.spacingS
property real activeLength: dotSize * 2.5
property real gap: Theme.spacingXS
property color activeColor: Theme.primary
property color occupiedColor: Theme.surfaceTextMedium
property color emptyColor: Theme.surfaceTextAlpha
property color urgentColor: Theme.error
property bool animated: !SettingsData.reduceMotion
implicitWidth: strip.implicitWidth
implicitHeight: strip.implicitHeight
function indexAt(x, y) {
let closest = -1;
let closestDist = Infinity;
for (let i = 0; i < dots.count; i++) {
const item = dots.itemAt(i);
if (!item || root.model.isPlaceholder(root.model.workspaceList[i]))
continue;
const center = item.mapToItem(root, item.width / 2, item.height / 2);
const dist = root.vertical ? Math.abs(y - center.y) : Math.abs(x - center.x);
if (dist < closestDist) {
closestDist = dist;
closest = i;
}
}
return closest;
}
function entryAt(x, y) {
const index = indexAt(x, y);
return index < 0 ? null : root.model.workspaceList[index];
}
Grid {
id: strip
anchors.centerIn: parent
columns: root.vertical ? 1 : Math.max(1, dots.count)
spacing: root.gap
horizontalItemAlignment: Grid.AlignHCenter
verticalItemAlignment: Grid.AlignVCenter
Repeater {
id: dots
model: ScriptModel {
values: root.model.workspaceList
}
Rectangle {
id: dot
required property var modelData
readonly property var record: root.model.recordOf(modelData)
readonly property bool placeholder: root.model.isPlaceholder(modelData)
readonly property bool active: root.model.isActive(modelData)
readonly property bool occupied: root.model.isOccupied(modelData)
readonly property bool urgent: !placeholder && root.model.useNativeWorkspaces && CompositorService.workspaceUrgent(record, CompositorService.loadWorkspaceUrgent(record))
readonly property real length: active ? root.activeLength : root.dotSize
width: root.vertical ? root.dotSize : length
height: root.vertical ? length : root.dotSize
radius: root.dotSize / 2
color: active ? root.activeColor : urgent ? root.urgentColor : occupied ? root.occupiedColor : root.emptyColor
Behavior on width {
enabled: root.animated && !root.vertical
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.standardEasing
}
}
Behavior on height {
enabled: root.animated && root.vertical
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.standardEasing
}
}
Behavior on color {
enabled: root.animated
ColorAnimation {
duration: Theme.shortDuration
}
}
}
}
}
}