Skip to content

Commit

Permalink
CanvasGL: support drag and zoom gestures
Browse files Browse the repository at this point in the history
  • Loading branch information
carrotIndustries committed Feb 23, 2020
1 parent c91949a commit 38ff613
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 0 deletions.
57 changes: 57 additions & 0 deletions src/canvas/canvas_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,63 @@ CanvasGL::CanvasGL()

update_palette_colors();
layer_colors = appearance.layer_colors;

gesture_zoom = Gtk::GestureZoom::create(*this);
gesture_zoom->signal_begin().connect(sigc::mem_fun(*this, &CanvasGL::zoom_gesture_begin_cb));
gesture_zoom->signal_update().connect(sigc::mem_fun(*this, &CanvasGL::zoom_gesture_update_cb));
gesture_zoom->set_propagation_phase(Gtk::PHASE_BUBBLE);

gesture_drag = Gtk::GestureDrag::create(*this);
gesture_drag->signal_begin().connect(sigc::mem_fun(*this, &CanvasGL::drag_gesture_begin_cb));
gesture_drag->signal_update().connect(sigc::mem_fun(*this, &CanvasGL::drag_gesture_update_cb));
gesture_drag->set_propagation_phase(Gtk::PHASE_BUBBLE);
gesture_drag->set_touch_only(true);
}

void CanvasGL::zoom_gesture_begin_cb(GdkEventSequence *seq)
{
if (pan_dragging) {
gesture_zoom->set_state(Gtk::EVENT_SEQUENCE_DENIED);
return;
}
gesture_zoom_scale_orig = scale;
gesture_zoom_offset_orig = offset;
double cx, cy;
gesture_zoom->get_bounding_box_center(cx, cy);
gesture_zoom_pos_orig = Coordf(cx, cy);
gesture_zoom->set_state(Gtk::EVENT_SEQUENCE_CLAIMED);
}

void CanvasGL::zoom_gesture_update_cb(GdkEventSequence *seq)
{
auto delta = gesture_zoom->get_scale_delta();
double cx, cy;
gesture_zoom->get_bounding_box_center(cx, cy);
set_scale(cx, cy, gesture_zoom_scale_orig * delta);
offset = gesture_zoom_offset_orig + Coordf(cx, cy) - gesture_zoom_pos_orig;
update_viewmat();
queue_draw();
}

void CanvasGL::drag_gesture_begin_cb(GdkEventSequence *seq)
{
inhibit_drag_selection();
if (pan_dragging) {
gesture_drag->set_state(Gtk::EVENT_SEQUENCE_DENIED);
}
else {
gesture_drag_offset_orig = offset;
gesture_drag->set_state(Gtk::EVENT_SEQUENCE_CLAIMED);
}
}
void CanvasGL::drag_gesture_update_cb(GdkEventSequence *seq)
{
double x, y;
if (gesture_drag->get_offset(x, y)) {
offset = gesture_drag_offset_orig + Coordf(x, y);
update_viewmat();
queue_draw();
}
}

void CanvasGL::on_size_allocate(Gtk::Allocation &alloc)
Expand Down
13 changes: 13 additions & 0 deletions src/canvas/canvas_gl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,19 @@ class CanvasGL : public Canvas, public Gtk::GLArea {

SelectionMode selection_mode = SelectionMode::HOVER;

Glib::RefPtr<Gtk::GestureZoom> gesture_zoom;
void zoom_gesture_begin_cb(GdkEventSequence *seq);
void zoom_gesture_update_cb(GdkEventSequence *seq);
Coord<float> gesture_zoom_pos_orig;
Coord<float> gesture_zoom_offset_orig;
float gesture_zoom_scale_orig = 1;

Glib::RefPtr<Gtk::GestureDrag> gesture_drag;
Coord<float> gesture_drag_offset_orig;

void drag_gesture_begin_cb(GdkEventSequence *seq);
void drag_gesture_update_cb(GdkEventSequence *seq);

protected:
void on_size_allocate(Gtk::Allocation &alloc) override;
void on_realize() override;
Expand Down
9 changes: 9 additions & 0 deletions src/canvas/pan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
namespace horizon {
void CanvasGL::pan_drag_begin(GdkEventButton *button_event)
{
if (gesture_zoom->is_recognized() || gesture_drag->is_recognized())
return;

gdouble x, y;
gdk_event_get_coords((GdkEvent *)button_event, &x, &y);
if (button_event->button == 2 || (button_event->button == 1 && (button_event->state & Gdk::SHIFT_MASK))) {
Expand Down Expand Up @@ -84,6 +87,10 @@ void CanvasGL::set_scale(float x, float y, float scale_new)
pan_offset_orig.x += xi;
pan_offset_orig.y += yi;
}
if (gesture_zoom->is_recognized()) {
gesture_zoom_offset_orig.x += xi;
gesture_zoom_offset_orig.y += yi;
}
update_viewmat();
queue_draw();
}
Expand Down Expand Up @@ -118,6 +125,8 @@ static int tick_cb(GtkWidget *cwidget, GdkFrameClock *frame_clock, gpointer user

void CanvasGL::pan_zoom(GdkEventScroll *scroll_event, bool to_cursor)
{
if (gesture_zoom->is_recognized() || gesture_drag->is_recognized())
return;
gdouble x, y;
if (to_cursor) {
gdk_event_get_coords((GdkEvent *)scroll_event, &x, &y);
Expand Down

0 comments on commit 38ff613

Please sign in to comment.