diff --git a/src/selection.cpp b/src/selection.cpp
index 3e4c622c1573848c8e4d412ce63c1805c8c24b81..68a9a2cd92e719ebd151cbbcb78725a113452743 100644 (file)
--- a/src/selection.cpp
+++ b/src/selection.cpp
#include "xml/repr.h"
#include "sp-shape.h"
+#include "sp-path.h"
+#include "sp-item-group.h"
#include <sigc++/functors/mem_fun.h>
/* Handler for selected objects "modified" signal */
-void Selection::_schedule_modified(SPObject *obj, guint flags) {
+void Selection::_schedule_modified(SPObject */*obj*/, guint flags) {
if (!this->_idle) {
/* Request handling to be run in _idle loop */
this->_idle = g_idle_add_full(SP_SELECTION_UPDATE_PRIORITY, GSourceFunc(&Selection::_emit_modified), this, NULL);
this->_flags |= flags;
}
-bool
+gboolean
Selection::_emit_modified(Selection *selection)
{
/* force new handler to be created if requested before we return */
return obj ? SP_OBJECT_REPR(obj) : NULL;
}
-NRRect *Selection::bounds(NRRect *bbox) const
+NRRect *Selection::bounds(NRRect *bbox, SPItem::BBoxType type) const
{
g_return_val_if_fail (bbox != NULL, NULL);
- NR::Rect const b = bounds();
- bbox->x0 = b.min()[NR::X];
- bbox->y0 = b.min()[NR::Y];
- bbox->x1 = b.max()[NR::X];
- bbox->y1 = b.max()[NR::Y];
+ *bbox = NRRect(bounds(type));
return bbox;
}
-NR::Rect Selection::bounds() const
+NR::Maybe<NR::Rect> Selection::bounds(SPItem::BBoxType type) const
{
GSList const *items = const_cast<Selection *>(this)->itemList();
- if (!items) {
- return NR::Rect(NR::Point(0, 0), NR::Point(0, 0));
- }
-
- GSList const *i = items;
- NR::Rect bbox = sp_item_bbox_desktop(SP_ITEM(i->data));
- GSList const *i_start = i;
- while (i != NULL) {
- if (i != i_start)
- bbox = NR::Rect::union_bounds(bbox, sp_item_bbox_desktop(SP_ITEM(i->data)));
- i = i->next;
+ NR::Maybe<NR::Rect> bbox = NR::Nothing();
+ for ( GSList const *i = items ; i != NULL ; i = i->next ) {
+ bbox = NR::union_bounds(bbox, sp_item_bbox_desktop(SP_ITEM(i->data), type));
}
-
return bbox;
}
-NRRect *Selection::boundsInDocument(NRRect *bbox) const {
+NRRect *Selection::boundsInDocument(NRRect *bbox, SPItem::BBoxType type) const {
g_return_val_if_fail (bbox != NULL, NULL);
GSList const *items=const_cast<Selection *>(this)->itemList();
for ( GSList const *iter=items ; iter != NULL ; iter = iter->next ) {
SPItem *item=SP_ITEM(iter->data);
- NR::Matrix const i2doc(sp_item_i2doc_affine(item));
- sp_item_invoke_bbox(item, bbox, i2doc, FALSE);
+ NR::Matrix i2doc(sp_item_i2doc_affine(item));
+ sp_item_invoke_bbox(item, bbox, i2doc, FALSE, type);
}
return bbox;
}
-NR::Rect Selection::boundsInDocument() const {
+NR::Maybe<NR::Rect> Selection::boundsInDocument(SPItem::BBoxType type) const {
NRRect r;
- return NR::Rect(*boundsInDocument(&r));
+ return boundsInDocument(&r, type)->upgrade();
}
/** Extract the position of the center from the first selected object */
-NR::Point Selection::center() const {
+NR::Maybe<NR::Point> Selection::center() const {
GSList *items = (GSList *) const_cast<Selection *>(this)->itemList();
NR::Point center;
if (items) {
SPItem *first = reinterpret_cast<SPItem*>(g_slist_last(items)->data); // from the first item in selection
if (first->isCenterSet()) { // only if set explicitly
- center = first->getCenter();
- } else {
- center = bounds().midpoint();
+ return first->getCenter();
}
+ }
+ NR::Maybe<NR::Rect> bbox = bounds();
+ if (bbox) {
+ return bounds()->midpoint();
} else {
- center = bounds().midpoint();
+ return NR::Nothing();
}
- return center;
}
/**
* Compute the list of points in the selection that are to be considered for snapping.
*/
-std::vector<NR::Point> Selection::getSnapPoints() const {
+std::vector<NR::Point> Selection::getSnapPoints(bool includeItemCenter) const {
GSList const *items = const_cast<Selection *>(this)->itemList();
std::vector<NR::Point> p;
for (GSList const *iter = items; iter != NULL; iter = iter->next) {
- sp_item_snappoints(SP_ITEM(iter->data), SnapPointsIter(p));
+ SPItem *this_item = SP_ITEM(iter->data);
+ sp_item_snappoints(this_item, false, SnapPointsIter(p));
+ //Include the transformation origin for snapping
+ //For a group only the group's origin is considered
+ if (includeItemCenter) {
+ p.push_back(this_item->getCenter());
+ }
}
return p;
std::vector<NR::Point> Selection::getSnapPointsConvexHull() const {
GSList const *items = const_cast<Selection *>(this)->itemList();
+
std::vector<NR::Point> p;
for (GSList const *iter = items; iter != NULL; iter = iter->next) {
- sp_item_snappoints(SP_ITEM(iter->data), SnapPointsIter(p));
+ sp_item_snappoints(SP_ITEM(iter->data), false, SnapPointsIter(p));
}
- std::vector<NR::Point>::iterator i;
- NR::ConvexHull cvh(*(p.begin()));
- for (i = p.begin(); i != p.end(); i++) {
- // these are the points we get back
- cvh.add(*i);
- }
-
- NR::Rect rHull = cvh.bounds();
- std::vector<NR::Point> pHull(4);
- pHull[0] = rHull.corner(0);
- pHull[1] = rHull.corner(1);
- pHull[2] = rHull.corner(2);
- pHull[3] = rHull.corner(3);
-
- return pHull;
-}
+ std::vector<NR::Point> pHull;
+ if (!p.empty()) {
+ std::vector<NR::Point>::iterator i;
+ NR::ConvexHull cvh(p.front());
+ for (i = p.begin(); i != p.end(); i++) {
+ // these are the points we get back
+ cvh.add(*i);
+ }
-std::vector<NR::Point> Selection::getBBoxPoints() const {
- GSList const *items = const_cast<Selection *>(this)->itemList();
- std::vector<NR::Point> p;
- for (GSList const *iter = items; iter != NULL; iter = iter->next) {
- NR::Rect b = sp_item_bbox_desktop(SP_ITEM(iter->data));
- p.push_back(b.min());
- p.push_back(b.max());
+ NR::Maybe<NR::Rect> rHull = cvh.bounds();
+ if (rHull) {
+ for ( unsigned i = 0 ; i < 4 ; ++i ) {
+ pHull.push_back(rHull->corner(i));
+ }
+ }
}
- return p;
-}
-
-std::vector<NR::Point> Selection::getBBoxPointsOuter() const {
- std::vector<NR::Point> p;
- NR::Rect bbox = bounds();
- p.push_back(bbox.min());
- p.push_back(bbox.max());
- return p;
+ return pHull;
}
void Selection::_removeObjectDescendants(SPObject *obj) {