diff options
| author | bulia byak <buliabyak@gmail.com> | 2007-10-24 00:56:44 +0000 |
|---|---|---|
| committer | buliabyak <buliabyak@users.sourceforge.net> | 2007-10-24 00:56:44 +0000 |
| commit | c07f56967ee699f37a95daf3ecbd44871c9d6b87 (patch) | |
| tree | 547ac714b1881ee502e5c98460ff9f2fe8e507e9 /src/ui/widget/rotateable.cpp | |
| parent | rename master opacity to opacity (diff) | |
| download | inkscape-c07f56967ee699f37a95daf3ecbd44871c9d6b87.tar.gz inkscape-c07f56967ee699f37a95daf3ecbd44871c9d6b87.zip | |
new class for widgets adjustable by rotation-like gestures
(bzr r3949)
Diffstat (limited to 'src/ui/widget/rotateable.cpp')
| -rw-r--r-- | src/ui/widget/rotateable.cpp | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/ui/widget/rotateable.cpp b/src/ui/widget/rotateable.cpp new file mode 100644 index 000000000..e434c10c5 --- /dev/null +++ b/src/ui/widget/rotateable.cpp @@ -0,0 +1,137 @@ +/** + * \brief widget adjustable by dragging it to rotate away from a zero-change axis + * + * Authors: + * buliabyak@gmail.com + * + * Copyright (C) 2007 authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#include "event-context.h" +#include "rotateable.h" +#include "libnr/nr-point.h" +#include "libnr/nr-point-fns.h" +#include <gtkmm/box.h> +#include <gtkmm/eventbox.h> +#include <glibmm/i18n.h> + +namespace Inkscape { +namespace UI { +namespace Widget { + + Rotateable::Rotateable(): + axis(-M_PI/4), + maxdecl(M_PI/4) + { + dragging = false; + working = false; + modifier = 0; + current_axis = axis; + + signal_button_press_event().connect(sigc::mem_fun(*this, &Rotateable::on_click)); + signal_motion_notify_event().connect(sigc::mem_fun(*this, &Rotateable::on_motion)); + signal_button_release_event().connect(sigc::mem_fun(*this, &Rotateable::on_release)); + } + + bool Rotateable::on_click(GdkEventButton *event) { + if (event->button == 1) { + drag_started_x = event->x; + drag_started_y = event->y; + modifier = get_single_modifier(modifier, event->state); + dragging = true; + working = false; + current_axis = axis; + return true; + } + return false; + } + + guint Rotateable::get_single_modifier(guint old, guint state) { + + if (old == 0) { + if (state & GDK_CONTROL_MASK) + return 1; // ctrl + if (state & GDK_SHIFT_MASK) + return 2; // shift + return 0; + } else { + if (!(state & GDK_CONTROL_MASK) && !(state & GDK_SHIFT_MASK)) + return 0; // none + if (old == 1) + if (state & GDK_SHIFT_MASK && !(state & GDK_CONTROL_MASK)) + return 2; // shift + else + return 1; + if (old == 2) + if (state & GDK_CONTROL_MASK && !(state & GDK_SHIFT_MASK)) + return 1; // ctrl + else + return 2; + return old; + } + } + + + bool Rotateable::on_motion(GdkEventMotion *event) { + if (dragging) { + double dist = NR::L2(NR::Point(event->x, event->y) - NR::Point(drag_started_x, drag_started_y)); + double angle = atan2(event->y - drag_started_y, event->x - drag_started_x); + if (dist > 20) { + working = true; + double force = CLAMP (-(angle - current_axis)/maxdecl, -1, 1); + if (fabs(force) < 0.002) + force = 0; // snap to zero + if (modifier != get_single_modifier(modifier, event->state)) { + // user has switched modifiers in mid drag, close past drag and start a new + // one, redefining axis temporarily + do_release(force, modifier); + current_axis = angle; + modifier = get_single_modifier(modifier, event->state); + } else { + do_motion(force, modifier); + } + } + gobble_motion_events(GDK_BUTTON1_MASK); + return true; + } + return false; + } + + + bool Rotateable::on_release(GdkEventButton *event) { + if (dragging && working) { + double angle = atan2(event->y - drag_started_y, event->x - drag_started_x); + double force = CLAMP (-(angle - current_axis)/maxdecl, -1, 1); + if (fabs(force) < 0.002) + force = 0; // snap to zero + do_release(force, modifier); + dragging = false; + working = false; + current_axis = axis; + return true; + } + return false; + } + + + Rotateable::~Rotateable() { + } + + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : |
