From 9abb5e658d005b3ac82afeec13fd59384a8e65eb Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Sun, 5 Jun 2016 23:20:55 +0200 Subject: Added object set (bzr r14954.1.1) --- src/object-set.cpp | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/object-set.cpp (limited to 'src/object-set.cpp') diff --git a/src/object-set.cpp b/src/object-set.cpp new file mode 100644 index 000000000..f071aa4d6 --- /dev/null +++ b/src/object-set.cpp @@ -0,0 +1,133 @@ +/* + * Multiindex container for selection + * + * Authors: + * Adrian Boguszewski + * + * Copyright (C) 2016 Adrian Boguszewski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "object-set.h" + +bool ObjectSet::add(Object* object) { + // any ancestor is in the set - do nothing + if (_anyAncestorIsInSet(object)) { + return false; + } + + // check if there is mutual ancestor for some elements, which can replace all of them in the set + Object* o = _getMutualAncestor(object); + + // remove all descendants from the set + _removeDescendantsFromSet(o); + + _add(o); + return true; +} + +bool ObjectSet::remove(Object* object) { + // object is the top of subtree + if (contains(object)) { + _remove(object); + return true; + } + + // any ancestor of object is in the set + if (_anyAncestorIsInSet(object)) { + _removeAncestorsFromSet(object); + return true; + } + + // no object nor any parent in the set + return false; +} + +bool ObjectSet::contains(Object* object) { + return container.get().find(object) != container.get().end(); +} + +void ObjectSet::clear() { + for (auto object: container) { + _remove(object); + } +} + +int ObjectSet::size() { + return container.size(); +} + +bool ObjectSet::_anyAncestorIsInSet(Object *object) { + Object* o = object; + while (o != nullptr) { + if (contains(o)) { + return true; + } + o = o->getParent(); + } + + return false; +} + +void ObjectSet::_removeDescendantsFromSet(Object *object) { + for (auto& child: object->getChildren()) { + if (contains(&child)) { + _remove(&child); + // there is certainly no children of this child in the set + continue; + } + + _removeDescendantsFromSet(&child); + } +} + +void ObjectSet::_remove(Object *object) { + releaseConnections[object].disconnect(); + releaseConnections.erase(object); + container.get().erase(object); +} + +void ObjectSet::_add(Object *object) { + releaseConnections[object] = object->connectRelease(sigc::mem_fun(*this, &ObjectSet::remove)); + container.push_back(object); +} + +Object *ObjectSet::_getMutualAncestor(Object *object) { + Object *o = object; + + bool flag = true; + while (o->getParent() != nullptr) { + for (auto &child: o->getParent()->getChildren()) { + if(&child != o && !contains(&child)) { + flag = false; + break; + } + } + if (!flag) { + break; + } + o = o->getParent(); + } + return o; +} + +void ObjectSet::_removeAncestorsFromSet(Object *object) { + Object* o = object; + while (o->getParent() != nullptr) { + for (auto &child: o->getParent()->getChildren()) { + if (&child != o) { + _add(&child); + } + } + if (contains(o->getParent())) { + _remove(o->getParent()); + break; + } + o = o->getParent(); + } +} + +ObjectSet::~ObjectSet() { + clear(); +} -- cgit v1.2.3 From 1636c1dd1651780d01759676b194312529f211f7 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Sat, 25 Jun 2016 22:24:26 +0200 Subject: Moved next functions, added namespace, renamed range functions (bzr r14954.1.10) --- src/object-set.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'src/object-set.cpp') diff --git a/src/object-set.cpp b/src/object-set.cpp index d282e7894..627544a21 100644 --- a/src/object-set.cpp +++ b/src/object-set.cpp @@ -16,6 +16,7 @@ #include "persp3d.h" #include "preferences.h" +namespace Inkscape { bool ObjectSet::add(SPObject* object) { g_return_val_if_fail(object != NULL, false); @@ -202,7 +203,7 @@ SPItem *ObjectSet::largestItem(CompareSize compare) { } SPItem *ObjectSet::_sizeistItem(bool sml, CompareSize compare) { - std::vector const items = itemList(); + std::vector const items = const_cast(this)->items(); gdouble max = sml ? 1e18 : 0; SPItem *ist = NULL; @@ -226,10 +227,10 @@ SPItem *ObjectSet::_sizeistItem(bool sml, CompareSize compare) { return ist; } -SPObjectRange ObjectSet::range() { +SPObjectRange ObjectSet::objects() { return SPObjectRange(container.get().begin(), container.get().end()); } -std::vector ObjectSet::itemList() { +std::vector ObjectSet::items() { std::vector tmp = std::vector(container.begin(), container.end()); std::vector result; std::remove_if(tmp.begin(), tmp.end(), [](SPObject* o){return !SP_IS_ITEM(o);}); @@ -237,6 +238,18 @@ std::vector ObjectSet::itemList() { return result; } +std::vector ObjectSet::xmlNodes() { + std::vector list = items(); + std::vector result; + std::transform(list.begin(), list.end(), std::back_inserter(result), [](SPItem* item) { return item->getRepr(); }); + return result; +} + +Inkscape::XML::Node *ObjectSet::singleRepr() { + SPObject *obj = single(); + return obj ? obj->getRepr() : nullptr; +} + void ObjectSet::set(SPObject *object) { _clear(); _add(object); @@ -273,7 +286,7 @@ Geom::OptRect ObjectSet::bounds(SPItem::BBoxType type) const Geom::OptRect ObjectSet::geometricBounds() const { - std::vector const items = const_cast(this)->itemList(); + std::vector const items = const_cast(this)->items(); Geom::OptRect bbox; for ( std::vector::const_iterator iter=items.begin();iter!=items.end(); ++iter) { @@ -284,7 +297,7 @@ Geom::OptRect ObjectSet::geometricBounds() const Geom::OptRect ObjectSet::visualBounds() const { - std::vector const items = const_cast(this)->itemList(); + std::vector const items = const_cast(this)->items(); Geom::OptRect bbox; for ( std::vector::const_iterator iter=items.begin();iter!=items.end(); ++iter) { @@ -305,7 +318,7 @@ Geom::OptRect ObjectSet::preferredBounds() const Geom::OptRect ObjectSet::documentBounds(SPItem::BBoxType type) const { Geom::OptRect bbox; - std::vector const items = const_cast(this)->itemList(); + std::vector const items = const_cast(this)->items(); if (items.empty()) return bbox; for ( std::vector::const_iterator iter=items.begin();iter!=items.end(); ++iter) { @@ -319,7 +332,7 @@ Geom::OptRect ObjectSet::documentBounds(SPItem::BBoxType type) const // If we have a selection of multiple items, then the center of the first item // will be returned; this is also the case in SelTrans::centerRequest() boost::optional ObjectSet::center() const { - std::vector const items = const_cast(this)->itemList(); + std::vector const items = const_cast(this)->items(); if (!items.empty()) { SPItem *first = items.back(); // from the first item in selection if (first->isCenterSet()) { // only if set explicitly @@ -381,4 +394,6 @@ void ObjectSet::_remove_3D_boxes_recursively(SPObject *obj) { } _3dboxes.erase(b); } -} \ No newline at end of file +} + +} // namespace Inkscape -- cgit v1.2.3 From a51df2ab1eb079b2588ccb9398440f403d11c34d Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Mon, 27 Jun 2016 16:59:48 +0200 Subject: Added more tests (bzr r14954.1.11) --- src/object-set.cpp | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) (limited to 'src/object-set.cpp') diff --git a/src/object-set.cpp b/src/object-set.cpp index 627544a21..518ce15a3 100644 --- a/src/object-set.cpp +++ b/src/object-set.cpp @@ -174,13 +174,8 @@ bool ObjectSet::isEmpty() { return container.size() == 0; } - SPObject *ObjectSet::single() { - if (container.size() == 1) { - return *container.begin(); - } - - return nullptr; + return container.size() == 1 ? *container.begin() : nullptr; } SPItem *ObjectSet::singleItem() { @@ -257,27 +252,6 @@ void ObjectSet::set(SPObject *object) { // _emitSignals(); } -void ObjectSet::setList(const std::vector &objs) { - _clear(); - addList(objs); -} - -void ObjectSet::addList(const std::vector &objs) { - for (std::vector::const_iterator iter = objs.begin(); iter != objs.end(); ++iter) { - SPObject *obj = *iter; - if (!includes(obj)) { - add(obj); - } - } -} - -void ObjectSet::add(const std::vector::iterator& from, const std::vector::iterator& to) { - for(auto it = from; it != to; ++it) { - _add(*it); - } -} - - Geom::OptRect ObjectSet::bounds(SPItem::BBoxType type) const { return (type == SPItem::GEOMETRIC_BBOX) ? -- cgit v1.2.3 From 22262f2db6747eb516283b92abcfd348c700911a Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Fri, 1 Jul 2016 20:57:32 +0200 Subject: Added xmlNodes as range function (bzr r14954.1.12) --- src/object-set.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src/object-set.cpp') diff --git a/src/object-set.cpp b/src/object-set.cpp index 518ce15a3..1240e5198 100644 --- a/src/object-set.cpp +++ b/src/object-set.cpp @@ -15,6 +15,8 @@ #include "box3d.h" #include "persp3d.h" #include "preferences.h" +#include +#include namespace Inkscape { @@ -233,13 +235,6 @@ std::vector ObjectSet::items() { return result; } -std::vector ObjectSet::xmlNodes() { - std::vector list = items(); - std::vector result; - std::transform(list.begin(), list.end(), std::back_inserter(result), [](SPItem* item) { return item->getRepr(); }); - return result; -} - Inkscape::XML::Node *ObjectSet::singleRepr() { SPObject *obj = single(); return obj ? obj->getRepr() : nullptr; -- cgit v1.2.3 From 058e95a59ccb2ab1748392acdfdbbffd516c9c81 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Mon, 11 Jul 2016 14:24:52 +0200 Subject: First part of new SPObject children list (bzr r14954.1.17) --- src/object-set.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/object-set.cpp') diff --git a/src/object-set.cpp b/src/object-set.cpp index 07f9ea0c8..b7b84e163 100644 --- a/src/object-set.cpp +++ b/src/object-set.cpp @@ -93,14 +93,14 @@ bool ObjectSet::_anyAncestorIsInSet(SPObject *object) { } void ObjectSet::_removeDescendantsFromSet(SPObject *object) { - for (auto& child: object->childList(false)) { - if (includes(child)) { - _remove(child); + for (auto& child: object->_children) { + if (includes(&child)) { + _remove(&child); // there is certainly no children of this child in the set continue; } - _removeDescendantsFromSet(child); + _removeDescendantsFromSet(&child); } } @@ -130,8 +130,8 @@ SPObject *ObjectSet::_getMutualAncestor(SPObject *object) { bool flag = true; while (o->parent != nullptr) { - for (auto &child: o->parent->childList(false)) { - if(child != o && !includes(child)) { + for (auto &child: o->parent->_children) { + if(&child != o && !includes(&child)) { flag = false; break; } @@ -147,9 +147,9 @@ SPObject *ObjectSet::_getMutualAncestor(SPObject *object) { void ObjectSet::_removeAncestorsFromSet(SPObject *object) { SPObject* o = object; while (o->parent != nullptr) { - for (auto &child: o->parent->childList(false)) { - if (child != o) { - _add(child); + for (auto &child: o->parent->_children) { + if (&child != o) { + _add(&child); } } if (includes(o->parent)) { -- cgit v1.2.3 From 24d3f50003ca3cec6a03a7f5267cc4fe5588c69f Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Thu, 14 Jul 2016 13:17:21 +0200 Subject: Renamed children list in SPObject (bzr r14954.1.21) --- src/object-set.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/object-set.cpp') diff --git a/src/object-set.cpp b/src/object-set.cpp index b7b84e163..1b994106a 100644 --- a/src/object-set.cpp +++ b/src/object-set.cpp @@ -93,7 +93,7 @@ bool ObjectSet::_anyAncestorIsInSet(SPObject *object) { } void ObjectSet::_removeDescendantsFromSet(SPObject *object) { - for (auto& child: object->_children) { + for (auto& child: object->children) { if (includes(&child)) { _remove(&child); // there is certainly no children of this child in the set @@ -130,7 +130,7 @@ SPObject *ObjectSet::_getMutualAncestor(SPObject *object) { bool flag = true; while (o->parent != nullptr) { - for (auto &child: o->parent->_children) { + for (auto &child: o->parent->children) { if(&child != o && !includes(&child)) { flag = false; break; @@ -147,7 +147,7 @@ SPObject *ObjectSet::_getMutualAncestor(SPObject *object) { void ObjectSet::_removeAncestorsFromSet(SPObject *object) { SPObject* o = object; while (o->parent != nullptr) { - for (auto &child: o->parent->_children) { + for (auto &child: o->parent->children) { if (&child != o) { _add(&child); } -- cgit v1.2.3 From 300d24dedddefb2f68ebd680fcd2234bfca53ad7 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Mon, 25 Jul 2016 22:16:54 +0200 Subject: Changed coding style (bzr r14954.1.27) --- src/object-set.cpp | 47 ++++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 19 deletions(-) (limited to 'src/object-set.cpp') diff --git a/src/object-set.cpp b/src/object-set.cpp index 1b994106a..92bcf6b07 100644 --- a/src/object-set.cpp +++ b/src/object-set.cpp @@ -24,7 +24,6 @@ bool ObjectSet::add(SPObject* object) { g_return_val_if_fail(object != NULL, false); g_return_val_if_fail(SP_IS_OBJECT(object), false); - // any ancestor is in the set - do nothing if (_anyAncestorIsInSet(object)) { return false; @@ -68,7 +67,7 @@ bool ObjectSet::includes(SPObject *object) { g_return_val_if_fail(object != NULL, false); g_return_val_if_fail(SP_IS_OBJECT(object), false); - return container.get().find(object) != container.get().end(); + return _container.get().find(object) != _container.get().end(); } void ObjectSet::clear() { @@ -77,7 +76,7 @@ void ObjectSet::clear() { } int ObjectSet::size() { - return container.size(); + return _container.size(); } bool ObjectSet::_anyAncestorIsInSet(SPObject *object) { @@ -105,22 +104,22 @@ void ObjectSet::_removeDescendantsFromSet(SPObject *object) { } void ObjectSet::_remove(SPObject *object) { - releaseConnections[object].disconnect(); - releaseConnections.erase(object); - container.get().erase(object); - _remove_3D_boxes_recursively(object); + _releaseConnections[object].disconnect(); + _releaseConnections.erase(object); + _container.get().erase(object); + _remove3DBoxesRecursively(object); _releaseSignals(object); } void ObjectSet::_add(SPObject *object) { - releaseConnections[object] = object->connectRelease(sigc::hide_return(sigc::mem_fun(*this, &ObjectSet::remove))); - container.push_back(object); - _add_3D_boxes_recursively(object); + _releaseConnections[object] = object->connectRelease(sigc::hide_return(sigc::mem_fun(*this, &ObjectSet::remove))); + _container.push_back(object); + _add3DBoxesRecursively(object); _connectSignals(object); } void ObjectSet::_clear() { - for (auto object: container) { + for (auto object: _container) { _remove(object); } } @@ -173,16 +172,16 @@ void ObjectSet::toggle(SPObject *obj) { } bool ObjectSet::isEmpty() { - return container.size() == 0; + return _container.size() == 0; } SPObject *ObjectSet::single() { - return container.size() == 1 ? *container.begin() : nullptr; + return _container.size() == 1 ? *_container.begin() : nullptr; } SPItem *ObjectSet::singleItem() { - if (container.size() == 1) { - SPObject* obj = *container.begin(); + if (_container.size() == 1) { + SPObject* obj = *_container.begin(); if (SP_IS_ITEM(obj)) { return SP_ITEM(obj); } @@ -225,7 +224,7 @@ SPItem *ObjectSet::_sizeistItem(bool sml, CompareSize compare) { } SPObjectRange ObjectSet::objects() { - return SPObjectRange(container.get().begin(), container.get().end()); + return SPObjectRange(_container.get().begin(), _container.get().end()); } Inkscape::XML::Node *ObjectSet::singleRepr() { @@ -309,7 +308,6 @@ boost::optional ObjectSet::center() const { } } - std::list const ObjectSet::perspList() { std::list pl; for (std::list::iterator i = _3dboxes.begin(); i != _3dboxes.end(); ++i) { @@ -335,7 +333,7 @@ std::list const ObjectSet::box3DList(Persp3D *persp) { return boxes; } -void ObjectSet::_add_3D_boxes_recursively(SPObject *obj) { +void ObjectSet::_add3DBoxesRecursively(SPObject *obj) { std::list boxes = box3d_extract_boxes(obj); for (std::list::iterator i = boxes.begin(); i != boxes.end(); ++i) { @@ -344,7 +342,7 @@ void ObjectSet::_add_3D_boxes_recursively(SPObject *obj) { } } -void ObjectSet::_remove_3D_boxes_recursively(SPObject *obj) { +void ObjectSet::_remove3DBoxesRecursively(SPObject *obj) { std::list boxes = box3d_extract_boxes(obj); for (std::list::iterator i = boxes.begin(); i != boxes.end(); ++i) { @@ -359,3 +357,14 @@ void ObjectSet::_remove_3D_boxes_recursively(SPObject *obj) { } } // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3