1 #pragma once
2 
3 #ifndef PLANE_VIEWER_H
4 #define PLANE_VIEWER_H
5 
6 // TnzCore includes
7 #include "tcommon.h"
8 #include "traster.h"
9 #include "timage.h"
10 
11 // TnzQt includes
12 #include "toonzqt/glwidget_for_highdpi.h"
13 
14 // Qt includes
15 #include <QOpenGLWidget>
16 #include <QTouchDevice>
17 
18 #undef DVAPI
19 #undef DVVAR
20 #ifdef TOONZQT_EXPORTS
21 #define DVAPI DV_EXPORT_API
22 #define DVVAR DV_EXPORT_VAR
23 #else
24 #define DVAPI DV_IMPORT_API
25 #define DVVAR DV_IMPORT_VAR
26 #endif
27 
28 //----------------------------------------------------------------------------
29 
30 //  Forward declarations
31 class TRasterImageP;
32 class TToonzImageP;
33 class TVectorImageP;
34 class QTouchEvent;
35 class QGestureEvent;
36 
37 //----------------------------------------------------------------------------
38 
39 /*!
40   \brief    The PlaneViewer class implements a basic OpenGL widget showing a
41   plane in a
42             standard top-down view, and supports image drawing from the Toonz
43   images API.
44 
45   \details  A PlaneViewer instance is designed to view bidimensional objects
46   layed-out
47             on a plane, providing standard mouse interaction functions and some
48   built-in
49             keyboard shortcuts to provide view navigation.
50 
51             The class implements the necessary methods to draw objects on the
52   plane -
53             prominently, functions to push both world and widget references for
54   standard
55             OpenGL drawing, conversions between world and widget coordinates,
56   and
57             efficient image-drawing functions for all Toonz image types.
58 */
59 
60 /*
61 CAUTION : Changing PlaneViewer to inherit QOpenGLWidget causes crash bug with
62 shader fx for some unknown reasons. So I will reluctantly keep using the
63 obsolete class until the shader fx being overhauled. 2016/6/22 Shun
64 */
65 
66 class DVAPI PlaneViewer : public GLWidgetForHighDpi {
67   Q_OBJECT
68   bool m_touchActive                     = false;
69   bool m_gestureActive                   = false;
70   QTouchDevice::DeviceType m_touchDevice = QTouchDevice::TouchScreen;
71   bool m_zooming                         = false;
72   bool m_panning                         = false;
73   double m_scaleFactor;  // used for zoom gesture
74 
75   bool m_stylusUsed = false;
76 
77   bool m_firstDraw;
78 
79 public:
80   PlaneViewer(QWidget *parent);
81 
82   // Background functions
83   void setBgColor(const TPixel32 &color1, const TPixel32 &color2);
84   void getBgColor(TPixel32 &color1, TPixel32 &color2) const;
85   void setChessSize(double size);
86   void drawBackground();
87 
88   // Image drawing functions
89   void draw(TRasterP ras, double dpiX, double dpiY, TPalette *palette = 0);
90   void draw(TRasterImageP ri);
91   void draw(TToonzImageP ti);
92   void draw(TVectorImageP vi);
93   void draw(TImageP img);
94 
95   // World-Widget conversion functions
winToWorld(int x,int y)96   TPointD winToWorld(int x, int y) { return m_aff.inv() * TPointD(x, y); }
worldToWin(double x,double y)97   TPointD worldToWin(double x, double y) { return m_aff * TPointD(x, y); }
qtWinToWin(int x,int y)98   TPoint qtWinToWin(int x, int y) { return TPoint(x, height() - y); }
qtWinToWorld(int x,int y)99   TPointD qtWinToWorld(int x, int y) {
100     return m_aff.inv() * TPointD(x, height() - y);
101   }
winToQtWin(int x,int y)102   TPoint winToQtWin(int x, int y) { return qtWinToWin(x, y); }
worldToQtWin(double x,double y)103   TPointD worldToQtWin(double x, double y) {
104     TPointD res(worldToWin(x, y));
105     return TPointD(res.x, height() - res.y);
106   }
107 
108   // World-Widget OpenGL references
109   void pushGLWorldCoordinates();
110   void pushGLWinCoordinates();
111   void popGLCoordinates();
112 
113   // View functions
viewAff()114   TAffine &viewAff() { return m_aff; }
viewAff()115   const TAffine &viewAff() const { return m_aff; }
116 
117   void zoomIn();
118   void zoomOut();
119 
120   void setViewPos(double x, double y);
121   void setViewZoom(double x, double y, double zoom);
setViewZoom(double zoom)122   void setViewZoom(double zoom) {
123     setViewZoom(0.5 * width(), 0.5 * height(), zoom);
124   }
125 
moveView(double dx,double dy)126   void moveView(double dx, double dy) {
127     setViewPos(m_aff.a13 + dx, m_aff.a23 + dy);
128   }
zoomView(double x,double y,double delta)129   void zoomView(double x, double y, double delta) {
130     setViewZoom(x, y, m_aff.a11 * delta);
131   }
132 
133   void setZoomRange(double zoomMin, double zoomMax);
134 
135   // Auxiliary functions
136   TRaster32P rasterBuffer();
137   void flushRasterBuffer();
138 
139 public slots:
140 
141   void resetView();
142   void fitView();
143 
144 protected:
145   int m_xpos, m_ypos;  //!< Mouse position on mouse operations.
146   TAffine m_aff;       //!< Affine transform from world to widget coords.
147 
148   float m_bgColorF[6];  //!< Widget bg color cast in the [0, 1] interval.
149   double m_chessSize;   //!< Size of the chessboard squares (default is 40).
150 
151   TRaster32P m_rasterBuffer;  //!< Auxiliary buffer used to draw on the widget
152                               //! directly.
153 
154   double m_zoomRange[2];  //!< Viewport zoom range (default: [-1024, 1024]).
155 
156   TRect m_imageBounds;
157 
158   double m_dpiX, m_dpiY;
159 
160 protected:
161   virtual void contextMenuEvent(QContextMenuEvent *event) override;
162   virtual void mouseMoveEvent(QMouseEvent *event) override;
163   virtual void mousePressEvent(QMouseEvent *event) override;
164   virtual void mouseReleaseEvent(QMouseEvent *event) override;
165   virtual void wheelEvent(QWheelEvent *event) override;
166   virtual void keyPressEvent(QKeyEvent *event) override;
167   virtual void hideEvent(QHideEvent *event) override;
168 
169   virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
170   virtual void tabletEvent(QTabletEvent *e) override;
171   void touchEvent(QTouchEvent *e, int type);
172   void gestureEvent(QGestureEvent *e);
173   virtual bool event(QEvent *e) override;
174 
175   void initializeGL() override final;
176   void resizeGL(int width, int height) override final;
177 
178 private:
179   GLdouble m_matrix[16];
180   bool m_firstResize;
181   int m_width;
182   int m_height;
183   QPointF m_firstPanPoint;
184 };
185 
186 #endif  // PLANE_VIEWER_H
187