diff --git a/Telegram/SourceFiles/editor/editor_paint.cpp b/Telegram/SourceFiles/editor/editor_paint.cpp index cdb38be34..4a12af104 100644 --- a/Telegram/SourceFiles/editor/editor_paint.cpp +++ b/Telegram/SourceFiles/editor/editor_paint.cpp @@ -36,10 +36,6 @@ std::shared_ptr EnsureScene( return mods.paint; } -auto Filter(QGraphicsItem *i) { - return i->type() != ItemCanvas::Type; -} - } // namespace Paint::Paint( @@ -72,7 +68,7 @@ Paint::Paint( ) | rpl::start_with_next([=](const Undo &command) { const auto isUndo = (command == Undo::Undo); - const auto filtered = filteredItems(isUndo + const auto filtered = _scene->items(isUndo ? Qt::DescendingOrder : Qt::AscendingOrder); @@ -150,7 +146,7 @@ std::shared_ptr Paint::saveScene() const { } void Paint::cancel() { - const auto filtered = filteredItems(Qt::AscendingOrder); + const auto filtered = _scene->items(Qt::AscendingOrder); if (filtered.empty()) { return; } @@ -184,17 +180,17 @@ void Paint::keepResult() { } bool Paint::hasUndo() const { - return ranges::any_of(filteredItems(), &QGraphicsItem::isVisible); + return ranges::any_of(_scene->items(), &QGraphicsItem::isVisible); } bool Paint::hasRedo() const { return ranges::any_of( - filteredItems(), + _scene->items(), [=](QGraphicsItem *i) { return isItemHidden(i); }); } void Paint::clearRedoList() { - const auto items = filteredItems(Qt::AscendingOrder); + const auto items = _scene->items(Qt::AscendingOrder); auto &&filtered = ranges::views::all( items ) | ranges::views::filter( @@ -222,13 +218,6 @@ void Paint::updateUndoState() { _hasRedo = hasRedo(); } -std::vector Paint::filteredItems(Qt::SortOrder order) const { - const auto items = _scene->items(order); - return ranges::views::all( - items - ) | ranges::views::filter(Filter) | ranges::to_vector; -} - void Paint::applyBrush(const Brush &brush) { _scene->applyBrush( brush.color, diff --git a/Telegram/SourceFiles/editor/editor_paint.h b/Telegram/SourceFiles/editor/editor_paint.h index eba8fc3d4..bee9c3ae7 100644 --- a/Telegram/SourceFiles/editor/editor_paint.h +++ b/Telegram/SourceFiles/editor/editor_paint.h @@ -50,9 +50,6 @@ private: bool isItemToRemove(not_null item) const; bool isItemHidden(not_null item) const; - std::vector filteredItems( - Qt::SortOrder order = Qt::DescendingOrder) const; - const std::shared_ptr _lastZ; const std::shared_ptr _scene; const base::unique_qptr _view; diff --git a/Telegram/SourceFiles/editor/scene.cpp b/Telegram/SourceFiles/editor/scene.cpp index fd83e8b66..1912702ae 100644 --- a/Telegram/SourceFiles/editor/scene.cpp +++ b/Telegram/SourceFiles/editor/scene.cpp @@ -22,7 +22,7 @@ Scene::Scene(const QRectF &rect) , _canvas(new ItemCanvas) { clearPath(); - addItem(_canvas); + QGraphicsScene::addItem(_canvas); _canvas->paintRequest( ) | rpl::start_with_next([=](not_null p) { @@ -33,6 +33,11 @@ Scene::Scene(const QRectF &rect) }, _lifetime); } +void Scene::addItem(not_null item) { + item->setNumber(_itemNumber++); + QGraphicsScene::addItem(item); +} + void Scene::mousePressEvent(QGraphicsSceneMouseEvent *event) { QGraphicsScene::mousePressEvent(event); if (event->isAccepted() || (event->button() == Qt::RightButton)) { @@ -93,6 +98,25 @@ rpl::producer<> Scene::mousePresses() const { return _mousePresses.events(); } +std::vector Scene::items(Qt::SortOrder order) const { + using Item = QGraphicsItem; + auto rawItems = QGraphicsScene::items(); + + auto filteredItems = ranges::views::all( + rawItems + ) | ranges::views::filter([](Item *i) { + return i->type() != ItemCanvas::Type; + }) | ranges::to_vector; + + ranges::sort(filteredItems, [&](not_null a, not_null b) { + const auto numA = qgraphicsitem_cast(a)->number(); + const auto numB = qgraphicsitem_cast(b)->number(); + return (order == Qt::AscendingOrder) ? (numA < numB) : (numA > numB); + }); + + return filteredItems; +} + Scene::~Scene() { } diff --git a/Telegram/SourceFiles/editor/scene.h b/Telegram/SourceFiles/editor/scene.h index 71a7f4ab8..1ae75f5c2 100644 --- a/Telegram/SourceFiles/editor/scene.h +++ b/Telegram/SourceFiles/editor/scene.h @@ -22,6 +22,7 @@ class RpWidget; namespace Editor { class ItemCanvas; +class NumberedItem; class Scene final : public QGraphicsScene { public: @@ -29,6 +30,9 @@ public: ~Scene(); void applyBrush(const QColor &color, float size); + [[nodiscard]] std::vector items( + Qt::SortOrder order = Qt::DescendingOrder) const; + void addItem(not_null item); [[nodiscard]] rpl::producer<> mousePresses() const; protected: @@ -46,6 +50,8 @@ private: float64 _lastLineZ = 0.; + int _itemNumber = 0; + struct { float size = 1.; QColor color; diff --git a/Telegram/SourceFiles/editor/scene_item_base.cpp b/Telegram/SourceFiles/editor/scene_item_base.cpp index 3ebc40311..50b006bb5 100644 --- a/Telegram/SourceFiles/editor/scene_item_base.cpp +++ b/Telegram/SourceFiles/editor/scene_item_base.cpp @@ -28,6 +28,14 @@ QPen PenStyled(QPen pen, Qt::PenStyle style) { } // namespace +int NumberedItem::number() const { + return _number; +} + +void NumberedItem::setNumber(int number) { + _number = number; +} + ItemBase::ItemBase(std::shared_ptr zPtr, int size, int x, int y) : _lastZ(zPtr) , _handleSize(st::photoEditorItemHandleSize) diff --git a/Telegram/SourceFiles/editor/scene_item_base.h b/Telegram/SourceFiles/editor/scene_item_base.h index b77941fed..df61ebf13 100644 --- a/Telegram/SourceFiles/editor/scene_item_base.h +++ b/Telegram/SourceFiles/editor/scene_item_base.h @@ -15,7 +15,17 @@ class QStyleOptionGraphicsItem; namespace Editor { -class ItemBase : public QGraphicsItem { +class NumberedItem : public QGraphicsItem { +public: + using QGraphicsItem::QGraphicsItem; + + void setNumber(int number); + [[nodiscard]] int number() const; +private: + int _number = 0; +}; + +class ItemBase : public NumberedItem { public: enum { Type = UserType + 1 }; diff --git a/Telegram/SourceFiles/editor/scene_item_line.h b/Telegram/SourceFiles/editor/scene_item_line.h index 1f24186d6..ca9a9197e 100644 --- a/Telegram/SourceFiles/editor/scene_item_line.h +++ b/Telegram/SourceFiles/editor/scene_item_line.h @@ -7,11 +7,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once -#include +#include "editor/scene_item_base.h" namespace Editor { -class ItemLine : public QGraphicsItem { +class ItemLine : public NumberedItem { public: enum { Type = UserType + 5 };