quickshell-toki-night/modules/launcher/ContentList.qml

293 lines
7.5 KiB
QML

pragma ComponentBehavior: Bound
import "items"
import "services"
import qs.config
import qs.custom
import qs.services
import qs.util
import Quickshell
import QtQuick
import QtQuick.Controls
Item {
id: root
required property PersistentProperties uiState
required property var wrapper
required property var panels
required property TextField search
required property int padding
required property int rounding
readonly property Item list: list
readonly property color color: list.color
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
implicitWidth: Config.launcher.itemWidth
implicitHeight: list.implicitHeight > 0 ? list.implicitHeight : empty.implicitHeight
clip: true
CustomListView {
id: list
model: ScriptModel {
id: model
onValuesChanged: list.currentIndex = 0
}
anchors.left: parent.left
anchors.right: parent.right
spacing: 7
orientation: Qt.Vertical
implicitHeight: (Config.launcher.itemHeight + spacing) * Math.min(Config.launcher.maxItemCount, count) - spacing
highlightMoveDuration: Config.anim.durations.normal
highlightResizeDuration: 0
keyNavigationWraps: true
property color color
highlight: CustomRect {
radius: 1000
color: list.color
opacity: 0.1
}
state: {
const text = root.search.text;
const prefix = Config.launcher.actionPrefix;
if (text.startsWith(prefix)) {
return "actions";
}
return "apps";
}
states: [
State {
name: "apps"
PropertyChanges {
model.values: Apps.search(root.search.text)
list.delegate: appItem
list.color: Config.colors.launcherApps
}
},
State {
name: "actions"
PropertyChanges {
model.values: Actions.query(root.search.text)
list.delegate: actionItem
list.color: Config.colors.launcherActions
}
}
]
// Disable animations before transition starts
onStateChanged: {
// NOTE: uiState check is necessary because this handler runs on startup
if (root.uiState.launcher) {
list.add.enabled = false;
list.remove.enabled = false;
}
}
transitions: Transition {
SequentialAnimation {
ParallelAnimation {
Anim {
target: list
property: "opacity"
from: 1
to: 0
duration: Config.anim.durations.small
easing.bezierCurve: Config.anim.curves.standardAccel
}
Anim {
target: list
property: "scale"
from: 1
to: 0.9
duration: Config.anim.durations.small
easing.bezierCurve: Config.anim.curves.standardAccel
}
}
PropertyAction {
targets: [model, list]
properties: "values,delegate,color"
}
ParallelAnimation {
Anim {
target: list
property: "opacity"
from: 0
to: 1
duration: Config.anim.durations.small
easing.bezierCurve: Config.anim.curves.standardDecel
}
Anim {
target: list
property: "scale"
from: 0.9
to: 1
duration: Config.anim.durations.small
easing.bezierCurve: Config.anim.curves.standardDecel
}
}
PropertyAction {
targets: [list.add, list.remove]
property: "enabled"
value: true
}
}
}
CustomScrollBar.vertical: CustomScrollBar {
flickable: list
}
add: Transition {
Anim {
property: "opacity"
from: 0
to: 1
}
Anim {
property: "scale"
from: 0.8
to: 1
}
}
remove: Transition {
Anim {
property: "opacity"
from: 1
to: 0
}
Anim {
property: "scale"
from: 1
to: 0.8
}
}
move: Transition {
Anim {
property: "y"
}
Anim {
properties: "opacity,scale"
to: 1
}
}
addDisplaced: Transition {
Anim {
property: "y"
duration: Config.anim.durations.small
}
Anim {
properties: "opacity,scale"
to: 1
}
}
displaced: Transition {
Anim {
property: "y"
}
Anim {
properties: "opacity,scale"
to: 1
}
}
Component {
id: appItem
AppItem {
uiState: root.uiState
}
}
Component {
id: actionItem
ActionItem {
uiState: root.uiState
list: list
}
}
}
Row {
id: empty
opacity: root.list?.count === 0 ? 1 : 0
scale: root.list?.count === 0 ? 1 : 0.5
spacing: 12
padding: 15
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
MaterialIcon {
text: "manage_search"
color: Config.colors.tertiary
font.pointSize: Config.font.size.largest
anchors.verticalCenter: parent.verticalCenter
}
Column {
anchors.verticalCenter: parent.verticalCenter
CustomText {
text: qsTr("No results")
color: Config.colors.tertiary
font.pointSize: Config.font.size.larger
font.weight: 500
}
CustomText {
text: qsTr("Try searching for something else")
color: Config.colors.tertiary
font.pointSize: Config.font.size.normal
}
}
Behavior on opacity {
Anim {}
}
Behavior on scale {
Anim {}
}
}
Behavior on implicitWidth {
enabled: root.uiState.launcher
Anim {
duration: Config.anim.durations.large
easing.bezierCurve: Config.anim.curves.emphasizedDecel
}
}
Behavior on implicitHeight {
enabled: root.uiState.launcher
Anim {
duration: Config.anim.durations.large
easing.bezierCurve: Config.anim.curves.emphasizedDecel
}
}
}