Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
snap-indicator.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Provides a class that shows a temporary indicator on the canvas of where the snap was, and what kind of snap
4 *
5 * Authors:
6 * Johan Engelen
7 * Diederik van Lierop
8 *
9 * Copyright (C) Johan Engelen 2009 <j.b.c.engelen@utwente.nl>
10 * Copyright (C) Diederik van Lierop 2010 - 2012 <mail@diedenrezi.nl>
11 *
12 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
13 */
14
15#include <glibmm/i18n.h>
16#include <string>
17#include <iomanip>
18#include <unordered_map>
19
20#include "snap-indicator.h"
21
22#include "desktop.h"
23#include "enums.h"
24#include "preferences.h"
25#include "util/units.h"
26#include "document.h"
27
28
29#include "canvas-item-ctrl.h"
30#include "canvas-item-rect.h"
31#include "canvas-item-text.h"
32#include "canvas-item-curve.h"
33
36
37#define DISTANCE_BG_RADIUS 0.3
38
39namespace Inkscape {
40namespace Display {
41
42static std::map<SnapSourceType, Glib::ustring> source2string = {
43 {SNAPSOURCE_UNDEFINED, _("UNDEFINED")},
44 {SNAPSOURCE_BBOX_CORNER, _("Bounding box corner")},
45 {SNAPSOURCE_BBOX_MIDPOINT, _("Bounding box midpoint")},
46 {SNAPSOURCE_BBOX_EDGE_MIDPOINT, _("Bounding box side midpoint")},
47 {SNAPSOURCE_NODE_SMOOTH, _("Smooth node")},
48 {SNAPSOURCE_NODE_CUSP, _("Cusp node")},
49 {SNAPSOURCE_LINE_MIDPOINT, _("Line midpoint")},
50 {SNAPSOURCE_PATH_INTERSECTION, _("Path intersection")},
51 {SNAPSOURCE_RECT_CORNER, _("Corner")},
52 {SNAPSOURCE_CONVEX_HULL_CORNER, _("Convex hull corner")},
53 {SNAPSOURCE_ELLIPSE_QUADRANT_POINT, _("Quadrant point")},
54 {SNAPSOURCE_NODE_HANDLE, _("Handle")},
55 {SNAPSOURCE_GUIDE, _("Guide")},
56 {SNAPSOURCE_GUIDE_ORIGIN, _("Guide origin")},
57 {SNAPSOURCE_ROTATION_CENTER, _("Object rotation center")},
58 {SNAPSOURCE_OBJECT_MIDPOINT, _("Object midpoint")},
59 {SNAPSOURCE_IMG_CORNER, _("Corner")},
60 {SNAPSOURCE_TEXT_ANCHOR, _("Text anchor")},
61 {SNAPSOURCE_OTHER_HANDLE, _("Handle")},
62 {SNAPSOURCE_GRID_PITCH, _("Multiple of grid spacing")},
63 {SNAPSOURCE_PAGE_CORNER, _("Page corner")},
64 {SNAPSOURCE_PAGE_CENTER, _("Page center")},
65};
66
67static std::map<SnapTargetType, Glib::ustring> target2string = {
68 {SNAPTARGET_UNDEFINED, _("UNDEFINED")},
69 {SNAPTARGET_BBOX_CORNER, _("bounding box corner")},
70 {SNAPTARGET_BBOX_EDGE, _("bounding box side")},
71 {SNAPTARGET_BBOX_EDGE_MIDPOINT, _("bounding box side midpoint")},
72 {SNAPTARGET_BBOX_MIDPOINT, _("bounding box midpoint")},
73 {SNAPTARGET_NODE_SMOOTH, _("smooth node")},
74 {SNAPTARGET_NODE_CUSP, _("cusp node")},
75 {SNAPTARGET_LINE_MIDPOINT, _("line midpoint")},
76 {SNAPTARGET_PATH, _("path")},
77 {SNAPTARGET_PATH_PERPENDICULAR, _("path (perpendicular)")},
78 {SNAPTARGET_PATH_TANGENTIAL, _("path (tangential)")},
79 {SNAPTARGET_PATH_INTERSECTION, _("path intersection")},
80 {SNAPTARGET_PATH_GUIDE_INTERSECTION, _("guide-path intersection")},
81 {SNAPTARGET_PATH_CLIP, _("clip-path")},
82 {SNAPTARGET_PATH_MASK, _("mask-path")},
83 {SNAPTARGET_ELLIPSE_QUADRANT_POINT, _("quadrant point")},
84 {SNAPTARGET_RECT_CORNER, _("corner")},
85 {SNAPTARGET_GRID_LINE, _("grid line")},
86 {SNAPTARGET_GRID_INTERSECTION, _("grid intersection")},
87 {SNAPTARGET_GRID_PERPENDICULAR, _("grid line (perpendicular)")},
88 {SNAPTARGET_GUIDE, _("guide")},
89 {SNAPTARGET_GUIDE_INTERSECTION, _("guide intersection")},
90 {SNAPTARGET_GUIDE_ORIGIN, _("guide origin")},
91 {SNAPTARGET_GUIDE_PERPENDICULAR, _("guide (perpendicular)")},
92 {SNAPTARGET_GRID_GUIDE_INTERSECTION, _("grid-guide intersection")},
93 {SNAPTARGET_PAGE_EDGE_BORDER, _("page border")},
94 {SNAPTARGET_PAGE_EDGE_CORNER, _("page corner")},
95 {SNAPTARGET_PAGE_EDGE_CENTER, _("page center")},
96 {SNAPTARGET_PAGE_MARGIN_BORDER, _("page margin border")},
97 {SNAPTARGET_PAGE_MARGIN_CORNER, _("page margin corner")},
98 {SNAPTARGET_PAGE_MARGIN_CENTER, _("page margin center")},
99 {SNAPTARGET_PAGE_BLEED_BORDER, _("page bleed border")},
100 {SNAPTARGET_PAGE_BLEED_CORNER, _("page bleed corner")},
101 {SNAPTARGET_OBJECT_MIDPOINT, _("object midpoint")},
102 {SNAPTARGET_IMG_CORNER, _("corner")},
103 {SNAPTARGET_ROTATION_CENTER, _("object rotation center")},
104 {SNAPTARGET_TEXT_ANCHOR, _("text anchor")},
105 {SNAPTARGET_TEXT_BASELINE, _("text baseline")},
106 {SNAPTARGET_CONSTRAINED_ANGLE, _("constrained angle")},
107 {SNAPTARGET_CONSTRAINT, _("constraint")},
108};
109
111 : _snaptarget(nullptr),
112 _snaptarget_tooltip(nullptr),
113 _snaptarget_bbox(nullptr),
114 _snapsource(nullptr),
115 _snaptarget_is_presnap(false),
116 _desktop(desktop)
117{
118}
119
121{
122 // remove item that might be present
125}
126
127void
129{
130 remove_snaptarget(); //only display one snaptarget at a time
131
132 g_assert(_desktop != nullptr);
133
134 if (!p.getSnapped()) {
135 return; // If we haven't snapped, then it is of no use to draw a snapindicator
136 }
137
138 if (p.getTarget() == SNAPTARGET_CONSTRAINT) {
139 // This is not a real snap, although moving along the constraint did affect the mouse pointer's position.
140 // Maybe we should only show a snap indicator when the user explicitly asked for a constraint by pressing ctrl?
141 // We should not show a snap indicator when stretching a selection box, which is also constrained. That would be
142 // too much information.
143 return;
144 }
145
146 bool is_alignment = p.getAlignmentTarget().has_value();
147 bool is_distribution = p.getTarget() & SNAPTARGET_DISTRIBUTION_CATEGORY;
148
150 double scale = prefs->getDouble("/tools/measure/scale", 100.0) / 100.0;
151
152 bool value = prefs->getBool("/options/snapindicator/value", true);
153
154 if (value) {
155 Glib::ustring target_name = _("UNDEFINED");
156 Glib::ustring source_name = _("UNDEFINED");
157
158 if (!is_alignment && !is_distribution) {
159 if (target2string.find(p.getTarget()) == target2string.end())
160 g_warning("Target type %i not present in target2string", p.getTarget());
161
162 if (source2string.find(p.getSource()) == source2string.end())
163 g_warning("Source type %i not present in target2string", p.getSource());
164
165 target_name = _(target2string[p.getTarget()].c_str());
166 source_name = _(source2string[p.getSource()].c_str());
167 }
168 //std::cout << "Snapped " << source_name << " to " << target_name << std::endl;
169
170 remove_snapsource(); // Don't set both the source and target indicators, as these will overlap
171
172 double timeout_val = prefs->getDouble("/options/snapindicatorpersistence/value", 2.0);
173 if (timeout_val < 0.1) {
174 timeout_val = 0.1; // a zero value would mean infinite persistence (i.e. until new snap occurs)
175 // Besides, negatives values would ....?
176 }
177
178 // TODO: should this be a constant or a separate prefrence
179 // we are using the preference of measure tool here.
180 double fontsize = prefs->getDouble("/tools/measure/fontsize", 10.0);
181
182 if (is_distribution) {
184 }
185
186 if (is_alignment) {
187 auto color = pre_snap ? 0x7f7f7fff : get_guide_color(p.getAlignmentTargetType());
188 make_alignment_indicator(p.getPoint(), *p.getAlignmentTarget(), color, fontsize, scale);
190 make_alignment_indicator(p.getPoint(), *p.getAlignmentTarget2(), color, fontsize, scale);
191 }
192 }
193
194 _snaptarget_is_presnap = pre_snap;
195
196 // Display the snap indicator (i.e. the cross)
198
199 if (!is_alignment && !is_distribution) {
200 // Display snap indicator at snap target
202 ctrl->set_selected(!pre_snap);
203
204 _snaptarget = _desktop->add_temporary_canvasitem(ctrl, timeout_val*1000.0);
205 // The snap indicator will be deleted after some time-out, and sp_canvas_item_dispose
206 // will be called. This will set canvas->current_item to NULL if the snap indicator was
207 // the current item, after which any events will go to the root handler instead of any
208 // item handler. Dragging an object which has just snapped might therefore not be possible
209 // without selecting / repicking it again. To avoid this, we make sure here that the
210 // snap indicator will never be picked, and will therefore never be the current item.
211 // Reported bugs:
212 // - scrolling when hovering above a pre-snap indicator won't work (for example)
213 // (https://bugs.launchpad.net/inkscape/+bug/522335/comments/8)
214 // - dragging doesn't work without repicking
215 // (https://bugs.launchpad.net/inkscape/+bug/1420301/comments/15)
216 ctrl->set_pickable(false);
217
218 // Display the tooltip, which reveals the type of snap source and the type of snap target
219 Glib::ustring tooltip_str;
221 tooltip_str = source_name + _(" to ") + target_name;
222 } else if (p.getSource() != SNAPSOURCE_UNDEFINED) {
223 tooltip_str = source_name;
224 }
225
226
227 if (!tooltip_str.empty()) {
228 Geom::Point tooltip_pos = p.getPoint();
229 if (dynamic_cast<Inkscape::UI::Tools::MeasureTool *>(_desktop->getTool())) {
230 // Make sure that the snap tooltips do not overlap the ones from the measure tool
231 tooltip_pos += _desktop->w2d(Geom::Point(0, -3*fontsize));
232 } else {
233 tooltip_pos += _desktop->w2d(Geom::Point(0, -2*fontsize));
234 }
235
236 auto canvas_tooltip = new Inkscape::CanvasItemText(_desktop->getCanvasTemp(), tooltip_pos, tooltip_str);
237 canvas_tooltip->set_fontsize(fontsize);
238 canvas_tooltip->set_fill(0xffffffff);
239 canvas_tooltip->set_background(pre_snap ? 0x33337f40 : 0x33337f7f);
240
241 _snaptarget_tooltip = _desktop->add_temporary_canvasitem(canvas_tooltip, timeout_val*1000.0);
242 }
243
244 // Display the bounding box, if we snapped to one
245 Geom::OptRect const bbox = p.getTargetBBox();
246 if (bbox) {
247 auto box = new Inkscape::CanvasItemRect(_desktop->getCanvasTemp(), *bbox);
248 box->set_stroke(pre_snap ? 0x7f7f7fff : 0xff0000ff);
249 box->set_dashed(true);
250 box->set_pickable(false); // Is false by default.
251 box->lower_to_bottom();
252 _snaptarget_bbox = _desktop->add_temporary_canvasitem(box, timeout_val*1000.0);
253 }
254 }
255 }
256}
257
258void
260{
261 if (only_if_presnap && !_snaptarget_is_presnap) {
262 return;
263 }
264
265 if (_snaptarget) {
267 _snaptarget = nullptr;
269 }
270
273 _snaptarget_tooltip = nullptr;
274 }
275
276 if (_snaptarget_bbox) {
278 _snaptarget_bbox = nullptr;
279 }
280
281 for (auto *item : _alignment_snap_indicators) {
283 }
285
286 for (auto *item : _distribution_snap_indicators) {
288 }
290}
291
292void
294{
296
297 g_assert(_desktop != nullptr); // If this fails, then likely setup() has not been called on the snap manager (see snap.cpp -> setup())
298
300 bool value = prefs->getBool("/options/snapindicator/value", true);
301
302 if (value) {
304 ctrl->set_position(p.getPoint());
306 }
307}
308
309void
317
318void
326
327void
329{
330 for (std::list<TemporaryItem *>::const_iterator i = _debugging_points.begin(); i != _debugging_points.end(); ++i) {
332 }
333 _debugging_points.clear();
334}
335
337{
338 switch(t) {
342 return 0xff0000ff;
348 return 0x00ff00ff;
350 return 0x0000ffff;
352 return 0xd13bd1ff;
353 default:
354 g_warning("Alignment guide color not handled %i", t);
355 return 0x000000ff;
356 }
357}
358
359std::pair<Geom::Coord, int> get_y_and_sign(Geom::Rect const &source, Geom::Rect const &target, double const offset)
360{
361 Geom::Coord y;
362 int sign;
363
364 // We add a margin of 5px here to make sure that very small movements of mouse
365 // pointer do not cause the position of distribution indicator to change.
366 if (source.midpoint().y() < target.midpoint().y() + 5) {
367 y = source.max().y() + offset;
368 sign = 1;
369 } else {
370 y = source.min().y() - offset;
371 sign = -1;
372 }
373
374 return {y, sign};
375}
376
377std::pair<Geom::Coord, int> get_x_and_sign(Geom::Rect const &source, Geom::Rect const &target, double const offset)
378{
379 Geom::Coord x;
380 int sign;
381
382 // We add a margin of 5px here to make sure that very small movements of mouse
383 // pointer do not cause the position of distribution indicator to change.
384 if (source.midpoint().x() < target.midpoint().x() + 5) {
385 x = source.max().x() + offset;
386 sign = 1;
387 } else {
388 x = source.min().x() - offset;
389 sign = -1;
390 }
391
392 return {x, sign};
393}
394
395void SnapIndicator::make_alignment_indicator(Geom::Point const &p1, Geom::Point const &p2, guint32 color, double fontsize, double scale)
396{
397 //make sure the line is straight
398 g_assert(p1.x() == p2.x() || p1.y() == p2.y());
399
400 Preferences *prefs = Preferences::get();
401 bool show_distance = prefs->getBool("/options/snapindicatordistance/value", false);
402
404
406 ctrl->set_position(p1);
407 ctrl->set_pickable(false);
409
411 ctrl->set_position(p2);
412 ctrl->set_pickable(false);
414
415 auto dist = Geom::L2(p2 - p1);
416 double offset = (fontsize + 5) / _desktop->current_zoom();
417 if (show_distance && dist > 2 * offset) {
418 auto direction = Geom::unit_vector(p1 - p2);
419 auto text_pos = (p1 + p2)/2;
420
421 Glib::ustring unit_name = _desktop->doc()->getDisplayUnit()->abbr.c_str();
422 if (!unit_name.compare("")) {
423 unit_name = DEFAULT_UNIT_NAME;
424 }
425
426 dist = Inkscape::Util::Quantity::convert(dist, "px", unit_name);
427
428 Glib::ustring distance = Inkscape::ustring::format_classic(std::fixed, std::setprecision(1), std::noshowpoint, scale*dist);
429
430 auto text = new Inkscape::CanvasItemText(_desktop->getCanvasTemp(), text_pos, distance);
431 text->set_fontsize(fontsize);
432 text->set_fill(color);
433 text->set_background(0xffffffc8);
434 text->set_bg_radius(DISTANCE_BG_RADIUS);
435 text->set_anchor({0.5, 0.5});
437
438 auto temp_point = text_pos + offset*direction;
439 line = new Inkscape::CanvasItemCurve(_desktop->getCanvasTemp(), p1, temp_point);
440 line->set_stroke(color);
441 line->set_bg_alpha(1.0f);
443
444 temp_point = text_pos - offset*direction;
445 line = new Inkscape::CanvasItemCurve(_desktop->getCanvasTemp(), temp_point, p2);
446 line->set_stroke(color);
447 line->set_bg_alpha(1.0f);
449 } else {
450 line = new Inkscape::CanvasItemCurve(_desktop->getCanvasTemp(), p1, p2);
451 line->set_stroke(color);
452 line->set_bg_alpha(1.0f);
454 }
455}
456
458{
459 Geom::Coord length = 10/_desktop->current_zoom();
460 auto line = new Inkscape::CanvasItemCurve(_desktop->getCanvasTemp(), p + Geom::Point(0, length/2), p - Geom::Point(0, length/2));
461 line->set_stroke(0xff5f1fff);
462 return line;
463}
464
466{
467 Geom::Coord length = 10/_desktop->current_zoom();
468 auto line = new Inkscape::CanvasItemCurve(_desktop->getCanvasTemp(), p + Geom::Point(length/2, 0), p - Geom::Point(length/2, 0));
469 line->set_stroke(0xff5f1fff);
470 return line;
471}
472
474 double fontsize,
475 double scale)
476{
477 Preferences *prefs = Preferences::get();
478 bool show_distance = prefs->getBool("/options/snapindicatordistance/value", false);
479
480 guint32 color = 0xff5f1fff;
481 guint32 text_fill = 0xffffffff;
482 guint32 text_bg = 0xff5f1fff; //0x33337f7f
483 Geom::Point text_pos;
484 double text_offset = (fontsize * 2);
485 // double line_offset = 5/_desktop->current_zoom();
486 double line_offset = 0;
487
488 Glib::ustring unit_name = _desktop->doc()->getDisplayUnit()->abbr.c_str();
489 if (!unit_name.compare("")) {
490 unit_name = DEFAULT_UNIT_NAME;
491 }
492 auto equal_dist = Inkscape::Util::Quantity::convert(p.getDistributionDistance(), "px", unit_name);
493 Glib::ustring distance = Inkscape::ustring::format_classic(std::fixed, std::setprecision(1), std::noshowpoint, scale*equal_dist);
494
495 switch (p.getTarget()) {
502 Geom::Point p1, p2;
503 Inkscape::CanvasItemCurve *point1, *point2;
504
505 for (auto it = p.getBBoxes().begin(); it + 1 != p.getBBoxes().end(); it++) {
506 switch (p.getTarget()) {
510 auto [y, sign] = get_y_and_sign(*it, *std::next(it), 5/_desktop->current_zoom());
511 p1 = Geom::Point(it->max().x() + line_offset, y);
512 p2 = Geom::Point(std::next(it)->min().x() - line_offset, y);
513 text_pos = (p1 + p2)/2 + _desktop->w2d(Geom::Point(0, sign*text_offset));
514
515 point1 = make_stub_line_v(p1);
516 point2 = make_stub_line_v(p2);
517 break;
518 }
519
523 auto [x, sign] = get_x_and_sign(*it, *std::next(it), 5/_desktop->current_zoom());
524 p1 = Geom::Point(x, it->max().y() + line_offset);
525 p2 = Geom::Point(x, std::next(it)->min().y() - line_offset);
526 text_pos = (p1 + p2)/2 + _desktop->w2d(Geom::Point(sign*text_offset, 0));
527
528 point1 = make_stub_line_h(p1);
529 point2 = make_stub_line_h(p2);
530 break;
531 }
532 }
533
536
537 auto line1 = new Inkscape::CanvasItemCurve(_desktop->getCanvasTemp(), p1, p2);
538 line1->set_stroke(color);
539 line1->set_width(2);
541
542 if (show_distance) {
543 auto text = new Inkscape::CanvasItemText(_desktop->getCanvasTemp(), text_pos, distance);
544 text->set_fontsize(fontsize);
545 text->set_fill(text_fill);
546 text->set_background(text_bg);
547 text->set_bg_radius(DISTANCE_BG_RADIUS);
548 text->set_anchor({0.5, 0.5});
550 }
551 }
552 break;
553 }
555 Geom::Point p1, p2;
556 Inkscape::CanvasItemCurve *point1, *point2;
557
558 auto equal_dist2 = Inkscape::Util::Quantity::convert(p.getDistributionDistance2(), "px", unit_name);
559 Glib::ustring distance2 = Inkscape::ustring::format_classic(std::fixed, std::setprecision(1), std::noshowpoint, scale*equal_dist2);
560
561 for (auto it = p.getBBoxes().begin(); it + 1 != p.getBBoxes().end(); it++) {
562 auto [y, sign] = get_y_and_sign(*it, *std::next(it), 5/_desktop->current_zoom());
563 p1 = Geom::Point(it->max().x() + line_offset, y);
564 p2 = Geom::Point(std::next(it)->min().x() - line_offset, y);
565 text_pos = (p1 + p2)/2 + _desktop->w2d(Geom::Point(0, sign*text_offset));
566
567 point1 = make_stub_line_v(p1);
568 point2 = make_stub_line_v(p2);
569
572
573 auto line1 = new Inkscape::CanvasItemCurve(_desktop->getCanvasTemp(), p1, p2);
574 line1->set_stroke(color);
575 line1->set_width(2);
577
578 if (show_distance) {
579 auto text = new Inkscape::CanvasItemText(_desktop->getCanvasTemp(), text_pos, distance);
580 text->set_fontsize(fontsize);
581 text->set_fill(text_fill);
582 text->set_background(text_bg);
583 text->set_bg_radius(DISTANCE_BG_RADIUS);
584 text->set_anchor({0.5, 0.5});
586 }
587 }
588
589 for (auto it = p.getBBoxes2().begin(); it + 1 != p.getBBoxes2().end(); it++) {
590 auto [x, sign] = get_x_and_sign(*it, *std::next(it), 5/_desktop->current_zoom());
591 p1 = Geom::Point(x, it->max().y() + line_offset);
592 p2 = Geom::Point(x, std::next(it)->min().y() - line_offset);
593 text_pos = (p1 + p2)/2 + _desktop->w2d(Geom::Point(sign*text_offset, 0));
594
595 point1 = make_stub_line_h(p1);
596 point2 = make_stub_line_h(p2);
597
600
601 auto line1 = new Inkscape::CanvasItemCurve(_desktop->getCanvasTemp(), p1, p2);
602 line1->set_stroke(color);
603 line1->set_width(2);
605
606 if (show_distance) {
607 auto text = new Inkscape::CanvasItemText(_desktop->getCanvasTemp(), text_pos, distance2);
608 text->set_fontsize(fontsize);
609 text->set_fill(text_fill);
610 text->set_background(text_bg);
611 text->set_bg_radius(DISTANCE_BG_RADIUS);
612 text->set_anchor({0.5, 0.5});
614 }
615 }
616
617 break;
618 }
619 }
620}
621
622} //namespace Display
623} /* namespace Inkscape */
624
625
626/*
627 Local Variables:
628 mode:c++
629 c-file-style:"stroustrup"
630 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
631 indent-tabs-mode:nil
632 fill-column:99
633 End:
634*/
635// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 :
double distance(Shape const *s, Geom::Point const &p)
Definition Shape.cpp:2136
double scale
Definition aa.cpp:228
CPoint midpoint() const
Get the point in the geometric center of the rectangle.
CPoint min() const
Get the corner of the rectangle with smallest coordinate values.
CPoint max() const
Get the corner of the rectangle with largest coordinate values.
Axis-aligned rectangle that can be empty.
Definition rect.h:203
Two-dimensional point that doubles as a vector.
Definition point.h:66
constexpr Coord y() const noexcept
Definition point.h:106
constexpr Coord x() const noexcept
Definition point.h:104
Axis aligned, non-empty rectangle.
Definition rect.h:92
void set_selected(bool selected=true)
void set_bg_alpha(float alpha)
Set background stroke alpha.
virtual void set_stroke(uint32_t rgba)
void set_pickable(bool pickable)
void make_alignment_indicator(Geom::Point const &p1, Geom::Point const &p2, guint32 color, double fontsize, double scale)
std::list< TemporaryItem * > _alignment_snap_indicators
void set_new_snapsource(Inkscape::SnapCandidatePoint const &p)
void remove_snaptarget(bool only_if_presnap=false)
Inkscape::CanvasItemCurve * make_stub_line_h(Geom::Point const &p)
std::list< TemporaryItem * > _distribution_snap_indicators
std::list< TemporaryItem * > _debugging_points
void make_distribution_indicators(SnappedPoint const &p, double fontsize, double scale)
void set_new_debugging_point(Geom::Point const &p)
guint32 get_guide_color(SnapTargetType t)
Inkscape::CanvasItemCurve * make_stub_line_v(Geom::Point const &p)
void set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap=false)
Preference storage class.
Definition preferences.h:61
bool getBool(Glib::ustring const &pref_path, bool def=false)
Retrieve a Boolean value.
double getDouble(Glib::ustring const &pref_path, double def=0.0, Glib::ustring const &unit="")
Retrieve a floating point value.
static Preferences * get()
Access the singleton Preferences object.
Class to store data for points which are snap candidates, either as a source or as a target.
Geom::Point const & getPoint() const
Class describing the result of an attempt to snap.
std::vector< Geom::Rect > const & getBBoxes2() const
std::optional< Geom::Point > getAlignmentTarget() const
Geom::Coord getDistributionDistance() const
Geom::OptRect const getTargetBBox() const
SnapTargetType getTarget() const
std::optional< Geom::Point > getAlignmentTarget2() const
Geom::Point getPoint() const
SnapTargetType getAlignmentTargetType() const
SnapSourceType getSource() const
Geom::Coord getDistributionDistance2() const
std::vector< Geom::Rect > const & getBBoxes() const
static double convert(double from_dist, Unit const *from, Unit const *to)
Convert distances.
Definition units.cpp:588
Glib::ustring abbr
Definition units.h:81
To do: update description of desktop.
Definition desktop.h:149
double current_zoom() const
Definition desktop.h:335
Inkscape::Display::TemporaryItem * add_temporary_canvasitem(Inkscape::CanvasItem *item, int lifetime_msecs, bool move_to_bottom=true)
One should not keep a reference to the SPCanvasItem, the temporary item code will delete the object f...
Definition desktop.cpp:229
Inkscape::CanvasItemGroup * getCanvasTemp() const
Definition desktop.h:202
void remove_temporary_canvasitem(Inkscape::Display::TemporaryItem *tempitem)
It is perfectly safe to call this function while the object has already been deleted due to a timeout...
Definition desktop.cpp:242
Inkscape::UI::Tools::ToolBase * getTool() const
Definition desktop.h:187
SPDocument * doc() const
Definition desktop.h:159
Geom::Affine const & w2d() const
Transformation from window to desktop coordinates (zoom/rotate).
Definition desktop.h:416
Inkscape::Util::Unit const * getDisplayUnit()
guaranteed not to return nullptr
Definition document.cpp:732
Editable view implementation.
unsigned int guint32
double Coord
Floating point type used to store coordinates.
Definition coord.h:76
SPItem * item
double offset
SBasis L2(D2< SBasis > const &a, unsigned k)
Definition d2-sbasis.cpp:42
Point unit_vector(Point const &a)
std::pair< Geom::Coord, int > get_x_and_sign(Geom::Rect const &source, Geom::Rect const &target, double const offset)
std::pair< Geom::Coord, int > get_y_and_sign(Geom::Rect const &source, Geom::Rect const &target, double const offset)
static std::map< SnapSourceType, Glib::ustring > source2string
static std::map< SnapTargetType, Glib::ustring > target2string
Glib::ustring format_classic(T const &... args)
Helper class to stream background task notifications as a series of messages.
@ SNAPSOURCE_NODE_CUSP
Definition snap-enums.h:37
@ SNAPSOURCE_BBOX_MIDPOINT
Definition snap-enums.h:26
@ SNAPSOURCE_GUIDE
Definition snap-enums.h:47
@ SNAPSOURCE_PATH_INTERSECTION
Definition snap-enums.h:39
@ SNAPSOURCE_UNDEFINED
Definition snap-enums.h:19
@ SNAPSOURCE_OTHER_HANDLE
Definition snap-enums.h:56
@ SNAPSOURCE_BBOX_CORNER
Definition snap-enums.h:25
@ SNAPSOURCE_TEXT_ANCHOR
Definition snap-enums.h:55
@ SNAPSOURCE_NODE_SMOOTH
Definition snap-enums.h:36
@ SNAPSOURCE_RECT_CORNER
Definition snap-enums.h:40
@ SNAPSOURCE_GUIDE_ORIGIN
Definition snap-enums.h:48
@ SNAPSOURCE_CONVEX_HULL_CORNER
Definition snap-enums.h:41
@ SNAPSOURCE_PAGE_CORNER
Definition snap-enums.h:31
@ SNAPSOURCE_GRID_PITCH
Definition snap-enums.h:57
@ SNAPSOURCE_OBJECT_MIDPOINT
Definition snap-enums.h:53
@ SNAPSOURCE_IMG_CORNER
Definition snap-enums.h:54
@ SNAPSOURCE_NODE_HANDLE
Definition snap-enums.h:43
@ SNAPSOURCE_LINE_MIDPOINT
Definition snap-enums.h:38
@ SNAPSOURCE_BBOX_EDGE_MIDPOINT
Definition snap-enums.h:27
@ SNAPSOURCE_PAGE_CENTER
Definition snap-enums.h:30
@ SNAPSOURCE_ELLIPSE_QUADRANT_POINT
Definition snap-enums.h:42
@ SNAPSOURCE_ROTATION_CENTER
Definition snap-enums.h:52
@ SNAPTARGET_ALIGNMENT_BBOX_MIDPOINT
Definition snap-enums.h:127
@ SNAPTARGET_GUIDE_ORIGIN
Definition snap-enums.h:102
@ SNAPTARGET_BBOX_EDGE_MIDPOINT
Definition snap-enums.h:78
@ SNAPTARGET_UNDEFINED
Definition snap-enums.h:71
@ SNAPTARGET_ALIGNMENT_PAGE_MARGIN_CORNER
Definition snap-enums.h:132
@ SNAPTARGET_PATH_GUIDE_INTERSECTION
Definition snap-enums.h:89
@ SNAPTARGET_RECT_CORNER
Definition snap-enums.h:93
@ SNAPTARGET_CONSTRAINT
Definition snap-enums.h:121
@ SNAPTARGET_PAGE_MARGIN_BORDER
Definition snap-enums.h:108
@ SNAPTARGET_PATH
Definition snap-enums.h:85
@ SNAPTARGET_ALIGNMENT_PAGE_BLEED_CORNER
Definition snap-enums.h:133
@ SNAPTARGET_NODE_CUSP
Definition snap-enums.h:83
@ SNAPTARGET_DISTRIBUTION_XY
Definition snap-enums.h:146
@ SNAPTARGET_PAGE_MARGIN_CENTER
Definition snap-enums.h:109
@ SNAPTARGET_DISTRIBUTION_LEFT
Definition snap-enums.h:143
@ SNAPTARGET_TEXT_ANCHOR
Definition snap-enums.h:118
@ SNAPTARGET_DISTRIBUTION_DOWN
Definition snap-enums.h:145
@ SNAPTARGET_ROTATION_CENTER
Definition snap-enums.h:117
@ SNAPTARGET_LINE_MIDPOINT
Definition snap-enums.h:84
@ SNAPTARGET_GUIDE_PERPENDICULAR
Definition snap-enums.h:103
@ SNAPTARGET_ALIGNMENT_PAGE_EDGE_CENTER
Definition snap-enums.h:129
@ SNAPTARGET_PAGE_BLEED_CORNER
Definition snap-enums.h:112
@ SNAPTARGET_BBOX_MIDPOINT
Definition snap-enums.h:79
@ SNAPTARGET_GRID_INTERSECTION
Definition snap-enums.h:98
@ SNAPTARGET_NODE_SMOOTH
Definition snap-enums.h:82
@ SNAPTARGET_ALIGNMENT_INTERSECTION
Definition snap-enums.h:135
@ SNAPTARGET_PATH_CLIP
Definition snap-enums.h:90
@ SNAPTARGET_PAGE_EDGE_CENTER
Definition snap-enums.h:106
@ SNAPTARGET_GUIDE
Definition snap-enums.h:100
@ SNAPTARGET_DISTRIBUTION_UP
Definition snap-enums.h:144
@ SNAPTARGET_ELLIPSE_QUADRANT_POINT
Definition snap-enums.h:92
@ SNAPTARGET_DISTRIBUTION_CATEGORY
Definition snap-enums.h:139
@ SNAPTARGET_PAGE_EDGE_CORNER
Definition snap-enums.h:107
@ SNAPTARGET_ALIGNMENT_BBOX_EDGE_MIDPOINT
Definition snap-enums.h:128
@ SNAPTARGET_ALIGNMENT_PAGE_MARGIN_CENTER
Definition snap-enums.h:131
@ SNAPTARGET_PAGE_EDGE_BORDER
Definition snap-enums.h:105
@ SNAPTARGET_DISTRIBUTION_X
Definition snap-enums.h:140
@ SNAPTARGET_GRID_GUIDE_INTERSECTION
Definition snap-enums.h:104
@ SNAPTARGET_ALIGNMENT_HANDLE
Definition snap-enums.h:134
@ SNAPTARGET_TEXT_BASELINE
Definition snap-enums.h:119
@ SNAPTARGET_GRID_PERPENDICULAR
Definition snap-enums.h:99
@ SNAPTARGET_BBOX_EDGE
Definition snap-enums.h:77
@ SNAPTARGET_GUIDE_INTERSECTION
Definition snap-enums.h:101
@ SNAPTARGET_PATH_MASK
Definition snap-enums.h:91
@ SNAPTARGET_ALIGNMENT_PAGE_EDGE_CORNER
Definition snap-enums.h:130
@ SNAPTARGET_IMG_CORNER
Definition snap-enums.h:116
@ SNAPTARGET_ALIGNMENT_BBOX_CORNER
Definition snap-enums.h:126
@ SNAPTARGET_PAGE_MARGIN_CORNER
Definition snap-enums.h:110
@ SNAPTARGET_OBJECT_MIDPOINT
Definition snap-enums.h:115
@ SNAPTARGET_DISTRIBUTION_Y
Definition snap-enums.h:141
@ SNAPTARGET_BBOX_CORNER
Definition snap-enums.h:76
@ SNAPTARGET_GRID_LINE
Definition snap-enums.h:97
@ SNAPTARGET_PATH_TANGENTIAL
Definition snap-enums.h:87
@ SNAPTARGET_PATH_PERPENDICULAR
Definition snap-enums.h:86
@ SNAPTARGET_PATH_INTERSECTION
Definition snap-enums.h:88
@ SNAPTARGET_PAGE_BLEED_BORDER
Definition snap-enums.h:111
@ SNAPTARGET_DISTRIBUTION_RIGHT
Definition snap-enums.h:142
@ SNAPTARGET_CONSTRAINED_ANGLE
Definition snap-enums.h:120
@ CANVAS_ITEM_CTRL_TYPE_POINT
@ CANVAS_ITEM_CTRL_TYPE_MARKER
@ CANVAS_ITEM_CTRL_TYPE_SHAPER
Singleton class to access the preferences file in a convenient way.
static double sign(double const x)
Returns -1 or 1 according to the sign of x.
Provides a class that shows a temporary indicator on the canvas of where the snap was,...
SPDesktop * desktop