summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza <jabier.arraiza@marker.es>2018-11-03 15:56:23 +0000
committerJabier Arraiza <jabier.arraiza@marker.es>2018-11-05 23:14:17 +0000
commitd9e1fb5db48f46e52dbb171e7bdcee1602d8eb14 (patch)
treee84adb8bf6f13e389aade356fa4e6c0abdd62dc3 /src
parentremove Inkscape::URI::toString (diff)
downloadinkscape-d9e1fb5db48f46e52dbb171e7bdcee1602d8eb14.tar.gz
inkscape-d9e1fb5db48f46e52dbb171e7bdcee1602d8eb14.zip
Improvemets to find items
Diffstat (limited to 'src')
-rw-r--r--src/desktop.cpp13
-rw-r--r--src/desktop.h2
-rw-r--r--src/document.cpp43
-rw-r--r--src/document.h4
-rw-r--r--src/ui/contextmenu.cpp2
-rw-r--r--src/ui/tools/measure-tool.cpp2
6 files changed, 47 insertions, 19 deletions
diff --git a/src/desktop.cpp b/src/desktop.cpp
index 335afa17d..7846599c7 100644
--- a/src/desktop.cpp
+++ b/src/desktop.cpp
@@ -726,6 +726,19 @@ SPItem *SPDesktop::getGroupAtPoint(Geom::Point const &p) const
g_return_val_if_fail (doc() != nullptr, NULL);
return doc()->getGroupAtPoint(dkey, p);
}
+/**
+ * Returns a vector of visible items in a desktop
+ */
+std::vector<SPItem *> SPDesktop::getVisibleItems(bool isFiltered) {
+ std::vector<SPItem *> result;
+ for(auto item:getDocument()->getItemsPartiallyInBox(dkey, get_display_area(), false, true, true, false, true)) {
+ if(isFiltered && !item->isFiltered()) {
+ continue;
+ }
+ result.push_back(item);
+ }
+ return result;
+}
/**
* Returns the mouse point in document coordinates; if mouse is
diff --git a/src/desktop.h b/src/desktop.h
index b4e5da35d..8e83b16b9 100644
--- a/src/desktop.h
+++ b/src/desktop.h
@@ -436,7 +436,7 @@ public:
void mouseover() override {}
void mouseout() override {}
-
+ std::vector<SPItem *> getVisibleItems(bool isFiltered = false);
virtual bool onDeleteUI (GdkEventAny*);
virtual bool onWindowStateEvent (GdkEventWindowState* event);
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
diff --git a/src/document.h b/src/document.h
index 5b93261de..9641db8bb 100644
--- a/src/document.h
+++ b/src/document.h
@@ -288,8 +288,8 @@ public:
bool addResource(char const *key, SPObject *object);
bool removeResource(char const *key, SPObject *object);
std::vector<SPObject *> const getResourceList(char const *key);
- std::vector<SPItem*> getItemsInBox(unsigned int dkey, Geom::Rect const &box, bool take_insensitive = false, bool into_groups = false) const;
- std::vector<SPItem*> getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box, bool take_insensitive = false, bool into_groups = false) const;
+ std::vector<SPItem*> getItemsInBox (unsigned int dkey, Geom::Rect const &box, bool take_hidden = false, bool take_insensitive = false, bool take_groups = true, bool take_into_groups = false, bool take_into_filtered = true) const;
+ std::vector<SPItem*> getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box, bool take_hidden = false, bool take_insensitive = false, bool take_groups = true, bool take_into_groups = false, bool take_into_filtered = true) const;
SPItem *getItemAtPoint(unsigned int key, Geom::Point const &p, bool into_groups, SPItem *upto = nullptr) const;
std::vector<SPItem*> getItemsAtPoints(unsigned const key, std::vector<Geom::Point> points, bool all_layers = true, size_t limit = 0) const ;
SPItem *getGroupAtPoint(unsigned int key, Geom::Point const &p) const;
diff --git a/src/ui/contextmenu.cpp b/src/ui/contextmenu.cpp
index 0139f2444..2a4415afa 100644
--- a/src/ui/contextmenu.cpp
+++ b/src/ui/contextmenu.cpp
@@ -89,7 +89,7 @@ ContextMenu::ContextMenu(SPDesktop *desktop, SPItem *item) :
AddSeparator();
/* Lock/Unock Hide/Unhide*/
Geom::Rect b(_desktop->point(),_desktop->point() + Geom::Point(1,1));
- std::vector< SPItem * > down_items = _desktop->getDocument()->getItemsPartiallyInBox( _desktop->dkey, b, true, true);
+ std::vector< SPItem * > down_items = _desktop->getDocument()->getItemsPartiallyInBox( _desktop->dkey, b, true, true, true, true, true);
bool has_down_hidden = false;
bool has_down_locked = false;
for(std::vector< SPItem * >::iterator down = down_items.begin(); down != down_items.end(); ++down){
diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp
index 3863d99d2..2a2578910 100644
--- a/src/ui/tools/measure-tool.cpp
+++ b/src/ui/tools/measure-tool.cpp
@@ -1300,7 +1300,7 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, bool to_phantom,
std::vector<SPItem*> items;
SPDocument *doc = desktop->getDocument();
Geom::Rect rect(start_p, end_p);
- items = doc->getItemsPartiallyInBox(desktop->dkey, rect, false, true);
+ items = doc->getItemsPartiallyInBox(desktop->dkey, rect, false, true, false, true, true);
Inkscape::LayerModel *layer_model = nullptr;
SPObject *current_layer = nullptr;
if(desktop){