summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMenTaLguY <mental@rydia.net>2007-03-11 19:57:07 +0000
committermental <mental@users.sourceforge.net>2007-03-11 19:57:07 +0000
commit58b0e69b7336a8a06c447cf786f73df903120e53 (patch)
tree7b4e064fee2a8813127b3c1f3ee3a68425d8990c
parentAdd ctrl+click to paint bucket to change clicked object's fill and stroke to ... (diff)
downloadinkscape-58b0e69b7336a8a06c447cf786f73df903120e53.tar.gz
inkscape-58b0e69b7336a8a06c447cf786f73df903120e53.zip
Switch selection bounds and center to use NR::Maybe, addressing most of the
recent bbox regressions. (bzr r2604)
-rw-r--r--src/desktop.cpp6
-rw-r--r--src/dialogs/export.cpp4
-rw-r--r--src/dialogs/object-properties.cpp24
-rw-r--r--src/dialogs/tiledialog.cpp8
-rw-r--r--src/extension/internal/grid.cpp5
-rw-r--r--src/file.cpp7
-rw-r--r--src/interface.cpp7
-rw-r--r--src/selection-chemistry.cpp88
-rw-r--r--src/selection.cpp61
-rw-r--r--src/selection.h18
-rw-r--r--src/seltrans.cpp117
-rw-r--r--src/seltrans.h5
-rw-r--r--src/splivarot.cpp7
-rw-r--r--src/ui/dialog/align-and-distribute.cpp17
-rw-r--r--src/ui/dialog/transformation.cpp155
-rw-r--r--src/verbs.cpp6
-rw-r--r--src/widgets/select-toolbar.cpp73
17 files changed, 327 insertions, 281 deletions
diff --git a/src/desktop.cpp b/src/desktop.cpp
index d159fbc78..5fa251842 100644
--- a/src/desktop.cpp
+++ b/src/desktop.cpp
@@ -855,13 +855,13 @@ SPDesktop::zoom_page_width()
void
SPDesktop::zoom_selection()
{
- NR::Rect const d = selection->bounds();
+ NR::Maybe<NR::Rect> const d = selection->bounds();
- if (d.dimensions()[NR::X] < 0.1 || d.dimensions()[NR::Y] < 0.1) {
+ if ( !d || d->dimensions()[NR::X] < 0.1 || d->dimensions()[NR::Y] < 0.1) {
return;
}
- set_display_area(d, 10);
+ set_display_area(*d, 10);
}
/**
diff --git a/src/dialogs/export.cpp b/src/dialogs/export.cpp
index 4dfdbbb5e..c6d7e89d8 100644
--- a/src/dialogs/export.cpp
+++ b/src/dialogs/export.cpp
@@ -1402,10 +1402,10 @@ sp_export_detect_size(GtkObject * base) {
switch (this_test[i]) {
case SELECTION_SELECTION:
if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
- NR::Rect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds();
+ NR::Maybe<NR::Rect> bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds();
//std::cout << "Selection " << bbox;
- if (sp_export_bbox_equal(bbox,current_bbox)) {
+ if ( bbox && sp_export_bbox_equal(*bbox,current_bbox)) {
key = SELECTION_SELECTION;
}
}
diff --git a/src/dialogs/object-properties.cpp b/src/dialogs/object-properties.cpp
index 53b9aa8cc..4db82385a 100644
--- a/src/dialogs/object-properties.cpp
+++ b/src/dialogs/object-properties.cpp
@@ -342,13 +342,15 @@ sp_fillstroke_selection_changed ( Inkscape::Application *inkscape,
case QUERY_STYLE_SINGLE:
case QUERY_STYLE_MULTIPLE_AVERAGED:
case QUERY_STYLE_MULTIPLE_SAME:
- NR::Rect bbox = sp_desktop_selection(SP_ACTIVE_DESKTOP)->bounds();
- double perimeter = bbox.extent(NR::X) + bbox.extent(NR::Y);
- gtk_widget_set_sensitive (b, TRUE);
- //update blur widget value
- float radius = query->filter_gaussianBlur_deviation.value;
- float percent = radius * 400 / perimeter; // so that for a square, 100% == half side
- gtk_adjustment_set_value(bluradjustment, percent);
+ NR::Maybe<NR::Rect> bbox = sp_desktop_selection(SP_ACTIVE_DESKTOP)->bounds();
+ if (bbox) {
+ double perimeter = bbox->extent(NR::X) + bbox->extent(NR::Y);
+ gtk_widget_set_sensitive (b, TRUE);
+ //update blur widget value
+ float radius = query->filter_gaussianBlur_deviation.value;
+ float percent = radius * 400 / perimeter; // so that for a square, 100% == half side
+ gtk_adjustment_set_value(bluradjustment, percent);
+ }
break;
}
@@ -411,13 +413,17 @@ sp_fillstroke_blur_changed (GtkAdjustment *a, SPWidget *base)
//get current selection
Inkscape::Selection *selection = sp_desktop_selection (desktop);
+
+ NR::Maybe<NR::Rect> bbox = selection->bounds();
+ if (!bbox) {
+ return;
+ }
//get list of selected items
GSList const *items = selection->itemList();
//get current document
SPDocument *document = sp_desktop_document (desktop);
- NR::Rect bbox = selection->bounds();
- double perimeter = bbox.extent(NR::X) + bbox.extent(NR::Y);
+ double perimeter = bbox->extent(NR::X) + bbox->extent(NR::Y);
double radius = a->value * perimeter / 400;
//apply created filter to every selected item
diff --git a/src/dialogs/tiledialog.cpp b/src/dialogs/tiledialog.cpp
index b10f952da..75311ddd0 100644
--- a/src/dialogs/tiledialog.cpp
+++ b/src/dialogs/tiledialog.cpp
@@ -268,14 +268,14 @@ void TileDialog::Grid_Arrange ()
}
+ NR::Maybe<NR::Rect> sel_bbox = selection->bounds();
// Fit to bbox, calculate padding between rows accordingly.
- if (!SpaceManualRadioButton.get_active()){
- NR::Rect b = selection->bounds();
+ if ( sel_bbox && !SpaceManualRadioButton.get_active() ){
#ifdef DEBUG_GRID_ARRANGE
g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_height,total_col_width, b.extent(NR::X), b.extent(NR::Y));
#endif
- paddingx = (b.extent(NR::X) - total_col_width) / (NoOfCols -1);
- paddingy = (b.extent(NR::Y) - total_row_height) / (NoOfRows -1);
+ paddingx = (sel_bbox->extent(NR::X) - total_col_width) / (NoOfCols -1);
+ paddingy = (sel_bbox->extent(NR::Y) - total_row_height) / (NoOfRows -1);
}
/*
diff --git a/src/extension/internal/grid.cpp b/src/extension/internal/grid.cpp
index 87e0c14ac..061035eac 100644
--- a/src/extension/internal/grid.cpp
+++ b/src/extension/internal/grid.cpp
@@ -86,7 +86,10 @@ Grid::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *doc
NR::Point(sp_document_width(doc),
sp_document_height(doc)));
} else {
- bounding_area = selection->bounds();
+ NR::Maybe<NR::Rect> bounds = selection->bounds();
+ if (bounds) {
+ bounding_area = *bounds;
+ }
gdouble doc_height = sp_document_height(document->doc());
NR::Rect temprec = NR::Rect(NR::Point(bounding_area.min()[NR::X], doc_height - bounding_area.min()[NR::Y]),
diff --git a/src/file.cpp b/src/file.cpp
index f4630719b..c1d035545 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -834,8 +834,11 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
int const saved_pref = prefs_get_int_attribute("options.transform", "pattern", 1);
prefs_set_int_attribute("options.transform", "pattern", 1);
sp_document_ensure_up_to_date(sp_desktop_document(desktop));
- NR::Point m( desktop->point() - selection->bounds().midpoint() );
- sp_selection_move_relative(selection, m);
+ NR::Maybe<NR::Rect> sel_bbox = selection->bounds();
+ if (sel_bbox) {
+ NR::Point m( desktop->point() - sel_bbox->midpoint() );
+ sp_selection_move_relative(selection, m);
+ }
prefs_set_int_attribute("options.transform", "pattern", saved_pref);
}
}
diff --git a/src/interface.cpp b/src/interface.cpp
index 83f4ac3c8..dad1146c0 100644
--- a/src/interface.cpp
+++ b/src/interface.cpp
@@ -1130,8 +1130,11 @@ sp_ui_drag_data_received(GtkWidget *widget,
int const saved_pref = prefs_get_int_attribute("options.transform", "pattern", 1);
prefs_set_int_attribute("options.transform", "pattern", 1);
sp_document_ensure_up_to_date(sp_desktop_document(desktop));
- NR::Point m( desktop->point() - selection->bounds().midpoint() );
- sp_selection_move_relative(selection, m);
+ NR::Maybe<NR::Rect> sel_bbox = selection->bounds();
+ if (sel_bbox) {
+ NR::Point m( desktop->point() - sel_bbox->midpoint() );
+ sp_selection_move_relative(selection, m);
+ }
prefs_set_int_attribute("options.transform", "pattern", saved_pref);
}
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index 171928865..5fa5b0d7e 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -81,7 +81,7 @@ using NR::Y;
GSList *clipboard = NULL;
GSList *defs_clipboard = NULL;
SPCSSAttr *style_clipboard = NULL;
-NR::Rect size_clipboard(NR::Point(0,0), NR::Point(0,0));
+NR::Maybe<NR::Rect> size_clipboard;
static void sp_copy_stuff_used_by_item(GSList **defs_clip, SPItem *item, const GSList *items);
@@ -1128,7 +1128,11 @@ void sp_selection_paste(bool in_place)
if (!in_place) {
sp_document_ensure_up_to_date(document);
- NR::Point m( desktop->point() - selection->bounds().midpoint() );
+ NR::Maybe<NR::Rect> sel_bbox = selection->bounds();
+ NR::Point m( desktop->point() );
+ if (sel_bbox) {
+ m -= sel_bbox->midpoint();
+ }
/* Snap the offset of the new item(s) to the grid */
/* FIXME: this gridsnap fiddling is a hack. */
@@ -1179,7 +1183,7 @@ void sp_selection_paste_size (bool apply_x, bool apply_y)
Inkscape::Selection *selection = sp_desktop_selection(desktop);
// check if something is in the clipboard
- if (size_clipboard.extent(NR::X) < 1e-6 || size_clipboard.extent(NR::Y) < 1e-6) {
+ if (!size_clipboard) {
desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing on the clipboard."));
return;
}
@@ -1190,15 +1194,15 @@ void sp_selection_paste_size (bool apply_x, bool apply_y)
return;
}
- NR::Rect current = selection->bounds();
- if (current.extent(NR::X) < 1e-6 || current.extent(NR::Y) < 1e-6) {
+ NR::Maybe<NR::Rect> current = selection->bounds();
+ if ( !current || current->extent(NR::X) < 1e-6 || current->extent(NR::Y) < 1e-6 ) {
return;
}
- double scale_x = size_clipboard.extent(NR::X) / current.extent(NR::X);
- double scale_y = size_clipboard.extent(NR::Y) / current.extent(NR::Y);
+ double scale_x = size_clipboard->extent(NR::X) / current->extent(NR::X);
+ double scale_y = size_clipboard->extent(NR::Y) / current->extent(NR::Y);
- sp_selection_scale_relative (selection, current.midpoint(),
+ sp_selection_scale_relative (selection, current->midpoint(),
NR::scale(
apply_x? scale_x : (desktop->isToolboxButtonActive ("lock")? scale_y : 1.0),
apply_y? scale_y : (desktop->isToolboxButtonActive ("lock")? scale_x : 1.0)));
@@ -1215,7 +1219,7 @@ void sp_selection_paste_size_separately (bool apply_x, bool apply_y)
Inkscape::Selection *selection = sp_desktop_selection(desktop);
// check if something is in the clipboard
- if (size_clipboard.extent(NR::X) < 1e-6 || size_clipboard.extent(NR::Y) < 1e-6) {
+ if ( !size_clipboard ) {
desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing on the clipboard."));
return;
}
@@ -1234,8 +1238,8 @@ void sp_selection_paste_size_separately (bool apply_x, bool apply_y)
continue;
}
- double scale_x = size_clipboard.extent(NR::X) / current->extent(NR::X);
- double scale_y = size_clipboard.extent(NR::Y) / current->extent(NR::Y);
+ double scale_x = size_clipboard->extent(NR::X) / current->extent(NR::X);
+ double scale_y = size_clipboard->extent(NR::Y) / current->extent(NR::Y);
sp_item_scale_rel (item,
NR::scale(
@@ -1522,16 +1526,16 @@ sp_selection_scale_absolute(Inkscape::Selection *selection,
if (selection->isEmpty())
return;
- NR::Rect const bbox(selection->bounds());
- if (bbox.isEmpty()) {
+ NR::Maybe<NR::Rect> const bbox(selection->bounds());
+ if ( !bbox || bbox->isEmpty() ) {
return;
}
- NR::translate const p2o(-bbox.min());
+ NR::translate const p2o(-bbox->min());
NR::scale const newSize(x1 - x0,
y1 - y0);
- NR::scale const scale( newSize / NR::scale(bbox.dimensions()) );
+ NR::scale const scale( newSize / NR::scale(bbox->dimensions()) );
NR::translate const o2n(x0, y0);
NR::Matrix const final( p2o * scale * o2n );
@@ -1544,15 +1548,15 @@ void sp_selection_scale_relative(Inkscape::Selection *selection, NR::Point const
if (selection->isEmpty())
return;
- NR::Rect const bbox(selection->bounds());
+ NR::Maybe<NR::Rect> const bbox(selection->bounds());
- if (bbox.isEmpty()) {
+ if ( !bbox || bbox->isEmpty() ) {
return;
}
// FIXME: ARBITRARY LIMIT: don't try to scale above 1 Mpx, it won't display properly and will crash sooner or later anyway
- if ( bbox.extent(NR::X) * scale[NR::X] > 1e6 ||
- bbox.extent(NR::Y) * scale[NR::Y] > 1e6 )
+ if ( bbox->extent(NR::X) * scale[NR::X] > 1e6 ||
+ bbox->extent(NR::Y) * scale[NR::Y] > 1e6 )
{
return;
}
@@ -1657,9 +1661,12 @@ sp_selection_rotate(Inkscape::Selection *selection, gdouble const angle_degrees)
if (selection->isEmpty())
return;
- NR::Point center = selection->center();
+ NR::Maybe<NR::Point> center = selection->center();
+ if (!center) {
+ return;
+ }
- sp_selection_rotate_relative(selection, center, angle_degrees);
+ sp_selection_rotate_relative(selection, *center, angle_degrees);
sp_document_maybe_done(sp_desktop_document(selection->desktop()),
( ( angle_degrees > 0 )
@@ -1678,17 +1685,20 @@ sp_selection_rotate_screen(Inkscape::Selection *selection, gdouble angle)
if (selection->isEmpty())
return;
- NR::Rect const bbox(selection->bounds());
+ NR::Maybe<NR::Rect> const bbox(selection->bounds());
+ NR::Maybe<NR::Point> center = selection->center();
- NR::Point center = selection->center();
+ if ( !bbox || !center ) {
+ return;
+ }
gdouble const zoom = selection->desktop()->current_zoom();
gdouble const zmove = angle / zoom;
- gdouble const r = NR::L2(bbox.max() - center);
+ gdouble const r = NR::L2(bbox->max() - *center);
gdouble const zangle = 180 * atan2(zmove, r) / M_PI;
- sp_selection_rotate_relative(selection, center, zangle);
+ sp_selection_rotate_relative(selection, *center, zangle);
sp_document_maybe_done(sp_desktop_document(selection->desktop()),
( (angle > 0)
@@ -1704,11 +1714,15 @@ sp_selection_scale(Inkscape::Selection *selection, gdouble grow)
if (selection->isEmpty())
return;
- NR::Rect const bbox(selection->bounds());
- NR::Point const center(bbox.midpoint());
- double const max_len = bbox.maxExtent();
+ NR::Maybe<NR::Rect> const bbox(selection->bounds());
+ if (!bbox) {
+ return;
+ }
+
+ NR::Point const center(bbox->midpoint());
// you can't scale "do nizhe pola" (below zero)
+ double const max_len = bbox->maxExtent();
if ( max_len + grow <= 1e-3 ) {
return;
}
@@ -1737,7 +1751,13 @@ sp_selection_scale_times(Inkscape::Selection *selection, gdouble times)
if (selection->isEmpty())
return;
- NR::Point const center(selection->bounds().midpoint());
+ NR::Maybe<NR::Rect> sel_bbox = selection->bounds();
+
+ if (!sel_bbox) {
+ return;
+ }
+
+ NR::Point const center(sel_bbox->midpoint());
sp_selection_scale_relative(selection, center, NR::scale(times, times));
sp_document_done(sp_desktop_document(selection->desktop()), SP_VERB_CONTEXT_SELECT,
_("Scale by whole factor"));
@@ -2181,13 +2201,13 @@ sp_selection_tile(bool apply)
}
sp_document_ensure_up_to_date(document);
- NR::Rect r = selection->bounds();
- if (r.isEmpty()) {
+ NR::Maybe<NR::Rect> r = selection->bounds();
+ if ( !r || r->isEmpty() ) {
return;
}
// calculate the transform to be applied to objects to move them to 0,0
- NR::Point move_p = NR::Point(0, sp_document_height(document)) - (r.min() + NR::Point (0, r.extent(NR::Y)));
+ NR::Point move_p = NR::Point(0, sp_document_height(document)) - (r->min() + NR::Point (0, r->extent(NR::Y)));
move_p[NR::Y] = -move_p[NR::Y];
NR::Matrix move = NR::Matrix (NR::translate (move_p));
@@ -2210,7 +2230,7 @@ sp_selection_tile(bool apply)
repr_copies = g_slist_prepend (repr_copies, dup);
}
- NR::Rect bounds(desktop->dt2doc(r.min()), desktop->dt2doc(r.max()));
+ NR::Rect bounds(desktop->dt2doc(r->min()), desktop->dt2doc(r->max()));
if (apply) {
// delete objects so that their clones don't get alerted; this object will be restored shortly
@@ -2227,7 +2247,7 @@ sp_selection_tile(bool apply)
prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED);
const gchar *pat_id = pattern_tile (repr_copies, bounds, document,
- NR::Matrix(NR::translate(desktop->dt2doc(NR::Point(r.min()[NR::X], r.max()[NR::Y])))) * parent_transform.inverse(), parent_transform * move);
+ NR::Matrix(NR::translate(desktop->dt2doc(NR::Point(r->min()[NR::X], r->max()[NR::Y])))) * parent_transform.inverse(), parent_transform * move);
// restore compensation setting
prefs_set_int_attribute("options.clonecompensation", "value", saved_compensation);
diff --git a/src/selection.cpp b/src/selection.cpp
index d39086e8c..c6b307c3b 100644
--- a/src/selection.cpp
+++ b/src/selection.cpp
@@ -306,15 +306,11 @@ Inkscape::XML::Node *Selection::singleRepr() {
NRRect *Selection::bounds(NRRect *bbox) 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());
return bbox;
}
-NR::Rect Selection::bounds() const
+NR::Maybe<NR::Rect> Selection::bounds() const
{
GSList const *items = const_cast<Selection *>(this)->itemList();
@@ -322,13 +318,7 @@ NR::Rect Selection::bounds() const
for ( GSList const *i = items ; i != NULL ; i = i->next ) {
bbox = NR::union_bounds(bbox, sp_item_bbox_desktop(SP_ITEM(i->data)));
}
-
- // TODO: return NR::Maybe<NR::Rect>
- if (bbox) {
- return *bbox;
- } else {
- return NR::Rect(NR::Point(0, 0), NR::Point(0, 0));
- }
+ return bbox;
}
NRRect *Selection::boundsInDocument(NRRect *bbox) const {
@@ -352,32 +342,27 @@ NRRect *Selection::boundsInDocument(NRRect *bbox) const {
return bbox;
}
-NR::Rect Selection::boundsInDocument() const {
+NR::Maybe<NR::Rect> Selection::boundsInDocument() const {
NRRect r;
- NR::Maybe<NR::Rect> rect(boundsInDocument(&r)->upgrade());
- if (rect) {
- return *rect;
- } else {
- // FIXME
- return NR::Rect(NR::Point(0, 0), NR::Point(0, 0));
- }
+ return boundsInDocument(&r)->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;
}
/**
@@ -417,28 +402,6 @@ std::vector<NR::Point> Selection::getSnapPointsConvexHull() const {
return pHull;
}
-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::Maybe<NR::Rect> b = sp_item_bbox_desktop(SP_ITEM(iter->data));
- if (b) {
- p.push_back(b->min());
- p.push_back(b->max());
- }
- }
-
- 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;
-}
-
void Selection::_removeObjectDescendants(SPObject *obj) {
GSList *iter, *next;
for ( iter = _objs ; iter ; iter = next ) {
diff --git a/src/selection.h b/src/selection.h
index bae368e81..f9368f5ee 100644
--- a/src/selection.h
+++ b/src/selection.h
@@ -233,7 +233,7 @@ public:
/** @brief Returns the bounding rectangle of the selection */
NRRect *bounds(NRRect *dest) const;
/** @brief Returns the bounding rectangle of the selection */
- ::NR::Rect bounds() const;
+ NR::Maybe<NR::Rect> bounds() const;
/**
* @brief Returns the bounding rectangle of the selection
@@ -247,12 +247,12 @@ public:
*
* \todo how is this different from bounds()?
*/
- ::NR::Rect boundsInDocument() const;
+ NR::Maybe<NR::Rect> boundsInDocument() const;
/**
* @brief Returns the rotation/skew center of the selection
*/
- ::NR::Point center() const;
+ NR::Maybe<NR::Point> center() const;
/**
* @brief Gets the selection's snap points.
@@ -267,18 +267,6 @@ public:
std::vector<NR::Point> getSnapPointsConvexHull() const;
/**
- * @return A vector containing the top-left and bottom-right
- * corners of each selected object's bounding box.
- */
- std::vector<NR::Point> getBBoxPoints() const;
-
- /**
- * @return A vector containing the 2 (bottom-left and upper-right)
- * corners of the selection bounding box.
- */
- std::vector<NR::Point> getBBoxPointsOuter() const;
-
- /**
* @brief Connects a slot to be notified of selection changes
*
* This method connects the given slot such that it will
diff --git a/src/seltrans.cpp b/src/seltrans.cpp
index 5368628b8..a1a200282 100644
--- a/src/seltrans.cpp
+++ b/src/seltrans.cpp
@@ -88,7 +88,7 @@ Inkscape::SelTrans::SelTrans(SPDesktop *desktop) :
_show(SHOW_CONTENT),
_grabbed(false),
_show_handles(true),
- _box(NR::Point(0,0), NR::Point(0,0)),
+ _box(NR::Nothing()),
_chandle(NULL),
_stamp_cache(NULL),
_message_context(desktop->messageStack())
@@ -256,25 +256,33 @@ void Inkscape::SelTrans::grab(NR::Point const &p, gdouble x, gdouble y, bool sho
_point = p;
_snap_points = selection->getSnapPointsConvexHull();
- _bbox_points = selection->getBBoxPointsOuter();
- _bbox_4points = _bbox_points;
- _bbox_4points.push_back(NR::Point(_bbox_points[0][NR::X], _bbox_points[1][NR::Y]));
- _bbox_4points.push_back(NR::Point(_bbox_points[1][NR::X], _bbox_points[0][NR::Y]));
+ _box = selection->bounds();
+ _bbox_points.clear();
+ if (_box) {
+ for ( unsigned i = 0 ; i < 4 ; i++ ) {
+ _bbox_points.push_back(_box->corner(i));
+ }
+ }
gchar const *scale_origin = prefs_get_string_attribute("tools.select", "scale_origin");
bool const origin_on_bbox = (scale_origin == NULL || !strcmp(scale_origin, "bbox"));
- NR::Rect op_box = _box;
- if (origin_on_bbox == false && _snap_points.empty() == false) {
- std::vector<NR::Point>::iterator i = _snap_points.begin();
- op_box = NR::Rect(*i, *i);
- i++;
- while (i != _snap_points.end()) {
- op_box.expandTo(*i);
+
+ if (_box) {
+ NR::Rect op_box = *_box;
+ // FIXME: should be using ConvexHull here
+ if (origin_on_bbox == false && _snap_points.empty() == false) {
+ std::vector<NR::Point>::iterator i = _snap_points.begin();
+ op_box = NR::Rect(*i, *i);
i++;
+ while (i != _snap_points.end()) {
+ op_box.expandTo(*i);
+ i++;
+ }
}
+
+ _opposite = ( op_box.min() + ( op_box.dimensions() * NR::scale(1-x, 1-y) ) );
}
- _opposite = ( op_box.min() + ( op_box.dimensions() * NR::scale(1-x, 1-y) ) );
if ((x != -1) && (y != -1)) {
sp_canvas_item_show(_norm);
@@ -286,7 +294,6 @@ void Inkscape::SelTrans::grab(NR::Point const &p, gdouble x, gdouble y, bool sho
sp_canvas_item_show(_l[i]);
}
-
_updateHandles();
g_return_if_fail(_stamp_cache == NULL);
}
@@ -306,13 +313,15 @@ void Inkscape::SelTrans::transform(NR::Matrix const &rel_affine, NR::Point const
sp_item_set_i2d_affine(&item, prev_transform * affine);
}
} else {
- NR::Point p[4];
- /* update the outline */
- for (unsigned i = 0 ; i < 4 ; i++) {
- p[i] = _box.corner(i) * affine;
- }
- for (unsigned i = 0 ; i < 4 ; i++) {
- sp_ctrlline_set_coords(SP_CTRLLINE(_l[i]), p[i], p[(i+1)%4]);
+ if (_box) {
+ NR::Point p[4];
+ /* update the outline */
+ for (unsigned i = 0 ; i < 4 ; i++) {
+ p[i] = _box->corner(i) * affine;
+ }
+ for (unsigned i = 0 ; i < 4 ; i++) {
+ sp_ctrlline_set_coords(SP_CTRLLINE(_l[i]), p[i], p[(i+1)%4]);
+ }
}
}
@@ -351,8 +360,10 @@ void Inkscape::SelTrans::ungrab()
if (!_empty && _changed) {
sp_selection_apply_affine(selection, _current, (_show == SHOW_OUTLINE)? true : false);
- _center *= _current;
- _center_is_set = true;
+ if (_center) {
+ *_center *= _current;
+ _center_is_set = true;
+ }
// If dragging showed content live, sp_selection_apply_affine cannot change the centers
// appropriately - it does not know the original positions of the centers (all objects already have
@@ -458,8 +469,8 @@ void Inkscape::SelTrans::stamp()
sp_item_write_transform(copy_item, copy_repr, *new_affine);
- if (copy_item->isCenterSet()) {
- copy_item->setCenter(_center * _current);
+ if ( copy_item->isCenterSet() && _center ) {
+ copy_item->setCenter(*_center * _current);
}
Inkscape::GC::release(copy_repr);
@@ -529,11 +540,11 @@ void Inkscape::SelTrans::_updateHandles()
_center_is_set = true;
}
- if ( _state == STATE_SCALE ) {
+ if ( _state == STATE_SCALE || !_center ) {
sp_knot_hide(_chandle);
} else {
sp_knot_show(_chandle);
- sp_knot_moveto(_chandle, &_center);
+ sp_knot_moveto(_chandle, &*_center);
}
}
@@ -547,7 +558,7 @@ void Inkscape::SelTrans::_updateVolatileState()
}
_box = selection->bounds();
- if (_box.isEmpty()) {
+ if (!_box) {
_empty = true;
return;
}
@@ -595,8 +606,10 @@ void Inkscape::SelTrans::_showHandles(SPKnot *knot[], SPSelTransHandle const han
sp_knot_show(knot[i]);
NR::Point const handle_pt(handle[i].x, handle[i].y);
- NR::Point p( _box.min()
- + ( _box.dimensions()
+ // shouldn't have nullary bbox, but knots
+ g_assert(_box);
+ NR::Point p( _box->min()
+ + ( _box->dimensions()
* NR::scale(handle_pt) ) );
sp_knot_moveto(knot[i], &p);
@@ -715,8 +728,11 @@ gboolean Inkscape::SelTrans::handleRequest(SPKnot *knot, NR::Point *position, gu
if ((!(state & GDK_SHIFT_MASK) == !(_state == STATE_ROTATE)) && (&handle != &handle_center)) {
_origin = _opposite;
+ } else if (_center) {
+ _origin = *_center;
} else {
- _origin = _center;
+ // FIXME
+ return TRUE;
}
if (handle.request(this, handle, *position, state)) {
sp_knot_set_position(knot, position, state);
@@ -870,7 +886,7 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state)
/* Scale aspect ratio is unlocked */
std::pair<NR::scale, bool> bb = m.freeSnapScale(Snapper::BBOX_POINT,
- _bbox_4points,
+ _bbox_points,
it,
s,
_origin);
@@ -1169,22 +1185,21 @@ gboolean Inkscape::SelTrans::centerRequest(NR::Point &pt, guint state)
}
}
- if (!(state & GDK_SHIFT_MASK)) {
+ if ( !(state & GDK_SHIFT_MASK) && _box ) {
// screen pixels to snap center to bbox
#define SNAP_DIST 5
// FIXME: take from prefs
double snap_dist = SNAP_DIST / _desktop->current_zoom();
for (int i = 0; i < 2; i++) {
-
- if (fabs(pt[i] - _box.min()[i]) < snap_dist) {
- pt[i] = _box.min()[i];
+ if (fabs(pt[i] - _box->min()[i]) < snap_dist) {
+ pt[i] = _box->min()[i];
}
- if (fabs(pt[i] - _box.midpoint()[i]) < snap_dist) {
- pt[i] = _box.midpoint()[i];
+ if (fabs(pt[i] - _box->midpoint()[i]) < snap_dist) {
+ pt[i] = _box->midpoint()[i];
}
- if (fabs(pt[i] - _box.max()[i]) < snap_dist) {
- pt[i] = _box.max()[i];
+ if (fabs(pt[i] - _box->max()[i]) < snap_dist) {
+ pt[i] = _box->max()[i];
}
}
}
@@ -1264,11 +1279,15 @@ void Inkscape::SelTrans::stretch(SPSelTransHandle const &handle, NR::Point &pt,
s[!dim] = fabs(s[dim]);
}
- NR::Point new_bbox_min = _box.min() * (NR::translate(-scale_origin) * NR::Matrix(s) * NR::translate(scale_origin));
- NR::Point new_bbox_max = _box.max() * (NR::translate(-scale_origin) * NR::Matrix(s) * NR::translate(scale_origin));
+ if (!_box) {
+ return;
+ }
+
+ NR::Point new_bbox_min = _box->min() * (NR::translate(-scale_origin) * NR::Matrix(s) * NR::translate(scale_origin));
+ NR::Point new_bbox_max = _box->max() * (NR::translate(-scale_origin) * NR::Matrix(s) * NR::translate(scale_origin));
int transform_stroke = prefs_get_int_attribute ("options.transform", "stroke", 1);
- NR::Matrix scaler = get_scale_transform_with_stroke (_box, _strokewidth, transform_stroke,
+ NR::Matrix scaler = get_scale_transform_with_stroke (*_box, _strokewidth, transform_stroke,
new_bbox_min[NR::X], new_bbox_min[NR::Y], new_bbox_max[NR::X], new_bbox_max[NR::Y]);
transform(scaler, NR::Point(0, 0)); // we have already accounted for origin, so pass 0,0
@@ -1276,6 +1295,10 @@ void Inkscape::SelTrans::stretch(SPSelTransHandle const &handle, NR::Point &pt,
void Inkscape::SelTrans::scale(NR::Point &pt, guint state)
{
+ if (!_box) {
+ return;
+ }
+
NR::Point const offset = _point - _origin;
NR::scale s (1, 1);
@@ -1285,11 +1308,11 @@ void Inkscape::SelTrans::scale(NR::Point &pt, guint state)
if (fabs(s[i]) < 1e-9)
s[i] = 1e-9;
}
- NR::Point new_bbox_min = _box.min() * (NR::translate(-_origin) * NR::Matrix(s) * NR::translate(_origin));
- NR::Point new_bbox_max = _box.max() * (NR::translate(-_origin) * NR::Matrix(s) * NR::translate(_origin));
+ NR::Point new_bbox_min = _box->min() * (NR::translate(-_origin) * NR::Matrix(s) * NR::translate(_origin));
+ NR::Point new_bbox_max = _box->max() * (NR::translate(-_origin) * NR::Matrix(s) * NR::translate(_origin));
int transform_stroke = prefs_get_int_attribute ("options.transform", "stroke", 1);
- NR::Matrix scaler = get_scale_transform_with_stroke (_box, _strokewidth, transform_stroke,
+ NR::Matrix scaler = get_scale_transform_with_stroke (*_box, _strokewidth, transform_stroke,
new_bbox_min[NR::X], new_bbox_min[NR::Y], new_bbox_max[NR::X], new_bbox_max[NR::Y]);
transform(scaler, NR::Point(0, 0)); // we have already accounted for origin, so pass 0,0
@@ -1416,7 +1439,7 @@ void Inkscape::SelTrans::moveTo(NR::Point const &xy, guint state)
/* Snap to things with no constraint */
s.push_back(m.freeSnapTranslation(Inkscape::Snapper::BBOX_POINT,
- _bbox_4points, it, dxy));
+ _bbox_points, it, dxy));
s.push_back(m.freeSnapTranslation(Inkscape::Snapper::SNAP_POINT,
_snap_points, it, dxy));
}
diff --git a/src/seltrans.h b/src/seltrans.h
index 8d527ca5c..e8aee252e 100644
--- a/src/seltrans.h
+++ b/src/seltrans.h
@@ -105,7 +105,6 @@ private:
std::vector<NR::Point> _snap_points;
std::vector<NR::Point> _bbox_points;
- std::vector<NR::Point> _bbox_4points;
Inkscape::SelCue _selcue;
@@ -118,12 +117,12 @@ private:
bool _empty;
bool _changed;
- NR::Rect _box;
+ NR::Maybe<NR::Rect> _box;
gdouble _strokewidth;
NR::Matrix _current;
NR::Point _opposite; ///< opposite point to where a scale is taking place
- NR::Point _center;
+ NR::Maybe<NR::Point> _center;
bool _center_is_set; ///< we've already set _center, no need to reread it from items
SPKnot *_shandle[8];
diff --git a/src/splivarot.cpp b/src/splivarot.cpp
index cf07fba16..f5f0a6481 100644
--- a/src/splivarot.cpp
+++ b/src/splivarot.cpp
@@ -1555,8 +1555,11 @@ sp_selected_path_simplify_items(SPDesktop *desktop,
bool didSomething = false;
- NR::Rect selectionBbox = selection->bounds();
- gdouble selectionSize = L2(selectionBbox.dimensions());
+ NR::Maybe<NR::Rect> selectionBbox = selection->bounds();
+ if (!selectionBbox) {
+ return false;
+ }
+ gdouble selectionSize = L2(selectionBbox->dimensions());
gdouble simplifySize = selectionSize;
diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp
index c1f4a10a1..7c5908e58 100644
--- a/src/ui/dialog/align-and-distribute.cpp
+++ b/src/ui/dialog/align-and-distribute.cpp
@@ -183,9 +183,13 @@ private :
case AlignAndDistribute::SELECTION:
{
- NR::Rect b = selection->bounds();
- mp = NR::Point(a.mx0 * b.min()[NR::X] + a.mx1 * b.max()[NR::X],
- a.my0 * b.min()[NR::Y] + a.my1 * b.max()[NR::Y]);
+ NR::Maybe<NR::Rect> b = selection->bounds();
+ if (b) {
+ mp = NR::Point(a.mx0 * b->min()[NR::X] + a.mx1 * b->max()[NR::X],
+ a.my0 * b->min()[NR::Y] + a.my1 * b->max()[NR::Y]);
+ } else {
+ return;
+ }
break;
}
@@ -590,11 +594,16 @@ private :
//Check 2 or more selected objects
if (selected.size() < 2) return;
+ NR::Maybe<NR::Rect> sel_bbox = selection->bounds();
+ if (!sel_bbox) {
+ return;
+ }
+
// This bbox is cached between calls to randomize, so that there's no growth nor shrink
// nor drift on sequential randomizations. Discard cache on global (or better active
// desktop's) selection_change signal.
if (!_dialog.randomize_bbox_set) {
- _dialog.randomize_bbox = selection->bounds();
+ _dialog.randomize_bbox = *sel_bbox;
_dialog.randomize_bbox_set = true;
}
diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp
index 90cac7425..98623849f 100644
--- a/src/ui/dialog/transformation.cpp
+++ b/src/ui/dialog/transformation.cpp
@@ -455,13 +455,14 @@ Transformation::updatePageMove(Inkscape::Selection *selection)
{
if (selection && !selection->isEmpty()) {
if (!_check_move_relative.get_active()) {
+ NR::Maybe<NR::Rect> bbox = selection->bounds();
+ if (bbox) {
+ double x = bbox->min()[NR::X];
+ double y = bbox->min()[NR::Y];
- NR::Rect bbox = selection->bounds();
- double x = bbox.min()[NR::X];
- double y = bbox.min()[NR::Y];
-
- _scalar_move_horizontal.setValue(x, "px");
- _scalar_move_vertical.setValue(y, "px");
+ _scalar_move_horizontal.setValue(x, "px");
+ _scalar_move_vertical.setValue(y, "px");
+ }
} else {
// do nothing, so you can apply the same relative move to many objects in turn
}
@@ -475,13 +476,17 @@ void
Transformation::updatePageScale(Inkscape::Selection *selection)
{
if (selection && !selection->isEmpty()) {
- NR::Rect bbox = selection->bounds();
- double w = bbox.extent(NR::X);
- double h = bbox.extent(NR::Y);
- _scalar_scale_horizontal.setHundredPercent(w);
- _scalar_scale_vertical.setHundredPercent(h);
- onScaleXValueChanged(); // to update x/y proportionality if switch is on
- _page_scale.set_sensitive(true);
+ NR::Maybe<NR::Rect> bbox = selection->bounds();
+ if (bbox) {
+ double w = bbox->extent(NR::X);
+ double h = bbox->extent(NR::Y);
+ _scalar_scale_horizontal.setHundredPercent(w);
+ _scalar_scale_vertical.setHundredPercent(h);
+ onScaleXValueChanged(); // to update x/y proportionality if switch is on
+ _page_scale.set_sensitive(true);
+ } else {
+ _page_scale.set_sensitive(false);
+ }
} else {
_page_scale.set_sensitive(false);
}
@@ -586,9 +591,11 @@ Transformation::applyPageMove(Inkscape::Selection *selection)
if (_check_move_relative.get_active()) {
sp_selection_move_relative(selection, x, y);
} else {
- NR::Rect bbox = selection->bounds();
- sp_selection_move_relative(selection,
- x - bbox.min()[NR::X], y - bbox.min()[NR::Y]);
+ NR::Maybe<NR::Rect> bbox = selection->bounds();
+ if (bbox) {
+ sp_selection_move_relative(selection,
+ x - bbox->min()[NR::X], y - bbox->min()[NR::Y]);
+ }
}
sp_document_done ( sp_desktop_document (selection->desktop()) , SP_VERB_DIALOG_TRANSFORM,
@@ -625,24 +632,26 @@ Transformation::applyPageScale(Inkscape::Selection *selection)
sp_item_scale_rel (item, scale);
}
} else {
- NR::Rect bbox(selection->bounds());
- NR::Point center(bbox.midpoint()); // use rotation center?
- NR::scale scale (0,0);
- // the values are increments!
- if (_units_scale.isAbsolute()) {
- double new_width = bbox.extent(NR::X) + scaleX;
- if (new_width < 1e-6) new_width = 1e-6;
- double new_height = bbox.extent(NR::Y) + scaleY;
- if (new_height < 1e-6) new_height = 1e-6;
- scale = NR::scale(new_width / bbox.extent(NR::X), new_height / bbox.extent(NR::Y));
- } else {
- double new_width = 100 + scaleX;
- if (new_width < 1e-6) new_width = 1e-6;
- double new_height = 100 + scaleY;
- if (new_height < 1e-6) new_height = 1e-6;
- scale = NR::scale(new_width / 100.0, new_height / 100.0);
+ NR::Maybe<NR::Rect> bbox(selection->bounds());
+ if (bbox) {
+ NR::Point center(bbox->midpoint()); // use rotation center?
+ NR::scale scale (0,0);
+ // the values are increments!
+ if (_units_scale.isAbsolute()) {
+ double new_width = bbox->extent(NR::X) + scaleX;
+ if (new_width < 1e-6) new_width = 1e-6;
+ double new_height = bbox->extent(NR::Y) + scaleY;
+ if (new_height < 1e-6) new_height = 1e-6;
+ scale = NR::scale(new_width / bbox->extent(NR::X), new_height / bbox->extent(NR::Y));
+ } else {
+ double new_width = 100 + scaleX;
+ if (new_width < 1e-6) new_width = 1e-6;
+ double new_height = 100 + scaleY;
+ if (new_height < 1e-6) new_height = 1e-6;
+ scale = NR::scale(new_width / 100.0, new_height / 100.0);
+ }
+ sp_selection_scale_relative(selection, center, scale);
}
- sp_selection_scale_relative(selection, center, scale);
}
sp_document_done(sp_desktop_document(selection->desktop()), SP_VERB_DIALOG_TRANSFORM,
@@ -660,8 +669,10 @@ Transformation::applyPageRotate(Inkscape::Selection *selection)
sp_item_rotate_rel(item, NR::rotate (angle*M_PI/180.0));
}
} else {
- NR::Point center = selection->center();
- sp_selection_rotate_relative(selection, center, angle);
+ NR::Maybe<NR::Point> center = selection->center();
+ if (center) {
+ sp_selection_rotate_relative(selection, *center, angle);
+ }
}
sp_document_done(sp_desktop_document(selection->desktop()), SP_VERB_DIALOG_TRANSFORM,
@@ -690,32 +701,35 @@ Transformation::applyPageSkew(Inkscape::Selection *selection)
double skewY = _scalar_skew_vertical.getValue("px");
NR::Maybe<NR::Rect> bbox(sp_item_bbox_desktop(item));
if (bbox) {
- double width = bbox->dimensions()[NR::X];
- double height = bbox->dimensions()[NR::Y];
+ double width = bbox->extent(NR::X);
+ double height = bbox->extent(NR::Y);
sp_item_skew_rel (item, skewX/height, skewY/width);
}
}
}
} else { // transform whole selection
- NR::Rect bbox = selection->bounds();
- double width = bbox.max()[NR::X] - bbox.min()[NR::X];
- double height = bbox.max()[NR::Y] - bbox.min()[NR::Y];
- NR::Point center = selection->center();
-
- if (!_units_skew.isAbsolute()) { // percentage
- double skewX = _scalar_skew_horizontal.getValue("%");
- double skewY = _scalar_skew_vertical.getValue("%");
- sp_selection_skew_relative(selection, center, 0.01*skewX, 0.01*skewY);
- } else if (_units_skew.isRadial()) { //deg or rad
- double angleX = _scalar_skew_horizontal.getValue("rad");
- double angleY = _scalar_skew_vertical.getValue("rad");
- double skewX = tan(-angleX);
- double skewY = tan(angleY);
- sp_selection_skew_relative(selection, center, skewX, skewY);
- } else { // absolute displacement
- double skewX = _scalar_skew_horizontal.getValue("px");
- double skewY = _scalar_skew_vertical.getValue("px");
- sp_selection_skew_relative(selection, center, skewX/height, skewY/width);
+ NR::Maybe<NR::Rect> bbox = selection->bounds();
+ NR::Maybe<NR::Point> center = selection->center();
+
+ if ( bbox && center ) {
+ double width = bbox->extent(NR::X);
+ double height = bbox->extent(NR::Y);
+
+ if (!_units_skew.isAbsolute()) { // percentage
+ double skewX = _scalar_skew_horizontal.getValue("%");
+ double skewY = _scalar_skew_vertical.getValue("%");
+ sp_selection_skew_relative(selection, *center, 0.01*skewX, 0.01*skewY);
+ } else if (_units_skew.isRadial()) { //deg or rad
+ double angleX = _scalar_skew_horizontal.getValue("rad");
+ double angleY = _scalar_skew_vertical.getValue("rad");
+ double skewX = tan(-angleX);
+ double skewY = tan(angleY);
+ sp_selection_skew_relative(selection, *center, skewX, skewY);
+ } else { // absolute displacement
+ double skewX = _scalar_skew_horizontal.getValue("px");
+ double skewY = _scalar_skew_vertical.getValue("px");
+ sp_selection_skew_relative(selection, *center, skewX/height, skewY/width);
+ }
}
}
@@ -777,19 +791,20 @@ Transformation::onMoveRelativeToggled()
//g_message("onMoveRelativeToggled: %f, %f px\n", x, y);
- NR::Rect bbox = selection->bounds();
+ NR::Maybe<NR::Rect> bbox = selection->bounds();
- if (_check_move_relative.get_active()) {
- // From absolute to relative
- _scalar_move_horizontal.setValue(x - bbox.min()[NR::X], "px");
- _scalar_move_vertical.setValue( y - bbox.min()[NR::Y], "px");
- } else {
- // From relative to absolute
- _scalar_move_horizontal.setValue(bbox.min()[NR::X] + x, "px");
- _scalar_move_vertical.setValue( bbox.min()[NR::Y] + y, "px");
+ if (bbox) {
+ if (_check_move_relative.get_active()) {
+ // From absolute to relative
+ _scalar_move_horizontal.setValue(x - bbox->min()[NR::X], "px");
+ _scalar_move_vertical.setValue( y - bbox->min()[NR::Y], "px");
+ } else {
+ // From relative to absolute
+ _scalar_move_horizontal.setValue(bbox->min()[NR::X] + x, "px");
+ _scalar_move_vertical.setValue( bbox->min()[NR::Y] + y, "px");
+ }
}
-
set_response_sensitive(Gtk::RESPONSE_APPLY, true);
}
@@ -916,9 +931,11 @@ Transformation::onClear()
_scalar_move_horizontal.setValue(0);
_scalar_move_vertical.setValue(0);
} else {
- NR::Rect bbox = selection->bounds();
- _scalar_move_horizontal.setValue(bbox.min()[NR::X], "px");
- _scalar_move_vertical.setValue(bbox.min()[NR::Y], "px");
+ NR::Maybe<NR::Rect> bbox = selection->bounds();
+ if (bbox) {
+ _scalar_move_horizontal.setValue(bbox->min()[NR::X], "px");
+ _scalar_move_vertical.setValue(bbox->min()[NR::Y], "px");
+ }
}
break;
}
diff --git a/src/verbs.cpp b/src/verbs.cpp
index 25c805c3c..cc01706ea 100644
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
@@ -1257,7 +1257,11 @@ ObjectVerb::perform( SPAction *action, void *data, void *pdata )
if (sel->isEmpty())
return;
- NR::Point const center(sel->bounds().midpoint());
+ NR::Maybe<NR::Rect> bbox = sel->bounds();
+ if (!bbox) {
+ return;
+ }
+ NR::Point const center(bbox->midpoint());
switch (reinterpret_cast<std::size_t>(data)) {
case SP_VERB_OBJECT_ROTATE_90_CW:
diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp
index ebdc267c1..fce5ff9b9 100644
--- a/src/widgets/select-toolbar.cpp
+++ b/src/widgets/select-toolbar.cpp
@@ -58,9 +58,8 @@ sp_selection_layout_widget_update(SPWidget *spw, Inkscape::Selection *sel)
using NR::X;
using NR::Y;
if ( sel && !sel->isEmpty() ) {
- NR::Rect const bbox(sel->bounds());
- NR::Point const dimensions(bbox.dimensions());
- if ((dimensions[X] > 1e-6) || (dimensions[Y] > 1e-6)) {
+ NR::Maybe<NR::Rect> const bbox(sel->bounds());
+ if ( bbox && ( bbox->extent(X) > 1e-6 || bbox->extent(Y) > 1e-6 ) ) {
GtkWidget *us = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(spw), "units");
SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(us));
@@ -73,10 +72,10 @@ sp_selection_layout_widget_update(SPWidget *spw, Inkscape::Selection *sel)
}
} else {
struct { char const *key; double val; } const keyval[] = {
- { "X", bbox.min()[X] },
- { "Y", bbox.min()[Y] },
- { "width", dimensions[X] },
- { "height", dimensions[Y] }
+ { "X", bbox->min()[X] },
+ { "Y", bbox->min()[Y] },
+ { "width", bbox->extent(X) },
+ { "height", bbox->extent(Y) }
};
for (unsigned i = 0; i < G_N_ELEMENTS(keyval); ++i) {
GtkAdjustment *a = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), keyval[i].key);
@@ -140,9 +139,9 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw)
SPDocument *document = sp_desktop_document(desktop);
sp_document_ensure_up_to_date (document);
- NR::Rect bbox = selection->bounds();
+ NR::Maybe<NR::Rect> bbox = selection->bounds();
- if (!((bbox.max()[NR::X] - bbox.min()[NR::X] > 1e-6) || (bbox.max()[NR::Y] - bbox.min()[NR::Y] > 1e-6))) {
+ if ( !bbox || bbox->extent(NR::X) < 1e-6 || bbox->extent(NR::Y) < 1e-6 ) {
return;
}
@@ -158,41 +157,41 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw)
y0 = sp_units_get_pixels (a->value, unit);
a_w = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "width");
x1 = x0 + sp_units_get_pixels (a_w->value, unit);
- xrel = sp_units_get_pixels (a_w->value, unit) / bbox.extent(NR::X);
+ xrel = sp_units_get_pixels (a_w->value, unit) / bbox->extent(NR::X);
a_h = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "height");
y1 = y0 + sp_units_get_pixels (a_h->value, unit);
- yrel = sp_units_get_pixels (a_h->value, unit) / bbox.extent(NR::Y);
+ yrel = sp_units_get_pixels (a_h->value, unit) / bbox->extent(NR::Y);
} else {
GtkAdjustment *a;
a = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "X");
double const x0_propn = a->value * unit.unittobase;
- x0 = bbox.min()[NR::X] * x0_propn;
+ x0 = bbox->min()[NR::X] * x0_propn;
a = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "Y");
double const y0_propn = a->value * unit.unittobase;
- y0 = y0_propn * bbox.min()[NR::Y];
+ y0 = y0_propn * bbox->min()[NR::Y];
a_w = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "width");
xrel = a_w->value * unit.unittobase;
- x1 = x0 + xrel * bbox.extent(NR::X);
+ x1 = x0 + xrel * bbox->extent(NR::X);
a_h = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "height");
yrel = a_h->value * unit.unittobase;
- y1 = y0 + yrel * bbox.extent(NR::Y);
+ y1 = y0 + yrel * bbox->extent(NR::Y);
}
// Keep proportions if lock is on
GtkWidget *lock = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(spw), "lock"));
if (SP_BUTTON_IS_DOWN(lock)) {
if (adj == a_h) {
- x1 = x0 + yrel * bbox.extent(NR::X);
+ x1 = x0 + yrel * bbox->extent(NR::X);
} else if (adj == a_w) {
- y1 = y0 + xrel * bbox.extent(NR::Y);
+ y1 = y0 + xrel * bbox->extent(NR::Y);
}
}
// scales and moves, in px
- double mh = fabs(x0 - bbox.min()[NR::X]);
- double sh = fabs(x1 - bbox.max()[NR::X]);
- double mv = fabs(y0 - bbox.min()[NR::Y]);
- double sv = fabs(y1 - bbox.max()[NR::Y]);
+ double mh = fabs(x0 - bbox->min()[NR::X]);
+ double sh = fabs(x1 - bbox->max()[NR::X]);
+ double mv = fabs(y0 - bbox->min()[NR::Y]);
+ double sv = fabs(y1 - bbox->max()[NR::Y]);
// unless the unit is %, convert the scales and moves to the unit
if (unit.base == SP_UNIT_ABSOLUTE || unit.base == SP_UNIT_DEVICE) {
@@ -220,7 +219,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw)
gdouble strokewidth = stroke_average_width (selection->itemList());
int transform_stroke = prefs_get_int_attribute ("options.transform", "stroke", 1);
- NR::Matrix scaler = get_scale_transform_with_stroke (bbox, strokewidth, transform_stroke, x0, y0, x1, y1);
+ NR::Matrix scaler = get_scale_transform_with_stroke (*bbox, strokewidth, transform_stroke, x0, y0, x1, y1);
sp_selection_apply_affine(selection, scaler);
sp_document_maybe_done (document, actionkey, SP_VERB_CONTEXT_SELECT,
@@ -289,6 +288,11 @@ static gboolean aux_set_unit(SPUnitSelector *,
&& (new_units->base == SP_UNIT_DIMENSIONLESS))
{
+ NR::Maybe<NR::Rect> bbox = selection->bounds();
+ if (!bbox) {
+ return FALSE;
+ }
+
/* Absolute to percentage */
g_object_set_data(dlg, "update", GUINT_TO_POINTER(TRUE));
@@ -302,18 +306,21 @@ static gboolean aux_set_unit(SPUnitSelector *,
double const w = sp_units_get_pixels (aw->value, *old);
double const h = sp_units_get_pixels (ah->value, *old);
- NR::Rect bbox = selection->bounds();
-
- gtk_adjustment_set_value(ax, fabs(bbox.min()[NR::X]) > 1e-6? 100.0 * x / bbox.min()[NR::X] : 100.0);
- gtk_adjustment_set_value(ay, fabs(bbox.min()[NR::Y]) > 1e-6? 100.0 * y / bbox.min()[NR::Y] : 100.0);
- gtk_adjustment_set_value(aw, fabs(bbox.extent(NR::X)) > 1e-6? 100.0 * w / bbox.extent(NR::X) : 100.0);
- gtk_adjustment_set_value(ah, fabs(bbox.extent(NR::Y)) > 1e-6? 100.0 * h / bbox.extent(NR::Y) : 100.0);
+ gtk_adjustment_set_value(ax, fabs(bbox->min()[NR::X]) > 1e-6? 100.0 * x / bbox->min()[NR::X] : 100.0);
+ gtk_adjustment_set_value(ay, fabs(bbox->min()[NR::Y]) > 1e-6? 100.0 * y / bbox->min()[NR::Y] : 100.0);
+ gtk_adjustment_set_value(aw, fabs(bbox->extent(NR::X)) > 1e-6? 100.0 * w / bbox->extent(NR::X) : 100.0);
+ gtk_adjustment_set_value(ah, fabs(bbox->extent(NR::Y)) > 1e-6? 100.0 * h / bbox->extent(NR::Y) : 100.0);
g_object_set_data(dlg, "update", GUINT_TO_POINTER(FALSE));
return TRUE;
} else if ((old->base == SP_UNIT_DIMENSIONLESS)
&& (new_units->base == SP_UNIT_ABSOLUTE || new_units->base == SP_UNIT_DEVICE)) {
+ NR::Maybe<NR::Rect> bbox = selection->bounds();
+ if (!bbox) {
+ return FALSE;
+ }
+
/* Percentage to absolute */
g_object_set_data(dlg, "update", GUINT_TO_POINTER(TRUE));
@@ -322,12 +329,10 @@ static gboolean aux_set_unit(SPUnitSelector *,
GtkAdjustment *aw = GTK_ADJUSTMENT(g_object_get_data(dlg, "width"));
GtkAdjustment *ah = GTK_ADJUSTMENT(g_object_get_data(dlg, "height"));
- NR::Rect bbox = selection->bounds();
-
- gtk_adjustment_set_value(ax, sp_pixels_get_units(0.01 * ax->value * bbox.min()[NR::X], *new_units));
- gtk_adjustment_set_value(ay, sp_pixels_get_units(0.01 * ay->value * bbox.min()[NR::Y], *new_units));
- gtk_adjustment_set_value(aw, sp_pixels_get_units(0.01 * aw->value * bbox.extent(NR::X), *new_units));
- gtk_adjustment_set_value(ah, sp_pixels_get_units(0.01 * ah->value * bbox.extent(NR::Y), *new_units));
+ gtk_adjustment_set_value(ax, sp_pixels_get_units(0.01 * ax->value * bbox->min()[NR::X], *new_units));
+ gtk_adjustment_set_value(ay, sp_pixels_get_units(0.01 * ay->value * bbox->min()[NR::Y], *new_units));
+ gtk_adjustment_set_value(aw, sp_pixels_get_units(0.01 * aw->value * bbox->extent(NR::X), *new_units));
+ gtk_adjustment_set_value(ah, sp_pixels_get_units(0.01 * ah->value * bbox->extent(NR::Y), *new_units));
g_object_set_data(dlg, "update", GUINT_TO_POINTER(FALSE));
return TRUE;