Added hotkeys to get next / previous item of search messages in dialogs.

This commit is contained in:
23rd 2022-06-08 09:26:17 +03:00
parent 86cc83b491
commit 9861370b75
3 changed files with 85 additions and 12 deletions

View file

@ -4459,7 +4459,7 @@ void HistoryWidget::searchInChat() {
} }
if (controller()->isPrimary()) { if (controller()->isPrimary()) {
controller()->content()->searchInChat(_history); controller()->content()->searchInChat(_history);
} else { } else if (!_composeSearch) {
const auto search = [=] { const auto search = [=] {
const auto update = [=] { const auto update = [=] {
updateControlsVisibility(); updateControlsVisibility();

View file

@ -251,8 +251,13 @@ public:
[[nodiscard]] rpl::producer<> queryChanges() const; [[nodiscard]] rpl::producer<> queryChanges() const;
[[nodiscard]] rpl::producer<> closeRequests() const; [[nodiscard]] rpl::producer<> closeRequests() const;
[[nodiscard]] rpl::producer<> cancelRequests() const; [[nodiscard]] rpl::producer<> cancelRequests() const;
[[nodiscard]] rpl::producer<not_null<QKeyEvent*>> keyEvents() const;
void setFrom(PeerData *peer); void setFrom(PeerData *peer);
bool handleKeyPress(not_null<QKeyEvent*> e);
protected:
void keyPressEvent(QKeyEvent *e) override;
private: private:
void clearItems(); void clearItems();
@ -271,6 +276,7 @@ private:
rpl::event_stream<SearchRequest> _searchRequests; rpl::event_stream<SearchRequest> _searchRequests;
rpl::event_stream<> _queryChanges; rpl::event_stream<> _queryChanges;
rpl::event_stream<> _cancelRequests; rpl::event_stream<> _cancelRequests;
rpl::event_stream<not_null<QKeyEvent*>> _keyEvents;
}; };
TopBar::TopBar(not_null<Ui::RpWidget*> parent) TopBar::TopBar(not_null<Ui::RpWidget*> parent)
@ -319,6 +325,18 @@ TopBar::TopBar(not_null<Ui::RpWidget*> parent)
}); });
} }
void TopBar::keyPressEvent(QKeyEvent *e) {
_keyEvents.fire_copy(e);
}
bool TopBar::handleKeyPress(not_null<QKeyEvent*> e) {
return false;
}
rpl::producer<not_null<QKeyEvent*>> TopBar::keyEvents() const {
return _keyEvents.events();
}
void TopBar::setInnerFocus() { void TopBar::setInnerFocus() {
_select->setInnerFocus(); _select->setInnerFocus();
} }
@ -410,13 +428,24 @@ public:
void buttonFromToggleOn(rpl::producer<bool> &&visible); void buttonFromToggleOn(rpl::producer<bool> &&visible);
void buttonCalendarToggleOn(rpl::producer<bool> &&visible); void buttonCalendarToggleOn(rpl::producer<bool> &&visible);
bool handleKeyPress(not_null<QKeyEvent*> e);
private: private:
void updateText(int current); void updateText(int current);
base::unique_qptr<Ui::FlatButton> _showList; base::unique_qptr<Ui::FlatButton> _showList;
base::unique_qptr<Ui::IconButton> _previous; struct Navigation {
base::unique_qptr<Ui::IconButton> _next; base::unique_qptr<Ui::IconButton> button;
bool enabled = false;
Ui::IconButton *operator->() const {
return button.get();
}
};
Navigation _previous;
Navigation _next;
base::unique_qptr<Ui::IconButton> _jumpToDate; base::unique_qptr<Ui::IconButton> _jumpToDate;
base::unique_qptr<Ui::IconButton> _chooseFromUser; base::unique_qptr<Ui::IconButton> _chooseFromUser;
@ -433,8 +462,8 @@ BottomBar::BottomBar(not_null<Ui::RpWidget*> parent, bool fastShowChooseFrom)
QString(), QString(),
st::historyComposeButton)) st::historyComposeButton))
// Icons are swaped. // Icons are swaped.
, _previous(base::make_unique_q<Ui::IconButton>(this, st::calendarNext)) , _previous({ base::make_unique_q<Ui::IconButton>(this, st::calendarNext) })
, _next(base::make_unique_q<Ui::IconButton>(this, st::calendarPrevious)) , _next({ base::make_unique_q<Ui::IconButton>(this, st::calendarPrevious) })
, _jumpToDate(base::make_unique_q<Ui::IconButton>(this, st::dialogCalendar)) , _jumpToDate(base::make_unique_q<Ui::IconButton>(this, st::dialogCalendar))
, _chooseFromUser( , _chooseFromUser(
base::make_unique_q<Ui::IconButton>(this, st::dialogSearchFrom)) base::make_unique_q<Ui::IconButton>(this, st::dialogSearchFrom))
@ -490,6 +519,8 @@ BottomBar::BottomBar(not_null<Ui::RpWidget*> parent, bool fastShowChooseFrom)
) | rpl::start_with_next([=](int current) { ) | rpl::start_with_next([=](int current) {
const auto nextDisabled = (current <= 0) || (current >= _total); const auto nextDisabled = (current <= 0) || (current >= _total);
const auto prevDisabled = (current <= 1); const auto prevDisabled = (current <= 1);
_next.enabled = !nextDisabled;
_previous.enabled = !prevDisabled;
_next->setAttribute(Qt::WA_TransparentForMouseEvents, nextDisabled); _next->setAttribute(Qt::WA_TransparentForMouseEvents, nextDisabled);
_previous->setAttribute( _previous->setAttribute(
Qt::WA_TransparentForMouseEvents, Qt::WA_TransparentForMouseEvents,
@ -515,6 +546,34 @@ BottomBar::BottomBar(not_null<Ui::RpWidget*> parent, bool fastShowChooseFrom)
}, lifetime()); }, lifetime());
} }
bool BottomBar::handleKeyPress(not_null<QKeyEvent*> e) {
if (e->key() == Qt::Key_F3) {
const auto modifiers = e->modifiers();
if (modifiers == Qt::NoModifier && _next.enabled) {
_next->clicked(Qt::KeyboardModifiers(), Qt::LeftButton);
return true;
} else if (modifiers == Qt::ShiftModifier && _previous.enabled) {
_previous->clicked(Qt::KeyboardModifiers(), Qt::LeftButton);
return true;
}
}
#ifdef Q_OS_MAC
if (e->key() == Qt::Key_G) {
const auto modifiers = e->modifiers();
if (modifiers.testFlag(Qt::ControlModifier)) {
const auto &navigation = (modifiers.testFlag(Qt::ShiftModifier)
? _previous
: _next);
if (navigation.enabled) {
navigation->clicked(Qt::KeyboardModifiers(), Qt::LeftButton);
return true;
}
}
}
#endif
return false;
}
void BottomBar::setTotal(int total) { void BottomBar::setTotal(int total) {
_total = total; _total = total;
setCurrent(1); setCurrent(1);
@ -632,6 +691,13 @@ ComposeSearch::Inner::Inner(
bottom.topLeft() + QPoint(bottom.width(), 0))); bottom.topLeft() + QPoint(bottom.width(), 0)));
}, _list.container->lifetime()); }, _list.container->lifetime());
_topBar->keyEvents(
) | rpl::start_with_next([=](not_null<QKeyEvent*> e) {
if (!_bottomBar->handleKeyPress(e)) {
_topBar->handleKeyPress(e);
}
}, _topBar->lifetime());
_topBar->searchRequests( _topBar->searchRequests(
) | rpl::start_with_next([=](const SearchRequest &search) { ) | rpl::start_with_next([=](const SearchRequest &search) {
if (search.query.isEmpty() && !search.from) { if (search.query.isEmpty() && !search.from) {

View file

@ -577,13 +577,20 @@ bool MainWindow::eventFilter(QObject *object, QEvent *e) {
FeedLangTestingKey(key); FeedLangTestingKey(key);
} }
#ifdef _DEBUG #ifdef _DEBUG
switch (static_cast<QKeyEvent*>(e)->key()) { if (static_cast<QKeyEvent*>(e)->modifiers().testFlag(
case Qt::Key_F3: Qt::ControlModifier)) {
anim::SetSlowMultiplier((anim::SlowMultiplier() == 10) ? 1 : 10); switch (static_cast<QKeyEvent*>(e)->key()) {
return true; case Qt::Key_F11:
case Qt::Key_F4: anim::SetSlowMultiplier((anim::SlowMultiplier() == 10)
anim::SetSlowMultiplier((anim::SlowMultiplier() == 50) ? 1 : 50); ? 1
return true; : 10);
return true;
case Qt::Key_F12:
anim::SetSlowMultiplier((anim::SlowMultiplier() == 50)
? 1
: 50);
return true;
}
} }
#endif #endif
} break; } break;