1 /* 2 This file is part of Telegram Desktop, 3 the official desktop application for the Telegram messaging service. 4 5 For license and copyright information please follow this link: 6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL 7 */ 8 #pragma once 9 10 #include "base/unique_qptr.h" 11 #include "editor/photo_editor_inner_common.h" 12 13 #include <QGraphicsItem> 14 15 class QGraphicsSceneHoverEvent; 16 class QGraphicsSceneMouseEvent; 17 class QStyleOptionGraphicsItem; 18 19 namespace Ui { 20 class PopupMenu; 21 } // namespace Ui 22 23 namespace Editor { 24 25 class NumberedItem : public QGraphicsItem { 26 public: 27 enum class Status { 28 Normal, 29 Undid, 30 Removed, 31 }; 32 33 enum { Type = UserType + 1 }; 34 using QGraphicsItem::QGraphicsItem; 35 36 int type() const override; 37 void setNumber(int number); 38 [[nodiscard]] int number() const; 39 40 [[nodiscard]] Status status() const; 41 void setStatus(Status status); 42 [[nodiscard]] bool isNormalStatus() const; 43 [[nodiscard]] bool isUndidStatus() const; 44 [[nodiscard]] bool isRemovedStatus() const; 45 46 virtual void save(SaveState state); 47 virtual void restore(SaveState state); 48 virtual bool hasState(SaveState state) const; 49 private: 50 int _number = 0; 51 Status _status = Status::Normal; 52 }; 53 54 class ItemBase : public NumberedItem { 55 public: 56 enum { Type = UserType + 2 }; 57 58 struct Data { 59 float64 initialZoom = 0.; 60 std::shared_ptr<float64> zPtr; 61 int size = 0; 62 int x = 0; 63 int y = 0; 64 bool flipped = false; 65 int rotation = 0; 66 QSize imageSize; 67 }; 68 69 ItemBase(Data data); 70 QRectF boundingRect() const override; 71 void paint( 72 QPainter *p, 73 const QStyleOptionGraphicsItem *option, 74 QWidget *widget) override; 75 int type() const override; 76 77 bool flipped() const; 78 void setFlip(bool value); 79 80 void updateZoom(float64 zoom); 81 82 bool hasState(SaveState state) const override; 83 void save(SaveState state) override; 84 void restore(SaveState state) override; 85 protected: 86 enum HandleType { 87 None, 88 Left, 89 Right, 90 }; 91 void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; 92 void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override; 93 void mousePressEvent(QGraphicsSceneMouseEvent *event) override; 94 void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; 95 void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; 96 void keyPressEvent(QKeyEvent *e) override; 97 98 using Action = void(ItemBase::*)(); 99 void performForSelectedItems(Action action); 100 void actionFlip(); 101 void actionDelete(); 102 void actionDuplicate(); 103 104 QRectF contentRect() const; 105 QRectF innerRect() const; 106 float64 size() const; 107 float64 horizontalSize() const; 108 float64 verticalSize() const; 109 void setAspectRatio(float64 aspectRatio); 110 111 virtual void performFlip(); 112 virtual std::shared_ptr<ItemBase> duplicate(Data data) const = 0; 113 private: 114 HandleType handleType(const QPointF &pos) const; 115 QRectF rightHandleRect() const; 116 QRectF leftHandleRect() const; 117 bool isHandling() const; 118 void updateVerticalSize(); 119 void updatePens(QPen pen); 120 void handleActionKey(not_null<QKeyEvent*> e); 121 122 Data generateData() const; 123 void applyData(const Data &data); 124 125 const std::shared_ptr<float64> _lastZ; 126 const QSize _imageSize; 127 128 struct { 129 QPen select; 130 QPen selectInactive; 131 QPen handle; 132 QPen handleInactive; 133 } _pens; 134 135 base::unique_qptr<Ui::PopupMenu> _menu; 136 137 struct { 138 Data data; 139 float64 zValue = 0.; 140 NumberedItem::Status status; 141 } _saved, _keeped; 142 143 struct { 144 int min = 0; 145 int max = 0; 146 } _sizeLimits; 147 float64 _scaledHandleSize = 1.0; 148 QMarginsF _scaledInnerMargins; 149 150 float64 _horizontalSize = 0; 151 float64 _verticalSize = 0; 152 float64 _aspectRatio = 1.0; 153 HandleType _handle = HandleType::None; 154 155 bool _flipped = false; 156 157 }; 158 159 } // namespace Editor 160