Code

Fix some console warning spam (most cannot be fixed, unfortunately)
[inkscape.git] / src / ui / widget / rotateable.cpp
1 /**
2  * \brief widget adjustable by dragging it to rotate away from a zero-change axis
3  *
4  * Authors:
5  *   buliabyak@gmail.com
6  *
7  * Copyright (C) 2007 authors
8  *
9  * Released under GNU GPL.  Read the file 'COPYING' for more information.
10  */
12 #include "event-context.h"
13 #include "rotateable.h"
14 #include "libnr/nr-point.h"
15 #include "libnr/nr-point-fns.h"
16 #include <gtkmm/box.h>
17 #include <gtkmm/eventbox.h>
18 #include <glibmm/i18n.h>
20 namespace Inkscape {
21 namespace UI {
22 namespace Widget {
24 Rotateable::Rotateable():
25     axis(-M_PI/4),
26     maxdecl(M_PI/4)
27 {
28                 dragging = false;
29                 working = false;
30                 modifier = 0;
31                 current_axis = axis;
33     signal_button_press_event().connect(sigc::mem_fun(*this, &Rotateable::on_click));
34     signal_motion_notify_event().connect(sigc::mem_fun(*this, &Rotateable::on_motion));
35     signal_button_release_event().connect(sigc::mem_fun(*this, &Rotateable::on_release));
36 }
38 bool Rotateable::on_click(GdkEventButton *event) {
39                 if (event->button == 1) {
40         drag_started_x = event->x;
41         drag_started_y = event->y;
42         modifier = get_single_modifier(modifier, event->state); 
43         dragging = true;
44         working = false;
45         current_axis = axis;
46         return true;
47                 } 
48                 return false; 
49 }
51 guint Rotateable::get_single_modifier(guint old, guint state) {
53                 if (old == 0 || old == 3) {
54         if (state & GDK_CONTROL_MASK)
55             return 1; // ctrl
56         if (state & GDK_SHIFT_MASK)
57             return 2; // shift
58         if (state & GDK_MOD1_MASK)
59             return 3; // alt
60         return 0;
61                 } else {
62         if (!(state & GDK_CONTROL_MASK) && !(state & GDK_SHIFT_MASK)) {
63             if (state & GDK_MOD1_MASK)
64                 return 3; // alt
65             else
66                 return 0; // none
67         }
68         if (old == 1) {
69             if (state & GDK_SHIFT_MASK && !(state & GDK_CONTROL_MASK))
70                 return 2; // shift
71             if (state & GDK_MOD1_MASK && !(state & GDK_CONTROL_MASK))
72                return 3; // alt
73             return 1;
74         }
75         if (old == 2) {
76             if (state & GDK_CONTROL_MASK && !(state & GDK_SHIFT_MASK))
77                 return 1; // ctrl
78             if (state & GDK_MOD1_MASK && !(state & GDK_SHIFT_MASK))
79                return 3; // alt
80             return 2;
81         }
82         return old;
83                 }
84 }
87 bool Rotateable::on_motion(GdkEventMotion *event) {
88                 if (dragging) {
89         double dist = Geom::L2(Geom::Point(event->x, event->y) - Geom::Point(drag_started_x, drag_started_y));
90         double angle = atan2(event->y - drag_started_y, event->x - drag_started_x);
91         if (dist > 20) {
92             working = true;
93             double force = CLAMP (-(angle - current_axis)/maxdecl, -1, 1);
94             if (fabs(force) < 0.002)
95                 force = 0; // snap to zero
96             if (modifier != get_single_modifier(modifier, event->state)) { 
97                 // user has switched modifiers in mid drag, close past drag and start a new
98                 // one, redefining axis temporarily
99                 do_release(force, modifier);
100                 current_axis = angle;
101                 modifier = get_single_modifier(modifier, event->state); 
102             } else {
103                 do_motion(force, modifier);
104             }
105         }
106         gobble_motion_events(GDK_BUTTON1_MASK);
107         return true;
108                 } 
109                 return false; 
113 bool Rotateable::on_release(GdkEventButton *event) {
114                 if (dragging && working) {
115         double angle = atan2(event->y - drag_started_y, event->x - drag_started_x);
116         double force = CLAMP (-(angle - current_axis)/maxdecl, -1, 1);
117         if (fabs(force) < 0.002)
118             force = 0; // snap to zero
119         do_release(force, modifier);
120         current_axis = axis;
121         dragging = false;
122         working = false;
123         return true;
124                 }
125     dragging = false;
126     working = false;
127                 return false;
131 Rotateable::~Rotateable() {
136 } // namespace Widget
137 } // namespace UI
138 } // namespace Inkscape
140 /* 
141   Local Variables:
142   mode:c++
143   c-file-style:"stroustrup"
144   c-file-offsets:((innamespace . 0)(inline-open . 0))
145   indent-tabs-mode:nil
146   fill-column:99
147   End:
148 */
149 // vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :