Moved draft painting in photo editor to separate files.
This commit is contained in:
parent
23c67bb2a2
commit
a3e54fcd7c
11 changed files with 393 additions and 87 deletions
|
@ -523,8 +523,14 @@ PRIVATE
|
||||||
editor/photo_editor_controls.h
|
editor/photo_editor_controls.h
|
||||||
editor/photo_editor_layer_widget.cpp
|
editor/photo_editor_layer_widget.cpp
|
||||||
editor/photo_editor_layer_widget.h
|
editor/photo_editor_layer_widget.h
|
||||||
|
editor/scene.cpp
|
||||||
|
editor/scene.h
|
||||||
editor/scene_item_base.cpp
|
editor/scene_item_base.cpp
|
||||||
editor/scene_item_base.h
|
editor/scene_item_base.h
|
||||||
|
editor/scene_item_canvas.cpp
|
||||||
|
editor/scene_item_canvas.h
|
||||||
|
editor/scene_item_line.cpp
|
||||||
|
editor/scene_item_line.h
|
||||||
editor/scene_item_sticker.cpp
|
editor/scene_item_sticker.cpp
|
||||||
editor/scene_item_sticker.h
|
editor/scene_item_sticker.h
|
||||||
editor/stickers_panel_controller.cpp
|
editor/stickers_panel_controller.cpp
|
||||||
|
|
|
@ -7,13 +7,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "editor/editor_paint.h"
|
#include "editor/editor_paint.h"
|
||||||
|
|
||||||
|
#include "editor/scene.h"
|
||||||
#include "editor/scene_item_base.h"
|
#include "editor/scene_item_base.h"
|
||||||
|
#include "editor/scene_item_canvas.h"
|
||||||
#include "editor/scene_item_sticker.h"
|
#include "editor/scene_item_sticker.h"
|
||||||
#include "editor/controllers.h"
|
#include "editor/controllers.h"
|
||||||
#include "base/event_filter.h"
|
#include "base/event_filter.h"
|
||||||
|
|
||||||
#include <QGraphicsItemGroup>
|
|
||||||
#include <QGraphicsSceneMouseEvent>
|
|
||||||
#include <QGraphicsView>
|
#include <QGraphicsView>
|
||||||
|
|
||||||
namespace Editor {
|
namespace Editor {
|
||||||
|
@ -27,15 +27,17 @@ constexpr auto kViewStyle = "QGraphicsView {\
|
||||||
border: 0px\
|
border: 0px\
|
||||||
}"_cs;
|
}"_cs;
|
||||||
|
|
||||||
std::shared_ptr<QGraphicsScene> EnsureScene(PhotoModifications &mods) {
|
std::shared_ptr<Scene> EnsureScene(
|
||||||
|
PhotoModifications &mods,
|
||||||
|
const QSize &size) {
|
||||||
if (!mods.paint) {
|
if (!mods.paint) {
|
||||||
mods.paint = std::make_shared<QGraphicsScene>(nullptr);
|
mods.paint = std::make_shared<Scene>(QRectF(QPointF(), size));
|
||||||
}
|
}
|
||||||
return mods.paint;
|
return mods.paint;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto GroupsFilter(QGraphicsItem *i) {
|
auto Filter(QGraphicsItem *i) {
|
||||||
return i->type() == QGraphicsItemGroup::Type;
|
return i->type() != ItemCanvas::Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -46,8 +48,8 @@ Paint::Paint(
|
||||||
const QSize &imageSize,
|
const QSize &imageSize,
|
||||||
std::shared_ptr<Controllers> controllers)
|
std::shared_ptr<Controllers> controllers)
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
, _lastZ(std::make_shared<float64>(0.))
|
, _lastZ(std::make_shared<float64>(9000.))
|
||||||
, _scene(EnsureScene(modifications))
|
, _scene(EnsureScene(modifications, imageSize))
|
||||||
, _view(base::make_unique_q<QGraphicsView>(_scene.get(), this))
|
, _view(base::make_unique_q<QGraphicsView>(_scene.get(), this))
|
||||||
, _imageSize(imageSize) {
|
, _imageSize(imageSize) {
|
||||||
Expects(modifications.paint != nullptr);
|
Expects(modifications.paint != nullptr);
|
||||||
|
@ -59,16 +61,18 @@ Paint::Paint(
|
||||||
_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
_view->setStyleSheet(kViewStyle.utf8());
|
_view->setStyleSheet(kViewStyle.utf8());
|
||||||
|
|
||||||
_scene->setSceneRect(0, 0, imageSize.width(), imageSize.height());
|
_scene->mousePresses(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
initDrawing();
|
_hasUndo = true;
|
||||||
|
clearRedoList();
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
// Undo / Redo.
|
// Undo / Redo.
|
||||||
controllers->undoController->performRequestChanges(
|
controllers->undoController->performRequestChanges(
|
||||||
) | rpl::start_with_next([=](const Undo &command) {
|
) | rpl::start_with_next([=](const Undo &command) {
|
||||||
const auto isUndo = (command == Undo::Undo);
|
const auto isUndo = (command == Undo::Undo);
|
||||||
|
|
||||||
const auto filtered = groups(isUndo
|
const auto filtered = filteredItems(isUndo
|
||||||
? Qt::DescendingOrder
|
? Qt::DescendingOrder
|
||||||
: Qt::AscendingOrder);
|
: Qt::AscendingOrder);
|
||||||
|
|
||||||
|
@ -136,56 +140,7 @@ void Paint::applyTransform(QRect geometry, int angle, bool flipped) {
|
||||||
_view->setGeometry(QRect(QPoint(), size));
|
_view->setGeometry(QRect(QPoint(), size));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Paint::initDrawing() {
|
std::shared_ptr<Scene> Paint::saveScene() const {
|
||||||
using Result = base::EventFilterResult;
|
|
||||||
|
|
||||||
auto callback = [=](not_null<QEvent*> event) {
|
|
||||||
const auto type = event->type();
|
|
||||||
const auto isPress = (type == QEvent::GraphicsSceneMousePress);
|
|
||||||
const auto isMove = (type == QEvent::GraphicsSceneMouseMove);
|
|
||||||
const auto isRelease = (type == QEvent::GraphicsSceneMouseRelease);
|
|
||||||
if (!isPress && !isMove && !isRelease) {
|
|
||||||
return Result::Continue;
|
|
||||||
}
|
|
||||||
const auto e = static_cast<QGraphicsSceneMouseEvent*>(event.get());
|
|
||||||
|
|
||||||
const auto &size = _brushData.size;
|
|
||||||
const auto &color = _brushData.color;
|
|
||||||
const auto mousePoint = e->scenePos();
|
|
||||||
if (isPress) {
|
|
||||||
_hasUndo = true;
|
|
||||||
clearRedoList();
|
|
||||||
|
|
||||||
auto dot = _scene->addEllipse(
|
|
||||||
mousePoint.x() - size / 2,
|
|
||||||
mousePoint.y() - size / 2,
|
|
||||||
size,
|
|
||||||
size,
|
|
||||||
QPen(Qt::NoPen),
|
|
||||||
QBrush(color));
|
|
||||||
_brushData.group = _scene->createItemGroup(
|
|
||||||
QList<QGraphicsItem*>{ std::move(dot) });
|
|
||||||
}
|
|
||||||
if (isMove && _brushData.group) {
|
|
||||||
_brushData.group->addToGroup(_scene->addLine(
|
|
||||||
_brushData.lastPoint.x(),
|
|
||||||
_brushData.lastPoint.y(),
|
|
||||||
mousePoint.x(),
|
|
||||||
mousePoint.y(),
|
|
||||||
QPen(color, size, Qt::SolidLine, Qt::RoundCap)));
|
|
||||||
}
|
|
||||||
if (isRelease) {
|
|
||||||
_brushData.group = nullptr;
|
|
||||||
}
|
|
||||||
_brushData.lastPoint = mousePoint;
|
|
||||||
|
|
||||||
return Result::Cancel;
|
|
||||||
};
|
|
||||||
|
|
||||||
base::install_event_filter(this, _scene.get(), std::move(callback));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<QGraphicsScene> Paint::saveScene() const {
|
|
||||||
_scene->clearSelection();
|
_scene->clearSelection();
|
||||||
return _scene->items().empty()
|
return _scene->items().empty()
|
||||||
? nullptr
|
? nullptr
|
||||||
|
@ -195,7 +150,7 @@ std::shared_ptr<QGraphicsScene> Paint::saveScene() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Paint::cancel() {
|
void Paint::cancel() {
|
||||||
const auto filtered = groups(Qt::AscendingOrder);
|
const auto filtered = filteredItems(Qt::AscendingOrder);
|
||||||
if (filtered.empty()) {
|
if (filtered.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -229,17 +184,17 @@ void Paint::keepResult() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Paint::hasUndo() const {
|
bool Paint::hasUndo() const {
|
||||||
return ranges::any_of(groups(), &QGraphicsItem::isVisible);
|
return ranges::any_of(filteredItems(), &QGraphicsItem::isVisible);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Paint::hasRedo() const {
|
bool Paint::hasRedo() const {
|
||||||
return ranges::any_of(
|
return ranges::any_of(
|
||||||
groups(),
|
filteredItems(),
|
||||||
[=](QGraphicsItem *i) { return isItemHidden(i); });
|
[=](QGraphicsItem *i) { return isItemHidden(i); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Paint::clearRedoList() {
|
void Paint::clearRedoList() {
|
||||||
const auto items = groups(Qt::AscendingOrder);
|
const auto items = filteredItems(Qt::AscendingOrder);
|
||||||
auto &&filtered = ranges::views::all(
|
auto &&filtered = ranges::views::all(
|
||||||
items
|
items
|
||||||
) | ranges::views::filter(
|
) | ranges::views::filter(
|
||||||
|
@ -267,17 +222,17 @@ void Paint::updateUndoState() {
|
||||||
_hasRedo = hasRedo();
|
_hasRedo = hasRedo();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<QGraphicsItem*> Paint::groups(Qt::SortOrder order) const {
|
std::vector<QGraphicsItem*> Paint::filteredItems(Qt::SortOrder order) const {
|
||||||
const auto items = _scene->items(order);
|
const auto items = _scene->items(order);
|
||||||
return ranges::views::all(
|
return ranges::views::all(
|
||||||
items
|
items
|
||||||
) | ranges::views::filter(GroupsFilter) | ranges::to_vector;
|
) | ranges::views::filter(Filter) | ranges::to_vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Paint::applyBrush(const Brush &brush) {
|
void Paint::applyBrush(const Brush &brush) {
|
||||||
_brushData.color = brush.color;
|
_scene->applyBrush(
|
||||||
_brushData.size =
|
brush.color,
|
||||||
(kMinBrush + float64(kMaxBrush - kMinBrush) * brush.sizeRatio);
|
(kMinBrush + float64(kMaxBrush - kMinBrush) * brush.sizeRatio));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Editor
|
} // namespace Editor
|
||||||
|
|
|
@ -11,13 +11,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "editor/photo_editor_common.h"
|
#include "editor/photo_editor_common.h"
|
||||||
|
|
||||||
class QGraphicsItemGroup;
|
class QGraphicsItem;
|
||||||
class QGraphicsView;
|
class QGraphicsView;
|
||||||
|
|
||||||
namespace Editor {
|
namespace Editor {
|
||||||
|
|
||||||
struct Controllers;
|
struct Controllers;
|
||||||
class ItemBase;
|
class ItemBase;
|
||||||
|
class Scene;
|
||||||
|
|
||||||
// Paint control.
|
// Paint control.
|
||||||
class Paint final : public Ui::RpWidget {
|
class Paint final : public Ui::RpWidget {
|
||||||
|
@ -28,7 +29,7 @@ public:
|
||||||
const QSize &imageSize,
|
const QSize &imageSize,
|
||||||
std::shared_ptr<Controllers> controllers);
|
std::shared_ptr<Controllers> controllers);
|
||||||
|
|
||||||
[[nodiscard]] std::shared_ptr<QGraphicsScene> saveScene() const;
|
[[nodiscard]] std::shared_ptr<Scene> saveScene() const;
|
||||||
|
|
||||||
void applyTransform(QRect geometry, int angle, bool flipped);
|
void applyTransform(QRect geometry, int angle, bool flipped);
|
||||||
void applyBrush(const Brush &brush);
|
void applyBrush(const Brush &brush);
|
||||||
|
@ -42,7 +43,6 @@ private:
|
||||||
bool undid = false;
|
bool undid = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
void initDrawing();
|
|
||||||
bool hasUndo() const;
|
bool hasUndo() const;
|
||||||
bool hasRedo() const;
|
bool hasRedo() const;
|
||||||
void clearRedoList();
|
void clearRedoList();
|
||||||
|
@ -50,25 +50,17 @@ private:
|
||||||
bool isItemToRemove(not_null<QGraphicsItem*> item) const;
|
bool isItemToRemove(not_null<QGraphicsItem*> item) const;
|
||||||
bool isItemHidden(not_null<QGraphicsItem*> item) const;
|
bool isItemHidden(not_null<QGraphicsItem*> item) const;
|
||||||
|
|
||||||
std::vector<QGraphicsItem*> groups(
|
std::vector<QGraphicsItem*> filteredItems(
|
||||||
Qt::SortOrder order = Qt::DescendingOrder) const;
|
Qt::SortOrder order = Qt::DescendingOrder) const;
|
||||||
|
|
||||||
const std::shared_ptr<float64> _lastZ;
|
const std::shared_ptr<float64> _lastZ;
|
||||||
const std::shared_ptr<QGraphicsScene> _scene;
|
const std::shared_ptr<Scene> _scene;
|
||||||
const base::unique_qptr<QGraphicsView> _view;
|
const base::unique_qptr<QGraphicsView> _view;
|
||||||
const QSize _imageSize;
|
const QSize _imageSize;
|
||||||
|
|
||||||
std::vector<SavedItem> _previousItems;
|
std::vector<SavedItem> _previousItems;
|
||||||
QList<QGraphicsItem*> _itemsToRemove;
|
QList<QGraphicsItem*> _itemsToRemove;
|
||||||
|
|
||||||
struct {
|
|
||||||
QPointF lastPoint;
|
|
||||||
|
|
||||||
float size = 1.;
|
|
||||||
QColor color;
|
|
||||||
QGraphicsItemGroup *group;
|
|
||||||
} _brushData;
|
|
||||||
|
|
||||||
rpl::variable<bool> _hasUndo = true;
|
rpl::variable<bool> _hasUndo = true;
|
||||||
rpl::variable<bool> _hasRedo = true;
|
rpl::variable<bool> _hasRedo = true;
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "editor/photo_editor_common.h"
|
#include "editor/photo_editor_common.h"
|
||||||
|
|
||||||
|
#include "editor/scene.h"
|
||||||
|
|
||||||
namespace Editor {
|
namespace Editor {
|
||||||
|
|
||||||
QImage ImageModified(QImage image, const PhotoModifications &mods) {
|
QImage ImageModified(QImage image, const PhotoModifications &mods) {
|
||||||
|
|
|
@ -7,10 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QGraphicsScene>
|
|
||||||
|
|
||||||
namespace Editor {
|
namespace Editor {
|
||||||
|
|
||||||
|
class Scene;
|
||||||
|
|
||||||
struct PhotoEditorMode {
|
struct PhotoEditorMode {
|
||||||
enum class Mode {
|
enum class Mode {
|
||||||
Transform,
|
Transform,
|
||||||
|
@ -28,7 +28,7 @@ struct PhotoModifications {
|
||||||
int angle = 0;
|
int angle = 0;
|
||||||
bool flipped = false;
|
bool flipped = false;
|
||||||
QRect crop;
|
QRect crop;
|
||||||
std::shared_ptr<QGraphicsScene> paint = nullptr;
|
std::shared_ptr<Scene> paint = nullptr;
|
||||||
|
|
||||||
[[nodiscard]] bool empty() const;
|
[[nodiscard]] bool empty() const;
|
||||||
[[nodiscard]] explicit operator bool() const;
|
[[nodiscard]] explicit operator bool() const;
|
||||||
|
|
99
Telegram/SourceFiles/editor/scene.cpp
Normal file
99
Telegram/SourceFiles/editor/scene.cpp
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
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/scene.h"
|
||||||
|
|
||||||
|
#include "editor/scene_item_canvas.h"
|
||||||
|
#include "editor/scene_item_line.h"
|
||||||
|
#include "ui/rp_widget.h"
|
||||||
|
|
||||||
|
#include <QGraphicsSceneMouseEvent>
|
||||||
|
#include <QGraphicsSceneMouseEvent>
|
||||||
|
#include <QGraphicsSceneMouseEvent>
|
||||||
|
|
||||||
|
namespace Editor {
|
||||||
|
|
||||||
|
Scene::Scene(const QRectF &rect)
|
||||||
|
: QGraphicsScene(rect)
|
||||||
|
, _canvas(new ItemCanvas) {
|
||||||
|
clearPath();
|
||||||
|
|
||||||
|
addItem(_canvas);
|
||||||
|
|
||||||
|
_canvas->paintRequest(
|
||||||
|
) | rpl::start_with_next([=](not_null<QPainter*> p) {
|
||||||
|
p->fillRect(sceneRect(), Qt::transparent);
|
||||||
|
|
||||||
|
p->setPen(QPen(_brushData.color, _brushData.size));
|
||||||
|
p->drawPath(_path);
|
||||||
|
}, _lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
|
QGraphicsScene::mousePressEvent(event);
|
||||||
|
if (event->isAccepted() || (event->button() == Qt::RightButton)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_mousePresses.fire({});
|
||||||
|
_path.moveTo(event->scenePos());
|
||||||
|
_drawing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
|
QGraphicsScene::mouseReleaseEvent(event);
|
||||||
|
if (event->isAccepted() || (event->button() == Qt::RightButton)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_path.lineTo(event->scenePos());
|
||||||
|
addLineItem();
|
||||||
|
_drawing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
|
QGraphicsScene::mouseMoveEvent(event);
|
||||||
|
if (event->isAccepted()
|
||||||
|
|| (event->button() == Qt::RightButton)
|
||||||
|
|| !_drawing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto scenePos = event->scenePos();
|
||||||
|
_path.lineTo(scenePos);
|
||||||
|
_path.moveTo(scenePos);
|
||||||
|
_canvas->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::addLineItem() {
|
||||||
|
if (_path.capacity() < 3) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addItem(new ItemLine(
|
||||||
|
_path,
|
||||||
|
sceneRect().size().toSize() * cIntRetinaFactor(),
|
||||||
|
_brushData.color,
|
||||||
|
_brushData.size));
|
||||||
|
_canvas->setZValue(++_lastLineZ);
|
||||||
|
clearPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::applyBrush(const QColor &color, float size) {
|
||||||
|
_brushData.color = color;
|
||||||
|
_brushData.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::clearPath() {
|
||||||
|
_path = QPainterPath();
|
||||||
|
_path.setFillRule(Qt::WindingFill);
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> Scene::mousePresses() const {
|
||||||
|
return _mousePresses.events();
|
||||||
|
}
|
||||||
|
|
||||||
|
Scene::~Scene() {
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Editor
|
59
Telegram/SourceFiles/editor/scene.h
Normal file
59
Telegram/SourceFiles/editor/scene.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
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 <base/unique_qptr.h>
|
||||||
|
|
||||||
|
#include <QGraphicsScene>
|
||||||
|
|
||||||
|
class QGraphicsSceneMouseEvent;
|
||||||
|
class QGraphicsSceneMouseEvent;
|
||||||
|
class QGraphicsSceneMouseEvent;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class RpWidget;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace Editor {
|
||||||
|
|
||||||
|
class ItemCanvas;
|
||||||
|
|
||||||
|
class Scene final : public QGraphicsScene {
|
||||||
|
public:
|
||||||
|
Scene(const QRectF &rect);
|
||||||
|
~Scene();
|
||||||
|
void applyBrush(const QColor &color, float size);
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<> mousePresses() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
|
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
|
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
|
private:
|
||||||
|
void clearPath();
|
||||||
|
void addLineItem();
|
||||||
|
|
||||||
|
const not_null<ItemCanvas*> _canvas;
|
||||||
|
|
||||||
|
QPainterPath _path;
|
||||||
|
bool _drawing = false;
|
||||||
|
|
||||||
|
float64 _lastLineZ = 0.;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
float size = 1.;
|
||||||
|
QColor color;
|
||||||
|
} _brushData;
|
||||||
|
|
||||||
|
rpl::event_stream<> _mousePresses;
|
||||||
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Editor
|
49
Telegram/SourceFiles/editor/scene_item_canvas.cpp
Normal file
49
Telegram/SourceFiles/editor/scene_item_canvas.cpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
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/scene_item_canvas.h"
|
||||||
|
|
||||||
|
#include <QGraphicsScene>
|
||||||
|
|
||||||
|
namespace Editor {
|
||||||
|
|
||||||
|
ItemCanvas::ItemCanvas() {
|
||||||
|
setAcceptedMouseButtons(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF ItemCanvas::boundingRect() const {
|
||||||
|
return scene()->sceneRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemCanvas::paint(
|
||||||
|
QPainter *p,
|
||||||
|
const QStyleOptionGraphicsItem *,
|
||||||
|
QWidget *) {
|
||||||
|
_paintRequest.fire_copy(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ItemCanvas::type() const {
|
||||||
|
return Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<not_null<QPainter*>> ItemCanvas::paintRequest() const {
|
||||||
|
return _paintRequest.events();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ItemCanvas::collidesWithItem(
|
||||||
|
const QGraphicsItem *,
|
||||||
|
Qt::ItemSelectionMode) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ItemCanvas::collidesWithPath(
|
||||||
|
const QPainterPath &,
|
||||||
|
Qt::ItemSelectionMode) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Editor
|
41
Telegram/SourceFiles/editor/scene_item_canvas.h
Normal file
41
Telegram/SourceFiles/editor/scene_item_canvas.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
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 <QGraphicsItem>
|
||||||
|
|
||||||
|
namespace Editor {
|
||||||
|
|
||||||
|
class ItemCanvas : public QGraphicsItem {
|
||||||
|
public:
|
||||||
|
enum { Type = UserType + 6 };
|
||||||
|
|
||||||
|
ItemCanvas();
|
||||||
|
|
||||||
|
QRectF boundingRect() const override;
|
||||||
|
void paint(
|
||||||
|
QPainter *p,
|
||||||
|
const QStyleOptionGraphicsItem *option,
|
||||||
|
QWidget *widget) override;
|
||||||
|
int type() const override;
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<not_null<QPainter*>> paintRequest() const;
|
||||||
|
protected:
|
||||||
|
bool collidesWithItem(
|
||||||
|
const QGraphicsItem *,
|
||||||
|
Qt::ItemSelectionMode) const override;
|
||||||
|
|
||||||
|
bool collidesWithPath(
|
||||||
|
const QPainterPath &,
|
||||||
|
Qt::ItemSelectionMode) const override;
|
||||||
|
private:
|
||||||
|
rpl::event_stream<not_null<QPainter*>> _paintRequest;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Editor
|
62
Telegram/SourceFiles/editor/scene_item_line.cpp
Normal file
62
Telegram/SourceFiles/editor/scene_item_line.cpp
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
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/scene_item_line.h"
|
||||||
|
|
||||||
|
#include <QGraphicsScene>
|
||||||
|
|
||||||
|
namespace Editor {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
QPixmap PathToPixmap(
|
||||||
|
const QPainterPath &path,
|
||||||
|
const QSize &size,
|
||||||
|
const QColor &brushColor,
|
||||||
|
float brushSize) {
|
||||||
|
auto pixmap = QPixmap(size);
|
||||||
|
pixmap.setDevicePixelRatio(cRetinaFactor());
|
||||||
|
pixmap.fill(Qt::transparent);
|
||||||
|
Painter p(&pixmap);
|
||||||
|
p.setPen(QPen(brushColor, brushSize));
|
||||||
|
p.drawPath(path);
|
||||||
|
return pixmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
ItemLine::ItemLine(
|
||||||
|
const QPainterPath &path,
|
||||||
|
const QSize &size,
|
||||||
|
const QColor &brushColor,
|
||||||
|
float brushSize)
|
||||||
|
: _pixmap(PathToPixmap(path, size, brushColor, brushSize)) {
|
||||||
|
Expects(path.capacity() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF ItemLine::boundingRect() const {
|
||||||
|
return scene()->sceneRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemLine::paint(
|
||||||
|
QPainter *p,
|
||||||
|
const QStyleOptionGraphicsItem *,
|
||||||
|
QWidget *) {
|
||||||
|
p->drawPixmap(0, 0, _pixmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ItemLine::collidesWithItem(
|
||||||
|
const QGraphicsItem *,
|
||||||
|
Qt::ItemSelectionMode) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool ItemLine::collidesWithPath(
|
||||||
|
const QPainterPath &,
|
||||||
|
Qt::ItemSelectionMode) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Editor
|
41
Telegram/SourceFiles/editor/scene_item_line.h
Normal file
41
Telegram/SourceFiles/editor/scene_item_line.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
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 <QGraphicsItem>
|
||||||
|
|
||||||
|
namespace Editor {
|
||||||
|
|
||||||
|
class ItemLine : public QGraphicsItem {
|
||||||
|
public:
|
||||||
|
enum { Type = UserType + 5 };
|
||||||
|
|
||||||
|
ItemLine(
|
||||||
|
const QPainterPath &path,
|
||||||
|
const QSize &size,
|
||||||
|
const QColor &brushColor,
|
||||||
|
float brushSize);
|
||||||
|
QRectF boundingRect() const override;
|
||||||
|
void paint(
|
||||||
|
QPainter *p,
|
||||||
|
const QStyleOptionGraphicsItem *option,
|
||||||
|
QWidget *widget) override;
|
||||||
|
protected:
|
||||||
|
bool collidesWithItem(
|
||||||
|
const QGraphicsItem *,
|
||||||
|
Qt::ItemSelectionMode) const override;
|
||||||
|
bool collidesWithPath(
|
||||||
|
const QPainterPath &,
|
||||||
|
Qt::ItemSelectionMode) const override;
|
||||||
|
private:
|
||||||
|
const QRectF _rect;
|
||||||
|
const QPixmap _pixmap;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Editor
|
Loading…
Reference in a new issue