Code

Fixed directory for inkscape executable.
[inkscape.git] / src / selcue.cpp
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::_newItemBboxes))
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::vector<SPCanvasItem*>::iterator i = _item_bboxes.begin(); i != _item_bboxes.end(); i++) {
51         gtk_object_destroy(*i);
52     }
53     _item_bboxes.clear();
55     for (std::vector<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     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
64     gint mode = prefs->getInt("/options/selcue/value", MARK);
65     if (mode == NONE) {
66         return;
67     }
69     g_return_if_fail(_selection != NULL);
71     int prefs_bbox = prefs->getBool("/tools/bounding_box");
72     SPItem::BBoxType bbox_type = !prefs_bbox ? 
73         SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX;
75     GSList const *items = _selection->itemList();
76     if (_item_bboxes.size() != g_slist_length((GSList *) items)) {
77         _newItemBboxes();
78         return;
79     }
81     int bcount = 0;
82     for (GSList const *l = _selection->itemList(); l != NULL; l = l->next) {
83         SPItem *item = (SPItem *) l->data;
84         SPCanvasItem* box = _item_bboxes[bcount ++];
86         if (box) {
87             Geom::OptRect const b = sp_item_bbox_desktop(item, bbox_type);
89             if (b) {
90                 sp_canvas_item_show(box);
91                 if (mode == MARK) {
92                     SP_CTRL(box)->moveto(Geom::Point(b->min()[Geom::X], b->max()[Geom::Y]));
93                 } else if (mode == BBOX) {
94                     SP_CTRLRECT(box)->setRectangle(*b);
95                 }
96             } else { // no bbox
97                 sp_canvas_item_hide(box);
98             }
99         }
100     }
102     _newTextBaselines();
106 void Inkscape::SelCue::_newItemBboxes()
108     for (std::vector<SPCanvasItem*>::iterator i = _item_bboxes.begin(); i != _item_bboxes.end(); i++) {
109         gtk_object_destroy(*i);
110     }
111     _item_bboxes.clear();
113     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
114     gint mode = prefs->getInt("/options/selcue/value", MARK);
115     if (mode == NONE) {
116         return;
117     }
119     g_return_if_fail(_selection != NULL);
121     int prefs_bbox = prefs->getBool("/tools/bounding_box");
122     SPItem::BBoxType bbox_type = !prefs_bbox ? 
123         SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX;
124     
125     for (GSList const *l = _selection->itemList(); l != NULL; l = l->next) {
126         SPItem *item = (SPItem *) l->data;
128         Geom::OptRect const b = sp_item_bbox_desktop(item, bbox_type);
130         SPCanvasItem* box = NULL;
132         if (b) {
133             if (mode == MARK) {
134                 box = sp_canvas_item_new(sp_desktop_controls(_desktop),
135                                          SP_TYPE_CTRL,
136                                          "mode", SP_CTRL_MODE_XOR,
137                                          "shape", SP_CTRL_SHAPE_DIAMOND,
138                                          "size", 5.0,
139                                          "filled", TRUE,
140                                          "fill_color", 0x000000ff,
141                                          "stroked", FALSE,
142                                          "stroke_color", 0x000000ff,
143                                          NULL);
144                 sp_canvas_item_show(box);
145                 SP_CTRL(box)->moveto(Geom::Point(b->min()[Geom::X], b->max()[Geom::Y]));
147                 sp_canvas_item_move_to_z(box, 0); // just low enough to not get in the way of other draggable knots
149             } else if (mode == BBOX) {
150                 box = sp_canvas_item_new(sp_desktop_controls(_desktop),
151                                          SP_TYPE_CTRLRECT,
152                                          NULL);
154                 SP_CTRLRECT(box)->setRectangle(*b);
155                 SP_CTRLRECT(box)->setColor(0x000000a0, 0, 0);
156                 SP_CTRLRECT(box)->setDashed(true);
158                 sp_canvas_item_move_to_z(box, 0);
159             }
160         }
162         if (box) {
163             _item_bboxes.push_back(box);
164         }
165     }
167     _newTextBaselines();
170 void Inkscape::SelCue::_newTextBaselines()
172     for (std::vector<SPCanvasItem*>::iterator i = _text_baselines.begin(); i != _text_baselines.end(); i++) {
173         gtk_object_destroy(*i);
174     }
175     _text_baselines.clear();
177     for (GSList const *l = _selection->itemList(); l != NULL; l = l->next) {
178         SPItem *item = (SPItem *) l->data;
180         SPCanvasItem* baseline_point = NULL;
181         if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { // visualize baseline
182             Inkscape::Text::Layout const *layout = te_get_layout(item);
183             if (layout != NULL && layout->outputExists()) {
184                 Geom::Point a = layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(item);
185                 baseline_point = sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRL,
186                                                     "mode", SP_CTRL_MODE_XOR,
187                                                     "size", 4.0,
188                                                     "filled", 0,
189                                                     "stroked", 1,
190                                                     "stroke_color", 0x000000ff,
191                                                     NULL);
193                 sp_canvas_item_show(baseline_point);
194                 SP_CTRL(baseline_point)->moveto(a);
195                 sp_canvas_item_move_to_z(baseline_point, 0);
196             }
197         }
199         if (baseline_point) {
200                _text_baselines.push_back(baseline_point);
201         }
202     }
206 /*
207   Local Variables:
208   mode:c++
209   c-file-style:"stroustrup"
210   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
211   indent-tabs-mode:nil
212   fill-column:99
213   End:
214 */
215 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :