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_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;
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_cursor_size(float size);
72  void set_cursor_size(Appearance::CursorSize);
73 
74  void clear() override;
75 
76  typedef sigc::signal<void> type_signal_selection_changed;
77  type_signal_selection_changed signal_selection_changed()
78  {
79  return s_signal_selection_changed;
80  }
81 
82  type_signal_selection_changed signal_hover_selection_changed()
83  {
84  return s_signal_hover_selection_changed;
85  }
86 
87  typedef sigc::signal<void, const Coordi &> type_signal_cursor_moved;
88  type_signal_cursor_moved signal_cursor_moved()
89  {
90  return s_signal_cursor_moved;
91  }
92 
93  typedef sigc::signal<void, unsigned int> type_signal_grid_mul_changed;
94  type_signal_grid_mul_changed signal_grid_mul_changed()
95  {
96  return s_signal_grid_mul_changed;
97  }
98  unsigned int get_grid_mul() const
99  {
100  return grid.mul;
101  }
102 
103  typedef sigc::signal<std::string, const SelectableRef &> type_signal_request_display_name;
104  type_signal_request_display_name signal_request_display_name()
105  {
106  return s_signal_request_display_name;
107  }
108 
109  typedef sigc::signal<void, bool &> type_signal_can_steal_focus;
110  type_signal_can_steal_focus signal_can_steal_focus()
111  {
112  return s_signal_can_steal_focus;
113  }
114 
115  typedef sigc::signal<void> type_signal_scale_changed;
116  type_signal_scale_changed signal_scale_changed()
117  {
118  return s_signal_scale_changed;
119  }
120 
121  void center_and_zoom(const Coordi &center, float scale = -1);
122  void zoom_to_bbox(const Coordf &a, const Coordf &b);
123  void zoom_to_bbox(const std::pair<Coordf, Coordf> &bb);
124  void ensure_min_size(float w, float h);
125  void zoom_to_center(float factor);
126 
127  Glib::PropertyProxy<int> property_work_layer()
128  {
129  return p_property_work_layer.get_proxy();
130  }
131  Glib::PropertyProxy<float> property_layer_opacity()
132  {
133  return p_property_layer_opacity.get_proxy();
134  }
135  Glib::PropertyProxy_ReadOnly<float> property_layer_opacity() const
136  {
137  return Glib::PropertyProxy_ReadOnly<float>(this, "layer-opacity");
138  }
139  Markers markers;
140  void update_markers() override;
141 
142  std::set<SelectableRef> get_selection_at(const Coordi &c);
143  Coordf screen2canvas(const Coordf &p) const;
144  void update_cursor_pos(double x, double y);
145 
146  const Appearance &get_appearance() const;
147  void set_appearance(const Appearance &a);
148  const Color &get_color(ColorP colorp) const;
149 
150  bool touchpad_pan = false;
151 
152  bool smooth_zoom = true;
153  bool snap_to_targets = true;
154 
155  float zoom_base = 1.5;
156 
157  void inhibit_drag_selection();
158 
159  int _animate_step(GdkFrameClock *frame_clock);
160 
161  float get_width() const
162  {
163  return m_width;
164  }
165  float get_height() const
166  {
167  return m_height;
168  }
169 
170  CanvasAnnotation *create_annotation();
171  void remove_annotation(CanvasAnnotation *a);
172  bool layer_is_annotation(int l) const;
173 
174  std::set<SnapFilter> snap_filter;
175 
176  void set_grid_spacing(uint64_t x, uint64_t y);
177  void set_grid_spacing(uint64_t s);
178  Coordi get_grid_spacing() const;
179  void set_grid_origin(const Coordi &c);
180 
181  SelectionFilter selection_filter;
182 
183  bool layer_is_visible(int layer) const;
184  bool layer_is_visible(LayerRange layer) const;
185 
186  void set_colors2(const std::vector<ColorI> &c);
187 
188  int get_last_grid_div() const;
189 
190 protected:
191  void push() override;
192  void request_push() override;
193 
194 private:
195  static const int MAT3_XX = 0;
196  static const int MAT3_X0 = 2;
197  static const int MAT3_YY = 4;
198  static const int MAT3_Y0 = 5;
199 
200  float m_width, m_height;
201  glm::mat3 screenmat;
202  float scale = 1e-5;
203  Coord<float> offset;
204  glm::mat3 viewmat;
205  glm::mat3 viewmat_noflip;
206  bool flip_view = false;
207  void update_viewmat();
208 
209  Coord<float> cursor_pos;
210  Coord<int64_t> cursor_pos_grid;
211  bool cursor_external = false;
212 
213  GLuint renderbuffer;
214  GLuint stencilrenderbuffer;
215  GLuint fbo;
216  bool needs_resize = false;
217  enum PushFilter {
218  PF_NONE = 0,
219  PF_TRIANGLES = (1 << 0),
220  PF_CURSOR = (1 << 1),
221  PF_SELECTABLES = (1 << 2),
222  PF_MARKER = (1 << 3),
223  PF_DRAG_SELECTION = (1 << 4),
224  PF_ALL = 0xff
225  };
226  PushFilter push_filter = PF_ALL;
227  void request_push(PushFilter filter);
228 
229  void resize_buffers();
230 
231  Grid grid;
232  DragSelection drag_selection;
233  SelectablesRenderer selectables_renderer;
234  TriangleRenderer triangle_renderer;
235 
236  MarkerRenderer marker_renderer;
237 
238  PictureRenderer picture_renderer;
239 
240  void pan_drag_begin(GdkEventButton *button_event);
241  void pan_drag_end(GdkEventButton *button_event);
242  void pan_drag_move(GdkEventMotion *motion_event);
243  void pan_drag_move(GdkEventScroll *scroll_event);
244  void pan_zoom(GdkEventScroll *scroll_event, bool to_cursor = true);
245  void cursor_move(GdkEvent *motion_event);
246  void hover_prelight_update(GdkEvent *motion_event);
247  bool pan_dragging = false;
248  Coord<float> pan_pointer_pos_orig;
249  Coord<float> pan_offset_orig;
250 
251  void set_scale(float x, float y, float new_scale);
252 
253  bool selection_allowed = true;
254  Glib::Property<int> p_property_work_layer;
255  Glib::Property<float> p_property_layer_opacity;
256 
257  Gtk::Menu *clarify_menu;
258 
259  HighlightMode highlight_mode = HighlightMode::HIGHLIGHT;
260  bool highlight_enabled = false;
261  bool highlight_on_top = false;
262  Appearance appearance;
263 
264  LayerMode layer_mode = LayerMode::AS_IS;
265 
266  bool drag_selection_inhibited = false;
267 
268  MSDAnimator zoom_animator;
269  float zoom_animation_scale_orig = 1;
270  Coordf zoom_animation_pos;
271 
272  Gdk::ModifierType grid_fine_modifier = Gdk::MOD1_MASK;
273  float cursor_size = 20;
274 
275  static const int first_annotation_layer = 20000;
276  int annotation_layer_current = first_annotation_layer;
277  std::map<int, CanvasAnnotation> annotations;
278 
279  void draw_bitmap_text(const Coordf &p, float scale, const std::string &rtext, int angle, ColorP color,
280  int layer) override;
281  std::pair<Coordf, Coordf> measure_bitmap_text(const std::string &text) const override;
282  void draw_bitmap_text_box(const Placement &q, float width, float height, const std::string &s, ColorP color,
283  int layer, TextBoxMode mode) override;
284 
285  SelectionMode selection_mode = SelectionMode::HOVER;
286 
287  Glib::RefPtr<Gtk::GestureZoom> gesture_zoom;
288  void zoom_gesture_begin_cb(GdkEventSequence *seq);
289  void zoom_gesture_update_cb(GdkEventSequence *seq);
290  Coord<float> gesture_zoom_pos_orig;
291  Coord<float> gesture_zoom_offset_orig;
292  float gesture_zoom_scale_orig = 1;
293 
294  Glib::RefPtr<Gtk::GestureDrag> gesture_drag;
295  Coord<float> gesture_drag_offset_orig;
296 
297  void drag_gesture_begin_cb(GdkEventSequence *seq);
298  void drag_gesture_update_cb(GdkEventSequence *seq);
299 
300  bool can_snap_to_target(const Target &t) const;
301 
302  std::vector<ColorI> colors2;
303 
304  bool can_set_scale() const;
305 
306  int last_grid_div = 1;
307 
308 protected:
309  void on_size_allocate(Gtk::Allocation &alloc) override;
310  void on_realize() override;
311  bool on_render(const Glib::RefPtr<Gdk::GLContext> &context) override;
312  bool on_button_press_event(GdkEventButton *button_event) override;
313  bool on_button_release_event(GdkEventButton *button_event) override;
314  bool on_motion_notify_event(GdkEventMotion *motion_event) override;
315  bool on_scroll_event(GdkEventScroll *scroll_event) override;
316  Glib::RefPtr<Gdk::GLContext> on_create_context() override;
317 
318  type_signal_selection_changed s_signal_selection_changed;
319  type_signal_selection_changed s_signal_hover_selection_changed;
320  type_signal_selection_mode_changed s_signal_selection_mode_changed;
321  type_signal_cursor_moved s_signal_cursor_moved;
322  type_signal_grid_mul_changed s_signal_grid_mul_changed;
323  type_signal_request_display_name s_signal_request_display_name;
324  type_signal_can_steal_focus s_signal_can_steal_focus;
325  type_signal_scale_changed s_signal_scale_changed;
326 };
327 } // namespace horizon
horizon::MarkerRenderer
Definition: marker.hpp:54
horizon::LayerRange
Definition: layer_range.hpp:7
horizon::SelectionFilter
Definition: selection_filter.hpp:6
horizon::CanvasAnnotation
Definition: annotation.hpp:7
horizon::SelectablesRenderer
Definition: selectables_renderer.hpp:5
horizon::CanvasGL
Definition: canvas_gl.hpp:18
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:220
horizon::Canvas
Definition: canvas.hpp:22
horizon::Coord< int64_t >
horizon::Appearance
Definition: appearance.hpp:7
horizon::PictureRenderer
Definition: picture_renderer.hpp:11
horizon::Target
Definition: target.hpp:7
horizon::Placement
Definition: placement.hpp:8
horizon::TriangleRenderer
Definition: triangle_renderer.hpp:9
libzip::uint64_t
zip_uint64_t uint64_t
zip_uint64_t_t typedef.
Definition: zip.hpp:108