1 #define __SELCUE_C__
3 /*
4 * Helper object for showing selected items
5 *
6 * Authors:
7 * bulia byak <bulia@users.sf.net>
8 * Carl Hetherington <inkscape@carlh.net>
9 *
10 * Copyright (C) 2004 Authors
11 *
12 * Released under GNU GPL, read the file 'COPYING' for more information
13 */
15 #include <string.h>
17 #include "desktop-handles.h"
18 #include "selection.h"
19 #include "display/sp-canvas-util.h"
20 #include "display/sodipodi-ctrl.h"
21 #include "display/sodipodi-ctrlrect.h"
22 #include "libnrtype/Layout-TNG.h"
23 #include "text-editing.h"
24 #include "sp-text.h"
25 #include "sp-flowtext.h"
26 #include "preferences.h"
27 #include "selcue.h"
29 Inkscape::SelCue::SelCue(SPDesktop *desktop)
30 : _desktop(desktop)
31 {
32 _selection = sp_desktop_selection(_desktop);
34 _sel_changed_connection = _selection->connectChanged(
35 sigc::hide(sigc::mem_fun(*this, &Inkscape::SelCue::_updateItemBboxes))
36 );
38 _sel_modified_connection = _selection->connectModified(
39 sigc::hide(sigc::hide(sigc::mem_fun(*this, &Inkscape::SelCue::_updateItemBboxes)))
40 );
42 _updateItemBboxes();
43 }
45 Inkscape::SelCue::~SelCue()
46 {
47 _sel_changed_connection.disconnect();
48 _sel_modified_connection.disconnect();
50 for (std::list<SPCanvasItem*>::iterator i = _item_bboxes.begin(); i != _item_bboxes.end(); i++) {
51 gtk_object_destroy(*i);
52 }
53 _item_bboxes.clear();
55 for (std::list<SPCanvasItem*>::iterator i = _text_baselines.begin(); i != _text_baselines.end(); i++) {
56 gtk_object_destroy(*i);
57 }
58 _text_baselines.clear();
59 }
61 void Inkscape::SelCue::_updateItemBboxes()
62 {
63 for (std::list<SPCanvasItem*>::iterator i = _item_bboxes.begin(); i != _item_bboxes.end(); i++) {
64 gtk_object_destroy(*i);
65 }
66 _item_bboxes.clear();
68 for (std::list<SPCanvasItem*>::iterator i = _text_baselines.begin(); i != _text_baselines.end(); i++) {
69 gtk_object_destroy(*i);
70 }
71 _text_baselines.clear();
73 Inkscape::Preferences *prefs = Inkscape::Preferences::get();
74 gint mode = prefs->getInt("/options/selcue/value", MARK);
75 if (mode == NONE) {
76 return;
77 }
79 g_return_if_fail(_selection != NULL);
81 int prefs_bbox = prefs->getBool("/tools/bounding_box");
82 SPItem::BBoxType bbox_type = !prefs_bbox ?
83 SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX;
85 for (GSList const *l = _selection->itemList(); l != NULL; l = l->next) {
86 SPItem *item = (SPItem *) l->data;
88 Geom::OptRect const b = sp_item_bbox_desktop(item, bbox_type);
90 SPCanvasItem* box = NULL;
92 if (b) {
93 if (mode == MARK) {
94 box = sp_canvas_item_new(sp_desktop_controls(_desktop),
95 SP_TYPE_CTRL,
96 "mode", SP_CTRL_MODE_XOR,
97 "shape", SP_CTRL_SHAPE_DIAMOND,
98 "size", 5.0,
99 "filled", TRUE,
100 "fill_color", 0x000000ff,
101 "stroked", FALSE,
102 "stroke_color", 0x000000ff,
103 NULL);
104 sp_canvas_item_show(box);
105 SP_CTRL(box)->moveto(Geom::Point(b->min()[Geom::X], b->max()[Geom::Y]));
107 sp_canvas_item_move_to_z(box, 0); // just low enough to not get in the way of other draggable knots
109 } else if (mode == BBOX) {
110 box = sp_canvas_item_new(sp_desktop_controls(_desktop),
111 SP_TYPE_CTRLRECT,
112 NULL);
114 SP_CTRLRECT(box)->setRectangle(*b);
115 SP_CTRLRECT(box)->setColor(0x000000a0, 0, 0);
116 SP_CTRLRECT(box)->setDashed(true);
118 sp_canvas_item_move_to_z(box, 0);
119 }
120 }
122 if (box) {
123 _item_bboxes.push_back(box);
124 }
126 SPCanvasItem* baseline_point = NULL;
127 if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { // visualize baseline
128 Inkscape::Text::Layout const *layout = te_get_layout(item);
129 if (layout != NULL) {
130 Geom::Point a = layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(item);
131 baseline_point = sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRL,
132 "mode", SP_CTRL_MODE_XOR,
133 "size", 4.0,
134 "filled", 0,
135 "stroked", 1,
136 "stroke_color", 0x000000ff,
137 NULL);
139 sp_canvas_item_show(baseline_point);
140 SP_CTRL(baseline_point)->moveto(a);
141 sp_canvas_item_move_to_z(baseline_point, 0);
142 }
143 }
145 if (baseline_point) {
146 _text_baselines.push_back(baseline_point);
147 }
148 }
149 }
151 /*
152 Local Variables:
153 mode:c++
154 c-file-style:"stroustrup"
155 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
156 indent-tabs-mode:nil
157 fill-column:99
158 End:
159 */
160 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :