fractorium/Source/Fractorium/GLEmberController.h

163 lines
5.2 KiB
C
Raw Permalink Normal View History

#pragma once
#include "FractoriumPch.h"
/// <summary>
/// GLEmberControllerBase and GLEmberController<T> classes.
/// </summary>
/// <summary>
/// Use/draw pre or post affine transform.
/// </summary>
enum class eAffineType : et { AffinePre, AffinePost };
/// <summary>
/// Hovering over nothing, the x axis, the y axis or the center.
/// </summary>
enum class eHoverType : et { HoverNone, HoverXAxis, HoverYAxis, HoverTranslation };
/// <summary>
/// Dragging an affine transform or panning, rotating or scaling the image.
/// </summary>
enum class eDragState : et { DragNone, DragSelect, DragPanning, DragDragging, DragRotateScale, DragPitchYaw };
/// <summary>
/// Dragging with no keys pressed, shift, control or alt.
/// </summary>
enum class eDragModifier : et { DragModNone = 0x00, DragModShift = 0x01, DragModControl = 0x02, DragModAlt = 0x04 };
/// <summary>
/// GLController, FractoriumEmberController, GLWidget and Fractorium need each other, but each can't all include the other.
/// So GLWidget includes this file, and GLWidget, FractoriumEmberController and Fractorium are declared as forward declarations here.
/// </summary>
class GLWidget;
class Fractorium;
template <typename T> class FractoriumEmberController;
#define USE_GLSL 1
/// <summary>
/// GLEmberControllerBase serves as a non-templated base class with virtual
/// functions which will be overridden in a derived class that takes a template parameter.
/// The controller serves as a way to access both the GLWidget and the underlying ember
/// objects through an interface that doesn't require template argument, but does allow
/// templated objects to be used underneath.
/// The functions not implemented in this file can be found in GLWidget.cpp near the area of code which uses them.
/// </summary>
class GLEmberControllerBase
{
public:
GLEmberControllerBase(Fractorium* fractorium, GLWidget* glWidget);
virtual ~GLEmberControllerBase();
void ClearDrag();
bool Allocate(bool force = false);
bool GetAlt();
bool GetShift();
bool GetControl();
void SetAlt();
void SetShift();
void SetControl();
void ClearAlt();
void ClearShift();
void ClearControl();
eDragState DragState() { return m_DragState; }
eAffineType AffineType() { return m_AffineType; }
virtual void DrawImage() { }
virtual void DrawAffines(bool pre, bool post) { }
virtual void ClearWindow() { }
virtual bool KeyPress_(QKeyEvent* e);
virtual bool KeyRelease_(QKeyEvent* e);
virtual void MousePress(QMouseEvent* e) { }
virtual void MouseRelease(QMouseEvent* e) { }
virtual void MouseMove(QMouseEvent* e) { }
virtual void Wheel(QWheelEvent* e) { }
virtual bool SizesMatch() { return false; }
virtual bool CheckForSizeMismatch(int w, int h) { return true; }
virtual void QueryMatrices(bool print) { }
virtual void ResetMouseState() { }
protected:
uint m_DragModifier;
glm::ivec2 m_MousePos;
glm::ivec2 m_MouseDownPos;
glm::ivec4 m_Viewport;
eDragState m_DragState;
eHoverType m_HoverType;
eAffineType m_AffineType;
GLWidget* m_GL;
Fractorium* m_Fractorium;
};
/// <summary>
/// Templated derived class which implements all interaction functionality between the embers
/// of a specific template type and the GLWidget;
/// </summary>
template<typename T>
class GLEmberController : public GLEmberControllerBase
{
public:
GLEmberController(Fractorium* fractorium, GLWidget* glWidget, FractoriumEmberController<T>* controller);
virtual ~GLEmberController();
void DrawImage() override;
void DrawAffines(bool pre, bool post) override;
void ClearWindow() override;
void MousePress(QMouseEvent* e) override;
void MouseRelease(QMouseEvent* e) override;
void MouseMove(QMouseEvent* e) override;
void Wheel(QWheelEvent* e) override;
void QueryMatrices(bool print) override;
bool SizesMatch() override;
bool CheckForSizeMismatch(int w, int h) override;
void ResetMouseState() override;
T CalcScale();
T CalcRotation();
v3T ScrolledCenter(bool toWorld = false);
void CalcDragXAxis();
void CalcDragYAxis();
void CalcDragTranslation();
void SetSelectedXform(Xform<T>* xform);
void DrawGrid();
void DrawAffine(const Xform<T>* xform, bool pre, bool selected, bool hovered);
int UpdateHover(const v3T& glCoords);
bool CheckXformHover(const Xform<T>* xform, const v3T& glCoords, T& bestDist, bool pre, bool post);
private:
v2T SnapToGrid(const v2T& vec) const;
v3T SnapToGrid(const v3T& vec) const;
v3T SnapToNormalizedAngle(const v3T& vec, uint divisions) const;
v3T WindowToWorld(const v3T& v, bool flip) const;
void QueryVMP();
#ifndef USE_GLSL
void MultMatrix(m4T& mat);
#endif
T m_CenterDownX;
T m_CenterDownY;
T m_RotationDown;
T m_ScaleDown;
T m_PitchDown;
T m_YawDown;
v4T m_BoundsDown;
v3T m_MouseWorldPos;
v3T m_MouseDownWorldPos;
v3T m_DragHandlePos;
v3T m_HoverHandlePos;
m4T m_Modelview;
m4T m_Projection;
Affine2D<T> m_DragSrcTransform;
std::map<size_t, Affine2D<T>> m_DragSrcPreTransforms;
std::map<size_t, Affine2D<T>> m_DragSrcPostTransforms;
Xform<T>* m_HoverXform;
Xform<T>* m_SelectedXform;
FractoriumEmberController<T>* m_FractoriumEmberController;
T GridStep;
vector<float> m_Verts;//Can't make this T because GLSL only works with floats.
};