Fixed undo and redo paint actions.

This commit is contained in:
23rd 2021-03-14 12:44:49 +03:00
parent a3e54fcd7c
commit 690a7d1608
7 changed files with 57 additions and 23 deletions

View file

@ -36,10 +36,6 @@ std::shared_ptr<Scene> 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<Scene> 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<QGraphicsItem*> 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,

View file

@ -50,9 +50,6 @@ private:
bool isItemToRemove(not_null<QGraphicsItem*> item) const;
bool isItemHidden(not_null<QGraphicsItem*> item) const;
std::vector<QGraphicsItem*> filteredItems(
Qt::SortOrder order = Qt::DescendingOrder) const;
const std::shared_ptr<float64> _lastZ;
const std::shared_ptr<Scene> _scene;
const base::unique_qptr<QGraphicsView> _view;

View file

@ -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<QPainter*> p) {
@ -33,6 +33,11 @@ Scene::Scene(const QRectF &rect)
}, _lifetime);
}
void Scene::addItem(not_null<NumberedItem*> 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<QGraphicsItem*> 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<Item*> a, not_null<Item*> b) {
const auto numA = qgraphicsitem_cast<NumberedItem*>(a)->number();
const auto numB = qgraphicsitem_cast<NumberedItem*>(b)->number();
return (order == Qt::AscendingOrder) ? (numA < numB) : (numA > numB);
});
return filteredItems;
}
Scene::~Scene() {
}

View file

@ -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<QGraphicsItem*> items(
Qt::SortOrder order = Qt::DescendingOrder) const;
void addItem(not_null<NumberedItem*> item);
[[nodiscard]] rpl::producer<> mousePresses() const;
protected:
@ -46,6 +50,8 @@ private:
float64 _lastLineZ = 0.;
int _itemNumber = 0;
struct {
float size = 1.;
QColor color;

View file

@ -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<float64> zPtr, int size, int x, int y)
: _lastZ(zPtr)
, _handleSize(st::photoEditorItemHandleSize)

View file

@ -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 };

View file

@ -7,11 +7,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <QGraphicsItem>
#include "editor/scene_item_base.h"
namespace Editor {
class ItemLine : public QGraphicsItem {
class ItemLine : public NumberedItem {
public:
enum { Type = UserType + 5 };