diff --git a/Telegram/SourceFiles/editor/editor_paint.cpp b/Telegram/SourceFiles/editor/editor_paint.cpp index 410f9ab534..c127484841 100644 --- a/Telegram/SourceFiles/editor/editor_paint.cpp +++ b/Telegram/SourceFiles/editor/editor_paint.cpp @@ -161,6 +161,7 @@ void Paint::applyTransform(QRect geometry, int angle, bool flipped) { } std::shared_ptr Paint::saveScene() const { + _scene->saveItemsState(SaveState::Save); _scene->clearSelection(); return _scene->items().empty() ? nullptr @@ -169,7 +170,12 @@ std::shared_ptr Paint::saveScene() const { : _scene; } +void Paint::restoreScene() { + _scene->restoreItemsState(SaveState::Save); +} + void Paint::cancel() { + _scene->restoreItemsState(SaveState::Keep); _scene->clearSelection(); _scene->cancelDrawing(); @@ -194,6 +200,7 @@ void Paint::cancel() { } void Paint::keepResult() { + _scene->saveItemsState(SaveState::Keep); _scene->clearSelection(); _scene->cancelDrawing(); diff --git a/Telegram/SourceFiles/editor/editor_paint.h b/Telegram/SourceFiles/editor/editor_paint.h index 00bb6c0d4d..a255f4e41b 100644 --- a/Telegram/SourceFiles/editor/editor_paint.h +++ b/Telegram/SourceFiles/editor/editor_paint.h @@ -31,6 +31,7 @@ public: std::shared_ptr controllers); [[nodiscard]] std::shared_ptr saveScene() const; + void restoreScene(); void applyTransform(QRect geometry, int angle, bool flipped); void applyBrush(const Brush &brush); diff --git a/Telegram/SourceFiles/editor/photo_editor.cpp b/Telegram/SourceFiles/editor/photo_editor.cpp index f1db920ef0..6032b81769 100644 --- a/Telegram/SourceFiles/editor/photo_editor.cpp +++ b/Telegram/SourceFiles/editor/photo_editor.cpp @@ -136,6 +136,10 @@ PhotoEditor::PhotoEditor( .action = PhotoEditorMode::Action::Save, }; } else if (mode == PhotoEditorMode::Mode::Transform) { + _mode = PhotoEditorMode{ + .mode = PhotoEditorMode::Mode::Out, + .action = PhotoEditorMode::Action::Save, + }; save(); } }, lifetime()); @@ -149,6 +153,10 @@ PhotoEditor::PhotoEditor( .action = PhotoEditorMode::Action::Discard, }; } else if (mode == PhotoEditorMode::Mode::Transform) { + _mode = PhotoEditorMode{ + .mode = PhotoEditorMode::Mode::Out, + .action = PhotoEditorMode::Action::Discard, + }; _cancel.fire({}); } }, lifetime()); diff --git a/Telegram/SourceFiles/editor/photo_editor_content.cpp b/Telegram/SourceFiles/editor/photo_editor_content.cpp index 1e109759e9..8a217940d6 100644 --- a/Telegram/SourceFiles/editor/photo_editor_content.cpp +++ b/Telegram/SourceFiles/editor/photo_editor_content.cpp @@ -113,6 +113,12 @@ void PhotoEditorContent::save(PhotoModifications &modifications) { } void PhotoEditorContent::applyMode(const PhotoEditorMode &mode) { + if (mode.mode == PhotoEditorMode::Mode::Out) { + if (mode.action == PhotoEditorMode::Action::Discard) { + _paint->restoreScene(); + } + return; + } const auto isTransform = (mode.mode == PhotoEditorMode::Mode::Transform); _crop->setVisible(isTransform); @@ -139,9 +145,9 @@ bool PhotoEditorContent::handleKeyPress(not_null e) const { void PhotoEditorContent::setupDragArea() { auto dragEnterFilter = [=](const QMimeData *data) { - return (_mode.mode == PhotoEditorMode::Mode::Transform) - ? false - : Storage::ValidatePhotoEditorMediaDragData(data); + return (_mode.mode == PhotoEditorMode::Mode::Paint) + ? Storage::ValidatePhotoEditorMediaDragData(data) + : false; }; const auto areas = DragArea::SetupDragAreaToContainer( diff --git a/Telegram/SourceFiles/editor/photo_editor_controls.cpp b/Telegram/SourceFiles/editor/photo_editor_controls.cpp index 035f3cbbbe..ce7ac5ab3a 100644 --- a/Telegram/SourceFiles/editor/photo_editor_controls.cpp +++ b/Telegram/SourceFiles/editor/photo_editor_controls.cpp @@ -267,6 +267,9 @@ PhotoEditorControls::PhotoEditorControls( _mode.changes( ) | rpl::start_with_next([=](const PhotoEditorMode &mode) { + if (mode.mode == PhotoEditorMode::Mode::Out) { + return; + } const auto animated = (_paintBottomButtons->isVisible() == _transformButtons->isVisible()) ? anim::type::instant diff --git a/Telegram/SourceFiles/editor/photo_editor_inner_common.h b/Telegram/SourceFiles/editor/photo_editor_inner_common.h index f3b33b5d59..cbb9bd2883 100644 --- a/Telegram/SourceFiles/editor/photo_editor_inner_common.h +++ b/Telegram/SourceFiles/editor/photo_editor_inner_common.h @@ -15,6 +15,7 @@ struct PhotoEditorMode { enum class Mode { Transform, Paint, + Out, } mode = Mode::Transform; enum class Action { @@ -29,4 +30,9 @@ struct Brush { QColor color; }; +enum class SaveState { + Save, + Keep, +}; + } // namespace Editor diff --git a/Telegram/SourceFiles/editor/scene/scene.cpp b/Telegram/SourceFiles/editor/scene/scene.cpp index 865c1c8b62..5aa1d5ff53 100644 --- a/Telegram/SourceFiles/editor/scene/scene.cpp +++ b/Telegram/SourceFiles/editor/scene/scene.cpp @@ -147,6 +147,22 @@ void Scene::updateZoom(float64 zoom) { } } +void Scene::saveItemsState(SaveState state) { + for (const auto &item : items()) { + if (item->type() >= ItemBase::Type) { + static_cast(item.get())->save(state); + } + } +} + +void Scene::restoreItemsState(SaveState state) { + for (const auto &item : items()) { + if (item->type() >= ItemBase::Type) { + static_cast(item.get())->restore(state); + } + } +} + Scene::~Scene() { // Prevent destroying by scene of all items. QGraphicsScene::removeItem(_canvas.get()); diff --git a/Telegram/SourceFiles/editor/scene/scene.h b/Telegram/SourceFiles/editor/scene/scene.h index 820515f9f6..dca1c20d5f 100644 --- a/Telegram/SourceFiles/editor/scene/scene.h +++ b/Telegram/SourceFiles/editor/scene/scene.h @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include +#include #include @@ -45,6 +46,9 @@ public: void updateZoom(float64 zoom); void cancelDrawing(); + + void saveItemsState(SaveState state); + void restoreItemsState(SaveState state); protected: void mousePressEvent(QGraphicsSceneMouseEvent *event) override; void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; diff --git a/Telegram/SourceFiles/editor/scene/scene_item_base.cpp b/Telegram/SourceFiles/editor/scene/scene_item_base.cpp index eb6cf3da8e..907d8e8937 100644 --- a/Telegram/SourceFiles/editor/scene/scene_item_base.cpp +++ b/Telegram/SourceFiles/editor/scene/scene_item_base.cpp @@ -383,4 +383,27 @@ void ItemBase::applyData(const Data &data) { update(); } +void ItemBase::save(SaveState state) { + if (state == SaveState::Keep) { + const auto z = zValue(); + _keeped = { + .data = generateData(), + .zValue = z, + .visible = isVisible(), + }; + } else if (state == SaveState::Save) { + _saved = _keeped; + } +} + +void ItemBase::restore(SaveState state) { + const auto &saved = (state == SaveState::Keep) ? _keeped : _saved; + if (!saved.zValue) { + return; + } + applyData(saved.data); + setZValue(saved.zValue); + setVisible(saved.visible); +} + } // namespace Editor diff --git a/Telegram/SourceFiles/editor/scene/scene_item_base.h b/Telegram/SourceFiles/editor/scene/scene_item_base.h index f28d9c2be1..4486ba0d70 100644 --- a/Telegram/SourceFiles/editor/scene/scene_item_base.h +++ b/Telegram/SourceFiles/editor/scene/scene_item_base.h @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include "base/unique_qptr.h" +#include "editor/photo_editor_inner_common.h" #include @@ -60,6 +61,9 @@ public: void setFlip(bool value); void updateZoom(float64 zoom); + + void save(SaveState state); + void restore(SaveState state); protected: enum HandleType { None, @@ -113,8 +117,14 @@ private: base::unique_qptr _menu; struct { - int min = 0.; - int max = 0.; + Data data; + float64 zValue = 0.; + bool visible = true; + } _saved, _keeped; + + struct { + int min = 0; + int max = 0; } _sizeLimits; float64 _scaledHandleSize = 1.0; QMarginsF _scaledInnerMargins;