12#include <gdk/gdkkeysyms.h>
50 , _position(initial_pos)
114 char *dyntip = g_strdup_vprintf(format, args);
116 Glib::ustring ret = dyntip;
143 g_warning(
"ControlPoint: desktop pointers not equal!");
149 static unsigned next_release_doubleclick = 0;
154 int const drag_tolerance = prefs->getIntLimited(
"/options/dragtolerance/value", 0, 0, 100);
158 auto key_event_handler = [
this] (
KeyEvent const &event) {
175 if (event.num_press == 1) {
176 next_release_doubleclick = 0;
177 if (event.button == 1 && !tool->is_space_panning()) {
180 _drag_event_origin = event.pos;
181 pointer_offset = _position - _desktop->w2d(_drag_event_origin);
182 _drag_initiated = false;
184 _canvas_item_ctrl->grab(grab_event_mask);
186 _setState(STATE_CLICKED);
191 }
else if (event.num_press == 2) {
193 next_release_doubleclick = event.button;
199 if (_event_grab && !tool->is_space_panning()) {
200 _desktop->getSnapIndicator()->remove_snaptarget();
201 bool transferred =
false;
202 if (!_drag_initiated) {
203 if (
Geom::LInfty(event.pos - _drag_event_origin) <= drag_tolerance) {
209 _drag_origin = _position;
210 transferred = grabbed(event);
212 _drag_initiated =
true;
217 auto new_pos = _desktop->w2d(event.pos) + pointer_offset;
219 dragged(new_pos, event);
221 _updateDragTip(event);
223 _desktop->getCanvas()->enable_autoscroll();
224 _desktop->set_coordinate_status(_position);
231 [&] (ButtonReleaseEvent
const &event) {
232 if (_event_grab && event.button == 1) {
239 tool->process_delayed_snap_event();
241 _canvas_item_ctrl->ungrab();
242 _setMouseover(
this, event.modifiers);
245 if (_drag_initiated) {
247 _drag_initiated =
false;
252 if (next_release_doubleclick) {
253 _double_clicked =
true;
254 ret = doubleclicked(event);
256 ret = clicked(event);
262 [&] (EnterEvent
const &event) {
263 _setMouseover(
this, event.modifiers);
267 [&] (LeaveEvent
const &event) {
274 [&] (KeyPressEvent
const &event) {
276 case GDK_KEY_Escape: {
278 if (!_drag_initiated)
break;
281 tool->discard_delayed_snap_event();
282 auto &snapprefs = _desktop->getNamedView()->snap_manager.snapprefs;
283 bool snap_save = snapprefs.getSnapEnabledGlobally();
284 snapprefs.setSnapEnabledGlobally(
false);
286 auto new_pos = _drag_origin;
291 auto fake = MotionEvent();
292 fake.pos = _drag_event_origin;
294 fake.time =
event.time;
295 fake.control_point_synthesized =
true;
296 dragged(new_pos, fake);
298 _canvas_item_ctrl->ungrab();
301 _drag_initiated =
false;
304 snapprefs.setSnapEnabledGlobally(snap_save);
311 if (
auto th =
dynamic_cast<TransformHandle*
>(
this)) {
312 th->getNextClosestPoint(
false);
318 case GDK_KEY_ISO_Left_Tab: {
321 if (
auto th =
dynamic_cast<TransformHandle*
>(
this)) {
322 th->getNextClosestPoint(
true);
332 ret = key_event_handler(event);
335 [&] (KeyReleaseEvent
const &event) {
336 ret = key_event_handler(event);
339 [&] (CanvasEvent
const &event) {}
343 return ret || _event_grab;
354 if (
visible && mouseovered_point != p) {
355 mouseovered_point = p;
356 signal_mouseover_change.emit(mouseovered_point);
360bool ControlPoint::_updateTip(
unsigned state)
362 Glib::ustring tip = _getTip(state);
368 _desktop->getTool()->defaultMessageContext()->clear();
375 if (!_hasDragTips()) {
378 Glib::ustring tip = _getDragTip(event);
384 _desktop->getTool()->defaultMessageContext()->clear();
389void ControlPoint::_clearMouseover()
391 if (mouseovered_point) {
392 mouseovered_point->_desktop->getTool()->defaultMessageContext()->clear();
393 mouseovered_point->_setState(STATE_NORMAL);
394 mouseovered_point =
nullptr;
395 signal_mouseover_change.emit(mouseovered_point);
401 if (!_event_grab)
return;
407 _drag_initiated =
true;
413void ControlPoint::_setState(
State state)
415 _canvas_item_ctrl->set_normal(_selected_appearance);
420 case STATE_MOUSEOVER:
421 _canvas_item_ctrl->set_hover();
424 _canvas_item_ctrl->set_click();
430void ControlPoint::set_selected_appearance(
bool selected) {
431 if (_selected_appearance == selected)
return;
433 _selected_appearance = selected;
434 _canvas_item_ctrl->set_selected(selected);
438void ControlPoint::_handleControlStyling()
440 _canvas_item_ctrl->set_size_default();
445 return event.control_point_synthesized;
Cartesian point / 2D vector and related operations.
3x3 matrix representing an affine transformation.
Two-dimensional point that doubles as a vector.
static Preferences * get()
Access the singleton Preferences object.
Draggable point, the workhorse of on-canvas editing.
bool _updateTip(unsigned state)
static Geom::Point _drag_origin
Stores the desktop point from which the last drag was initiated.
void _setControlType(Inkscape::CanvasItemCtrlType type)
Geom::Point const & position() const
Current position of the control point.
static sigc::signal< void(ControlPoint *)> signal_mouseover_change
Emitted when the mouseovered point changes.
static void _clearMouseover()
static Geom::Point _drag_event_origin
Stores the window point over which the cursor was during the last mouse button press.
virtual void move(Geom::Point const &pos)
Move the control point to new position with side effects.
static Glib::ustring format_tip(char const *format,...) G_GNUC_PRINTF(1
ControlPoint(ControlPoint const &other)=delete
static ControlPoint * mouseovered_point
Holds the currently mouseovered control point.
virtual void setVisible(bool v)
Set the visibility of the control point.
virtual void _setState(State state)
Change the state of the knot.
virtual void setPosition(Geom::Point const &pos)
Relocate the control point without side effects.
State
Enumeration representing the possible states of the control point, used to determine its appearance.
SPDesktop *const _desktop
The desktop this control point resides on.
static Glib::ustring virtual bool _eventHandler(Inkscape::UI::Tools::ToolBase *event_context, CanvasEvent const &event)
sigc::scoped_connection _event_handler_connection
static bool _drag_initiated
CanvasItemPtr< Inkscape::CanvasItemCtrl > _canvas_item_ctrl
Visual representation of the control point.
virtual void transform(Geom::Affine const &m)
Apply an arbitrary affine transformation to a control point.
void _setSize(unsigned int size)
Geom::Point _position
Current position in desktop coordinates.
To do: update description of desktop.
Inkscape::CanvasItemGroup * getCanvasControls() const
Inkscape::UI::Tools::ToolBase * getTool() const
Editable view implementation.
constexpr Coord infinity()
Get a value representing infinity.
Interface for locally managing a current status message.
Coord LInfty(Point const &p)
static constexpr auto grab_event_mask
Events which should be captured when a handle is being dragged.
void inspect_event(E &&event, Fs... funcs)
Perform pattern-matching on a CanvasEvent.
int const char va_start(args, fmt)
Provides a class that shows a temporary indicator on the canvas of where the snap was,...
Abstract base class for events.
unsigned modifiers
The modifiers mask immediately before the event.
virtual unsigned modifiersChange() const
Get the change in the modifiers due to this event.
Movement of the mouse pointer.