quickshell-toki-night/modules/launcher/Content.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 }
}
}
}
}