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
17namespace horizon {
18class CanvasGL : public Canvas, public Gtk::GLArea {
19 friend Grid;
20 friend DragSelection;
22 friend TriangleRenderer;
23 friend MarkerRenderer;
24 friend Markers;
25 friend CanvasAnnotation;
26 friend PictureRenderer;
27
28public:
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() const;
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() const;
61 Coordf get_cursor_pos_win() const;
62 Target get_current_target() const;
63 void set_selection_allowed(bool a);
64 std::pair<float, Coordf> get_scale_and_offset() const;
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;
80 type_signal_selection_changed signal_selection_changed()
81 {
82 return s_signal_selection_changed;
83 }
84
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;
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;
97 type_signal_grid_mul_changed signal_grid_mul_changed()
98 {
99 return s_signal_grid_mul_changed;
100 }
101 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;
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;
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;
119 type_signal_scale_changed signal_scale_changed()
120 {
121 return s_signal_scale_changed;
122 }
123
124 void center_and_zoom(const Coordf &center, 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
130 Glib::PropertyProxy<int> property_work_layer()
131 {
132 return p_property_work_layer.get_proxy();
133 }
134 Glib::PropertyProxy<float> property_layer_opacity()
135 {
136 return p_property_layer_opacity.get_proxy();
137 }
138 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) const;
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
164 float get_width() const
165 {
166 return m_width;
167 }
168 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 void set_msd_params(const MSD::Params &params);
196
197 bool show_pictures = true;
198
199protected:
200 void push() override;
201 void request_push() override;
202
203private:
204 static const int MAT3_XX = 0;
205 static const int MAT3_X0 = 2;
206 static const int MAT3_YY = 4;
207 static const int MAT3_Y0 = 5;
208
209 float m_width, m_height;
210 glm::mat3 screenmat;
211 float scale = 1e-5;
212 Coord<float> offset;
213 glm::mat3 viewmat;
214 glm::mat3 viewmat_noflip;
215 bool flip_view = false;
216 float view_angle = 0;
217 void update_viewmat();
218 Coordf canvas2screen(const Coordf &p) const;
219
220 Coord<float> cursor_pos;
221 Coord<int64_t> cursor_pos_grid;
222 bool cursor_external = false;
223
224 GLuint renderbuffer;
225 GLuint stencilrenderbuffer;
226 GLuint fbo;
227 bool needs_resize = false;
228 enum PushFilter {
229 PF_NONE = 0,
230 PF_TRIANGLES = (1 << 0),
231 PF_CURSOR = (1 << 1),
232 PF_SELECTABLES = (1 << 2),
233 PF_MARKER = (1 << 3),
234 PF_DRAG_SELECTION = (1 << 4),
235 PF_ALL = 0xff
236 };
237 PushFilter push_filter = PF_ALL;
238 void request_push(PushFilter filter);
239
240 void resize_buffers();
241
242 Grid grid;
243 DragSelection drag_selection;
244 SelectablesRenderer selectables_renderer;
245 TriangleRenderer triangle_renderer;
246
247 MarkerRenderer marker_renderer;
248
249 PictureRenderer picture_renderer;
250
251 void pan_drag_begin(GdkEventButton *button_event);
252 void pan_drag_end(GdkEventButton *button_event);
253 void pan_drag_move(GdkEventMotion *motion_event);
254 void pan_drag_move(GdkEventScroll *scroll_event);
255 void pan_zoom(GdkEventScroll *scroll_event, bool to_cursor = true);
256 void start_smooth_zoom(const Coordf &c, float inc);
257 void cursor_move(GdkEvent *motion_event);
258 void hover_prelight_update(GdkEvent *motion_event);
259 bool pan_dragging = false;
260 Coord<float> pan_pointer_pos_orig;
261 Coord<float> pan_offset_orig;
262
263 void set_scale(float x, float y, float new_scale);
264
265 bool selection_allowed = true;
266 Glib::Property<int> p_property_work_layer;
267 Glib::Property<float> p_property_layer_opacity;
268
269 Gtk::Menu *clarify_menu;
270
271 HighlightMode highlight_mode = HighlightMode::HIGHLIGHT;
272 bool highlight_enabled = false;
273 bool highlight_on_top = false;
274 Appearance appearance;
275
276 LayerMode layer_mode = LayerMode::AS_IS;
277
278 bool drag_selection_inhibited = false;
279
280 MSDAnimator zoom_animator;
281 float zoom_animation_scale_orig = 1;
282 Coordf zoom_animation_pos;
283
284 Gdk::ModifierType grid_fine_modifier = Gdk::MOD1_MASK;
285 float cursor_size = 20;
286
287 static const int first_annotation_layer = 20000;
288 int annotation_layer_current = first_annotation_layer;
289 std::map<int, CanvasAnnotation> annotations;
290
291 void draw_bitmap_text(const Coordf &p, float scale, const std::string &rtext, int angle, ColorP color,
292 int layer) override;
293 std::pair<Coordf, Coordf> measure_bitmap_text(const std::string &text) const override;
294 void draw_bitmap_text_box(const Placement &q, float width, float height, const std::string &s, ColorP color,
295 int layer, TextBoxMode mode) override;
296
297 SelectionMode selection_mode = SelectionMode::HOVER;
298
299 Glib::RefPtr<Gtk::GestureZoom> gesture_zoom;
300 void zoom_gesture_begin_cb(GdkEventSequence *seq);
301 void zoom_gesture_update_cb(GdkEventSequence *seq);
302 Coord<float> gesture_zoom_pos_orig;
303 Coord<float> gesture_zoom_offset_orig;
304 float gesture_zoom_scale_orig = 1;
305
306 Glib::RefPtr<Gtk::GestureDrag> gesture_drag;
307 Coord<float> gesture_drag_offset_orig;
308
309 void drag_gesture_begin_cb(GdkEventSequence *seq);
310 void drag_gesture_update_cb(GdkEventSequence *seq);
311
312 bool can_snap_to_target(const Target &t) const;
313
314 std::vector<ColorI> colors2;
315
316 bool can_set_scale() const;
317
318 int last_grid_div = 1;
319
320protected:
321 void on_size_allocate(Gtk::Allocation &alloc) override;
322 void on_realize() override;
323 bool on_render(const Glib::RefPtr<Gdk::GLContext> &context) override;
324 bool on_button_press_event(GdkEventButton *button_event) override;
325 bool on_button_release_event(GdkEventButton *button_event) override;
326 bool on_motion_notify_event(GdkEventMotion *motion_event) override;
327 bool on_scroll_event(GdkEventScroll *scroll_event) override;
328 Glib::RefPtr<Gdk::GLContext> on_create_context() override;
329
330 type_signal_selection_changed s_signal_selection_changed;
331 type_signal_selection_changed s_signal_hover_selection_changed;
332 type_signal_selection_mode_changed s_signal_selection_mode_changed;
333 type_signal_cursor_moved s_signal_cursor_moved;
334 type_signal_grid_mul_changed s_signal_grid_mul_changed;
335 type_signal_request_display_name s_signal_request_display_name;
336 type_signal_can_steal_focus s_signal_can_steal_focus;
337 type_signal_scale_changed s_signal_scale_changed;
338};
339} // namespace horizon
Definition: appearance.hpp:7
Definition: annotation.hpp:7
Definition: canvas_gl.hpp:18
Definition: canvas.hpp:24
Definition: common.hpp:270
Definition: drag_selection.hpp:8
Definition: grid.hpp:6
Definition: layer_range.hpp:7
Definition: msd_animator.hpp:5
Definition: marker.hpp:67
Definition: marker.hpp:42
Definition: picture_renderer.hpp:11
Definition: placement.hpp:8
Definition: selectables_renderer.hpp:5
Definition: selection_filter.hpp:6
Definition: target.hpp:7
Definition: triangle_renderer.hpp:10
Definition: msd.hpp:13