From c9affe0da55180bd536050da8ab85df75310d757 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 18 Feb 2021 03:06:44 +0300 Subject: [PATCH] Added custom layer widget with photo editor. --- Telegram/CMakeLists.txt | 2 + Telegram/SourceFiles/editor/color_picker.cpp | 2 +- Telegram/SourceFiles/editor/photo_editor.cpp | 21 ++++--- Telegram/SourceFiles/editor/photo_editor.h | 4 +- .../editor/photo_editor_controls.cpp | 6 +- .../editor/photo_editor_layer_widget.cpp | 63 +++++++++++++++++++ .../editor/photo_editor_layer_widget.h | 43 +++++++++++++ 7 files changed, 131 insertions(+), 10 deletions(-) create mode 100644 Telegram/SourceFiles/editor/photo_editor_layer_widget.cpp create mode 100644 Telegram/SourceFiles/editor/photo_editor_layer_widget.h diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 060c8d306..f4b50b354 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -522,6 +522,8 @@ PRIVATE editor/photo_editor_content.h editor/photo_editor_controls.cpp editor/photo_editor_controls.h + editor/photo_editor_layer_widget.cpp + editor/photo_editor_layer_widget.h editor/undo_controller.cpp editor/undo_controller.h export/export_manager.cpp diff --git a/Telegram/SourceFiles/editor/color_picker.cpp b/Telegram/SourceFiles/editor/color_picker.cpp index 1a5391728..238f52d2e 100644 --- a/Telegram/SourceFiles/editor/color_picker.cpp +++ b/Telegram/SourceFiles/editor/color_picker.cpp @@ -308,7 +308,7 @@ void ColorPicker::setVisible(bool visible) { } rpl::producer ColorPicker::saveBrushRequests() const { - return _saveBrushRequests.events(); + return _saveBrushRequests.events_starting_with_copy(_brush); } int ColorPicker::colorToPosition(const QColor &color) const { diff --git a/Telegram/SourceFiles/editor/photo_editor.cpp b/Telegram/SourceFiles/editor/photo_editor.cpp index 4009dec0a..ad5628eda 100644 --- a/Telegram/SourceFiles/editor/photo_editor.cpp +++ b/Telegram/SourceFiles/editor/photo_editor.cpp @@ -110,28 +110,31 @@ PhotoEditor::PhotoEditor( _controls->doneRequests( ) | rpl::start_with_next([=] { - if (_mode.current().mode == PhotoEditorMode::Mode::Paint) { + const auto mode = _mode.current().mode; + if (mode == PhotoEditorMode::Mode::Paint) { _mode = PhotoEditorMode{ .mode = PhotoEditorMode::Mode::Transform, .action = PhotoEditorMode::Action::Save, }; + } else if (mode == PhotoEditorMode::Mode::Transform) { + save(); } }, lifetime()); _controls->cancelRequests( ) | rpl::start_with_next([=] { - if (_mode.current().mode == PhotoEditorMode::Mode::Paint) { + const auto mode = _mode.current().mode; + if (mode == PhotoEditorMode::Mode::Paint) { _mode = PhotoEditorMode{ .mode = PhotoEditorMode::Mode::Transform, .action = PhotoEditorMode::Action::Discard, }; + } else if (mode == PhotoEditorMode::Mode::Transform) { + _cancel.fire({}); } }, lifetime()); - rpl::single( - Deserialize(Core::App().settings().photoEditorBrush()) - ) | rpl::then( - _colorPicker->saveBrushRequests() + _colorPicker->saveBrushRequests( ) | rpl::start_with_next([=](const Brush &brush) { _content->applyBrush(brush); @@ -148,8 +151,12 @@ void PhotoEditor::save() { _done.fire_copy(_modifications); } -rpl::producer PhotoEditor::done() const { +rpl::producer PhotoEditor::doneRequests() const { return _done.events(); } +rpl::producer<> PhotoEditor::cancelRequests() const { + return _cancel.events(); +} + } // namespace Editor diff --git a/Telegram/SourceFiles/editor/photo_editor.h b/Telegram/SourceFiles/editor/photo_editor.h index a0bcf2195..79974aade 100644 --- a/Telegram/SourceFiles/editor/photo_editor.h +++ b/Telegram/SourceFiles/editor/photo_editor.h @@ -28,7 +28,8 @@ public: PhotoModifications modifications); void save(); - rpl::producer done() const; + rpl::producer doneRequests() const; + rpl::producer<> cancelRequests() const; private: @@ -45,6 +46,7 @@ private: .action = PhotoEditorMode::Action::None, }; rpl::event_stream _done; + rpl::event_stream<> _cancel; }; diff --git a/Telegram/SourceFiles/editor/photo_editor_controls.cpp b/Telegram/SourceFiles/editor/photo_editor_controls.cpp index 38dc36d9c..97dec1285 100644 --- a/Telegram/SourceFiles/editor/photo_editor_controls.cpp +++ b/Telegram/SourceFiles/editor/photo_editor_controls.cpp @@ -186,9 +186,13 @@ PhotoEditorControls::PhotoEditorControls( ) | rpl::start_with_next([=](const QRect &clip) { Painter p(this); + const auto ¤t = _transformButtons->isHidden() + ? _paintButtons + : _transformButtons; + p.setPen(Qt::NoPen); p.setBrush(_bg); - p.drawRect(_transformButtons->geometry()); + p.drawRect(current->geometry()); }, lifetime()); diff --git a/Telegram/SourceFiles/editor/photo_editor_layer_widget.cpp b/Telegram/SourceFiles/editor/photo_editor_layer_widget.cpp new file mode 100644 index 000000000..8bbef6758 --- /dev/null +++ b/Telegram/SourceFiles/editor/photo_editor_layer_widget.cpp @@ -0,0 +1,63 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "editor/photo_editor_layer_widget.h" + +#include "editor/photo_editor.h" + +namespace Editor { + +LayerWidget::LayerWidget( + not_null parent, + not_null window, + std::shared_ptr photo, + PhotoModifications modifications, + Fn &&doneCallback) +: Ui::LayerWidget(parent) +, _content(base::make_unique_q( + this, + std::move(photo), + std::move(modifications))) { + + paintRequest( + ) | rpl::start_with_next([=](const QRect &clip) { + Painter p(this); + + p.fillRect(clip, st::boxBg); + }, lifetime()); + + _content->cancelRequests( + ) | rpl::start_with_next([=] { + closeLayer(); + }, lifetime()); + + _content->doneRequests( + ) | rpl::start_with_next([=, done = std::move(doneCallback)]( + const PhotoModifications &mods) { + doneCallback(mods); + closeLayer(); + }, lifetime()); + + sizeValue( + ) | rpl::start_with_next([=](const QSize &size) { + _content->resize(size); + }, lifetime()); +} + +void LayerWidget::parentResized() { + resizeToWidth(parentWidget()->width()); +} + +int LayerWidget::resizeGetHeight(int newWidth) { + return parentWidget()->height(); +} + +bool LayerWidget::closeByOutsideClick() const { + return false; +} + +} // namespace Editor diff --git a/Telegram/SourceFiles/editor/photo_editor_layer_widget.h b/Telegram/SourceFiles/editor/photo_editor_layer_widget.h new file mode 100644 index 000000000..c44f81c7a --- /dev/null +++ b/Telegram/SourceFiles/editor/photo_editor_layer_widget.h @@ -0,0 +1,43 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +#include "ui/layers/layer_widget.h" + +#include "editor/photo_editor_common.h" +#include "base/unique_qptr.h" + +namespace Window { +class Controller; +} // namespace Window + +namespace Editor { + +class PhotoEditor; + +class LayerWidget : public Ui::LayerWidget { +public: + LayerWidget( + not_null parent, + not_null window, + std::shared_ptr photo, + PhotoModifications modifications, + Fn &&doneCallback); + + void parentResized() override; + bool closeByOutsideClick() const override; + +protected: + int resizeGetHeight(int newWidth) override; + +private: + const base::unique_qptr _content; + +}; + +} // namespace Editor