status-desktop/ui/app/AppLayouts/Chat/panels/InlineSelectorPanel.qml

235 lines
7.7 KiB
QML

import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import QtGraphicalEffects 1.0
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Popups.Dialog 0.1
Item {
id: root
property alias model: listView.model
property alias delegate: listView.delegate
property alias suggestionsModel: suggestionsListView.model
property alias suggestionsDelegate: suggestionsListView.delegate
readonly property alias label: label
readonly property alias warningLabel: warningLabel
readonly property alias edit: edit
signal confirmed()
signal rejected()
signal entryAccepted(var suggestionsDelegate)
signal entryRemoved(var delegate)
implicitWidth: mainLayout.implicitWidth
implicitHeight: mainLayout.implicitHeight
RowLayout {
id: mainLayout
spacing: 8
anchors.fill: parent
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 44
color: Theme.palette.baseColor2
radius: 8
RowLayout {
anchors {
fill: parent
leftMargin: 16
rightMargin: 16
topMargin: 7
bottomMargin: 7
}
StatusBaseText {
id: label
Layout.alignment: Qt.AlignVCenter
visible: text !== ""
font.pixelSize: 15
color: Theme.palette.baseColor1
}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
StatusScrollView {
id: scrollView
anchors.fill: parent
padding: 0
onContentWidthChanged: {
if (scrollView.contentWidth > scrollView.width) {
scrollView.contentX = scrollView.contentWidth - scrollView.width
} else {
scrollView.contentX = 0
}
}
RowLayout {
height: scrollView.height
spacing: 8
StatusListView {
id: listView
Layout.fillWidth: true
Layout.fillHeight: true
implicitWidth: contentWidth
orientation: ListView.Horizontal
spacing: 8
}
TextInput {
id: edit
Layout.fillHeight: true
Layout.minimumWidth: 4
verticalAlignment: Text.AlignVCenter
font.pixelSize: 15
color: Theme.palette.directColor1
cursorDelegate: Rectangle {
color: Theme.palette.primaryColor1
implicitWidth: 2
radius: 1
visible: edit.cursorVisible
SequentialAnimation on visible {
loops: Animation.Infinite
running: edit.cursorVisible
PropertyAnimation { to: false; duration: 600; }
PropertyAnimation { to: true; duration: 600; }
}
}
Keys.onPressed: {
if (suggestionsDialog.visible) {
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
root.entryAccepted(suggestionsListView.itemAtIndex(suggestionsListView.currentIndex))
} else if (event.key === Qt.Key_Up) {
suggestionsListView.decrementCurrentIndex()
} else if (event.key === Qt.Key_Down) {
suggestionsListView.incrementCurrentIndex()
}
} else {
if (event.key === Qt.Key_Backspace && edit.text === "") {
root.entryRemoved(listView.itemAtIndex(listView.count - 1))
} else if (event.key === Qt.Key_Return || event.key === Qt.Enter) {
root.confirmed()
} else if (event.key === Qt.Key_Escape) {
root.rejected()
}
}
}
}
// ensure edit cursor is visible
Item {
Layout.fillHeight: true
implicitWidth: 1
}
}
ScrollBar.horizontal: StatusScrollBar {
id: scrollBar
parent: scrollView.parent
anchors.top: scrollView.bottom
anchors.left: scrollView.left
anchors.right: scrollView.right
policy: ScrollBar.AsNeeded
visible: resolveVisibility(policy, scrollView.width, scrollView.contentWidth)
}
}
}
StatusBaseText {
id: warningLabel
Layout.alignment: Qt.AlignVCenter
visible: text !== ""
font.pixelSize: 10
color: Theme.palette.dangerColor1
}
}
MouseArea {
anchors.fill: parent
propagateComposedEvents: true
onPressed: {
edit.forceActiveFocus()
mouse.accepted = false
}
}
}
StatusButton {
Layout.leftMargin: 10
text: qsTr("Confirm")
onClicked: root.confirmed()
}
StatusButton {
text: qsTr("Reject")
type: StatusBaseButton.Type.Danger
onClicked: root.rejected()
}
}
Popup {
id: suggestionsDialog
visible: edit.text !== "" && root.suggestionsModel.count
parent: edit
y: parent.height
padding: 8
background: StatusDialogBackground {
id: bg
layer.enabled: true
layer.effect: DropShadow {
source: bg
horizontalOffset: 0
verticalOffset: 4
radius: 12
samples: 25
spread: 0.2
color: Theme.palette.dropShadow
}
}
StatusListView {
id: suggestionsListView
anchors.fill: parent
implicitWidth: contentItem.childrenRect.width
implicitHeight: contentItem.childrenRect.height
onVisibleChanged: currentIndex = 0
}
}
}