#pragma once
#ifndef PLANE_VIEWER_H
#define PLANE_VIEWER_H
// TnzCore includes
#include "tcommon.h"
#include "traster.h"
#include "timage.h"
// TnzQt includes
#include "toonzqt/glwidget_for_highdpi.h"
// Qt includes
#include <QOpenGLWidget>
#include <QTouchDevice>
#undef DVAPI
#undef DVVAR
#ifdef TOONZQT_EXPORTS
#define DVAPI DV_EXPORT_API
#define DVVAR DV_EXPORT_VAR
#else
#define DVAPI DV_IMPORT_API
#define DVVAR DV_IMPORT_VAR
#endif
//----------------------------------------------------------------------------
// Forward declarations
class TRasterImageP;
class TToonzImageP;
class TVectorImageP;
class QTouchEvent;
class QGestureEvent;
//----------------------------------------------------------------------------
/*!
\brief The PlaneViewer class implements a basic OpenGL widget showing a
plane in a
standard top-down view, and supports image drawing from the Toonz
images API.
\details A PlaneViewer instance is designed to view bidimensional objects
layed-out
on a plane, providing standard mouse interaction functions and some
built-in
keyboard shortcuts to provide view navigation.
The class implements the necessary methods to draw objects on the
plane -
prominently, functions to push both world and widget references for
standard
OpenGL drawing, conversions between world and widget coordinates,
and
efficient image-drawing functions for all Toonz image types.
*/
/*
CAUTION : Changing PlaneViewer to inherit QOpenGLWidget causes crash bug with
shader fx for some unknown reasons. So I will reluctantly keep using the
obsolete class until the shader fx being overhauled. 2016/6/22 Shun
*/
class DVAPI PlaneViewer : public GLWidgetForHighDpi {
Q_OBJECT
bool m_touchActive = false;
bool m_gestureActive = false;
QTouchDevice::DeviceType m_touchDevice = QTouchDevice::TouchScreen;
bool m_zooming = false;
bool m_panning = false;
double m_scaleFactor; // used for zoom gesture
bool m_stylusUsed = false;
bool m_firstDraw;
public:
PlaneViewer(QWidget *parent);
// Background functions
void setBgColor(const TPixel32 &color1, const TPixel32 &color2);
void getBgColor(TPixel32 &color1, TPixel32 &color2) const;
void setChessSize(double size);
void drawBackground();
// Image drawing functions
void draw(TRasterP ras, double dpiX, double dpiY, TPalette *palette = 0);
void draw(TRasterImageP ri);
void draw(TToonzImageP ti);
void draw(TVectorImageP vi);
void draw(TImageP img);
// World-Widget conversion functions
TPointD winToWorld(int x, int y) { return m_aff.inv() * TPointD(x, y); }
TPointD worldToWin(double x, double y) { return m_aff * TPointD(x, y); }
TPoint qtWinToWin(int x, int y) { return TPoint(x, height() - y); }
TPointD qtWinToWorld(int x, int y) {
return m_aff.inv() * TPointD(x, height() - y);
}
TPoint winToQtWin(int x, int y) { return qtWinToWin(x, y); }
TPointD worldToQtWin(double x, double y) {
TPointD res(worldToWin(x, y));
return TPointD(res.x, height() - res.y);
}
// World-Widget OpenGL references
void pushGLWorldCoordinates();
void pushGLWinCoordinates();
void popGLCoordinates();
// View functions
TAffine &viewAff() { return m_aff; }
const TAffine &viewAff() const { return m_aff; }
void zoomIn();
void zoomOut();
void setViewPos(double x, double y);
void setViewZoom(double x, double y, double zoom);
void setViewZoom(double zoom) {
setViewZoom(0.5 * width(), 0.5 * height(), zoom);
}
void moveView(double dx, double dy) {
setViewPos(m_aff.a13 + dx, m_aff.a23 + dy);
}
void zoomView(double x, double y, double delta) {
setViewZoom(x, y, m_aff.a11 * delta);
}
void setZoomRange(double zoomMin, double zoomMax);
// Auxiliary functions
TRaster32P rasterBuffer();
void flushRasterBuffer();
public slots:
void resetView();
void fitView();
protected:
int m_xpos, m_ypos; //!< Mouse position on mouse operations.
TAffine m_aff; //!< Affine transform from world to widget coords.
float m_bgColorF[6]; //!< Widget bg color cast in the [0, 1] interval.
double m_chessSize; //!< Size of the chessboard squares (default is 40).
TRaster32P m_rasterBuffer; //!< Auxiliary buffer used to draw on the widget
//! directly.
double m_zoomRange[2]; //!< Viewport zoom range (default: [-1024, 1024]).
TRect m_imageBounds;
double m_dpiX, m_dpiY;
protected:
virtual void contextMenuEvent(QContextMenuEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
virtual void wheelEvent(QWheelEvent *event) override;
virtual void keyPressEvent(QKeyEvent *event) override;
virtual void hideEvent(QHideEvent *event) override;
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
virtual void tabletEvent(QTabletEvent *e) override;
void touchEvent(QTouchEvent *e, int type);
void gestureEvent(QGestureEvent *e);
virtual bool event(QEvent *e) override;
void initializeGL() override final;
void resizeGL(int width, int height) override final;
private:
GLdouble m_matrix[16];
bool m_firstResize;
int m_width;
int m_height;
QPointF m_firstPanPoint;
};
#endif // PLANE_VIEWER_H