diff --git a/resources/qml/Completer.qml b/resources/qml/Completer.qml index df327e49..3acc91cc 100644 --- a/resources/qml/Completer.qml +++ b/resources/qml/Completer.qml @@ -9,7 +9,7 @@ import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import im.nheko 1.0 -Popup { +Control { id: popup property alias currentIndex: listView.currentIndex @@ -75,19 +75,23 @@ Popup { } else { completer = undefined; } + currentIndex = -1 } - padding: 1 - onAboutToShow: currentIndex = -1 - // If we have fewer than 7 items, just use the list view's content height. - // Otherwise, we want to show 7 items. Each item consists of row spacing between rows, row margins - // on each side of a row, 1px of padding above the first item and below the last item, and nominally - // some kind of content height. avatarHeight is used for just about every delegate, so we're using - // that until we find something better. Put is all together and you have the formula below! - height: Math.min(listView.contentHeight + 2, 6*rowSpacing + 7*(popup.avatarHeight + 2*rowMargin) + 2) + padding: 0 + leftInset: 1 + bottomInset: 1 + topInset: 1 + rightInset: 1 - ListView { + contentItem: ListView { id: listView + // If we have fewer than 7 items, just use the list view's content height. + // Otherwise, we want to show 7 items. Each item consists of row spacing between rows, row margins + // on each side of a row, 1px of padding above the first item and below the last item, and nominally + // some kind of content height. avatarHeight is used for just about every delegate, so we're using + // that until we find something better. Put is all together and you have the formula below! + implicitHeight: Math.min(contentHeight, 6*rowSpacing + 7*(popup.avatarHeight + 2*rowMargin)) clip: true ScrollHelper { flickable: parent @@ -103,8 +107,8 @@ Popup { onContentYChanged: deadTimer.restart() reuseItems: true - anchors.fill: parent - implicitWidth: fullWidth ? parent.width : contentItem.childrenRect.width + //anchors.fill: parent + implicitWidth: listView.contentItem.childrenRect.width model: completer verticalLayoutDirection: popup.bottomToTop ? ListView.BottomToTop : ListView.TopToBottom spacing: rowSpacing @@ -116,7 +120,7 @@ Popup { color: model.index == popup.currentIndex ? Nheko.colors.highlight : Nheko.colors.base height: chooser.child.implicitHeight + 2 * popup.rowMargin - implicitWidth: fullWidth ? popup.contentWidth : chooser.child.implicitWidth + 4 + implicitWidth: fullWidth ? popup.implicitContentWidth : chooser.child.implicitWidth + 4 MouseArea { id: mouseArea @@ -303,30 +307,9 @@ Popup { } - enter: Transition { - NumberAnimation { - property: "opacity" - from: 0 - to: 1 - duration: 100 - } - - } - - exit: Transition { - NumberAnimation { - property: "opacity" - from: 1 - to: 0 - duration: 100 - } - - } background: Rectangle { color: Nheko.colors.base - implicitHeight: popup.contentHeight - implicitWidth: popup.contentWidth border.color: Nheko.colors.mid } diff --git a/resources/qml/ForwardCompleter.qml b/resources/qml/ForwardCompleter.qml index 67a67906..76d77bfd 100644 --- a/resources/qml/ForwardCompleter.qml +++ b/resources/qml/ForwardCompleter.qml @@ -18,21 +18,16 @@ Popup { } x: Math.round(parent.width / 2 - width / 2) - y: Math.round(parent.height / 2 - height / 2) + y: Math.round(parent.height / 4) modal: true palette: Nheko.colors parent: Overlay.overlay - width: implicitWidth >= (timelineRoot.width * 0.8) ? implicitWidth : (timelineRoot.width * 0.8) - height: implicitHeight + completerPopup.height + padding * 2 + width: timelineRoot.width * 0.8 leftPadding: 10 rightPadding: 10 onOpened: { - completerPopup.open(); roomTextInput.forceActiveFocus(); } - onClosed: { - completerPopup.close(); - } Column { id: forwardColumn @@ -54,6 +49,8 @@ Popup { property var modelData: room ? room.getDump(mid, "") : { } + width: parent.width + userColor: TimelineManager.userColor(modelData.userId, Nheko.colors.window) blurhash: modelData.blurhash ?? "" body: modelData.body ?? "" @@ -81,10 +78,10 @@ Popup { completerPopup.completer.searchString = text; } Keys.onPressed: { - if ((event.key == Qt.Key_Up || event.key == Qt.Key_Backtab) && completerPopup.opened) { + if (event.key == Qt.Key_Up || event.key == Qt.Key_Backtab) { event.accepted = true; completerPopup.up(); - } else if ((event.key == Qt.Key_Down || event.key == Qt.Key_Tab) && completerPopup.opened) { + } else if (event.key == Qt.Key_Down || event.key == Qt.Key_Tab) { event.accepted = true; if (event.key == Qt.Key_Tab && (event.modifiers & Qt.ShiftModifier)) completerPopup.up(); @@ -97,20 +94,18 @@ Popup { } } - } + Completer { + id: completerPopup - Completer { - id: completerPopup + width: forwardMessagePopup.width - forwardMessagePopup.leftPadding * 2 + completerName: "room" + fullWidth: true + centerRowContent: false + avatarHeight: 24 + avatarWidth: 24 + bottomToTop: false + } - y: titleLabel.height + replyPreview.height + roomTextInput.height + roomTextInput.bottomPadding + forwardColumn.spacing * 3 - width: forwardMessagePopup.width - forwardMessagePopup.leftPadding * 2 - completerName: "room" - fullWidth: true - centerRowContent: false - avatarHeight: 24 - avatarWidth: 24 - bottomToTop: false - closePolicy: Popup.NoAutoClose } Connections { diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml index da841b7f..7ad4ef69 100644 --- a/resources/qml/MessageInput.qml +++ b/resources/qml/MessageInput.qml @@ -110,9 +110,9 @@ Rectangle { function openCompleter(pos, type) { if (popup.opened) return; completerTriggeredAt = pos; - popup.completerName = type; + completer.completerName = type; popup.open(); - popup.completer.setSearchString(messageInput.getText(completerTriggeredAt, cursorPosition)); + completer.completer.setSearchString(messageInput.getText(completerTriggeredAt, cursorPosition)); } function positionCursorAtEnd() { @@ -149,7 +149,7 @@ Rectangle { popup.close(); if (popup.opened) - popup.completer.setSearchString(messageInput.getText(completerTriggeredAt, cursorPosition)); + completer.completer.setSearchString(messageInput.getText(completerTriggeredAt, cursorPosition)); } onSelectionStartChanged: room.input.updateState(selectionStart, selectionEnd, cursorPosition, text) @@ -183,16 +183,16 @@ Rectangle { } else if (event.text == "~") { messageInput.openCompleter(selectionStart, "customEmoji"); } else if (event.key == Qt.Key_Escape && popup.opened) { - popup.completerName = ""; + completer.completerName = ""; popup.close(); event.accepted = true; } else if (event.matches(StandardKey.SelectAll) && popup.opened) { - popup.completerName = ""; + completer.completerName = ""; popup.close(); } else if (event.matches(StandardKey.InsertParagraphSeparator)) { if (popup.opened) { - var currentCompletion = popup.currentCompletion(); - popup.completerName = ""; + var currentCompletion = completer.currentCompletion(); + completer.completerName = ""; popup.close(); if (currentCompletion) { messageInput.insertCompletion(currentCompletion); @@ -206,9 +206,9 @@ Rectangle { event.accepted = true; if (popup.opened) { if (event.modifiers & Qt.ShiftModifier) - popup.down(); + completer.down(); else - popup.up(); + completer.up(); } else { var pos = cursorPosition - 1; while (pos > -1) { @@ -234,10 +234,10 @@ Rectangle { } } else if (event.key == Qt.Key_Up && popup.opened) { event.accepted = true; - popup.up(); + completer.up(); } else if ((event.key == Qt.Key_Down || event.key == Qt.Key_Backtab) && popup.opened) { event.accepted = true; - popup.down(); + completer.down(); } else if (event.key == Qt.Key_Up && event.modifiers == Qt.NoModifier) { if (cursorPosition == 0) { event.accepted = true; @@ -283,7 +283,7 @@ Rectangle { if (room) messageInput.append(room.input.text); - popup.completerName = ""; + completer.completerName = ""; messageInput.forceActiveFocus(); } @@ -295,14 +295,40 @@ Rectangle { messageInput.insertCompletion(completion); } - target: popup + target: completer } - Completer { + Popup { id: popup x: messageInput.positionToRectangle(messageInput.completerTriggeredAt).x y: messageInput.positionToRectangle(messageInput.completerTriggeredAt).y - height + padding: 0 + background: null + + Completer { + anchors.fill: parent + id: completer + } + + enter: Transition { + NumberAnimation { + property: "opacity" + from: 0 + to: 1 + duration: 100 + } + + } + + exit: Transition { + NumberAnimation { + property: "opacity" + from: 1 + to: 0 + duration: 100 + } + } } Connections { diff --git a/resources/qml/QuickSwitcher.qml b/resources/qml/QuickSwitcher.qml index 3b8ceb15..103f7584 100644 --- a/resources/qml/QuickSwitcher.qml +++ b/resources/qml/QuickSwitcher.qml @@ -3,8 +3,9 @@ // // SPDX-License-Identifier: GPL-3.0-or-later -import QtQuick 2.9 -import QtQuick.Controls 2.3 +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 import im.nheko 1.0 Popup { @@ -14,62 +15,60 @@ Popup { background: null width: Math.min(Math.max(Math.round(parent.width / 2),450),parent.width) // limiting width to parent.width/2 can be a bit narrow - x: Math.round(parent.width / 2 - width / 2) - y: Math.round(parent.height / 4 - height / 2) + x: Math.round(parent.width / 2 - contentWidth / 2) + y: Math.round(parent.height / 4) modal: true closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside parent: Overlay.overlay palette: Nheko.colors onOpened: { - completerPopup.open(); roomTextInput.forceActiveFocus(); } - onClosed: { - completerPopup.close(); - } - - MatrixTextField { - id: roomTextInput + Column{ anchors.fill: parent - font.pixelSize: Math.ceil(quickSwitcher.textHeight * 0.6) - color: Nheko.colors.text - onTextEdited: { - completerPopup.completer.searchString = text; - } - Keys.onPressed: { - if ((event.key == Qt.Key_Up || event.key == Qt.Key_Backtab) && completerPopup.opened) { - event.accepted = true; - completerPopup.up(); - } else if ((event.key == Qt.Key_Down || event.key == Qt.Key_Tab) && completerPopup.opened) { - event.accepted = true; - if (event.key == Qt.Key_Tab && (event.modifiers & Qt.ShiftModifier)) + spacing: 1 + + MatrixTextField { + id: roomTextInput + + width: parent.width + font.pixelSize: Math.ceil(quickSwitcher.textHeight * 0.6) + color: Nheko.colors.text + onTextEdited: { + completerPopup.completer.searchString = text; + } + Keys.onPressed: { + if (event.key == Qt.Key_Up || event.key == Qt.Key_Backtab) { + event.accepted = true; completerPopup.up(); - else + } else if (event.key == Qt.Key_Down || event.key == Qt.Key_Tab) { + event.accepted = true; + if (event.key == Qt.Key_Tab && (event.modifiers & Qt.ShiftModifier)) + completerPopup.up(); + else completerPopup.down(); - } else if (event.matches(StandardKey.InsertParagraphSeparator)) { - completerPopup.finishCompletion(); - event.accepted = true; + } else if (event.matches(StandardKey.InsertParagraphSeparator)) { + completerPopup.finishCompletion(); + event.accepted = true; + } } } - } - Completer { - id: completerPopup + Completer { + id: completerPopup - x: roomTextInput.x - y: roomTextInput.y + quickSwitcher.textHeight - visible: roomTextInput.length > 0 - width: parent.width - completerName: "room" - bottomToTop: false - fullWidth: true - avatarHeight: quickSwitcher.textHeight - avatarWidth: quickSwitcher.textHeight - centerRowContent: false - rowMargin: Math.round(quickSwitcher.textMargin / 2) - rowSpacing: quickSwitcher.textMargin - closePolicy: Popup.NoAutoClose + visible: roomTextInput.text.length > 0 + width: parent.width + completerName: "room" + bottomToTop: false + fullWidth: true + avatarHeight: quickSwitcher.textHeight + avatarWidth: quickSwitcher.textHeight + centerRowContent: false + rowMargin: Math.round(quickSwitcher.textMargin / 2) + rowSpacing: quickSwitcher.textMargin + } } Connections { @@ -80,7 +79,7 @@ Popup { function onCountChanged() { if (completerPopup.count > 0 && (completerPopup.currentIndex < 0 || completerPopup.currentIndex >= completerPopup.count)) - completerPopup.currentIndex = 0; + completerPopup.currentIndex = 0; }