mirror of https://github.com/Nheko-Reborn/nheko
pull/493/head
commit
7a356f3832
@ -0,0 +1,56 @@ |
|||||||
|
import QtQuick 2.13 |
||||||
|
import QtQuick.Layouts 1.13 |
||||||
|
import QtQuick.Controls 2.13 |
||||||
|
|
||||||
|
TextField { |
||||||
|
id: input |
||||||
|
palette: colors |
||||||
|
|
||||||
|
background: Rectangle { |
||||||
|
color: colors.base |
||||||
|
} |
||||||
|
|
||||||
|
Rectangle { |
||||||
|
id: blueBar |
||||||
|
|
||||||
|
anchors.top: parent.bottom |
||||||
|
anchors.horizontalCenter: parent.horizontalCenter |
||||||
|
|
||||||
|
color: colors.highlight |
||||||
|
height: 1 |
||||||
|
width: parent.width |
||||||
|
|
||||||
|
Rectangle { |
||||||
|
id: blackBar |
||||||
|
|
||||||
|
anchors.verticalCenter: blueBar.verticalCenter |
||||||
|
anchors.horizontalCenter: parent.horizontalCenter |
||||||
|
|
||||||
|
height: parent.height+1 |
||||||
|
width: 0 |
||||||
|
color: colors.text |
||||||
|
|
||||||
|
states: State { |
||||||
|
name: "focused"; when: input.activeFocus == true |
||||||
|
PropertyChanges { |
||||||
|
target: blackBar |
||||||
|
width: blueBar.width |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
transitions: Transition { |
||||||
|
from: "" |
||||||
|
to: "focused" |
||||||
|
reversible: true |
||||||
|
|
||||||
|
NumberAnimation { |
||||||
|
target: blackBar |
||||||
|
properties: "width" |
||||||
|
duration: 500 |
||||||
|
easing.type: Easing.InOutQuad |
||||||
|
alwaysRunToEnd: true |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,97 @@ |
|||||||
|
import QtQuick 2.9 |
||||||
|
import QtQuick.Controls 2.3 |
||||||
|
import im.nheko 1.0 |
||||||
|
|
||||||
|
Popup { |
||||||
|
id: quickSwitcher |
||||||
|
|
||||||
|
property int textHeight: 32 |
||||||
|
property int textMargin: 8 |
||||||
|
|
||||||
|
x: parent.width / 2 - width / 2 |
||||||
|
y: parent.height / 4 - height / 2 |
||||||
|
width: parent.width / 2 |
||||||
|
modal: true |
||||||
|
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside |
||||||
|
parent: Overlay.overlay |
||||||
|
palette: colors |
||||||
|
|
||||||
|
Overlay.modal: Rectangle { |
||||||
|
color: "#aa1E1E1E" |
||||||
|
} |
||||||
|
|
||||||
|
MatrixTextField { |
||||||
|
id: roomTextInput |
||||||
|
|
||||||
|
anchors.fill: parent |
||||||
|
font.pixelSize: quickSwitcher.textHeight * 0.6 |
||||||
|
padding: textMargin |
||||||
|
color: colors.text |
||||||
|
|
||||||
|
onTextEdited: { |
||||||
|
completerPopup.completer.setSearchString(text) |
||||||
|
} |
||||||
|
|
||||||
|
Keys.onPressed: { |
||||||
|
if (event.key == Qt.Key_Up && completerPopup.opened) { |
||||||
|
event.accepted = true; |
||||||
|
completerPopup.up(); |
||||||
|
} else if (event.key == Qt.Key_Down && completerPopup.opened) { |
||||||
|
event.accepted = true; |
||||||
|
completerPopup.down(); |
||||||
|
} else if (event.matches(StandardKey.InsertParagraphSeparator)) { |
||||||
|
completerPopup.finishCompletion() |
||||||
|
event.accepted = true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Completer { |
||||||
|
id: completerPopup |
||||||
|
|
||||||
|
x: roomTextInput.x |
||||||
|
y: roomTextInput.y + roomTextInput.height + textMargin |
||||||
|
width: parent.width |
||||||
|
completerName: "room" |
||||||
|
bottomToTop: false |
||||||
|
fullWidth: true |
||||||
|
avatarHeight: textHeight |
||||||
|
avatarWidth: textHeight |
||||||
|
centerRowContent: false |
||||||
|
rowMargin: 8 |
||||||
|
rowSpacing: 6 |
||||||
|
|
||||||
|
closePolicy: Popup.NoAutoClose |
||||||
|
} |
||||||
|
|
||||||
|
onOpened: { |
||||||
|
completerPopup.open() |
||||||
|
delay(200, function() { |
||||||
|
roomTextInput.forceActiveFocus() |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
onClosed: { |
||||||
|
completerPopup.close() |
||||||
|
} |
||||||
|
|
||||||
|
Connections { |
||||||
|
onCompletionSelected: { |
||||||
|
TimelineManager.setHistoryView(id) |
||||||
|
TimelineManager.highlightRoom(id) |
||||||
|
quickSwitcher.close() |
||||||
|
} |
||||||
|
target: completerPopup |
||||||
|
} |
||||||
|
|
||||||
|
Timer { |
||||||
|
id: timer |
||||||
|
} |
||||||
|
|
||||||
|
function delay(delayTime, cb) { |
||||||
|
timer.interval = delayTime; |
||||||
|
timer.repeat = false; |
||||||
|
timer.triggered.connect(cb); |
||||||
|
timer.start(); |
||||||
|
} |
||||||
|
} |
@ -1,129 +0,0 @@ |
|||||||
// SPDX-FileCopyrightText: 2017 Konstantinos Sideris <siderisk@auth.gr>
|
|
||||||
// SPDX-FileCopyrightText: 2021 Nheko Contributors
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
#include <QCompleter> |
|
||||||
#include <QPainter> |
|
||||||
#include <QStringListModel> |
|
||||||
#include <QStyleOption> |
|
||||||
#include <QTimer> |
|
||||||
#include <QtConcurrent> |
|
||||||
|
|
||||||
#include "Cache.h" |
|
||||||
#include "QuickSwitcher.h" |
|
||||||
#include "popups/SuggestionsPopup.h" |
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(std::vector<RoomSearchResult>) |
|
||||||
|
|
||||||
RoomSearchInput::RoomSearchInput(QWidget *parent) |
|
||||||
: TextField(parent) |
|
||||||
{} |
|
||||||
|
|
||||||
void |
|
||||||
RoomSearchInput::keyPressEvent(QKeyEvent *event) |
|
||||||
{ |
|
||||||
switch (event->key()) { |
|
||||||
case Qt::Key_Tab: |
|
||||||
case Qt::Key_Down: { |
|
||||||
emit selectNextCompletion(); |
|
||||||
event->accept(); |
|
||||||
break; |
|
||||||
} |
|
||||||
case Qt::Key_Backtab: |
|
||||||
case Qt::Key_Up: { |
|
||||||
emit selectPreviousCompletion(); |
|
||||||
event->accept(); |
|
||||||
break; |
|
||||||
} |
|
||||||
default: |
|
||||||
TextField::keyPressEvent(event); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void |
|
||||||
RoomSearchInput::hideEvent(QHideEvent *event) |
|
||||||
{ |
|
||||||
emit hiding(); |
|
||||||
TextField::hideEvent(event); |
|
||||||
} |
|
||||||
|
|
||||||
QuickSwitcher::QuickSwitcher(QWidget *parent) |
|
||||||
: QWidget(parent) |
|
||||||
{ |
|
||||||
qRegisterMetaType<std::vector<RoomSearchResult>>(); |
|
||||||
setMaximumWidth(450); |
|
||||||
|
|
||||||
QFont font; |
|
||||||
font.setPointSizeF(font.pointSizeF() * 1.5); |
|
||||||
|
|
||||||
roomSearch_ = new RoomSearchInput(this); |
|
||||||
roomSearch_->setFont(font); |
|
||||||
roomSearch_->setPlaceholderText(tr("Search for a room...")); |
|
||||||
|
|
||||||
topLayout_ = new QVBoxLayout(this); |
|
||||||
topLayout_->addWidget(roomSearch_); |
|
||||||
|
|
||||||
connect(this, |
|
||||||
&QuickSwitcher::queryResults, |
|
||||||
this, |
|
||||||
[this](const std::vector<RoomSearchResult> &rooms) { |
|
||||||
auto pos = mapToGlobal(roomSearch_->geometry().bottomLeft()); |
|
||||||
|
|
||||||
popup_.setFixedWidth(width()); |
|
||||||
popup_.addRooms(rooms); |
|
||||||
popup_.move(pos.x() - topLayout_->margin(), pos.y() + topLayout_->margin()); |
|
||||||
popup_.show(); |
|
||||||
}); |
|
||||||
|
|
||||||
connect(roomSearch_, &QLineEdit::textEdited, this, [this](const QString &query) { |
|
||||||
if (query.isEmpty()) { |
|
||||||
popup_.hide(); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
QtConcurrent::run([this, query = query.toLower()]() { |
|
||||||
try { |
|
||||||
emit queryResults(cache::searchRooms(query.toStdString())); |
|
||||||
} catch (const lmdb::error &e) { |
|
||||||
qWarning() << "room search failed:" << e.what(); |
|
||||||
} |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
connect(roomSearch_, |
|
||||||
&RoomSearchInput::selectNextCompletion, |
|
||||||
&popup_, |
|
||||||
&SuggestionsPopup::selectNextSuggestion); |
|
||||||
connect(roomSearch_, |
|
||||||
&RoomSearchInput::selectPreviousCompletion, |
|
||||||
&popup_, |
|
||||||
&SuggestionsPopup::selectPreviousSuggestion); |
|
||||||
connect(&popup_, &SuggestionsPopup::itemSelected, this, [this](const QString &room_id) { |
|
||||||
reset(); |
|
||||||
emit roomSelected(room_id); |
|
||||||
}); |
|
||||||
connect(roomSearch_, &RoomSearchInput::hiding, this, [this]() { popup_.hide(); }); |
|
||||||
connect(roomSearch_, &QLineEdit::returnPressed, this, [this]() { |
|
||||||
reset(); |
|
||||||
popup_.selectHoveredSuggestion(); |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
void |
|
||||||
QuickSwitcher::paintEvent(QPaintEvent *) |
|
||||||
{ |
|
||||||
QStyleOption opt; |
|
||||||
opt.init(this); |
|
||||||
QPainter p(this); |
|
||||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); |
|
||||||
} |
|
||||||
|
|
||||||
void |
|
||||||
QuickSwitcher::keyPressEvent(QKeyEvent *event) |
|
||||||
{ |
|
||||||
if (event->key() == Qt::Key_Escape) { |
|
||||||
event->accept(); |
|
||||||
reset(); |
|
||||||
} |
|
||||||
} |
|
@ -1,65 +0,0 @@ |
|||||||
// SPDX-FileCopyrightText: 2017 Konstantinos Sideris <siderisk@auth.gr>
|
|
||||||
// SPDX-FileCopyrightText: 2021 Nheko Contributors
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
#pragma once |
|
||||||
|
|
||||||
#include <QAbstractItemView> |
|
||||||
#include <QKeyEvent> |
|
||||||
#include <QVBoxLayout> |
|
||||||
#include <QWidget> |
|
||||||
|
|
||||||
#include "popups/SuggestionsPopup.h" |
|
||||||
#include "ui/TextField.h" |
|
||||||
|
|
||||||
class RoomSearchInput : public TextField |
|
||||||
{ |
|
||||||
Q_OBJECT |
|
||||||
public: |
|
||||||
explicit RoomSearchInput(QWidget *parent = nullptr); |
|
||||||
|
|
||||||
signals: |
|
||||||
void selectNextCompletion(); |
|
||||||
void selectPreviousCompletion(); |
|
||||||
void hiding(); |
|
||||||
|
|
||||||
protected: |
|
||||||
void keyPressEvent(QKeyEvent *event) override; |
|
||||||
void hideEvent(QHideEvent *event) override; |
|
||||||
bool focusNextPrevChild(bool) override { return false; }; |
|
||||||
}; |
|
||||||
|
|
||||||
class QuickSwitcher : public QWidget |
|
||||||
{ |
|
||||||
Q_OBJECT |
|
||||||
|
|
||||||
public: |
|
||||||
QuickSwitcher(QWidget *parent = nullptr); |
|
||||||
|
|
||||||
signals: |
|
||||||
void closing(); |
|
||||||
void roomSelected(const QString &roomid); |
|
||||||
void queryResults(const std::vector<RoomSearchResult> &rooms); |
|
||||||
|
|
||||||
protected: |
|
||||||
void keyPressEvent(QKeyEvent *event) override; |
|
||||||
void showEvent(QShowEvent *) override { roomSearch_->setFocus(); } |
|
||||||
void paintEvent(QPaintEvent *event) override; |
|
||||||
|
|
||||||
private: |
|
||||||
void reset() |
|
||||||
{ |
|
||||||
emit closing(); |
|
||||||
roomSearch_->clear(); |
|
||||||
} |
|
||||||
|
|
||||||
// Current highlighted selection from the completer.
|
|
||||||
int selection_ = -1; |
|
||||||
|
|
||||||
QVBoxLayout *topLayout_; |
|
||||||
RoomSearchInput *roomSearch_; |
|
||||||
|
|
||||||
//! Autocomplete popup box with the room suggestions.
|
|
||||||
SuggestionsPopup popup_; |
|
||||||
}; |
|
Loading…
Reference in new issue