summaryrefslogtreecommitdiffstats
path: root/src/document.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/document.cpp')
-rw-r--r--src/document.cpp48
1 files changed, 26 insertions, 22 deletions
diff --git a/src/document.cpp b/src/document.cpp
index 621cb071e..ae03b1ba1 100644
--- a/src/document.cpp
+++ b/src/document.cpp
@@ -1335,34 +1335,24 @@ SPItem *SPDocument::getItemFromListAtPointBottom(unsigned int dkey, SPGroup *gro
/**
Turn the SVG DOM into a flat list of nodes that can be searched from top-down.
The list can be persisted, which improves "find at multiple points" speed.
-Returns true if upto is reached.
*/
-bool SPDocument::build_flat_item_list(unsigned int dkey, SPGroup *group, gboolean into_groups, bool take_insensitive, SPItem *upto)
+void SPDocument::build_flat_item_list(unsigned int dkey, SPGroup *group, gboolean into_groups) const
{
- bool found_upto = false;
for ( SPObject *o = group->firstChild() ; o ; o = o->getNext() ) {
if (!SP_IS_ITEM(o)) {
continue;
}
- if (upto && SP_ITEM(o) == upto) {
- found_upto = true;
- break;
- }
-
if (SP_IS_GROUP(o) && (SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) {
- found_upto = build_flat_item_list(dkey, SP_GROUP(o), into_groups, take_insensitive, upto);
- if (found_upto)
- break;
+ build_flat_item_list(dkey, SP_GROUP(o), into_groups);
} else {
SPItem *child = SP_ITEM(o);
- if (take_insensitive || child->isVisibleAndUnlocked(dkey)) {
+ if (child->isVisibleAndUnlocked(dkey)) {
_node_cache.push_front(child);
}
}
}
- return found_upto;
}
/**
@@ -1374,15 +1364,21 @@ upwards in z-order and returns what it has found so far (i.e. the found item is
guaranteed to be lower than upto). Requires a list of nodes built by
build_flat_item_list.
*/
-static SPItem *find_item_at_point(std::deque<SPItem*> *nodes, unsigned int dkey, Geom::Point const &p)
+static SPItem *find_item_at_point(std::deque<SPItem*> *nodes, unsigned int dkey, Geom::Point const &p, SPItem* upto=NULL)
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0);
SPItem *seen = NULL;
SPItem *child;
+ bool seen_upto = (!upto);
for (std::deque<SPItem*>::const_iterator i = nodes->begin(); i != nodes->end(); ++i) {
child = *i;
+ if (!seen_upto){
+ if(child == upto)
+ seen_upto = true;
+ continue;
+ }
Inkscape::DrawingItem *arenaitem = child->get_arenaitem(dkey);
if (arenaitem && arenaitem->pick(p, delta, 1) != NULL) {
@@ -1454,7 +1450,7 @@ std::vector<SPItem*> SPDocument::getItemsPartiallyInBox(unsigned int dkey, Geom:
return find_items_in_area(x, SP_GROUP(this->root), dkey, box, overlaps, false, into_groups);
}
-std::vector<SPItem*> SPDocument::getItemsAtPoints(unsigned const key, std::vector<Geom::Point> points, bool all_layers, size_t limit)
+std::vector<SPItem*> SPDocument::getItemsAtPoints(unsigned const key, std::vector<Geom::Point> points, bool all_layers, size_t limit) const
{
std::vector<SPItem*> items;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -1468,7 +1464,7 @@ std::vector<SPItem*> SPDocument::getItemsAtPoints(unsigned const key, std::vecto
// Cache a flattened SVG DOM to speed up selection.
if(!_node_cache_valid){
_node_cache.clear();
- build_flat_item_list(key, SP_GROUP(this->root), true, false, NULL);
+ build_flat_item_list(key, SP_GROUP(this->root), true);
_node_cache_valid=true;
}
SPObject *current_layer = SP_ACTIVE_DESKTOP->currentLayer();
@@ -1499,18 +1495,26 @@ std::vector<SPItem*> SPDocument::getItemsAtPoints(unsigned const key, std::vecto
}
SPItem *SPDocument::getItemAtPoint( unsigned const key, Geom::Point const &p,
- bool const into_groups, SPItem *upto)
+ bool const into_groups, SPItem *upto) const
{
g_return_val_if_fail(this->priv != NULL, NULL);
// Build a flattened SVG DOM for find_item_at_point.
- if(!_node_cache_valid){
+ std::deque<SPItem*> bak(_node_cache);
+ if(!into_groups){
_node_cache.clear();
- build_flat_item_list(key, SP_GROUP(this->root), into_groups, false, upto);
- if(!upto)
- _node_cache_valid = true;
+ build_flat_item_list(key, SP_GROUP(this->root), into_groups);
}
- return find_item_at_point(&_node_cache, key, p);
+ if(!_node_cache_valid && into_groups){
+ _node_cache.clear();
+ build_flat_item_list(key, SP_GROUP(this->root), true);
+ _node_cache_valid=true;
+ }
+
+ SPItem *res = find_item_at_point(&_node_cache, key, p, upto);
+ if(!into_groups)
+ _node_cache = bak;
+ return res;
}
SPItem *SPDocument::getGroupAtPoint(unsigned int key, Geom::Point const &p) const