159 lines
4.3 KiB
QML
159 lines
4.3 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import QtQuick
|
|
import QtQuick.Layouts
|
|
import Quickshell.Services.SystemTray
|
|
import qs.Components
|
|
import qs.Config
|
|
import qs.Modules.SysTray.Widgets
|
|
import qs.Modules
|
|
|
|
GridLayout {
|
|
id: root
|
|
|
|
required property bool horizontal
|
|
readonly property alias items: repeater
|
|
required property GridLayout loader
|
|
required property Wrapper popouts
|
|
readonly property real shortSize: Config.bar.height + Appearance.padding.smallest * 2
|
|
readonly property real size: horizontal ? sysTray.implicitWidth + sysTrayMod.implicitWidth + Appearance.padding.small : sysTray.implicitHeight + sysTrayMod.implicitHeight + Appearance.padding.small
|
|
|
|
function closestRowChild(row, x) {
|
|
let child = row.childAt(x, row.height / 2);
|
|
if (child)
|
|
return child;
|
|
|
|
let closest = null;
|
|
let closestDistance = Infinity;
|
|
|
|
for (let i = 0; i < row.children.length; ++i) {
|
|
let c = row.children[i];
|
|
|
|
if (!c.visible || c.width <= 0)
|
|
continue;
|
|
|
|
let centerX = c.x + c.width / 2;
|
|
let dist = Math.abs(x - centerX);
|
|
|
|
if (dist < closestDistance) {
|
|
closestDistance = dist;
|
|
closest = c;
|
|
}
|
|
}
|
|
|
|
return closest;
|
|
}
|
|
|
|
function getHoveredSubItem(localX, localY) {
|
|
let modPos = mapToItem(sysTrayMod, localX, localY);
|
|
if (sysTrayMod.contains(Qt.point(modPos.x, modPos.y))) {
|
|
let modRowPos = sysTrayMod.mapToItem(sysIcons, modPos.x, modPos.y);
|
|
let child = closestRowChild(sysIcons, modRowPos.x);
|
|
if (child) {
|
|
if (child.objectName === "audio" && Config.bar.popouts.audio)
|
|
return {
|
|
id: "audio",
|
|
item: child
|
|
};
|
|
if (child.objectName === "microphone" && Config.bar.popouts.audio)
|
|
return {
|
|
id: "audio",
|
|
item: child
|
|
};
|
|
if (child.objectName === "upower" && Config.bar.popouts.upower)
|
|
return {
|
|
id: "upower",
|
|
item: child
|
|
};
|
|
}
|
|
}
|
|
|
|
let trayPos = mapToItem(sysTray, localX, localY);
|
|
if (Config.bar.tray.showOnHover && sysTray.contains(Qt.point(trayPos.x, trayPos.y))) {
|
|
let trayRowPos = sysTray.mapToItem(sysRow, trayPos.x, trayPos.y);
|
|
let child = sysRow.childAt(trayRowPos.x, trayRowPos.y);
|
|
if (child && child.hasOwnProperty("ind")) {
|
|
return {
|
|
id: `traymenu${child.ind}`,
|
|
item: child
|
|
};
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
columnSpacing: Appearance.padding.small
|
|
columns: horizontal ? -1 : 1
|
|
height: horizontal ? shortSize : size
|
|
rowSpacing: Appearance.padding.small
|
|
width: horizontal ? size : shortSize
|
|
|
|
CustomClippingRect {
|
|
id: sysTray
|
|
|
|
Layout.fillHeight: true
|
|
bottomRightRadius: Appearance.rounding.smallest / 2
|
|
color: DynamicColors.tPalette.m3surfaceContainer
|
|
implicitWidth: sysRow.width + Appearance.padding.small * 2
|
|
radius: Appearance.rounding.full
|
|
topRightRadius: Appearance.rounding.smallest / 2
|
|
|
|
GridLayout {
|
|
id: sysRow
|
|
|
|
anchors.bottom: root.horizontal ? undefined : parent.bottom
|
|
anchors.centerIn: parent
|
|
anchors.horizontalCenter: root.horizontal ? parent.horizontalCenter : undefined
|
|
anchors.left: root.horizontal ? undefined : parent.left
|
|
anchors.right: root.horizontal ? undefined : parent.right
|
|
anchors.verticalCenter: root.horizontal ? parent.verticalCenter : undefined
|
|
columnSpacing: Appearance.spacing.small / 2
|
|
columns: root.horizontal ? -1 : 1
|
|
rowSpacing: Appearance.spacing.small / 2
|
|
|
|
Repeater {
|
|
id: repeater
|
|
|
|
model: SystemTray.items
|
|
|
|
TrayItem {
|
|
id: trayItem
|
|
|
|
required property int index
|
|
required property SystemTrayItem modelData
|
|
|
|
implicitHeight: 34
|
|
implicitWidth: 34
|
|
ind: index
|
|
item: modelData
|
|
loader: root.loader
|
|
popouts: root.popouts
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CustomClippingRect {
|
|
id: sysTrayMod
|
|
|
|
Layout.fillHeight: root.horizontal
|
|
Layout.fillWidth: !root.horizontal
|
|
bottomLeftRadius: Appearance.rounding.smallest / 2
|
|
color: DynamicColors.tPalette.m3surfaceContainer
|
|
implicitHeight: root.horizontal ? sysIcons.implicitHeight : sysIcons.implicitHeight + Appearance.padding.smaller + Appearance.padding.normal
|
|
implicitWidth: root.horizontal ? sysIcons.implicitWidth + Appearance.padding.smaller + Appearance.padding.normal : sysIcons.implicitWidth
|
|
radius: Appearance.rounding.full
|
|
topLeftRadius: Appearance.rounding.smallest / 2
|
|
|
|
StatusIcons {
|
|
id: sysIcons
|
|
|
|
anchors.fill: parent
|
|
anchors.leftMargin: Appearance.padding.smaller
|
|
anchors.rightMargin: Appearance.padding.normal
|
|
horizontal: root.horizontal
|
|
}
|
|
}
|
|
}
|