1 /* 2 Drawpile - a collaborative drawing program. 3 4 Copyright (C) 2015 Calle Laakkonen 5 6 Drawpile is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 Drawpile is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with Drawpile. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef CANVASINPUTAREA_H 21 #define CANVASINPUTAREA_H 22 23 #include "core/point.h" 24 #include "tabletstate.h" 25 #include "pressure.h" 26 27 #include <QQuickItem> 28 #include <QCursor> 29 30 /** 31 * @brief This item handles input (mouse, touch and tablet) for the canvas 32 */ 33 class CanvasInputArea : public QQuickItem 34 { 35 Q_PROPERTY(qreal contentX READ contentX WRITE setContentX NOTIFY contentXChanged) 36 Q_PROPERTY(qreal contentY READ contentY WRITE setContentY NOTIFY contentYChanged) 37 Q_PROPERTY(qreal contentZoom READ contentZoom WRITE setContentZoom NOTIFY contentZoomChanged) 38 Q_PROPERTY(qreal contentRotation READ contentRotation WRITE setContentRotation NOTIFY contentRotationChanged) 39 40 Q_PROPERTY(bool locked READ isLocked WRITE setLocked NOTIFY isLockedChanged) 41 Q_PROPERTY(QCursor toolCursor READ toolCursor WRITE setToolCursor NOTIFY toolCursorChanged) 42 Q_PROPERTY(PressureMapping pressureMapping READ pressureMapping WRITE setPressureMapping NOTIFY pressureMappingChanged) 43 44 Q_PROPERTY(QQuickItem* canvas READ canvas WRITE setCanvas NOTIFY canvasChanged) 45 Q_PROPERTY(TabletState* tablet READ tabletState WRITE setTabletState NOTIFY tabletStateChanged) 46 47 Q_OBJECT 48 49 public: 50 explicit CanvasInputArea(QQuickItem *parent=nullptr); 51 52 //! Map a point from scene coordinates to canvas coordinates 53 Q_INVOKABLE QPointF mapToCanvas(const QPointF &point) const; mapToCanvas(const QPointF & point,qreal pressure)54 Q_INVOKABLE inline paintcore::Point mapToCanvas(const QPointF &point, qreal pressure) const { return paintcore::Point(mapToCanvas(point), pressure); } 55 canvas()56 QQuickItem *canvas() const { return m_canvas; } setCanvas(QQuickItem * canvas)57 void setCanvas(QQuickItem *canvas) { m_canvas = canvas; emit canvasChanged(); } 58 tabletState()59 TabletState *tabletState() const { return m_tabletstate; } setTabletState(TabletState * st)60 void setTabletState(TabletState *st) { m_tabletstate = st; emit tabletStateChanged(); } 61 contentX()62 qreal contentX() const { return m_contentx; } setContentX(qreal x)63 void setContentX(qreal x) { m_contentx = x; emit contentXChanged(x); } 64 contentY()65 qreal contentY() const { return m_contenty; } setContentY(qreal y)66 void setContentY(qreal y) { m_contenty = y; emit contentYChanged(y); } 67 contentZoom()68 qreal contentZoom() const { return m_zoom; } 69 void setContentZoom(qreal zoom); 70 contentRotation()71 qreal contentRotation() const { return m_rotation; } setContentRotation(qreal rotation)72 void setContentRotation(qreal rotation) { m_rotation = rotation; emit contentRotationChanged(rotation); } 73 isLocked()74 bool isLocked() const { return m_locked; } 75 void setLocked(bool lock); 76 toolCursor()77 QCursor toolCursor() const { return m_toolcursor; } 78 void setToolCursor(const QCursor &cursor); 79 pressureMapping()80 PressureMapping pressureMapping() const { return m_pressuremapping; } setPressureMapping(const PressureMapping & pm)81 void setPressureMapping(const PressureMapping &pm) { m_pressuremapping = pm; emit pressureMappingChanged(); } 82 83 public slots: 84 void zoomSteps(int steps); 85 86 signals: 87 void canvasChanged(); 88 void tabletStateChanged(); 89 void contentXChanged(qreal); 90 void contentYChanged(qreal); 91 void contentZoomChanged(qreal); 92 void contentRotationChanged(qreal); 93 void contentWidthChanged(qreal); 94 void contentHeightChanged(qreal); 95 void isLockedChanged(bool); 96 void toolCursorChanged(); 97 void pressureMappingChanged(); 98 99 void penDown(const QPointF &point, qreal pressure); 100 void penMove(const QPointF &point, qreal pressure, bool shift, bool alt); 101 void penUp(); 102 void quickAdjust(qreal value); 103 104 void colorPickRequested(const QPointF &point); 105 106 protected: 107 void mouseMoveEvent(QMouseEvent *event); 108 void hoverMoveEvent(QHoverEvent *event); 109 void mousePressEvent(QMouseEvent *event); 110 void mouseReleaseEvent(QMouseEvent *event); 111 void hoverEnterEvent(QHoverEvent *event); 112 void wheelEvent(QWheelEvent *event); 113 void keyPressEvent(QKeyEvent *event); 114 void keyReleaseEvent(QKeyEvent *event); 115 bool event(QEvent *event); 116 117 private: 118 void nativeGestureEvent(QNativeGestureEvent *event); 119 120 void resetCursor(); 121 122 // Dragging modes 123 enum ViewTransform {DRAG_NOTRANSFORM, DRAG_TRANSLATE, DRAG_ROTATE, DRAG_ZOOM, DRAG_QUICKADJUST1}; 124 125 // unified mouse/stylus event handlers 126 void penPressEvent(const QPointF &pos, float pressure, Qt::MouseButton button, Qt::KeyboardModifiers modifiers, bool isStylus); 127 void penMoveEvent(const QPointF &pos, float pressure, Qt::KeyboardModifiers modifiers, bool isStylus); 128 void penReleaseEvent(const QPointF &pos, Qt::MouseButton button); 129 130 qreal mapPressure(qreal pressure, bool stylus); 131 132 // View drag handlers 133 void startDrag(const QPointF &pos, ViewTransform mode); 134 void moveDrag(const QPointF &pos); 135 void stopDrag(); 136 137 QQuickItem *m_canvas; 138 TabletState *m_tabletstate; 139 140 // View settings 141 bool m_enableTouchScroll, m_enableTouchPinch, m_enableTouchRotate; 142 PressureMapping m_pressuremapping; 143 144 // Cursors 145 const QCursor m_colorPickerCursor; 146 const QCursor m_crosshairCursor; 147 148 // View state 149 bool m_locked; 150 QCursor m_toolcursor; 151 152 // View transformation state 153 qreal m_contentx; 154 qreal m_contenty; 155 qreal m_rotation; 156 qreal m_zoom; 157 158 // Input device state 159 bool m_specialpenmode; 160 161 ViewTransform m_isdragging; 162 ViewTransform m_dragbtndown; 163 qreal m_dragx, m_dragy; 164 165 QPointF m_prevpoint; 166 paintcore::Point m_prevoutlinepoint; 167 qreal m_pointerdistance; 168 qreal m_pointervelocity; 169 170 bool m_prevshift; 171 bool m_prevalt; 172 173 int m_zoomWheelDelta; 174 175 bool m_pendown; 176 bool m_touching; 177 178 }; 179 180 #endif // CANVASINPUTAREA_H 181