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