From 0adcd37030ab663e08f001d48c03b4befcc7aeac Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sat, 13 Feb 2021 11:23:21 +0300 Subject: [PATCH] Added edge buttons to controls of photo editor. --- Telegram/SourceFiles/editor/editor.style | 2 + .../editor/photo_editor_controls.cpp | 128 ++++++++++++++++-- .../editor/photo_editor_controls.h | 4 + 3 files changed, 126 insertions(+), 8 deletions(-) diff --git a/Telegram/SourceFiles/editor/editor.style b/Telegram/SourceFiles/editor/editor.style index bfc24dbb28..5b212f82de 100644 --- a/Telegram/SourceFiles/editor/editor.style +++ b/Telegram/SourceFiles/editor/editor.style @@ -38,3 +38,5 @@ photoEditorRedoButton: IconButton(historyAttach) { icon: icon {{ "photo_editor/undo-flip_horizontal", photoEditorButtonIconFg }}; iconOver: icon {{ "photo_editor/undo-flip_horizontal", photoEditorButtonIconFgOver }}; } + +photoEditorTextButtonPadding: margins(10px, 0px, 10px, 0px); diff --git a/Telegram/SourceFiles/editor/photo_editor_controls.cpp b/Telegram/SourceFiles/editor/photo_editor_controls.cpp index 89c7d77e0a..832343c244 100644 --- a/Telegram/SourceFiles/editor/photo_editor_controls.cpp +++ b/Telegram/SourceFiles/editor/photo_editor_controls.cpp @@ -7,12 +7,104 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "editor/photo_editor_controls.h" -#include "ui/cached_round_corners.h" +#include "lang/lang_keys.h" +#include "ui/image/image_prepare.h" #include "ui/widgets/buttons.h" + #include "styles/style_editor.h" namespace Editor { +class EdgeButton final : public Ui::RippleButton { +public: + EdgeButton( + not_null parent, + const QString &text, + int height, + bool left, + const style::color &bg, + const style::color &fg, + const style::RippleAnimation &st); + +protected: + QImage prepareRippleMask() const override; + QPoint prepareRippleStartPosition() const override; + +private: + void init(); + + const style::color &_fg; + Ui::Text::String _text; + const int _width; + const QRect _rippleRect; + const QColor _bg; + const bool _left; + + QImage rounded(std::optional color) const; + +}; + +EdgeButton::EdgeButton( + not_null parent, + const QString &text, + int height, + bool left, + const style::color &bg, + const style::color &fg, + const style::RippleAnimation &st) +: Ui::RippleButton(parent, st) +, _fg(fg) +, _text(st::semiboldTextStyle, text.toUpper()) +, _width(_text.maxWidth() + + st::photoEditorTextButtonPadding.left() + + st::photoEditorTextButtonPadding.right()) +, _rippleRect(QRect(0, 0, _width, height)) +, _bg(bg->c) +, _left(left) { + resize(_width, height); + init(); +} + +void EdgeButton::init() { + const auto bg = rounded(_bg); + + paintRequest( + ) | rpl::start_with_next([=] { + Painter p(this); + + p.drawImage(QPoint(), bg); + + paintRipple(p, _rippleRect.x(), _rippleRect.y()); + + p.setPen(_fg); + const auto textTop = (height() - _text.minHeight()) / 2; + _text.draw(p, 0, textTop, width(), style::al_center); + }, lifetime()); +} + +QImage EdgeButton::rounded(std::optional color) const { + auto result = QImage( + _rippleRect.size() * cIntRetinaFactor(), + QImage::Format_ARGB32_Premultiplied); + result.setDevicePixelRatio(cIntRetinaFactor()); + result.fill(color.value_or(Qt::white)); + + using Option = Images::Option; + const auto options = Option::Smooth + | Option::RoundedLarge + | (_left ? Option::RoundedTopLeft : Option::RoundedTopRight) + | (_left ? Option::RoundedBottomLeft : Option::RoundedBottomRight); + return Images::prepare(std::move(result), 0, 0, options, 0, 0); +} + +QImage EdgeButton::prepareRippleMask() const { + return rounded(std::nullopt); +} + +QPoint EdgeButton::prepareRippleStartPosition() const { + return mapFromGlobal(QCursor::pos()) - _rippleRect.topLeft(); +} + class HorizontalContainer final : public Ui::RpWidget { public: HorizontalContainer(not_null parent); @@ -43,6 +135,7 @@ PhotoEditorControls::PhotoEditorControls( not_null parent, bool doneControls) : RpWidget(parent) +, _bg(st::mediaviewSaveMsgBg) , _buttonsContainer(base::make_unique_q(this)) , _rotateButton(base::make_unique_q( _buttonsContainer, @@ -52,7 +145,23 @@ PhotoEditorControls::PhotoEditorControls( st::photoEditorFlipButton)) , _paintModeButton(base::make_unique_q( _buttonsContainer, - st::photoEditorPaintModeButton)) { + st::photoEditorPaintModeButton)) +, _cancel(base::make_unique_q( + this, + tr::lng_cancel(tr::now), + _flipButton->height(), + true, + _bg, + st::activeButtonFg, + st::photoEditorRotateButton.ripple)) +, _done(base::make_unique_q( + this, + tr::lng_box_done(tr::now), + _flipButton->height(), + false, + _bg, + st::lightButtonFg, + st::photoEditorRotateButton.ripple)) { _buttonsContainer->updateChildrenPosition(); @@ -60,11 +169,9 @@ PhotoEditorControls::PhotoEditorControls( ) | rpl::start_with_next([=](const QRect &clip) { Painter p(this); - Ui::FillRoundRect( - p, - _buttonsContainer->geometry(), - st::mediaviewSaveMsgBg, - Ui::MediaviewSaveCorners); + p.setPen(Qt::NoPen); + p.setBrush(_bg); + p.drawRect(_buttonsContainer->geometry()); }, lifetime()); @@ -75,12 +182,17 @@ PhotoEditorControls::PhotoEditorControls( (size.width() - _buttonsContainer->width()) / 2, 0); + _cancel->moveToLeft(_buttonsContainer->x() - _cancel->width(), 0); + _done->moveToLeft( + _buttonsContainer->x() + _buttonsContainer->width(), + 0); + }, lifetime()); } rpl::producer PhotoEditorControls::rotateRequests() const { - return _rotateButton->clicks() | rpl::map([] { return 90; }); + return _rotateButton->clicks() | rpl::map_to(90); } rpl::producer<> PhotoEditorControls::flipRequests() const { diff --git a/Telegram/SourceFiles/editor/photo_editor_controls.h b/Telegram/SourceFiles/editor/photo_editor_controls.h index e891b95cb0..0fd04f5f90 100644 --- a/Telegram/SourceFiles/editor/photo_editor_controls.h +++ b/Telegram/SourceFiles/editor/photo_editor_controls.h @@ -15,6 +15,7 @@ class IconButton; namespace Editor { +class EdgeButton; class HorizontalContainer; class PhotoEditorControls final : public Ui::RpWidget { @@ -29,10 +30,13 @@ public: private: + const style::color &_bg; const base::unique_qptr _buttonsContainer; const base::unique_qptr _rotateButton; const base::unique_qptr _flipButton; const base::unique_qptr _paintModeButton; + const base::unique_qptr _cancel; + const base::unique_qptr _done; };