167 lines
4.8 KiB
QML
167 lines
4.8 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import "services"
|
|
import qs.services
|
|
import qs.config
|
|
import qs.custom
|
|
import Quickshell
|
|
import QtQuick
|
|
|
|
Item {
|
|
id: root
|
|
|
|
required property PersistentProperties uiState
|
|
required property var wrapper
|
|
required property var panels
|
|
|
|
readonly property color color: list.color
|
|
readonly property int padding: 15
|
|
readonly property int rounding: 25
|
|
|
|
implicitWidth: listWrapper.width + padding * 2
|
|
implicitHeight: searchWrapper.height + listWrapper.height + padding * 2
|
|
|
|
anchors.top: parent.top
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
Item {
|
|
id: listWrapper
|
|
|
|
implicitWidth: list.width
|
|
implicitHeight: list.height + root.padding
|
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
anchors.bottom: searchWrapper.top
|
|
anchors.bottomMargin: root.padding
|
|
|
|
ContentList {
|
|
id: list
|
|
|
|
uiState: root.uiState
|
|
wrapper: root.wrapper
|
|
panels: root.panels
|
|
search: search
|
|
padding: root.padding
|
|
rounding: root.rounding
|
|
}
|
|
}
|
|
|
|
CustomRect {
|
|
id: searchWrapper
|
|
|
|
color: Config.colors.container
|
|
radius: 1000
|
|
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.bottom: parent.bottom
|
|
anchors.margins: root.padding
|
|
|
|
implicitHeight: Math.max(searchIcon.implicitHeight, search.implicitHeight, clearIcon.implicitHeight)
|
|
|
|
MaterialIcon {
|
|
id: searchIcon
|
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.left: parent.left
|
|
anchors.leftMargin: root.padding
|
|
|
|
text: "search"
|
|
color: Config.colors.tertiary
|
|
}
|
|
|
|
CustomTextField {
|
|
id: search
|
|
|
|
anchors.left: searchIcon.right
|
|
anchors.right: clearBtn.left
|
|
anchors.leftMargin: 7
|
|
anchors.rightMargin: 7
|
|
|
|
topPadding: 12
|
|
bottomPadding: 12
|
|
|
|
placeholderText: qsTr("Type \"%1\" for commands").arg(Config.launcher.actionPrefix)
|
|
|
|
onAccepted: {
|
|
const currentItem = list.list?.currentItem;
|
|
if (currentItem) {
|
|
if (text.startsWith(Config.launcher.actionPrefix)) {
|
|
currentItem.modelData.onClicked(root.uiState);
|
|
} else {
|
|
Apps.launch(currentItem.modelData);
|
|
root.uiState.launcher = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
Keys.onUpPressed: list.list?.decrementCurrentIndex()
|
|
Keys.onDownPressed: list.list?.incrementCurrentIndex()
|
|
|
|
Keys.onPressed: event => {
|
|
if (event.modifiers & Qt.ControlModifier) {
|
|
if (event.key === Qt.Key_J) {
|
|
list.list?.incrementCurrentIndex();
|
|
event.accepted = true;
|
|
} else if (event.key === Qt.Key_K) {
|
|
list.list?.decrementCurrentIndex();
|
|
event.accepted = true;
|
|
}
|
|
} else if (event.key === Qt.Key_Tab) {
|
|
list.list?.incrementCurrentIndex();
|
|
event.accepted = true;
|
|
} else if (event.key === Qt.Key_Backtab || (event.key === Qt.Key_Tab && (event.modifiers & Qt.ShiftModifier))) {
|
|
list.list?.decrementCurrentIndex();
|
|
event.accepted = true;
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: root.uiState
|
|
|
|
function onLauncherChanged(): void {
|
|
if (root.uiState.launcher)
|
|
search.focus = true;
|
|
else {
|
|
search.text = "";
|
|
list.list.currentIndex = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StateLayer {
|
|
id: clearBtn
|
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.right: parent.right
|
|
anchors.rightMargin: root.padding
|
|
|
|
implicitWidth: 24
|
|
implicitHeight: 24
|
|
|
|
disabled: search.text === ""
|
|
onClicked: search.text = ""
|
|
opacity: disabled ? 0 : 1
|
|
|
|
MaterialIcon {
|
|
id: clearIcon
|
|
|
|
anchors.centerIn: parent
|
|
|
|
width: search.text ? implicitWidth : implicitWidth / 2
|
|
|
|
text: "close"
|
|
color: Config.colors.tertiary
|
|
|
|
Behavior on width {
|
|
Anim { duration: Config.anim.durations.small }
|
|
}
|
|
}
|
|
|
|
Behavior on opacity {
|
|
Anim { duration: Config.anim.durations.small }
|
|
}
|
|
}
|
|
}
|
|
}
|