diff options
| author | Jabier Arraiza <jabier.arraiza@marker.es> | 2018-11-03 15:56:23 +0000 |
|---|---|---|
| committer | Jabier Arraiza <jabier.arraiza@marker.es> | 2018-11-05 23:14:17 +0000 |
| commit | d9e1fb5db48f46e52dbb171e7bdcee1602d8eb14 (patch) | |
| tree | e84adb8bf6f13e389aade356fa4e6c0abdd62dc3 /src/document.cpp | |
| parent | remove Inkscape::URI::toString (diff) | |
| download | inkscape-d9e1fb5db48f46e52dbb171e7bdcee1602d8eb14.tar.gz inkscape-d9e1fb5db48f46e52dbb171e7bdcee1602d8eb14.zip | |
Improvemets to find items
Diffstat (limited to 'src/document.cpp')
| -rw-r--r-- | src/document.cpp | 43 |
1 files changed, 29 insertions, 14 deletions
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<SPItem*> &find_items_in_area(std::vector<SPItem*> &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<SPItem*> &find_items_in_area(std::vector<SPItem*> &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<SPItem *>(&o)) { + if (SPGroup * childgroup = dynamic_cast<SPGroup *>(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<SPItem*> SPDocument::getItemsInBox(unsigned int dkey, Geom::Rect const &box, bool take_insensitive, bool into_groups) const +std::vector<SPItem*> 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<SPItem*> 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<SPItem*> SPDocument::getItemsInBox(unsigned int dkey, Geom::Rect con * */ -std::vector<SPItem*> SPDocument::getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box, bool take_insensitive, bool into_groups) const +std::vector<SPItem*> 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<SPItem*> 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<SPItem*> SPDocument::getItemsAtPoints(unsigned const key, std::vector<Geom::Point> points, bool all_layers, size_t limit) const |
