1 #pragma once 2 #include "canvas.hpp" 3 #include "drag_selection.hpp" 4 #include "grid.hpp" 5 #include "marker.hpp" 6 #include "triangle_renderer.hpp" 7 #include "selectables_renderer.hpp" 8 #include "util/msd_animator.hpp" 9 #include <gtkmm.h> 10 #include <glm/glm.hpp> 11 #include "appearance.hpp" 12 #include "annotation.hpp" 13 #include "snap_filter.hpp" 14 #include "picture_renderer.hpp" 15 #include "selection_filter.hpp" 16 17 namespace horizon { 18 class CanvasGL : public Canvas, public Gtk::GLArea { 19 friend Grid; 20 friend DragSelection; 21 friend SelectablesRenderer; 22 friend TriangleRenderer; 23 friend MarkerRenderer; 24 friend Markers; 25 friend CanvasAnnotation; 26 friend PictureRenderer; 27 28 public: 29 CanvasGL(); 30 31 enum class SelectionMode { HOVER, NORMAL }; 32 void set_selection_mode(SelectionMode mode); 33 SelectionMode get_selection_mode() const; 34 typedef sigc::signal<void, SelectionMode> type_signal_selection_mode_changed; signal_selection_mode_changed()35 type_signal_selection_mode_changed signal_selection_mode_changed() 36 { 37 return s_signal_selection_mode_changed; 38 } 39 40 enum class SelectionTool { BOX, LASSO, PAINT }; 41 SelectionTool selection_tool = SelectionTool::BOX; 42 43 enum class SelectionQualifier { INCLUDE_ORIGIN, INCLUDE_BOX, TOUCH_BOX, AUTO }; 44 SelectionQualifier selection_qualifier = SelectionQualifier::INCLUDE_ORIGIN; 45 46 enum class HighlightMode { HIGHLIGHT, DIM, SHADOW }; 47 void set_highlight_mode(HighlightMode mode); 48 HighlightMode get_highlight_mode() const; 49 void set_highlight_enabled(bool x); 50 void set_highlight_on_top(bool on_top); 51 52 enum class LayerMode { AS_IS, WORK_ONLY, SHADOW_OTHER }; 53 void set_layer_mode(LayerMode mode); 54 55 std::set<SelectableRef> get_selection(); 56 void set_selection(const std::set<SelectableRef> &sel, bool emit = true); 57 void select_all(); 58 void set_cursor_pos(const Coordi &c); 59 void set_cursor_external(bool v); 60 Coordi get_cursor_pos(); 61 Coordf get_cursor_pos_win(); 62 Target get_current_target(); 63 void set_selection_allowed(bool a); 64 std::pair<float, Coordf> get_scale_and_offset(); 65 void set_scale_and_offset(float sc, Coordf ofs); 66 Coordi snap_to_grid(const Coordi &c, unsigned int div = 1) const; 67 68 void set_flip_view(bool fl); 69 bool get_flip_view() const override; 70 71 void set_view_angle(float a); 72 float get_view_angle() const override; 73 74 void set_cursor_size(float size); 75 void set_cursor_size(Appearance::CursorSize); 76 77 void clear() override; 78 79 typedef sigc::signal<void> type_signal_selection_changed; signal_selection_changed()80 type_signal_selection_changed signal_selection_changed() 81 { 82 return s_signal_selection_changed; 83 } 84 signal_hover_selection_changed()85 type_signal_selection_changed signal_hover_selection_changed() 86 { 87 return s_signal_hover_selection_changed; 88 } 89 90 typedef sigc::signal<void, const Coordi &> type_signal_cursor_moved; signal_cursor_moved()91 type_signal_cursor_moved signal_cursor_moved() 92 { 93 return s_signal_cursor_moved; 94 } 95 96 typedef sigc::signal<void, unsigned int> type_signal_grid_mul_changed; signal_grid_mul_changed()97 type_signal_grid_mul_changed signal_grid_mul_changed() 98 { 99 return s_signal_grid_mul_changed; 100 } get_grid_mul() const101 unsigned int get_grid_mul() const 102 { 103 return grid.mul; 104 } 105 106 typedef sigc::signal<std::string, const SelectableRef &> type_signal_request_display_name; signal_request_display_name()107 type_signal_request_display_name signal_request_display_name() 108 { 109 return s_signal_request_display_name; 110 } 111 112 typedef sigc::signal<void, bool &> type_signal_can_steal_focus; signal_can_steal_focus()113 type_signal_can_steal_focus signal_can_steal_focus() 114 { 115 return s_signal_can_steal_focus; 116 } 117 118 typedef sigc::signal<void> type_signal_scale_changed; signal_scale_changed()119 type_signal_scale_changed signal_scale_changed() 120 { 121 return s_signal_scale_changed; 122 } 123 124 void center_and_zoom(const Coordf ¢er, float scale = -1); 125 void zoom_to_bbox(const Coordf &a, const Coordf &b); 126 void zoom_to_bbox(const std::pair<Coordf, Coordf> &bb); 127 void ensure_min_size(float w, float h); 128 void zoom_to(const Coordf &c, float inc); 129 property_work_layer()130 Glib::PropertyProxy<int> property_work_layer() 131 { 132 return p_property_work_layer.get_proxy(); 133 } property_layer_opacity()134 Glib::PropertyProxy<float> property_layer_opacity() 135 { 136 return p_property_layer_opacity.get_proxy(); 137 } property_layer_opacity() const138 Glib::PropertyProxy_ReadOnly<float> property_layer_opacity() const 139 { 140 return Glib::PropertyProxy_ReadOnly<float>(this, "layer-opacity"); 141 } 142 Markers markers; 143 void update_markers() override; 144 145 std::set<SelectableRef> get_selection_at(const Coordi &c); 146 Coordf screen2canvas(const Coordf &p) const; 147 void update_cursor_pos(double x, double y); 148 149 const Appearance &get_appearance() const; 150 void set_appearance(const Appearance &a); 151 const Color &get_color(ColorP colorp) const; 152 153 bool touchpad_pan = false; 154 155 bool smooth_zoom = true; 156 bool snap_to_targets = true; 157 158 float zoom_base = 1.5; 159 160 void inhibit_drag_selection(); 161 162 int _animate_step(GdkFrameClock *frame_clock); 163 get_width() const164 float get_width() const 165 { 166 return m_width; 167 } get_height() const168 float get_height() const 169 { 170 return m_height; 171 } 172 173 CanvasAnnotation *create_annotation(); 174 void remove_annotation(CanvasAnnotation *a); 175 bool layer_is_annotation(int l) const; 176 177 std::set<SnapFilter> snap_filter; 178 179 void set_grid_spacing(uint64_t x, uint64_t y); 180 void set_grid_spacing(uint64_t s); 181 Coordi get_grid_spacing() const; 182 void set_grid_origin(const Coordi &c); 183 184 SelectionFilter selection_filter; 185 186 bool layer_is_visible(int layer) const; 187 bool layer_is_visible(LayerRange layer) const; 188 189 void set_colors2(const std::vector<ColorI> &c); 190 191 int get_last_grid_div() const; 192 193 void append_target(const Target &target); 194 195 protected: 196 void push() override; 197 void request_push() override; 198 199 private: 200 static const int MAT3_XX = 0; 201 static const int MAT3_X0 = 2; 202 static const int MAT3_YY = 4; 203 static const int MAT3_Y0 = 5; 204 205 float m_width, m_height; 206 glm::mat3 screenmat; 207 float scale = 1e-5; 208 Coord<float> offset; 209 glm::mat3 viewmat; 210 glm::mat3 viewmat_noflip; 211 bool flip_view = false; 212 float view_angle = 0; 213 void update_viewmat(); 214 Coordf canvas2screen(const Coordf &p) const; 215 216 Coord<float> cursor_pos; 217 Coord<int64_t> cursor_pos_grid; 218 bool cursor_external = false; 219 220 GLuint renderbuffer; 221 GLuint stencilrenderbuffer; 222 GLuint fbo; 223 bool needs_resize = false; 224 enum PushFilter { 225 PF_NONE = 0, 226 PF_TRIANGLES = (1 << 0), 227 PF_CURSOR = (1 << 1), 228 PF_SELECTABLES = (1 << 2), 229 PF_MARKER = (1 << 3), 230 PF_DRAG_SELECTION = (1 << 4), 231 PF_ALL = 0xff 232 }; 233 PushFilter push_filter = PF_ALL; 234 void request_push(PushFilter filter); 235 236 void resize_buffers(); 237 238 Grid grid; 239 DragSelection drag_selection; 240 SelectablesRenderer selectables_renderer; 241 TriangleRenderer triangle_renderer; 242 243 MarkerRenderer marker_renderer; 244 245 PictureRenderer picture_renderer; 246 247 void pan_drag_begin(GdkEventButton *button_event); 248 void pan_drag_end(GdkEventButton *button_event); 249 void pan_drag_move(GdkEventMotion *motion_event); 250 void pan_drag_move(GdkEventScroll *scroll_event); 251 void pan_zoom(GdkEventScroll *scroll_event, bool to_cursor = true); 252 void start_smooth_zoom(const Coordf &c, float inc); 253 void cursor_move(GdkEvent *motion_event); 254 void hover_prelight_update(GdkEvent *motion_event); 255 bool pan_dragging = false; 256 Coord<float> pan_pointer_pos_orig; 257 Coord<float> pan_offset_orig; 258 259 void set_scale(float x, float y, float new_scale); 260 261 bool selection_allowed = true; 262 Glib::Property<int> p_property_work_layer; 263 Glib::Property<float> p_property_layer_opacity; 264 265 Gtk::Menu *clarify_menu; 266 267 HighlightMode highlight_mode = HighlightMode::HIGHLIGHT; 268 bool highlight_enabled = false; 269 bool highlight_on_top = false; 270 Appearance appearance; 271 272 LayerMode layer_mode = LayerMode::AS_IS; 273 274 bool drag_selection_inhibited = false; 275 276 MSDAnimator zoom_animator; 277 float zoom_animation_scale_orig = 1; 278 Coordf zoom_animation_pos; 279 280 Gdk::ModifierType grid_fine_modifier = Gdk::MOD1_MASK; 281 float cursor_size = 20; 282 283 static const int first_annotation_layer = 20000; 284 int annotation_layer_current = first_annotation_layer; 285 std::map<int, CanvasAnnotation> annotations; 286 287 void draw_bitmap_text(const Coordf &p, float scale, const std::string &rtext, int angle, ColorP color, 288 int layer) override; 289 std::pair<Coordf, Coordf> measure_bitmap_text(const std::string &text) const override; 290 void draw_bitmap_text_box(const Placement &q, float width, float height, const std::string &s, ColorP color, 291 int layer, TextBoxMode mode) override; 292 293 SelectionMode selection_mode = SelectionMode::HOVER; 294 295 Glib::RefPtr<Gtk::GestureZoom> gesture_zoom; 296 void zoom_gesture_begin_cb(GdkEventSequence *seq); 297 void zoom_gesture_update_cb(GdkEventSequence *seq); 298 Coord<float> gesture_zoom_pos_orig; 299 Coord<float> gesture_zoom_offset_orig; 300 float gesture_zoom_scale_orig = 1; 301 302 Glib::RefPtr<Gtk::GestureDrag> gesture_drag; 303 Coord<float> gesture_drag_offset_orig; 304 305 void drag_gesture_begin_cb(GdkEventSequence *seq); 306 void drag_gesture_update_cb(GdkEventSequence *seq); 307 308 bool can_snap_to_target(const Target &t) const; 309 310 std::vector<ColorI> colors2; 311 312 bool can_set_scale() const; 313 314 int last_grid_div = 1; 315 316 protected: 317 void on_size_allocate(Gtk::Allocation &alloc) override; 318 void on_realize() override; 319 bool on_render(const Glib::RefPtr<Gdk::GLContext> &context) override; 320 bool on_button_press_event(GdkEventButton *button_event) override; 321 bool on_button_release_event(GdkEventButton *button_event) override; 322 bool on_motion_notify_event(GdkEventMotion *motion_event) override; 323 bool on_scroll_event(GdkEventScroll *scroll_event) override; 324 Glib::RefPtr<Gdk::GLContext> on_create_context() override; 325 326 type_signal_selection_changed s_signal_selection_changed; 327 type_signal_selection_changed s_signal_hover_selection_changed; 328 type_signal_selection_mode_changed s_signal_selection_mode_changed; 329 type_signal_cursor_moved s_signal_cursor_moved; 330 type_signal_grid_mul_changed s_signal_grid_mul_changed; 331 type_signal_request_display_name s_signal_request_display_name; 332 type_signal_can_steal_focus s_signal_can_steal_focus; 333 type_signal_scale_changed s_signal_scale_changed; 334 }; 335 } // namespace horizon 336