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 "desktop-handles.h"
16 #include "selection.h"
17 #include "display/sp-canvas-util.h"
18 #include "display/sodipodi-ctrl.h"
19 #include "display/sodipodi-ctrlrect.h"
20 #include "libnrtype/Layout-TNG.h"
21 #include "text-editing.h"
22 #include "sp-text.h"
23 #include "sp-flowtext.h"
24 #include "prefs-utils.h"
25 #include "selcue.h"
27 Inkscape::SelCue::SelCue(SPDesktop *desktop)
28 : _desktop(desktop)
29 {
30 _selection = sp_desktop_selection(_desktop);
32 _sel_changed_connection = _selection->connectChanged(
33 sigc::hide(sigc::mem_fun(*this, &Inkscape::SelCue::_updateItemBboxes))
34 );
36 _sel_modified_connection = _selection->connectModified(
37 sigc::hide(sigc::hide(sigc::mem_fun(*this, &Inkscape::SelCue::_updateItemBboxes)))
38 );
40 _updateItemBboxes();
41 }
43 Inkscape::SelCue::~SelCue()
44 {
45 _sel_changed_connection.disconnect();
46 _sel_modified_connection.disconnect();
48 for (std::list<SPCanvasItem*>::iterator i = _item_bboxes.begin(); i != _item_bboxes.end(); i++) {
49 gtk_object_destroy(*i);
50 }
51 _item_bboxes.clear();
53 for (std::list<SPCanvasItem*>::iterator i = _text_baselines.begin(); i != _text_baselines.end(); i++) {
54 gtk_object_destroy(*i);
55 }
56 _text_baselines.clear();
57 }
59 void Inkscape::SelCue::_updateItemBboxes()
60 {
61 for (std::list<SPCanvasItem*>::iterator i = _item_bboxes.begin(); i != _item_bboxes.end(); i++) {
62 gtk_object_destroy(*i);
63 }
64 _item_bboxes.clear();
66 for (std::list<SPCanvasItem*>::iterator i = _text_baselines.begin(); i != _text_baselines.end(); i++) {
67 gtk_object_destroy(*i);
68 }
69 _text_baselines.clear();
71 gint mode = prefs_get_int_attribute ("options.selcue", "value", MARK);
72 if (mode == NONE) {
73 return;
74 }
76 g_return_if_fail(_selection != NULL);
78 gchar const *prefs_bbox = prefs_get_string_attribute("tools.select", "bounding_box");
79 SPItem::BBoxType bbox_type = (prefs_bbox != NULL && strcmp(prefs_bbox, "geometric")==0)? SPItem::GEOMETRIC_BBOX : SPItem::APPROXIMATE_BBOX;
81 for (GSList const *l = _selection->itemList(); l != NULL; l = l->next) {
82 SPItem *item = (SPItem *) l->data;
84 NR::Maybe<NR::Rect> const b = sp_item_bbox_desktop(item, bbox_type);
86 SPCanvasItem* box = NULL;
88 if (b) {
89 if (mode == MARK) {
90 box = sp_canvas_item_new(sp_desktop_controls(_desktop),
91 SP_TYPE_CTRL,
92 "mode", SP_CTRL_MODE_XOR,
93 "shape", SP_CTRL_SHAPE_DIAMOND,
94 "size", 5.0,
95 "filled", TRUE,
96 "fill_color", 0x000000ff,
97 "stroked", FALSE,
98 "stroke_color", 0x000000ff,
99 NULL);
100 sp_canvas_item_show(box);
101 SP_CTRL(box)->moveto(NR::Point(b->min()[NR::X], b->max()[NR::Y]));
103 sp_canvas_item_move_to_z(box, 0); // just low enough to not get in the way of other draggable knots
105 } else if (mode == BBOX) {
106 box = sp_canvas_item_new(sp_desktop_controls(_desktop),
107 SP_TYPE_CTRLRECT,
108 NULL);
110 SP_CTRLRECT(box)->setRectangle(*b);
111 SP_CTRLRECT(box)->setColor(0x000000a0, 0, 0);
112 SP_CTRLRECT(box)->setDashed(true);
114 sp_canvas_item_move_to_z(box, 0);
115 }
116 }
118 if (box) {
119 _item_bboxes.push_back(box);
120 }
122 SPCanvasItem* baseline_point = NULL;
123 if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { // visualize baseline
124 Inkscape::Text::Layout const *layout = te_get_layout(item);
125 if (layout != NULL) {
126 NR::Point a = layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(item);
127 baseline_point = sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRL,
128 "mode", SP_CTRL_MODE_XOR,
129 "size", 4.0,
130 "filled", 0,
131 "stroked", 1,
132 "stroke_color", 0x000000ff,
133 NULL);
135 sp_canvas_item_show(baseline_point);
136 SP_CTRL(baseline_point)->moveto(a);
137 sp_canvas_item_move_to_z(baseline_point, 0);
138 }
139 }
141 if (baseline_point) {
142 _text_baselines.push_back(baseline_point);
143 }
144 }
145 }
147 /*
148 Local Variables:
149 mode:c++
150 c-file-style:"stroustrup"
151 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
152 indent-tabs-mode:nil
153 fill-column:99
154 End:
155 */
156 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :