From c026c1125e4c23b7335753e60d4bc0da42cd7774 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 28 Mar 2022 12:26:41 +0300 Subject: [PATCH] Moved Ui::TimePart to separated file. --- CMakeLists.txt | 2 + ui/widgets/fields/time_part_input.cpp | 123 ++++++++++++++++++++++ ui/widgets/fields/time_part_input.h | 44 ++++++++ ui/widgets/time_input.cpp | 143 +------------------------- 4 files changed, 170 insertions(+), 142 deletions(-) create mode 100644 ui/widgets/fields/time_part_input.cpp create mode 100644 ui/widgets/fields/time_part_input.h diff --git a/CMakeLists.txt b/CMakeLists.txt index fb289c2..717e7d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,6 +176,8 @@ PRIVATE ui/widgets/input_fields.h ui/widgets/labels.cpp ui/widgets/labels.h + ui/widgets/fields/time_part_input.cpp + ui/widgets/fields/time_part_input.h ui/widgets/menu/menu.cpp ui/widgets/menu/menu.h ui/widgets/menu/menu_action.cpp diff --git a/ui/widgets/fields/time_part_input.cpp b/ui/widgets/fields/time_part_input.cpp new file mode 100644 index 0000000..f61a0db --- /dev/null +++ b/ui/widgets/fields/time_part_input.cpp @@ -0,0 +1,123 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// +#include "ui/widgets/fields/time_part_input.h" + +#include "ui/ui_utility.h" // WheelDirection + +#include + +namespace Ui { + +std::optional TimePart::number() { + const auto text = getLastText(); + auto view = QStringView(text); + while (view.size() > 1 && view.at(0) == '0') { + view = base::StringViewMid(view, 1); + } + return QRegularExpression("^\\d+$").match(view).hasMatch() + ? std::make_optional(view.toInt()) + : std::nullopt; +} + +void TimePart::setMaxValue(int value) { + _maxValue = value; + _maxDigits = 0; + while (value > 0) { + ++_maxDigits; + value /= 10; + } +} + +void TimePart::setWheelStep(int value) { + _wheelStep = value; +} + +rpl::producer<> TimePart::erasePrevious() const { + return _erasePrevious.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); + } +} + +void TimePart::wheelEvent(QWheelEvent *e) { + const auto direction = WheelDirection(e); + const auto now = number(); + if (!now.has_value()) { + return; + } + auto time = *now + (direction * _wheelStep); + const auto max = _maxValue + 1; + if (time < 0) { + time += max; + } else if (time >= max) { + time -= max; + } + setText(QString::number(time)); +} + +void TimePart::correctValue( + const QString &was, + int wasCursor, + QString &now, + int &nowCursor) { + auto newText = QString(); + auto newCursor = -1; + const auto oldCursor = nowCursor; + const auto oldLength = now.size(); + auto accumulated = 0; + auto limit = 0; + for (; limit != oldLength; ++limit) { + if (now[limit].isDigit()) { + accumulated *= 10; + accumulated += (now[limit].unicode() - '0'); + if (accumulated > _maxValue || limit == _maxDigits) { + break; + } + } + } + for (auto i = 0; i != limit;) { + if (now[i].isDigit()) { + newText += now[i]; + } + if (++i == oldCursor) { + newCursor = newText.size(); + } + } + if (newCursor < 0) { + newCursor = newText.size(); + } + if (newText != now) { + now = newText; + setText(now); + startPlaceholderAnimation(); + } + if (newCursor != nowCursor) { + nowCursor = newCursor; + setCursorPosition(nowCursor); + } + if (accumulated > _maxValue + || (limit == _maxDigits && oldLength > _maxDigits)) { + if (oldCursor > limit) { + _putNext.fire('0' + (accumulated % 10)); + } else { + _putNext.fire(0); + } + } +} + +} // namespace Ui diff --git a/ui/widgets/fields/time_part_input.h b/ui/widgets/fields/time_part_input.h new file mode 100644 index 0000000..bdd7d1b --- /dev/null +++ b/ui/widgets/fields/time_part_input.h @@ -0,0 +1,44 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// +#pragma once + +#include "ui/widgets/input_fields.h" + +namespace Ui { + +class TimePart : public MaskedInputField { +public: + using MaskedInputField::MaskedInputField; + + void setMaxValue(int value); + void setWheelStep(int value); + + [[nodiscard]] rpl::producer<> erasePrevious() const; + [[nodiscard]] rpl::producer putNext() const; + + [[nodiscard]] std::optional number(); + +protected: + void keyPressEvent(QKeyEvent *e) override; + void wheelEvent(QWheelEvent *e) override; + + void correctValue( + const QString &was, + int wasCursor, + QString &now, + int &nowCursor) override; + +private: + int _maxValue = 0; + int _maxDigits = 0; + int _wheelStep = 0; + rpl::event_stream<> _erasePrevious; + rpl::event_stream _putNext; + +}; + +} // namespace Ui diff --git a/ui/widgets/time_input.cpp b/ui/widgets/time_input.cpp index 2cf825e..a848849 100644 --- a/ui/widgets/time_input.cpp +++ b/ui/widgets/time_input.cpp @@ -6,9 +6,7 @@ // #include "ui/widgets/time_input.h" -#include "ui/widgets/input_fields.h" -#include "ui/ui_utility.h" -#include "base/qt/qt_common_adapters.h" +#include "ui/widgets/fields/time_part_input.h" #include #include @@ -48,145 +46,6 @@ QString GetMinute(const QString &value) { } // namespace -class TimePart final : public MaskedInputField { -public: - using MaskedInputField::MaskedInputField; - - void setMaxValue(int value); - void setWheelStep(int value); - - [[nodiscard]] rpl::producer<> erasePrevious() const; - [[nodiscard]] rpl::producer putNext() const; - - [[nodiscard]] std::optional number(); - -protected: - void keyPressEvent(QKeyEvent *e) override; - void wheelEvent(QWheelEvent *e) override; - - void correctValue( - const QString &was, - int wasCursor, - QString &now, - int &nowCursor) override; - -private: - int _maxValue = 0; - int _maxDigits = 0; - int _wheelStep = 0; - rpl::event_stream<> _erasePrevious; - rpl::event_stream _putNext; - -}; - -std::optional TimePart::number() { - const auto text = getLastText(); - auto view = QStringView(text); - while (view.size() > 1 && view.at(0) == '0') { - view = base::StringViewMid(view, 1); - } - return QRegularExpression("^\\d+$").match(view).hasMatch() - ? std::make_optional(view.toInt()) - : std::nullopt; -} - -void TimePart::setMaxValue(int value) { - _maxValue = value; - _maxDigits = 0; - while (value > 0) { - ++_maxDigits; - value /= 10; - } -} - -void TimePart::setWheelStep(int value) { - _wheelStep = value; -} - -rpl::producer<> TimePart::erasePrevious() const { - return _erasePrevious.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); - } -} - -void TimePart::wheelEvent(QWheelEvent *e) { - const auto direction = WheelDirection(e); - const auto now = number(); - if (!now.has_value()) { - return; - } - auto time = *now + (direction * _wheelStep); - const auto max = _maxValue + 1; - if (time < 0) { - time += max; - } else if (time >= max) { - time -= max; - } - setText(QString::number(time)); -} - -void TimePart::correctValue( - const QString &was, - int wasCursor, - QString &now, - int &nowCursor) { - auto newText = QString(); - auto newCursor = -1; - const auto oldCursor = nowCursor; - const auto oldLength = now.size(); - auto accumulated = 0; - auto limit = 0; - for (; limit != oldLength; ++limit) { - if (now[limit].isDigit()) { - accumulated *= 10; - accumulated += (now[limit].unicode() - '0'); - if (accumulated > _maxValue || limit == _maxDigits) { - break; - } - } - } - for (auto i = 0; i != limit;) { - if (now[i].isDigit()) { - newText += now[i]; - } - if (++i == oldCursor) { - newCursor = newText.size(); - } - } - if (newCursor < 0) { - newCursor = newText.size(); - } - if (newText != now) { - now = newText; - setText(now); - startPlaceholderAnimation(); - } - if (newCursor != nowCursor) { - nowCursor = newCursor; - setCursorPosition(nowCursor); - } - if (accumulated > _maxValue - || (limit == _maxDigits && oldLength > _maxDigits)) { - if (oldCursor > limit) { - _putNext.fire('0' + (accumulated % 10)); - } else { - _putNext.fire(0); - } - } -} - TimeInput::TimeInput( QWidget *parent, const QString &value,