Files
panopainter/src/canvas_modes.h
2019-11-21 10:22:48 +01:00

260 lines
7.7 KiB
C++

#pragma once
#include "event.h"
#include "shape.h"
#include "brush.h"
#include "texture.h"
#include "action.h"
#include <poly2tri.h>
#include "node_tool_bucket.h"
enum class kCanvasMode
{
Draw,
Erase,
Line,
Camera,
Grid,
Import,
Cut,
Copy,
Fill,
MaskFree,
MaskLine,
FloodFill,
COUNT,
};
struct CameraData
{
glm::mat4 m_mv{ 1 };
glm::mat4 m_proj{ 1 };
glm::vec4 m_box{ 0 };
glm::vec4 m_vp{ 0 };
glm::vec2 m_pan{ 0 };
glm::mat4 m_plane_unproject[6] = SIXPLETTE(glm::mat4(1));
glm::vec3 m_plane_dir[6] = SIXPLETTE(glm::vec3(0));
};
class CanvasMode
{
public:
static class NodeCanvas* node;
bool hide_curor = false;
bool m_draw_tip = false;
//static Canvas* canvas;
virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) {}
virtual void on_KeyEvent(KeyEvent* ke) {}
virtual void on_GestureEvent(GestureEvent* ge) {}
virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) {}
virtual void init() {}
virtual void enter(kCanvasMode prev) {}
virtual void leave(kCanvasMode next) {}
CanvasMode() = default;
virtual ~CanvasMode() = default;
};
class CanvasModeBasicCamera : public CanvasMode
{
bool m_draggingR = false;
bool m_draggingL = false;
bool m_draggingT = false; // touch drag
bool m_zooming = false;
glm::vec2 m_dragR_start;
glm::vec2 m_dragL_start;
glm::vec2 m_pan_start;
float m_fov_start;
float m_camera_fov;
float m_zoom_canvas = 1.f;
float m_zoom_start;
public:
virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;
virtual void on_GestureEvent(GestureEvent* ge) override;
};
class CanvasModePen : public CanvasMode
{
friend class App;
bool m_dragging = false;
glm::vec2 m_pan_start;
glm::vec2 m_size_pos_start;
float m_size_value_start;
float m_camera_fov;
float m_zoom_canvas = 1.f;
float m_zoom_start;
// resizing the tip
public:
CanvasModePen() { hide_curor = true; m_picking = false; }
virtual void on_GestureEvent(GestureEvent* ge) override;
virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;
virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override;
virtual void enter(kCanvasMode prev) override;
virtual void leave(kCanvasMode next) override;
bool m_resizing = false;
bool m_picking = false;
bool m_drawing = false;
glm::vec2 m_cur_pos;
bool m_draw_outline = true;
};
class CanvasModeLine : public CanvasMode
{
LineSegment m_line;
bool m_dragging = false;
glm::vec2 m_drag_start;
glm::vec2 m_drag_pos;
public:
glm::vec2 m_cur_pos;
virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;
virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override;
virtual void init() override;
virtual void enter(kCanvasMode prev) override;
virtual void leave(kCanvasMode next) override;
};
class CanvasModeFloodFill : public CanvasMode
{
const std::string m_cursor_path = "data/cursor/bucket-fill.png";
const uint16_t m_cursor_id = const_hash(m_cursor_path.c_str());
glm::vec2 m_cur_pos;
NodeToolBucket* m_tool;
public:
CanvasModeFloodFill() { hide_curor = true; }
virtual void init() override;
virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;
virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override;
virtual void enter(kCanvasMode prev) override;
virtual void leave(kCanvasMode next) override;
};
struct ray_t { glm::vec3 o, d; };
class CanvasModeGrid : public CanvasMode
{
LineSegment m_line;
glm::vec3 origin;
glm::vec3 dir;
int m_plane_id;
bool m_dragging = false;
bool m_added = false;
std::unique_ptr<class ActionModeGrid> m_action;
public:
bool m_highlight = false;
int m_selected_index = -1;
std::vector<ray_t> m_lines;
virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;
virtual void on_KeyEvent(KeyEvent* ke) override;
virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override;
virtual void init() override;
virtual void leave(kCanvasMode next) override;
void commit();
void clear();
};
struct ActionModeGrid : public Action
{
CanvasModeGrid* m_mode;
bool m_highlight;
int m_selected_index;
std::vector<ray_t> m_lines;
virtual void run() override { }
virtual Action* get_redo() override;
virtual void undo() override;
virtual size_t memory() override { return 0; }
};
class CanvasModeCamera : public CanvasMode
{
bool m_dragging = false;
glm::vec2 m_drag_start;
glm::vec2 m_pos_start;
public:
virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;
};
class CanvasModeFill : public CanvasMode
{
DynamicShape m_shape;
bool m_dragging = false;
std::vector<vertex_t> m_points;
std::map<int, int> m_dirty_planes;
public:
virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override;
virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;
virtual void init() override;
virtual void leave(kCanvasMode next) override;
};
class CanvasModeMaskBase : public CanvasMode
{
protected:
friend class CanvasModeTransform;
DynamicShape m_shape;
bool m_dragging = false;
std::vector<vertex_t> m_points;
std::vector<glm::vec2> m_points2d;
CameraData m_selection_cam;
public:
};
class CanvasModeMaskFree : public CanvasModeMaskBase
{
public:
virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override;
virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;
virtual void init() override;
virtual void leave(kCanvasMode next) override;
void clear();
};
class CanvasModeMaskLine : public CanvasModeMaskBase
{
std::map<int, int> m_dirty_planes;
bool m_active_tool = false;
public:
virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override;
virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;
virtual void init() override;
virtual void enter(kCanvasMode prev) override;
virtual void leave(kCanvasMode next) override;
};
class CanvasModeTransform : public CanvasMode
{
DynamicShape m_shape[6]{};
Sphere m_sphere{};
Circle m_circle{};
Texture2D m_tex[6]{};
glm::vec3 m_origin{0, 0, 1 };
std::vector<glm::vec3> corners{};
std::vector<glm::vec2> corners2d{};
int corner_hl = -1;
glm::vec3 m_center_point{};
glm::vec2 m_center_point_uv{};
glm::mat4 m_xform{1};
glm::mat4 m_xform_local{1};
int m_counter = 0;
bool m_dragging = false;
int m_drag_corner = -1;
float m_drag_diag = 0;
std::vector<glm::vec2> m_drag_corners2d{};
glm::vec2 m_drag_start{};
glm::mat4 m_drag_xform{1};
glm::mat4 m_drag_xform_local{1};
std::vector<vertex_t> m_points{};
std::vector<glm::vec2> m_points2d{};
std::vector<vertex_t> m_points_face[6];
std::map<int, int> m_dirty_planes{};
bool m_active_tool = false;
bool m_commit_on_leave = false;
public:
enum class ActionType : uint8_t { Copy, Cut, Import };
ActionType m_action;
Image m_source_image;
CanvasModeTransform() = default;
virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override;
virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;
virtual void init() override;;
virtual void enter(kCanvasMode prev) override;
virtual void leave(kCanvasMode next) override;
};