Code

Fix change in revision 9947 to be consistent with rest of the codebase.
[inkscape.git] / src / selcue.cpp
index 845561d1876a3388215eff4de41d492c25c80ffb..171178c4132f2bd7b46e87b98eb6d2da30273c49 100644 (file)
@@ -1,17 +1,18 @@
-#define __SELCUE_C__
-
 /*
  * Helper object for showing selected items
  *
  * Authors:
  *   bulia byak <bulia@users.sf.net>
  *   Carl Hetherington <inkscape@carlh.net>
+ *   Abhishek Sharma
  *
  * Copyright (C) 2004 Authors
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 
+#include <string.h>
+
 #include "desktop-handles.h"
 #include "selection.h"
 #include "display/sp-canvas-util.h"
 #include "text-editing.h"
 #include "sp-text.h"
 #include "sp-flowtext.h"
-#include "prefs-utils.h"
+#include "preferences.h"
 #include "selcue.h"
 
 Inkscape::SelCue::SelCue(SPDesktop *desktop)
     : _desktop(desktop)
 {
-    _selection = SP_DT_SELECTION(_desktop);
+    _selection = sp_desktop_selection(_desktop);
 
     _sel_changed_connection = _selection->connectChanged(
-        sigc::hide(sigc::mem_fun(*this, &Inkscape::SelCue::_updateItemBboxes))
+        sigc::hide(sigc::mem_fun(*this, &Inkscape::SelCue::_newItemBboxes))
         );
 
     _sel_modified_connection = _selection->connectModified(
@@ -45,12 +46,12 @@ Inkscape::SelCue::~SelCue()
     _sel_changed_connection.disconnect();
     _sel_modified_connection.disconnect();
 
-    for (std::list<SPCanvasItem*>::iterator i = _item_bboxes.begin(); i != _item_bboxes.end(); i++) {
+    for (std::vector<SPCanvasItem*>::iterator i = _item_bboxes.begin(); i != _item_bboxes.end(); i++) {
         gtk_object_destroy(*i);
     }
     _item_bboxes.clear();
 
-    for (std::list<SPCanvasItem*>::iterator i = _text_baselines.begin(); i != _text_baselines.end(); i++) {
+    for (std::vector<SPCanvasItem*>::iterator i = _text_baselines.begin(); i != _text_baselines.end(); i++) {
         gtk_object_destroy(*i);
     }
     _text_baselines.clear();
@@ -58,89 +59,151 @@ Inkscape::SelCue::~SelCue()
 
 void Inkscape::SelCue::_updateItemBboxes()
 {
-    for (std::list<SPCanvasItem*>::iterator i = _item_bboxes.begin(); i != _item_bboxes.end(); i++) {
-        gtk_object_destroy(*i);
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    gint mode = prefs->getInt("/options/selcue/value", MARK);
+    if (mode == NONE) {
+        return;
     }
-    _item_bboxes.clear();
 
-    for (std::list<SPCanvasItem*>::iterator i = _text_baselines.begin(); i != _text_baselines.end(); i++) {
+    g_return_if_fail(_selection != NULL);
+
+    int prefs_bbox = prefs->getBool("/tools/bounding_box");
+    SPItem::BBoxType bbox_type = !prefs_bbox ? 
+        SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX;
+
+    GSList const *items = _selection->itemList();
+    if (_item_bboxes.size() != g_slist_length((GSList *) items)) {
+        _newItemBboxes();
+        return;
+    }
+
+    int bcount = 0;
+    for (GSList const *l = _selection->itemList(); l != NULL; l = l->next) {
+        SPItem *item = (SPItem *) l->data;
+        SPCanvasItem* box = _item_bboxes[bcount ++];
+
+        if (box) {
+            Geom::OptRect const b = item->getBboxDesktop(bbox_type);
+
+            if (b) {
+                sp_canvas_item_show(box);
+                if (mode == MARK) {
+                    SP_CTRL(box)->moveto(Geom::Point(b->min()[Geom::X], b->max()[Geom::Y]));
+                } else if (mode == BBOX) {
+                    SP_CTRLRECT(box)->setRectangle(*b);
+                }
+            } else { // no bbox
+                sp_canvas_item_hide(box);
+            }
+        }
+    }
+
+    _newTextBaselines();
+}
+
+
+void Inkscape::SelCue::_newItemBboxes()
+{
+    for (std::vector<SPCanvasItem*>::iterator i = _item_bboxes.begin(); i != _item_bboxes.end(); i++) {
         gtk_object_destroy(*i);
     }
-    _text_baselines.clear();
+    _item_bboxes.clear();
 
-    gint mode = prefs_get_int_attribute ("options.selcue", "value", MARK);
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    gint mode = prefs->getInt("/options/selcue/value", MARK);
     if (mode == NONE) {
         return;
     }
 
     g_return_if_fail(_selection != NULL);
 
+    int prefs_bbox = prefs->getBool("/tools/bounding_box");
+    SPItem::BBoxType bbox_type = !prefs_bbox ? 
+        SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX;
+    
     for (GSList const *l = _selection->itemList(); l != NULL; l = l->next) {
         SPItem *item = (SPItem *) l->data;
 
-        NR::Rect const b = sp_item_bbox_desktop(item);
+        Geom::OptRect const b = item->getBboxDesktop(bbox_type);
 
         SPCanvasItem* box = NULL;
 
-        if (mode == MARK) {
-            box = sp_canvas_item_new(SP_DT_CONTROLS(_desktop),
-                                      SP_TYPE_CTRL,
-                                      "mode", SP_CTRL_MODE_XOR,
-                                      "shape", SP_CTRL_SHAPE_DIAMOND,
-                                      "size", 5.0,
-                                      "filled", TRUE,
-                                      "fill_color", 0x000000ff,
-                                      "stroked", FALSE,
-                                      "stroke_color", 0x000000ff,
-                                      NULL);
-            sp_canvas_item_show(box);
-            SP_CTRL(box)->moveto(NR::Point(b.min()[NR::X], b.max()[NR::Y]));
-            
-            sp_canvas_item_move_to_z(box, 0); // just low enough to not get in the way of other draggable knots
-
-        } else if (mode == BBOX) {
-            box = sp_canvas_item_new(
-                SP_DT_CONTROLS(_desktop),
-                SP_TYPE_CTRLRECT,
-                NULL
-                );
-            
-            SP_CTRLRECT(box)->setRectangle(b);
-            SP_CTRLRECT(box)->setColor(0x000000a0, 0, 0);
-            SP_CTRLRECT(box)->setDashed(true);
-            
-            sp_canvas_item_move_to_z(box, 0);
+        if (b) {
+            if (mode == MARK) {
+                box = sp_canvas_item_new(sp_desktop_controls(_desktop),
+                                         SP_TYPE_CTRL,
+                                         "mode", SP_CTRL_MODE_XOR,
+                                         "shape", SP_CTRL_SHAPE_DIAMOND,
+                                         "size", 5.0,
+                                         "filled", TRUE,
+                                         "fill_color", 0x000000ff,
+                                         "stroked", FALSE,
+                                         "stroke_color", 0x000000ff,
+                                         NULL);
+                sp_canvas_item_show(box);
+                SP_CTRL(box)->moveto(Geom::Point(b->min()[Geom::X], b->max()[Geom::Y]));
+
+                sp_canvas_item_move_to_z(box, 0); // just low enough to not get in the way of other draggable knots
+
+            } else if (mode == BBOX) {
+                box = sp_canvas_item_new(sp_desktop_controls(_desktop),
+                                         SP_TYPE_CTRLRECT,
+                                         NULL);
+
+                SP_CTRLRECT(box)->setRectangle(*b);
+                SP_CTRLRECT(box)->setColor(0x000000a0, 0, 0);
+                SP_CTRLRECT(box)->setDashed(true);
+
+                sp_canvas_item_move_to_z(box, 0);
+            }
         }
-                
+
         if (box) {
             _item_bboxes.push_back(box);
         }
+    }
+
+    _newTextBaselines();
+}
+
+void Inkscape::SelCue::_newTextBaselines()
+{
+    for (std::vector<SPCanvasItem*>::iterator i = _text_baselines.begin(); i != _text_baselines.end(); i++) {
+        gtk_object_destroy(*i);
+    }
+    _text_baselines.clear();
+
+    for (GSList const *l = _selection->itemList(); l != NULL; l = l->next) {
+        SPItem *item = (SPItem *) l->data;
 
         SPCanvasItem* baseline_point = NULL;
         if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { // visualize baseline
             Inkscape::Text::Layout const *layout = te_get_layout(item);
-            if (layout != NULL) {
-                NR::Point a = layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(item);
-                baseline_point = sp_canvas_item_new(SP_DT_CONTROLS(_desktop), SP_TYPE_CTRL,
-                                                    "mode", SP_CTRL_MODE_XOR,
-                                                    "size", 4.0,
-                                                    "filled", 0,
-                                                    "stroked", 1,
-                                                    "stroke_color", 0x000000ff,
-                                                    NULL);
-                
-                sp_canvas_item_show(baseline_point);
-                SP_CTRL(baseline_point)->moveto(a);
-                sp_canvas_item_move_to_z(baseline_point, 0);
+            if (layout != NULL && layout->outputExists()) {
+                boost::optional<Geom::Point> pt = layout->baselineAnchorPoint();
+                if (pt) {
+                    baseline_point = sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRL,
+                        "mode", SP_CTRL_MODE_XOR,
+                        "size", 4.0,
+                        "filled", 0,
+                        "stroked", 1,
+                        "stroke_color", 0x000000ff,
+                        NULL);
+
+                    sp_canvas_item_show(baseline_point);
+                    SP_CTRL(baseline_point)->moveto((*pt) * item->i2d_affine());
+                    sp_canvas_item_move_to_z(baseline_point, 0);
+                }
             }
         }
-        
+
         if (baseline_point) {
                _text_baselines.push_back(baseline_point);
         }
     }
 }
 
+
 /*
   Local Variables:
   mode:c++