summaryrefslogtreecommitdiff
path: root/raveos-hyprland-theme/theme-data/dms/Widgets/DankTooltipV2.qml
blob: 6cd53c8d9d2665155a63ed7868aba0b42065d035 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import QtQuick
import QtQuick.Controls
import qs.Common

Item {
    id: root

    property string text: ""

    function show(text, item, offsetX, offsetY, preferredSide) {
        if (!item)
            return;

        let windowContentItem = item.Window?.window?.contentItem;
        if (!windowContentItem) {
            let current = item;
            while (current) {
                if (current.Window?.window?.contentItem) {
                    windowContentItem = current.Window.window.contentItem;
                    break;
                }
                current = current.parent;
            }
        }
        if (!windowContentItem)
            return;

        tooltip.parent = windowContentItem;
        tooltip.text = text;

        const itemPos = item.mapToItem(windowContentItem, 0, 0);
        const parentWidth = windowContentItem.width;
        const parentHeight = windowContentItem.height;
        const tooltipWidth = tooltip.implicitWidth;
        const tooltipHeight = tooltip.implicitHeight;

        const side = preferredSide || _determineBestSide(itemPos, item, parentWidth, parentHeight, tooltipWidth, tooltipHeight);

        let targetX = 0;
        let targetY = 0;

        switch (side) {
        case "left":
            targetX = itemPos.x - tooltipWidth - 8;
            targetY = itemPos.y + (item.height - tooltipHeight) / 2;
            break;
        case "right":
            targetX = itemPos.x + item.width + 8;
            targetY = itemPos.y + (item.height - tooltipHeight) / 2;
            break;
        case "top":
            targetX = itemPos.x + (item.width - tooltipWidth) / 2;
            targetY = itemPos.y - tooltipHeight - 8;
            break;
        case "bottom":
        default:
            targetX = itemPos.x + (item.width - tooltipWidth) / 2;
            targetY = itemPos.y + item.height + 8;
            break;
        }

        tooltip.x = Math.max(4, Math.min(parentWidth - tooltipWidth - 4, targetX + (offsetX || 0)));
        tooltip.y = Math.max(4, Math.min(parentHeight - tooltipHeight - 4, targetY + (offsetY || 0)));

        tooltip.open();
    }

    function _determineBestSide(itemPos, item, parentWidth, parentHeight, tooltipWidth, tooltipHeight) {
        const itemCenterX = itemPos.x + item.width / 2;
        const itemCenterY = itemPos.y + item.height / 2;

        const spaceLeft = itemPos.x;
        const spaceRight = parentWidth - (itemPos.x + item.width);
        const spaceTop = itemPos.y;
        const spaceBottom = parentHeight - (itemPos.y + item.height);

        if (spaceRight >= tooltipWidth + 16) {
            return "right";
        }
        if (spaceLeft >= tooltipWidth + 16) {
            return "left";
        }
        if (spaceBottom >= tooltipHeight + 16) {
            return "bottom";
        }
        if (spaceTop >= tooltipHeight + 16) {
            return "top";
        }

        if (itemCenterX > parentWidth / 2) {
            return "left";
        }
        return "right";
    }

    function hide() {
        tooltip.close();
    }

    Popup {
        id: tooltip

        property string text: ""

        leftPadding: Theme.spacingM
        rightPadding: Theme.spacingM
        topPadding: Theme.spacingS
        bottomPadding: Theme.spacingS
        closePolicy: Popup.NoAutoClose
        modal: false
        dim: false

        background: Rectangle {
            color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
            radius: Theme.cornerRadius
            border.width: 1
            border.color: Theme.outlineMedium
        }

        contentItem: Text {
            id: textContent

            width: Math.min(implicitWidth, 500)
            text: tooltip.text
            font.pixelSize: Theme.fontSizeSmall
            color: Theme.surfaceText
            wrapMode: Text.NoWrap
            maximumLineCount: 1
            elide: Text.ElideRight
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
        }

        enter: Transition {
            NumberAnimation {
                property: "opacity"
                from: 0
                to: 1
                duration: Theme.shortDuration
                easing.type: Theme.standardEasing
            }
        }

        exit: Transition {
            NumberAnimation {
                property: "opacity"
                from: 1
                to: 0
                duration: Theme.shorterDuration
                easing.type: Theme.standardEasing
            }
        }
    }
}