Code

applying patch #1368738 from yselkowitz
[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 "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_DT_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     for (GSList const *l = _selection->itemList(); l != NULL; l = l->next) {
79         SPItem *item = (SPItem *) l->data;
81         NR::Rect const b = sp_item_bbox_desktop(item);
83         SPCanvasItem* box = NULL;
85         if (mode == MARK) {
86             box = sp_canvas_item_new(SP_DT_CONTROLS(_desktop),
87                                       SP_TYPE_CTRL,
88                                       "mode", SP_CTRL_MODE_XOR,
89                                       "shape", SP_CTRL_SHAPE_DIAMOND,
90                                       "size", 5.0,
91                                       "filled", TRUE,
92                                       "fill_color", 0x000000ff,
93                                       "stroked", FALSE,
94                                       "stroke_color", 0x000000ff,
95                                       NULL);
96             sp_canvas_item_show(box);
97             SP_CTRL(box)->moveto(NR::Point(b.min()[NR::X], b.max()[NR::Y]));
98             
99             sp_canvas_item_move_to_z(box, 0); // just low enough to not get in the way of other draggable knots
101         } else if (mode == BBOX) {
102             box = sp_canvas_item_new(
103                 SP_DT_CONTROLS(_desktop),
104                 SP_TYPE_CTRLRECT,
105                 NULL
106                 );
107             
108             SP_CTRLRECT(box)->setRectangle(b);
109             SP_CTRLRECT(box)->setColor(0x000000a0, 0, 0);
110             SP_CTRLRECT(box)->setDashed(true);
111             
112             sp_canvas_item_move_to_z(box, 0);
113         }
114                 
115         if (box) {
116             _item_bboxes.push_back(box);
117         }
119         SPCanvasItem* baseline_point = NULL;
120         if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { // visualize baseline
121             Inkscape::Text::Layout const *layout = te_get_layout(item);
122             if (layout != NULL) {
123                 NR::Point a = layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(item);
124                 baseline_point = sp_canvas_item_new(SP_DT_CONTROLS(_desktop), SP_TYPE_CTRL,
125                                                     "mode", SP_CTRL_MODE_XOR,
126                                                     "size", 4.0,
127                                                     "filled", 0,
128                                                     "stroked", 1,
129                                                     "stroke_color", 0x000000ff,
130                                                     NULL);
131                 
132                 sp_canvas_item_show(baseline_point);
133                 SP_CTRL(baseline_point)->moveto(a);
134                 sp_canvas_item_move_to_z(baseline_point, 0);
135             }
136         }
137         
138         if (baseline_point) {
139                _text_baselines.push_back(baseline_point);
140         }
141     }
144 /*
145   Local Variables:
146   mode:c++
147   c-file-style:"stroustrup"
148   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
149   indent-tabs-mode:nil
150   fill-column:99
151   End:
152 */
153 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :