From 372543de6e8f4f7a552634e620c50a1ec01b3979 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 16 Apr 2024 12:41:46 +0400 Subject: [PATCH] Jump by keyboard between time input fields. --- ui/widgets/fields/time_part_input.cpp | 30 ++++++++++++++++++++------- ui/widgets/fields/time_part_input.h | 2 ++ ui/widgets/time_input.cpp | 4 ++++ 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/ui/widgets/fields/time_part_input.cpp b/ui/widgets/fields/time_part_input.cpp index 5ca80a8..a2e7b40 100644 --- a/ui/widgets/fields/time_part_input.cpp +++ b/ui/widgets/fields/time_part_input.cpp @@ -42,18 +42,32 @@ rpl::producer<> TimePart::erasePrevious() const { return _erasePrevious.events(); } +rpl::producer<> TimePart::jumpToPrevious() const { + return _jumpToPrevious.events(); +} + rpl::producer TimePart::putNext() const { return _putNext.events(); } void TimePart::keyPressEvent(QKeyEvent *e) { - const auto isBackspace = (e->key() == Qt::Key_Backspace); - const auto isBeginning = (cursorPosition() == 0); - if (isBackspace && isBeginning && !hasSelectedText()) { - _erasePrevious.fire({}); - } else { - MaskedInputField::keyPressEvent(e); + const auto position = cursorPosition(); + const auto selection = hasSelectedText(); + if (!selection && !position) { + if (e->key() == Qt::Key_Backspace) { + _erasePrevious.fire({}); + return; + } else if (e->key() == Qt::Key_Left) { + _jumpToPrevious.fire({}); + return; + } + } else if (!selection && position == getLastText().size()) { + if (e->key() == Qt::Key_Right) { + _putNext.fire(QChar(0)); + return; + } } + MaskedInputField::keyPressEvent(e); } void TimePart::wheelEvent(QWheelEvent *e) { @@ -78,10 +92,10 @@ void TimePart::correctValue( int wasCursor, QString &now, int &nowCursor) { - auto newText = QString(); - auto newCursor = -1; const auto oldCursor = nowCursor; const auto oldLength = now.size(); + auto newCursor = (oldCursor > 0) ? -1 : 0; + auto newText = QString(); auto accumulated = 0; auto limit = 0; for (; limit != oldLength; ++limit) { diff --git a/ui/widgets/fields/time_part_input.h b/ui/widgets/fields/time_part_input.h index 306a471..0ca4dcf 100644 --- a/ui/widgets/fields/time_part_input.h +++ b/ui/widgets/fields/time_part_input.h @@ -18,6 +18,7 @@ public: void setWheelStep(int value); [[nodiscard]] rpl::producer<> erasePrevious() const; + [[nodiscard]] rpl::producer<> jumpToPrevious() const; [[nodiscard]] rpl::producer putNext() const; [[nodiscard]] std::optional number(); @@ -37,6 +38,7 @@ private: int _maxDigits = 0; int _wheelStep = 0; rpl::event_stream<> _erasePrevious; + rpl::event_stream<> _jumpToPrevious; rpl::event_stream _putNext; }; diff --git a/ui/widgets/time_input.cpp b/ui/widgets/time_input.cpp index 66041e6..b21f54e 100644 --- a/ui/widgets/time_input.cpp +++ b/ui/widgets/time_input.cpp @@ -110,6 +110,10 @@ TimeInput::TimeInput( _minute->erasePrevious() | rpl::start_with_next([=] { erasePrevious(_hour); }, lifetime()); + _minute->jumpToPrevious() | rpl::start_with_next([=] { + _hour->setCursorPosition(_hour->getLastText().size()); + _hour->setFocus(); + }, lifetime()); _separator1->setAttribute(Qt::WA_TransparentForMouseEvents); setMouseTracking(true);