summaryrefslogtreecommitdiff
path: root/modules/launcher/Content.qml
blob: d994ee60d47dd5607490283a3f59178fa8d9cdb5 (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
155
156
157
158
159
160
161
162
import "root:/widgets"
import "root:/services"
import "root:/config"
import Quickshell
import QtQuick
import QtQuick.Controls

Item {
    id: root

    required property Scope launcher
    readonly property int padding: Appearance.padding.large
    readonly property int spacing: Appearance.spacing.normal
    readonly property int rounding: Appearance.rounding.large

    implicitWidth: LauncherConfig.sizes.width
    implicitHeight: search.height + listWrapper.height + padding * 2 + spacing

    anchors.bottom: parent.bottom
    anchors.horizontalCenter: parent.horizontalCenter

    StyledRect {
        id: listWrapper

        color: Appearance.alpha(Appearance.colours.m3surfaceContainerHigh, true)
        radius: root.rounding
        implicitHeight: Math.max(empty.height, list.height) + root.padding * 2

        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: search.top
        anchors.bottomMargin: root.spacing
        anchors.margins: root.padding

        ListView {
            id: list

            model: ScriptModel {
                values: Apps.fuzzyQuery(search.text)
                onValuesChanged: list.currentIndex = 0
            }

            clip: true
            spacing: Appearance.spacing.small
            orientation: Qt.Vertical
            implicitHeight: ((currentItem?.height ?? 1) + spacing) * Math.min(LauncherConfig.maxShown, count) - spacing

            anchors.left: parent.left
            anchors.right: parent.right
            anchors.bottom: parent.bottom
            anchors.margins: root.padding

            delegate: AppItem {
                launcher: root.launcher
            }
            // TODO highlight

            ScrollBar.vertical: StyledScrollBar {
                // Move half out
                parent: list.parent
                anchors.top: list.top
                anchors.bottom: list.bottom
                anchors.right: list.right
                anchors.topMargin: root.padding / 2
                anchors.bottomMargin: root.padding / 2
                anchors.rightMargin: -root.padding / 2
            }

            add: Transition {
                Anim {
                    properties: "opacity,scale"
                    from: 0
                    to: 1
                }
            }

            remove: Transition {
                Anim {
                    properties: "opacity,scale"
                    from: 1
                    to: 0
                }
            }

            move: Transition {
                Anim {
                    property: "y"
                }
            }

            addDisplaced: Transition {
                Anim {
                    property: "y"
                    duration: Appearance.anim.durations.small
                }
            }

            displaced: Transition {
                Anim {
                    property: "y"
                }
            }

            Behavior on implicitHeight {
                Anim {}
            }
        }

        EmptyIndicator {
            id: empty

            empty: list.count === 0
        }
    }

    StyledTextField {
        id: search

        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        anchors.margins: root.padding

        topPadding: Appearance.padding.normal
        bottomPadding: Appearance.padding.normal
        leftPadding: root.padding
        rightPadding: root.padding

        placeholderText: qsTr("Type \">\" for commands")

        background: StyledRect {
            color: Appearance.alpha(Appearance.colours.m3surfaceContainerHigh, true)
            radius: root.rounding
        }

        onAccepted: {
            if (list.currentItem) {
                Apps.launch(list.currentItem?.modelData);
                root.launcher.launcherVisible = false;
            }
        }

        Keys.onEscapePressed: root.launcher.launcherVisible = false

        Connections {
            target: root.launcher

            function onLauncherVisibleChanged(): void {
                if (root.launcher.launcherVisible)
                    search.forceActiveFocus();
                else
                    search.text = "";
            }
        }
    }

    component Anim: NumberAnimation {
        duration: Appearance.anim.durations.normal
        easing.type: Easing.BezierSpline
        easing.bezierCurve: Appearance.anim.curves.standard
    }
}