#pragma once #include "event.h" #include "shape.h" #include "brush.h" #include "texture.h" #include "action.h" #include #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 m_action; public: bool m_highlight = false; int m_selected_index = -1; std::vector 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 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 m_points; std::map 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 m_points; std::vector 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 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 corners{}; std::vector 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 m_drag_corners2d{}; glm::vec2 m_drag_start{}; glm::mat4 m_drag_xform{1}; glm::mat4 m_drag_xform_local{1}; std::vector m_points{}; std::vector m_points2d{}; std::vector m_points_face[6]; std::map 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; };