File: example_gestures.cc

package info (click to toggle)
gtkmm3.0 3.24.0-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 22,680 kB
  • sloc: xml: 121,333; cpp: 8,531; sh: 4,250; makefile: 262; perl: 236
file content (166 lines) | stat: -rw-r--r-- 4,988 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/* Gestures
 *
 * Perform gestures on touchscreens and other input devices. This
 * demo reacts to long presses and swipes from all devices, plus
 * multi-touch rotate and zoom gestures from touchscreens.
 */

#include <gtkmm.h>

class Example_Gestures : public Gtk::Window
{
public:
  Example_Gestures();
  ~Example_Gestures() override;

protected:

  // Signal handlers:
  bool on_drawing_area_draw(const ::Cairo::RefPtr< ::Cairo::Context>& cr);
  void on_gesture_swipe_swipe(double velocity_x, double velocity_y);
  void on_gesture_long_press_pressed(double x, double y);
  void on_gesture_long_press_end(GdkEventSequence* sequence);
  void on_gesture_rotate_angle_changed(double angle, double angle_delta);
  void on_gesture_zoom_scale_changed(double scale);

  // Child widget:
  Gtk::DrawingArea m_DrawingArea;

  // Gestures:
  Glib::RefPtr<Gtk::GestureSwipe> m_GestureSwipe;
  Glib::RefPtr<Gtk::GestureLongPress> m_GestureLongPress;
  Glib::RefPtr<Gtk::GestureRotate> m_GestureRotate;
  Glib::RefPtr<Gtk::GestureZoom> m_GestureZoom;

  double m_swipe_x;
  double m_swipe_y;
  bool m_long_pressed;
};


Gtk::Window* do_gestures()
{
  return new Example_Gestures();
}

Example_Gestures::Example_Gestures()
:
  m_DrawingArea(),
  m_swipe_x(0.0), m_swipe_y(0.0), m_long_pressed(false)
{
  set_title("Gestures demo");
  set_default_size(400, 400);

  add(m_DrawingArea);
  m_DrawingArea.add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK |
                           Gdk::POINTER_MOTION_MASK | Gdk::TOUCH_MASK);
  m_DrawingArea.signal_draw().connect(sigc::mem_fun(*this, &Example_Gestures::on_drawing_area_draw));

  // Create gestures.
  m_GestureSwipe = Gtk::GestureSwipe::create(m_DrawingArea);
  m_GestureSwipe->set_propagation_phase(Gtk::PHASE_BUBBLE);
  m_GestureSwipe->signal_swipe().connect(sigc::mem_fun(*this, &Example_Gestures::on_gesture_swipe_swipe));
  m_GestureSwipe->set_touch_only(false);

  m_GestureLongPress = Gtk::GestureLongPress::create(m_DrawingArea);
  m_GestureLongPress->set_propagation_phase(Gtk::PHASE_BUBBLE);
  m_GestureLongPress->signal_pressed().connect(sigc::mem_fun(*this, &Example_Gestures::on_gesture_long_press_pressed));
  m_GestureLongPress->signal_end().connect(sigc::mem_fun(*this, &Example_Gestures::on_gesture_long_press_end));
  m_GestureLongPress->set_touch_only(false);

  m_GestureRotate = Gtk::GestureRotate::create(m_DrawingArea);
  m_GestureRotate->set_propagation_phase(Gtk::PHASE_BUBBLE);
  m_GestureRotate->signal_angle_changed().connect(sigc::mem_fun(*this, &Example_Gestures::on_gesture_rotate_angle_changed));

  m_GestureZoom = Gtk::GestureZoom::create(m_DrawingArea);
  m_GestureZoom->set_propagation_phase(Gtk::PHASE_BUBBLE);
  m_GestureZoom->signal_scale_changed().connect(sigc::mem_fun(*this, &Example_Gestures::on_gesture_zoom_scale_changed));

  show_all();
}

Example_Gestures::~Example_Gestures()
{
}

bool Example_Gestures::on_drawing_area_draw(const ::Cairo::RefPtr< ::Cairo::Context>& cr)
{
  Gtk::Allocation allocation = m_DrawingArea.get_allocation();

  // Coordinates for the center of the window
  const int xc = allocation.get_width() / 2;
  const int yc = allocation.get_height() / 2;

  if (m_GestureRotate->is_recognized() || m_GestureZoom->is_recognized())
  {
    Cairo::Matrix matrix = Cairo::translation_matrix(xc, yc);
    cr->save();

    const double angle = m_GestureRotate->get_angle_delta();
    matrix.rotate(angle);

    const double scale = m_GestureZoom->get_scale_delta();
    matrix.scale(scale, scale);

    cr->set_matrix(matrix);
    cr->rectangle(-100, -100, 200, 200);

    ::Cairo::RefPtr<Cairo::LinearGradient> pattern = Cairo::LinearGradient::create(-100, 0, 200, 0);
    pattern->add_color_stop_rgb(0, 0, 0, 1);
    pattern->add_color_stop_rgb(1, 1, 0, 0);
    cr->set_source(pattern);
    cr->fill();
    cr->restore();
  }

  if (m_swipe_x != 0.0 || m_swipe_y != 0.0)
  {
    cr->save();
    cr->set_line_width(6);
    cr->move_to(xc, yc);
    cr->rel_line_to(m_swipe_x, m_swipe_y);
    cr->set_source_rgba(1.0, 0.0, 0.0, 0.5);
    cr->stroke();
    cr->restore();
  }

  if (m_long_pressed)
  {
    cr->save();
    cr->arc(xc, yc, 50, 0, 2 * G_PI);
    cr->set_source_rgba(0.0, 1.0, 0.0, 0.5);
    cr->stroke();
    cr->restore();
  }

  return true;
}

void Example_Gestures::on_gesture_swipe_swipe(double velocity_x, double velocity_y)
{
  m_swipe_x = 0.2 * velocity_x;
  m_swipe_y = 0.2 * velocity_y;
  m_DrawingArea.queue_draw();
}

void Example_Gestures::on_gesture_long_press_pressed(double /* x */, double /* y */)
{
  m_long_pressed = true;
  m_DrawingArea.queue_draw();
}

void Example_Gestures::on_gesture_long_press_end(GdkEventSequence* /* sequence */)
{
  m_long_pressed = false;
  m_DrawingArea.queue_draw();
}

void Example_Gestures::on_gesture_rotate_angle_changed(double /* angle */, double /* angle_delta */)
{
  m_DrawingArea.queue_draw();
}

void Example_Gestures::on_gesture_zoom_scale_changed(double /* scale */)
{
  m_DrawingArea.queue_draw();
}