mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 14:17:12 +02:00
Added scene base item for photo editor.
This commit is contained in:
parent
183408cb2d
commit
812d616f66
4 changed files with 241 additions and 0 deletions
|
@ -522,6 +522,8 @@ PRIVATE
|
|||
editor/photo_editor_controls.h
|
||||
editor/photo_editor_layer_widget.cpp
|
||||
editor/photo_editor_layer_widget.h
|
||||
editor/scene_item_base.cpp
|
||||
editor/scene_item_base.h
|
||||
editor/undo_controller.cpp
|
||||
editor/undo_controller.h
|
||||
export/export_manager.cpp
|
||||
|
|
|
@ -56,3 +56,7 @@ photoEditorColorPickerCircleSkip: 50px;
|
|||
|
||||
photoEditorCropPointSize: 10px;
|
||||
photoEditorCropMinSize: 20px;
|
||||
|
||||
photoEditorItemHandleSize: 10px;
|
||||
photoEditorItemMinSize: 16px;
|
||||
photoEditorItemMaxSize: 512px;
|
||||
|
|
174
Telegram/SourceFiles/editor/scene_item_base.cpp
Normal file
174
Telegram/SourceFiles/editor/scene_item_base.cpp
Normal file
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
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_base.h"
|
||||
|
||||
#include "styles/style_editor.h"
|
||||
|
||||
#include <QGraphicsSceneHoverEvent>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QStyleOptionGraphicsItem>
|
||||
|
||||
namespace Editor {
|
||||
namespace {
|
||||
|
||||
auto Normalized(float64 angle) {
|
||||
return angle
|
||||
+ ((std::abs(angle) < 360) ? 0 : (-360 * (angle < 0 ? -1 : 1)));
|
||||
}
|
||||
|
||||
QPen PenStyled(QPen pen, Qt::PenStyle style) {
|
||||
pen.setStyle(style);
|
||||
return pen;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ItemBase::ItemBase(std::shared_ptr<float64> zPtr, int size, int x, int y)
|
||||
: _lastZ(zPtr)
|
||||
, _handleSize(st::photoEditorItemHandleSize)
|
||||
, _innerMargins(
|
||||
_handleSize / 2,
|
||||
_handleSize / 2,
|
||||
_handleSize / 2,
|
||||
_handleSize / 2)
|
||||
, _selectPen(QBrush(Qt::white), 1, Qt::DashLine, Qt::SquareCap, Qt::RoundJoin)
|
||||
, _selectPenInactive(
|
||||
QBrush(Qt::gray),
|
||||
1,
|
||||
Qt::DashLine,
|
||||
Qt::SquareCap,
|
||||
Qt::RoundJoin)
|
||||
, _size(size) {
|
||||
setFlags(QGraphicsItem::ItemIsMovable
|
||||
| QGraphicsItem::ItemIsSelectable
|
||||
| QGraphicsItem::ItemIsFocusable);
|
||||
setAcceptHoverEvents(true);
|
||||
setPos(x, y);
|
||||
}
|
||||
|
||||
QRectF ItemBase::boundingRect() const {
|
||||
return innerRect() + _innerMargins;
|
||||
}
|
||||
|
||||
QRectF ItemBase::innerRect() const {
|
||||
return QRectF(-_size / 2, -_size / 2, _size, _size);
|
||||
}
|
||||
|
||||
void ItemBase::paint(
|
||||
QPainter *p,
|
||||
const QStyleOptionGraphicsItem *option,
|
||||
QWidget *) {
|
||||
if (!(option->state & QStyle::State_Selected)) {
|
||||
return;
|
||||
}
|
||||
PainterHighQualityEnabler hq(*p);
|
||||
const auto &pen = (option->state & QStyle::State_HasFocus)
|
||||
? _selectPen
|
||||
: _selectPenInactive;
|
||||
p->setPen(pen);
|
||||
p->drawRect(innerRect());
|
||||
|
||||
p->setPen(PenStyled(pen, Qt::SolidLine));
|
||||
p->setBrush(st::photoEditorItemBaseHandleFg);
|
||||
p->drawEllipse(rightHandleRect());
|
||||
p->drawEllipse(leftHandleRect());
|
||||
}
|
||||
|
||||
void ItemBase::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
|
||||
if (isHandling()) {
|
||||
const auto mousePos = event->pos();
|
||||
const auto isLeft = (_handle == HandleType::Left);
|
||||
// Resize.
|
||||
const auto p = isLeft ? (mousePos * -1) : mousePos;
|
||||
const auto dx = int(2.0 * p.x());
|
||||
const auto dy = int(2.0 * p.y());
|
||||
prepareGeometryChange();
|
||||
_size = std::clamp(
|
||||
(dx > dy ? dx : dy),
|
||||
st::photoEditorItemMinSize,
|
||||
st::photoEditorItemMaxSize);
|
||||
|
||||
// Rotate.
|
||||
const auto origin = mapToScene(boundingRect().center());
|
||||
const auto pos = mapToScene(mousePos);
|
||||
|
||||
const auto diff = pos - origin;
|
||||
const auto angle = Normalized((isLeft ? 180 : 0)
|
||||
+ (std::atan2(diff.y(), diff.x()) * 180 / M_PI));
|
||||
setRotation(angle);
|
||||
} else {
|
||||
QGraphicsItem::mouseMoveEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void ItemBase::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
|
||||
setCursor(isHandling()
|
||||
? Qt::ClosedHandCursor
|
||||
: (handleType(event->pos()) != HandleType::None) && isSelected()
|
||||
? Qt::OpenHandCursor
|
||||
: Qt::ArrowCursor);
|
||||
QGraphicsItem::hoverMoveEvent(event);
|
||||
}
|
||||
|
||||
void ItemBase::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
||||
setZValue((*_lastZ)++);
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
_handle = handleType(event->pos());
|
||||
if (isHandling()) {
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
}
|
||||
} else {
|
||||
QGraphicsItem::mousePressEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void ItemBase::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
|
||||
if ((event->button() == Qt::LeftButton) && isHandling()) {
|
||||
_handle = HandleType::None;
|
||||
} else {
|
||||
QGraphicsItem::mouseReleaseEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
int ItemBase::type() const {
|
||||
return Type;
|
||||
}
|
||||
|
||||
QRectF ItemBase::rightHandleRect() const {
|
||||
return QRectF(
|
||||
(_size / 2) - (_handleSize / 2),
|
||||
0 - (_handleSize / 2),
|
||||
_handleSize,
|
||||
_handleSize);
|
||||
}
|
||||
|
||||
QRectF ItemBase::leftHandleRect() const {
|
||||
return QRectF(
|
||||
(-_size / 2) - (_handleSize / 2),
|
||||
0 - (_handleSize / 2),
|
||||
_handleSize,
|
||||
_handleSize);
|
||||
}
|
||||
|
||||
bool ItemBase::isHandling() const {
|
||||
return _handle != HandleType::None;
|
||||
}
|
||||
|
||||
int ItemBase::size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
ItemBase::HandleType ItemBase::handleType(const QPointF &pos) const {
|
||||
return rightHandleRect().contains(pos)
|
||||
? HandleType::Right
|
||||
: leftHandleRect().contains(pos)
|
||||
? HandleType::Left
|
||||
: HandleType::None;
|
||||
}
|
||||
|
||||
} // namespace Editor
|
61
Telegram/SourceFiles/editor/scene_item_base.h
Normal file
61
Telegram/SourceFiles/editor/scene_item_base.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
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>
|
||||
|
||||
class QGraphicsSceneHoverEvent;
|
||||
class QGraphicsSceneMouseEvent;
|
||||
class QStyleOptionGraphicsItem;
|
||||
|
||||
namespace Editor {
|
||||
|
||||
class ItemBase : public QGraphicsItem {
|
||||
public:
|
||||
enum { Type = UserType + 1 };
|
||||
|
||||
ItemBase(std::shared_ptr<float64> zPtr, int size, int x, int y);
|
||||
QRectF boundingRect() const override;
|
||||
void paint(
|
||||
QPainter *p,
|
||||
const QStyleOptionGraphicsItem *option,
|
||||
QWidget *widget) override;
|
||||
protected:
|
||||
enum HandleType {
|
||||
None,
|
||||
Left,
|
||||
Right,
|
||||
};
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
int type() const override;
|
||||
QRectF innerRect() const;
|
||||
int size() const;
|
||||
|
||||
private:
|
||||
HandleType handleType(const QPointF &pos) const;
|
||||
QRectF rightHandleRect() const;
|
||||
QRectF leftHandleRect() const;
|
||||
bool isHandling() const;
|
||||
|
||||
const std::shared_ptr<float64> _lastZ;
|
||||
const int _handleSize;
|
||||
const QMargins _innerMargins;
|
||||
const QPen _selectPen;
|
||||
const QPen _selectPenInactive;
|
||||
const QPen _handlePen;
|
||||
|
||||
int _size;
|
||||
HandleType _handle = HandleType::None;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Editor
|
Loading…
Add table
Reference in a new issue