From d9e1fb5db48f46e52dbb171e7bdcee1602d8eb14 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 3 Nov 2018 16:56:23 +0100 Subject: Improvemets to find items --- src/document.cpp | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) (limited to 'src/document.cpp') diff --git a/src/document.cpp b/src/document.cpp index 35e57871f..450936d25 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1381,25 +1381,39 @@ static bool overlaps(Geom::Rect const &area, Geom::Rect const &box) return area.intersects(box); } -static std::vector &find_items_in_area(std::vector &s, SPGroup *group, unsigned int dkey, Geom::Rect const &area, - bool (*test)(Geom::Rect const &, Geom::Rect const &), bool take_insensitive = false, bool into_groups = false) +static std::vector &find_items_in_area(std::vector &s, + SPGroup *group, unsigned int dkey, + Geom::Rect const &area, + bool (*test)(Geom::Rect const &, Geom::Rect const &), + bool take_hidden = false, + bool take_insensitive = false, + bool take_groups = true, + bool take_into_groups = false, + bool take_into_filtered = true) { g_return_val_if_fail(SP_IS_GROUP(group), s); for (auto& o: group->children) { - if ( SP_IS_ITEM(&o) ) { - if (SP_IS_GROUP(&o) && (SP_GROUP(&o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) { - s = find_items_in_area(s, SP_GROUP(&o), dkey, area, test, take_insensitive, into_groups); + if (SPItem *item = dynamic_cast(&o)) { + if (SPGroup * childgroup = dynamic_cast(item)) { + bool is_layer = childgroup->effectiveLayerMode(dkey) == SPGroup::LAYER; + if (is_layer || (take_into_groups && (!childgroup->isFiltered() || take_into_filtered))) { + s = find_items_in_area(s, childgroup, dkey, area, test, take_hidden, take_insensitive, take_groups, take_into_groups, take_into_filtered); + } + if (take_groups && !is_layer) { + Geom::OptRect box = childgroup->desktopVisualBounds(); + if ( box && test(area, *box) && (!childgroup->isLocked() || take_insensitive) && (!childgroup->isHidden() || take_hidden) ) { + s.push_back(item); + } + } } else { - SPItem *child = SP_ITEM(&o); - Geom::OptRect box = child->desktopVisualBounds(); - if ( box && test(area, *box) && (take_insensitive || child->isVisibleAndUnlocked(dkey))) { - s.push_back(child); + Geom::OptRect box = item->desktopVisualBounds(); + if ( box && test(area, *box) && (!item->isLocked() || take_insensitive) && (!item->isHidden() || take_hidden) ) { + s.push_back(item); } } } } - return s; } @@ -1456,6 +1470,7 @@ 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. */ +// TODO: study add `gboolean with_groups = false` as parameter. void SPDocument::build_flat_item_list(unsigned int dkey, SPGroup *group, gboolean into_groups) const { for (auto& o: group->children) { @@ -1554,10 +1569,10 @@ static SPItem *find_group_at_point(unsigned int dkey, SPGroup *group, Geom::Poin * Assumes box is normalized (and g_asserts it!) * */ -std::vector SPDocument::getItemsInBox(unsigned int dkey, Geom::Rect const &box, bool take_insensitive, bool into_groups) const +std::vector SPDocument::getItemsInBox(unsigned int dkey, Geom::Rect const &box, bool take_hidden, bool take_insensitive, bool take_groups, bool take_into_groups, bool take_into_filtered) const { std::vector x; - return find_items_in_area(x, SP_GROUP(this->root), dkey, box, is_within, take_insensitive, into_groups); + return find_items_in_area(x, SP_GROUP(this->root), dkey, box, is_within, take_hidden, take_insensitive, take_groups, take_into_groups, take_into_filtered); } /* @@ -1567,10 +1582,10 @@ std::vector SPDocument::getItemsInBox(unsigned int dkey, Geom::Rect con * */ -std::vector SPDocument::getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box, bool take_insensitive, bool into_groups) const +std::vector SPDocument::getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box, bool take_hidden, bool take_insensitive, bool take_groups, bool take_into_groups, bool take_into_filtered) const { std::vector x; - return find_items_in_area(x, SP_GROUP(this->root), dkey, box, overlaps, take_insensitive, into_groups); + return find_items_in_area(x, SP_GROUP(this->root), dkey, box, overlaps, take_hidden, take_insensitive, take_groups, take_into_groups, take_into_filtered); } std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vector points, bool all_layers, size_t limit) const -- cgit v1.2.3