mirror of
https://github.com/danbulant/dots-hyprland
synced 2026-05-24 12:22:09 +00:00
135 lines
4.5 KiB
QML
135 lines
4.5 KiB
QML
import "root:/"
|
|
import "root:/services"
|
|
import "root:/modules/common"
|
|
import "root:/modules/common/widgets"
|
|
import "root:/modules/common/functions/color_utils.js" as ColorUtils
|
|
import Qt5Compat.GraphicalEffects
|
|
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Effects
|
|
import QtQuick.Layouts
|
|
import Quickshell.Io
|
|
import Quickshell
|
|
import Quickshell.Widgets
|
|
import Quickshell.Wayland
|
|
import Quickshell.Hyprland
|
|
|
|
DockButton {
|
|
id: root
|
|
property var appToplevel
|
|
property var appListRoot
|
|
property int lastFocused: -1
|
|
property real iconSize: 35
|
|
property real countDotWidth: 10
|
|
property real countDotHeight: 4
|
|
property bool appIsActive: appToplevel.toplevels.find(t => (t.activated == true)) !== undefined
|
|
|
|
property bool isSeparator: appToplevel.appId === "SEPARATOR"
|
|
property var desktopEntry: DesktopEntries.byId(appToplevel.appId)
|
|
enabled: !isSeparator
|
|
implicitWidth: isSeparator ? 1 : implicitHeight - topInset - bottomInset
|
|
|
|
Loader {
|
|
active: isSeparator
|
|
anchors {
|
|
fill: parent
|
|
topMargin: dockVisualBackground.margin + dockRow.padding + Appearance.rounding.normal
|
|
bottomMargin: dockVisualBackground.margin + dockRow.padding + Appearance.rounding.normal
|
|
}
|
|
sourceComponent: DockSeparator {}
|
|
}
|
|
|
|
Loader {
|
|
anchors.fill: parent
|
|
active: appToplevel.toplevels.length > 0
|
|
sourceComponent: MouseArea {
|
|
id: mouseArea
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
acceptedButtons: Qt.NoButton
|
|
onEntered: {
|
|
appListRoot.lastHoveredButton = root
|
|
appListRoot.buttonHovered = true
|
|
lastFocused = appToplevel.toplevels.length - 1
|
|
}
|
|
onExited: {
|
|
if (appListRoot.lastHoveredButton === root) {
|
|
appListRoot.buttonHovered = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
onClicked: {
|
|
if (appToplevel.toplevels.length === 0) {
|
|
root.desktopEntry?.execute();
|
|
return;
|
|
}
|
|
lastFocused = (lastFocused + 1) % appToplevel.toplevels.length
|
|
appToplevel.toplevels[lastFocused].activate()
|
|
}
|
|
|
|
middleClickAction: () => {
|
|
root.desktopEntry?.execute();
|
|
}
|
|
|
|
contentItem: Loader {
|
|
active: !isSeparator
|
|
sourceComponent: Item {
|
|
anchors.centerIn: parent
|
|
|
|
Loader {
|
|
id: iconImageLoader
|
|
anchors {
|
|
left: parent.left
|
|
right: parent.right
|
|
verticalCenter: parent.verticalCenter
|
|
}
|
|
active: !root.isSeparator
|
|
sourceComponent: IconImage {
|
|
source: Quickshell.iconPath(AppSearch.guessIcon(appToplevel.appId), "image-missing")
|
|
implicitSize: root.iconSize
|
|
}
|
|
}
|
|
|
|
Loader {
|
|
active: Config.options.dock.monochromeIcons
|
|
anchors.fill: iconImageLoader
|
|
sourceComponent: Item {
|
|
Desaturate {
|
|
id: desaturatedIcon
|
|
visible: false // There's already color overlay
|
|
anchors.fill: parent
|
|
source: iconImageLoader
|
|
desaturation: 0.8
|
|
}
|
|
ColorOverlay {
|
|
anchors.fill: desaturatedIcon
|
|
source: desaturatedIcon
|
|
color: ColorUtils.transparentize(Appearance.colors.colPrimary, 0.9)
|
|
}
|
|
}
|
|
}
|
|
|
|
RowLayout {
|
|
spacing: 3
|
|
anchors {
|
|
top: iconImageLoader.bottom
|
|
topMargin: 2
|
|
horizontalCenter: parent.horizontalCenter
|
|
}
|
|
Repeater {
|
|
model: Math.min(appToplevel.toplevels.length, 3)
|
|
delegate: Rectangle {
|
|
required property int index
|
|
radius: Appearance.rounding.full
|
|
implicitWidth: (appToplevel.toplevels.length <= 3) ?
|
|
root.countDotWidth : root.countDotHeight // Circles when too many
|
|
implicitHeight: root.countDotHeight
|
|
color: appIsActive ? Appearance.colors.colPrimary : ColorUtils.transparentize(Appearance.colors.colOnLayer0, 0.4)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|