Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
selcue.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Helper object for showing selected items
4 *
5 * Authors:
6 * bulia byak <bulia@users.sf.net>
7 * Carl Hetherington <inkscape@carlh.net>
8 * Abhishek Sharma
9 *
10 * Copyright (C) 2004 Authors
11 *
12 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
13 */
14
15#include "selcue.h"
16
17#include <memory>
18
19#include "desktop.h"
24#include "object/sp-flowtext.h"
25#include "object/sp-text.h"
26#include "selection.h"
27#include "text-editing.h"
28
29namespace Inkscape {
30
32 : Observer("/tools/bounding_box")
33 , _sel_cue(sel_cue)
34{}
35
37{
38 _sel_cue._boundingBoxPrefsChanged(static_cast<int>(val.getBool()));
39}
40
44{
46
47 _sel_changed_connection = _selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &SelCue::_newItemBboxes)));
48
49 {
50 void (SelCue::*modifiedSignal)() = &SelCue::_updateItemBboxes;
52 _selection->connectModified(sigc::hide(sigc::hide(sigc::mem_fun(*this, modifiedSignal))));
53 }
54
56 _updateItemBboxes(prefs);
58}
59
61{
62 _sel_changed_connection.disconnect();
63 _sel_modified_connection.disconnect();
64}
65
70
72{
73 gint mode = prefs->getInt("/options/selcue/value", MARK);
74 if (mode == NONE) {
75 return;
76 }
77
78 g_return_if_fail(_selection != nullptr);
79
80 int prefs_bbox = prefs->getBool("/tools/bounding_box");
81
82 _updateItemBboxes(mode, prefs_bbox);
83}
84
85void SelCue::_updateItemBboxes(gint mode, int prefs_bbox)
86{
87 auto items = _selection->items();
88 if (_item_bboxes.size() != (unsigned int)boost::distance(items)) {
90 return;
91 }
92
93 int bcount = 0;
94 for (auto item : items) {
95 auto canvas_item = _item_bboxes[bcount++].get();
96
97 if (canvas_item) {
98 Geom::OptRect const b = (prefs_bbox == 0) ? item->desktopVisualBounds() : item->desktopGeometricBounds();
99
100 if (b) {
101 if (auto ctrl = dynamic_cast<CanvasItemCtrl *>(canvas_item)) {
102 ctrl->set_position(Geom::Point(b->min().x(), b->max().y()));
103 } else if (auto rect = dynamic_cast<CanvasItemRect *>(canvas_item)) {
104 rect->set_rect(*b);
105 }
106 canvas_item->set_visible(true);
107 } else { // no bbox
108 canvas_item->set_visible(false);
109 }
110 }
111 }
112
115}
116
118{
119 _item_bboxes.clear();
120
121 Preferences *prefs = Preferences::get();
122 gint mode = prefs->getInt("/options/selcue/value", MARK);
123 if (mode == NONE) {
124 return;
125 }
126
127 g_return_if_fail(_selection != nullptr);
128
129 int prefs_bbox = prefs->getBool("/tools/bounding_box");
130
131 auto items = _selection->items();
132 for (auto item : items) {
133 Geom::OptRect const bbox = (prefs_bbox == 0) ? item->desktopVisualBounds() : item->desktopGeometricBounds();
134
135 if (bbox) {
136 CanvasItemPtr<CanvasItem> canvas_item;
137
138 if (mode == MARK) {
139 auto ctrl = make_canvasitem<CanvasItemCtrl>(_desktop->getCanvasControls(), CANVAS_ITEM_CTRL_TYPE_SHAPER,
140 Geom::Point(bbox->min().x(), bbox->max().y()));
141 canvas_item = std::move(ctrl);
142 } else if (mode == BBOX) {
143 auto rect = make_canvasitem<CanvasItemRect>(_desktop->getCanvasControls(), *bbox);
144 rect->set_stroke(0xffffffa0);
145 rect->set_shadow(0x0000c0a0, 1);
146 rect->set_dashed(true);
147 rect->set_inverted(false);
148 canvas_item = std::move(rect);
149 }
150
151 if (canvas_item) {
152 canvas_item->set_pickable(false);
153 canvas_item->lower_to_bottom(); // Just low enough to not get in the way of other draggable knots.
154 canvas_item->set_visible(true);
155 _item_bboxes.emplace_back(std::move(canvas_item));
156 }
157 }
158 }
159
162}
163
168{
169 _item_lines.clear();
170
171 auto bbox = _selection->preferredBounds();
172
173 // Show a set of lines where the anchor is.
174 if (_selection->has_anchor && bbox) {
175 auto anchor = Geom::Scale(_selection->anchor);
176 auto point = bbox->min() + (bbox->dimensions() * anchor);
177 for (bool horz : {false, true}) {
178 auto line = make_canvasitem<CanvasItemGuideLine>(_desktop->getCanvasGuides(), "", point, Geom::Point(!horz, horz));
179 line->lower_to_bottom();
180 line->set_visible(true);
181 line->set_stroke(0xddddaa11);
182 line->set_inverted(true);
183 _item_lines.emplace_back(std::move(line));
184 }
185 }
186}
187
189{
190 _text_baselines.clear();
191
192 auto items = _selection->items();
193 for (auto item : items) {
194 std::optional<Geom::Point> pt;
195 if (auto text = cast<SPText>(item)) {
196 pt = text->getBaselinePoint();
197 } else if (auto flow = cast<SPFlowtext>(item)) {
198 pt = flow->getBaselinePoint();
199 }
200 if (pt) {
201 auto canvas_item = make_canvasitem<CanvasItemCtrl>(_desktop->getCanvasControls(), CANVAS_ITEM_CTRL_TYPE_SIZER, (*pt) * item->i2dt_affine());
202 canvas_item->set_size(Inkscape::HandleSize::XTINY);
203 canvas_item->lower_to_bottom();
204 canvas_item->set_visible(true);
205 _text_baselines.emplace_back(std::move(canvas_item));
206 }
207 }
208}
209
211{
212 Preferences *prefs = Preferences::get();
213 gint mode = prefs->getInt("/options/selcue/value", MARK);
214 if (mode == NONE) {
215 return;
216 }
217
218 g_return_if_fail(_selection != nullptr);
219
220 _updateItemBboxes(mode, prefs_bbox);
221}
222
223} // namespace Inkscape
224
225/*
226 Local Variables:
227 mode:c++
228 c-file-style:"stroustrup"
229 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
230 indent-tabs-mode:nil
231 fill-column:99
232 End:
233*/
234// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
std::unique_ptr< T, CanvasItemUnlinkDeleter > CanvasItemPtr
Smart pointer used to hold CanvasItems, like std::unique_ptr.
Axis-aligned rectangle that can be empty.
Definition rect.h:203
Two-dimensional point that doubles as a vector.
Definition point.h:66
Scaling from the origin.
Definition transforms.h:150
SPItemRange items()
Returns a range of selected SPItems.
Definition object-set.h:230
Geom::OptRect preferredBounds() const
Returns either the visual or geometric bounding rectangle of the selection, based on the preferences ...
Data type representing a typeless value of a preference.
bool getBool(bool def=false) const
Interpret the preference as a Boolean value.
Preference storage class.
Definition preferences.h:61
bool getBool(Glib::ustring const &pref_path, bool def=false)
Retrieve a Boolean value.
static Preferences * get()
Access the singleton Preferences object.
int getInt(Glib::ustring const &pref_path, int def=0)
Retrieve an integer.
void addObserver(Observer &)
Register a preference observer.
void notify(Preferences::Entry const &val) override
Notification about a preference change.
Definition selcue.cpp:36
sigc::connection _sel_modified_connection
Definition selcue.h:71
Selection * _selection
Definition selcue.h:69
std::vector< CanvasItemPtr< CanvasItem > > _item_bboxes
Definition selcue.h:72
SelCue(SPDesktop *desktop)
Definition selcue.cpp:41
void _updateItemBboxes()
Definition selcue.cpp:66
BoundingBoxPrefsObserver _bounding_box_prefs_observer
Definition selcue.h:76
void _newTextBaselines()
Definition selcue.cpp:188
std::vector< CanvasItemPtr< CanvasItem > > _text_baselines
Definition selcue.h:73
std::vector< CanvasItemPtr< CanvasItem > > _item_lines
Definition selcue.h:74
SPDesktop * _desktop
Definition selcue.h:68
sigc::connection _sel_changed_connection
Definition selcue.h:70
void _newItemLines()
Create any required visual-only guide lines related to the selection.
Definition selcue.cpp:167
void _boundingBoxPrefsChanged(int prefs_bbox)
Definition selcue.cpp:210
void _newItemBboxes()
Definition selcue.cpp:117
sigc::connection connectChanged(sigc::slot< void(Selection *)> slot)
Connects a slot to be notified of selection changes.
Definition selection.h:179
sigc::connection connectModified(sigc::slot< void(Selection *, unsigned)> slot)
Connects a slot to be notified of selected object modifications.
Definition selection.h:232
Geom::Point anchor
Definition selection.h:201
To do: update description of desktop.
Definition desktop.h:149
Inkscape::CanvasItemGroup * getCanvasGuides() const
Definition desktop.h:200
Inkscape::CanvasItemGroup * getCanvasControls() const
Definition desktop.h:196
Inkscape::Selection * getSelection() const
Definition desktop.h:188
Geom::Affine i2dt_affine() const
Returns the transformation from item to desktop coords.
Definition sp-item.cpp:1829
Geom::OptRect desktopVisualBounds() const
Get item's visual bbox in desktop coordinate system.
Definition sp-item.cpp:1057
Geom::OptRect desktopGeometricBounds() const
Get item's geometric bbox in desktop coordinate system.
Definition sp-item.cpp:1052
Editable view implementation.
SPItem * item
Helper class to stream background task notifications as a series of messages.
@ CANVAS_ITEM_CTRL_TYPE_SIZER
@ CANVAS_ITEM_CTRL_TYPE_SHAPER
int mode
GList * items
TODO: insert short description here.
SPDesktop * desktop