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 smooth_zoom = true;
135  bool snap_to_targets = true;
136 
137  void inhibit_drag_selection();
138 
139  int _animate_step(GdkFrameClock *frame_clock);
140 
141  float get_width() const
142  {
143  return width;
144  }
145  float get_height() const
146  {
147  return height;
148  }
149 
150  CanvasAnnotation *create_annotation();
151  void remove_annotation(CanvasAnnotation *a);
152 
153 protected:
154  void push() override;
155  void request_push() override;
156 
157 private:
158  static const int MAT3_XX = 0;
159  static const int MAT3_X0 = 2;
160  static const int MAT3_YY = 4;
161  static const int MAT3_Y0 = 5;
162 
163  float width, height;
164  glm::mat3 screenmat;
165  float scale = 1e-5;
166  Coord<float> offset;
167  glm::mat3 viewmat;
168  glm::mat3 viewmat_noflip;
169  bool flip_view = false;
170  void update_viewmat();
171 
172  Coord<float> cursor_pos;
173  Coord<int64_t> cursor_pos_grid;
174  bool cursor_external = false;
175  bool warped = false;
176 
177  GLuint renderbuffer;
178  GLuint stencilrenderbuffer;
179  GLuint fbo;
180  bool needs_resize = false;
181  enum PushFilter {
182  PF_NONE = 0,
183  PF_TRIANGLES = (1 << 0),
184  PF_CURSOR = (1 << 1),
185  PF_SELECTABLES = (1 << 2),
186  PF_MARKER = (1 << 3),
187  PF_DRAG_SELECTION = (1 << 4),
188  PF_ALL = 0xff
189  };
190  PushFilter push_filter = PF_ALL;
191  void request_push(PushFilter filter);
192 
193  void resize_buffers();
194 
195  Grid grid;
196  DragSelection drag_selection;
197  SelectablesRenderer selectables_renderer;
198  TriangleRenderer triangle_renderer;
199 
200  MarkerRenderer marker_renderer;
201 
202  void pan_drag_begin(GdkEventButton *button_event);
203  void pan_drag_end(GdkEventButton *button_event);
204  void pan_drag_move(GdkEventMotion *motion_event);
205  void pan_drag_move(GdkEventScroll *scroll_event);
206  void pan_zoom(GdkEventScroll *scroll_event, bool to_cursor = true);
207  void cursor_move(GdkEvent *motion_event);
208  void hover_prelight_update(GdkEvent *motion_event);
209  bool pan_dragging = false;
210  Coord<float> pan_pointer_pos_orig;
211  Coord<float> pan_offset_orig;
212 
213  void set_scale(float x, float y, float new_scale);
214 
215  bool selection_allowed = true;
216  Glib::Property<int> p_property_work_layer;
217  Glib::Property<uint64_t> p_property_grid_spacing;
218  Glib::Property<float> p_property_layer_opacity;
219 
220  Gtk::Menu *clarify_menu;
221 
222  HighlightMode highlight_mode = HighlightMode::HIGHLIGHT;
223  bool highlight_enabled = false;
224  bool highlight_on_top = false;
225  Appearance appearance;
226 
227  void update_palette_colors();
228  std::array<std::array<float, 4>, static_cast<size_t>(ColorP::N_COLORS)> palette_colors;
229 
230  bool drag_selection_inhibited = false;
231 
232  MSDAnimator zoom_animator;
233  float zoom_animation_scale_orig = 1;
234  Coordf zoom_animation_pos;
235 
236  Gdk::ModifierType grid_fine_modifier = Gdk::MOD1_MASK;
237  float cursor_size = 20;
238 
239  int annotation_layer_current = 20000;
240  std::map<int, CanvasAnnotation> annotations;
241 
242  void draw_bitmap_text(const Coordf &p, float scale, const std::string &rtext, int angle, ColorP color,
243  int layer) override;
244  std::pair<Coordf, Coordf> measure_bitmap_text(const std::string &text) const override;
245  void draw_bitmap_text_box(const Placement &q, float width, float height, const std::string &s, ColorP color,
246  int layer, TextBoxMode mode) override;
247 
248  SelectionMode selection_mode = SelectionMode::HOVER;
249 
250 protected:
251  void on_size_allocate(Gtk::Allocation &alloc) override;
252  void on_realize() override;
253  bool on_render(const Glib::RefPtr<Gdk::GLContext> &context) override;
254  bool on_button_press_event(GdkEventButton *button_event) override;
255  bool on_button_release_event(GdkEventButton *button_event) override;
256  bool on_motion_notify_event(GdkEventMotion *motion_event) override;
257  bool on_scroll_event(GdkEventScroll *scroll_event) override;
258  Glib::RefPtr<Gdk::GLContext> on_create_context() override;
259 
260  type_signal_selection_changed s_signal_selection_changed;
261  type_signal_selection_changed s_signal_hover_selection_changed;
262  type_signal_selection_mode_changed s_signal_selection_mode_changed;
263  type_signal_cursor_moved s_signal_cursor_moved;
264  type_signal_grid_mul_changed s_signal_grid_mul_changed;
265  type_signal_request_display_name s_signal_request_display_name;
266  type_signal_can_steal_focus s_signal_can_steal_focus;
267 };
268 } // 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:213
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