/* Authors:
* Krzysztof KosiĆski <tweenk.pl@gmail.com>
* Jon A. Cruz <jon@joncruz.org>
*
* Copyright (C) 2009 Authors
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#include <iostream>
#include <gdk/gdkkeysyms.h>
#include <gdkmm.h>
#include "desktop.h"
#include "display/sp-canvas.h"
#include "display/snap-indicator.h"
#include "ui/tools/tool-base.h"
#include "message-context.h"
#include "preferences.h"
#include "snap-preferences.h"
#include "sp-namedview.h"
#include "ui/control-manager.h"
#include "ui/tool/control-point.h"
#include "ui/tool/event-utils.h"
#include "ui/tool/transform-handle-set.h"
namespace Inkscape {
namespace UI {
// Default colors for control points
{0xffffff00, 0x01000000}, // normal fill, stroke
{0xff0000ff, 0x01000000}, // mouseover fill, stroke
{0x0000ffff, 0x01000000}, // clicked fill, stroke
//
{0x0000ffff, 0x000000ff}, // normal fill, stroke when selected
{0xff000000, 0x000000ff}, // mouseover fill, stroke when selected
{0xff000000, 0x000000ff} // clicked fill, stroke when selected
};
{0x00000000, 0x00000000},
{0x00000000, 0x00000000},
{0x00000000, 0x00000000},
{0x00000000, 0x00000000},
{0x00000000, 0x00000000},
{0x00000000, 0x00000000}
};
_desktop(d),
_lurking(false),
_double_clicked(false)
{
_commonInit();
}
_desktop(d),
_lurking(false),
_double_clicked(false)
{
_canvas_item = ControlManager::getManager().createControl(group ? group : _desktop->getControls(), type);
"anchor", anchor,
_commonInit();
}
{
// avoid storing invalid points in mouseovered_point
if (this == mouseovered_point) {
}
//sp_canvas_item_hide(_canvas_item);
}
{
G_CALLBACK(_event_handler), this);
}
{
}
{
}
}
{
return sp_canvas_item_is_visible(_canvas_item);
}
{
if (v) sp_canvas_item_show(_canvas_item);
else sp_canvas_item_hide(_canvas_item);
}
{
return ret;
}
{
double ret;
return static_cast<unsigned int>(ret);
}
{
return ret;
}
{
return ret;
}
{
}
// Same for setters.
{
}
{
}
{
}
{
}
// re-routes events into the virtual function
{
return FALSE;
}
}
// main event callback, which emits all other callbacks.
{
// NOTE the static variables below are shared for all points!
// TODO handle clicks and drags from other buttons too
{
return false;
}
if (event_context == NULL)
{
return false;
}
{
return false;
}
{
g_warning ("ControlPoint: desktop pointers not equal!");
//return false;
}
// offset from the pointer hotspot to the center of the grabbed knot in desktop coords
// number of last doubleclicked button
static unsigned next_release_doubleclick = 0;
_double_clicked = false;
{
case GDK_BUTTON_PRESS:
// 1st mouse button click. internally, start dragging, but do not emit signals
// or change position until drag tolerance is exceeded.
_drag_initiated = false;
// route all events to this handler
_event_grab = true;
return true;
}
return _event_grab;
case GDK_2BUTTON_PRESS:
// store the button number for next release
return true;
case GDK_MOTION_NOTIFY:
bool transferred = false;
if (!_drag_initiated) {
if (t){
return true;
}
// if we are here, it means the tolerance was just exceeded.
// _drag_initiated might change during the above virtual call
if (!_drag_initiated) {
// this guarantees smooth redraws while dragging
_drag_initiated = true;
}
}
if (!transferred) {
// dragging in progress
// the new position is passed by reference and can be changed in the handlers.
}
return true;
}
break;
case GDK_BUTTON_RELEASE:
// If we have any pending snap event, then invoke it now!
// (This is needed because we might not have snapped on the latest GDK_MOTION_NOTIFY event
// if the mouse speed was too high. This is inherent to the snap-delay mechanism.
// We must snap at some point in time though, and this is our last chance)
// PS: For other contexts this is handled already in sp_event_context_item_handler or
// sp_event_context_root_handler
//if (_desktop && _desktop->event_context && _desktop->event_context->_delayed_snap_event) {
if (event_context->_delayed_snap_event) {
}
_event_grab = false;
if (_drag_initiated) {
// it is the end of a drag
_drag_initiated = false;
return true;
} else {
// it is the end of a click
if (next_release_doubleclick) {
_double_clicked = true;
} else {
}
}
}
break;
case GDK_ENTER_NOTIFY:
return true;
case GDK_LEAVE_NOTIFY:
return true;
case GDK_GRAB_BROKEN:
{
if (_drag_initiated) {
}
}
_event_grab = false;
_drag_initiated = false;
return true;
}
break;
// update tips on modifier state change
// TODO add ESC keybinding as drag cancel
case GDK_KEY_PRESS:
{
case GDK_KEY_Escape: {
// ignore Escape if this is not a drag
if (!_drag_initiated) break;
// temporarily disable snapping - we might snap to a different place than we were initially
snapprefs.setSnapEnabledGlobally(false);
// make a fake event for dragging
// ASSUMPTION: dragging a point without modifiers will never prevent us from moving it
// to its original position
_clearMouseover(); // this will also reset state to normal
_event_grab = false;
_drag_initiated = false;
}
return true;
case GDK_KEY_Tab:
{// Downcast from ControlPoint to TransformHandle, if possible
// This is an ugly hack; we should have the transform handle intercept the keystrokes itself
if (th) {
th->getNextClosestPoint(false);
return true;
}
break;
}
case GDK_KEY_ISO_Left_Tab:
{// Downcast from ControlPoint to TransformHandle, if possible
// This is an ugly hack; we should have the transform handle intercept the keystrokes itself
if (th) {
th->getNextClosestPoint(true);
return true;
}
break;
}
default:
break;
}
// Do not break here, to allow for updating tooltips and such
case GDK_KEY_RELEASE:
if (mouseovered_point != this){
return false;
}
if (_drag_initiated) {
return true; // this prevents the tool from overwriting the drag tip
} else {
// we need to return true if there was a tip available, otherwise the tool's
// handler will process this event and set the tool's message, overwriting
// the point's message
return _updateTip(state);
}
}
break;
default: break;
}
// do not propagate events during grab - it might cause problems
return _event_grab;
}
{
if (visible) { // invisible points shouldn't get mouseovered
p->_setState(STATE_MOUSEOVER);
}
p->_updateTip(state);
if (visible && mouseovered_point != p) {
mouseovered_point = p;
}
}
{
return true;
} else {
return false;
}
}
{
if (!_hasDragTips()) {
return false;
}
return true;
} else {
return false;
}
}
{
if (mouseovered_point) {
mouseovered_point = 0;
}
}
{
if (!_event_grab) return;
if (!_drag_initiated) {
_drag_initiated = true;
}
}
{
switch(state) {
case STATE_NORMAL:
break;
case STATE_MOUSEOVER:
break;
case STATE_CLICKED:
break;
};
}
{
}
}
{
}
{
return _lurking;
}
{
}
}
{
}
// dummy implementations for handlers
{
return false;
}
{
}
{
}
{
return false;
}
{
return false;
}
} // namespace UI
} // namespace Inkscape
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :