nosignal-shell/modules/bar/components/ActiveWindow.qml
2 * r + 2 * t 158588ce89 refactor: no need to explicitly type as default spatial
Default spatial is the default type, so no need to type anims as such
2026-04-23 03:47:56 +10:00

136 lines
3.9 KiB
QML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

pragma ComponentBehavior: Bound
import QtQuick
import Caelestia.Config
import qs.components
import qs.services
import qs.utils
Item {
id: root
required property var bar
required property Brightness.Monitor monitor
property color colour: Colours.palette.m3primary
readonly property string windowTitle: {
const title = Hypr.activeToplevel?.title;
if (!title)
return qsTr("Desktop");
if (Config.bar.activeWindow.compact) {
// " - " (standard hyphen), " — " (em dash), " " (en dash)
const parts = title.split(/\s+[\-\u2013\u2014]\s+/);
if (parts.length > 1)
return parts[parts.length - 1].trim();
}
return title;
}
readonly property int maxHeight: {
const otherModules = bar.children.filter(c => c.id && c.item !== this && c.id !== "spacer");
const otherHeight = otherModules.reduce((acc, curr) => acc + (curr.item.nonAnimHeight ?? curr.height), 0);
// Length - 2 cause repeater counts as a child
return bar.height - otherHeight - bar.spacing * (bar.children.length - 1) - bar.vPadding * 2;
}
property Title current: text1
clip: true
implicitWidth: Math.max(icon.implicitWidth, current.implicitHeight)
implicitHeight: icon.implicitHeight + current.implicitWidth + current.anchors.topMargin
Loader {
asynchronous: true
anchors.fill: parent
active: !Config.bar.activeWindow.showOnHover
sourceComponent: MouseArea {
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onPositionChanged: {
const popouts = root.bar.popouts;
if (popouts.hasCurrent && popouts.currentName !== "activewindow")
popouts.hasCurrent = false;
}
onClicked: {
const popouts = root.bar.popouts;
if (popouts.hasCurrent) {
popouts.hasCurrent = false;
} else {
popouts.currentName = "activewindow";
popouts.currentCenter = root.mapToItem(root.bar, 0, root.implicitHeight / 2).y;
popouts.hasCurrent = true;
}
}
}
}
MaterialIcon {
id: icon
anchors.horizontalCenter: parent.horizontalCenter
animate: true
text: Icons.getAppCategoryIcon(Hypr.activeToplevel?.lastIpcObject.class, "desktop_windows")
color: root.colour
}
Title {
id: text1
}
Title {
id: text2
}
TextMetrics {
id: metrics
text: root.windowTitle
font: root.Tokens.font.mono.small
elide: Qt.ElideRight
elideWidth: root.maxHeight - icon.height
onTextChanged: {
const next = root.current === text1 ? text2 : text1;
next.text = elidedText;
root.current = next;
}
onElideWidthChanged: root.current.text = elidedText
}
Behavior on implicitHeight {
Anim {}
}
component Title: StyledText {
id: text
anchors.horizontalCenter: icon.horizontalCenter
anchors.top: icon.bottom
anchors.topMargin: Tokens.spacing.small
font: metrics.font
color: root.colour
opacity: root.current === this ? 1 : 0
transform: [
Translate {
x: root.Config.bar.activeWindow.inverted ? -text.implicitWidth + text.implicitHeight : 0
},
Rotation {
angle: root.Config.bar.activeWindow.inverted ? 270 : 90
origin.x: text.implicitHeight / 2
origin.y: text.implicitHeight / 2
}
]
width: implicitHeight
height: implicitWidth
Behavior on opacity {
Anim {
type: Anim.DefaultEffects
}
}
}
}