X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fui%2Fdialog%2Ftransformation.cpp;h=1cab38d98151d11efa90839cc84a8ebcc2d51217;hb=942364bf59021425927c18ba42767d91a3eb6dfd;hp=9e6cd7f50f3dae59ceedf0cfa4569f95b89d6a1b;hpb=963f23115db07f460bdd862b957f8bd9dba88b9b;p=inkscape.git diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp index 9e6cd7f50..1cab38d98 100644 --- a/src/ui/dialog/transformation.cpp +++ b/src/ui/dialog/transformation.cpp @@ -1,12 +1,11 @@ -/** - * \brief Object Transformation dialog - * - * Authors: +/** @file + * \brief Transform dialog - implementation + */ +/* Authors: * Bryce W. Harrington * buliabyak@gmail.com * * Copyright (C) 2004, 2005 Authors - * * Released under GNU GPL. Read the file 'COPYING' for more information. */ @@ -20,15 +19,17 @@ #include "document.h" #include "desktop-handles.h" #include "transformation.h" +#include "align-and-distribute.h" #include "libnr/nr-matrix-ops.h" #include "inkscape.h" #include "selection.h" #include "selection-chemistry.h" #include "verbs.h" -#include "prefs-utils.h" +#include "preferences.h" #include "sp-item-transform.h" #include "macros.h" #include "sp-item.h" +#include "util/glib-list-iterators.h" namespace Inkscape { namespace UI { @@ -72,26 +73,26 @@ void on_selection_modified( Inkscape::Application */*inkscape*/, * */ Transformation::Transformation() - : UI::Widget::Panel ("", "dialogs.transformation", SP_VERB_DIALOG_TRANSFORM), + : UI::Widget::Panel ("", "/dialogs/transformation", SP_VERB_DIALOG_TRANSFORM), _page_move (4, 2), _page_scale (4, 2), _page_rotate (4, 2), _page_skew (4, 2), _page_transform (3, 3), _scalar_move_horizontal (_("_Horizontal"), _("Horizontal displacement (relative) or position (absolute)"), UNIT_TYPE_LINEAR, - "", "arrows_hor", &_units_move), + "", "transform-move-horizontal", &_units_move), _scalar_move_vertical (_("_Vertical"), _("Vertical displacement (relative) or position (absolute)"), UNIT_TYPE_LINEAR, - "", "arrows_ver", &_units_move), + "", "transform-move-vertical", &_units_move), _scalar_scale_horizontal(_("_Width"), _("Horizontal size (absolute or percentage of current)"), UNIT_TYPE_DIMENSIONLESS, - "", "transform_scale_hor", &_units_scale), + "", "transform-scale-horizontal", &_units_scale), _scalar_scale_vertical (_("_Height"), _("Vertical size (absolute or percentage of current)"), UNIT_TYPE_DIMENSIONLESS, - "", "transform_scale_ver", &_units_scale), + "", "transform-scale-vertical", &_units_scale), _scalar_rotate (_("A_ngle"), _("Rotation angle (positive = counterclockwise)"), UNIT_TYPE_RADIAL, - "", "transform_rotate", &_units_rotate), + "", "transform-rotate", &_units_rotate), _scalar_skew_horizontal (_("_Horizontal"), _("Horizontal skew angle (positive = counterclockwise), or absolute displacement, or percentage displacement"), UNIT_TYPE_LINEAR, - "", "transform_scew_hor", &_units_skew), + "", "transform-skew-horizontal", &_units_skew), _scalar_skew_vertical (_("_Vertical"), _("Vertical skew angle (positive = counterclockwise), or absolute displacement, or percentage displacement"), UNIT_TYPE_LINEAR, - "", "transform_scew_ver", &_units_skew), + "", "transform-skew-vertical", &_units_skew), _scalar_transform_a ("_A", _("Transformation matrix element A")), _scalar_transform_b ("_B", _("Transformation matrix element B")), @@ -132,7 +133,8 @@ Transformation::Transformation() // Apply separately contents->pack_start(_check_apply_separately, true, true); - _check_apply_separately.set_active(prefs_get_int_attribute_limited ("dialogs.transformation", "applyseparately", 0, 0, 1)); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + _check_apply_separately.set_active(prefs->getBool("/dialogs/transformation/applyseparately")); _check_apply_separately.signal_toggled().connect(sigc::mem_fun(*this, &Transformation::onApplySeparatelyToggled)); // make sure all spinbuttons activate Apply on pressing Enter @@ -446,18 +448,19 @@ void Transformation::onSwitchPage(GtkNotebookPage */*page*/, guint pagenum) { - updateSelection((PageType)pagenum, sp_desktop_selection(SP_ACTIVE_DESKTOP)); + updateSelection((PageType)pagenum, sp_desktop_selection(getDesktop())); } + void Transformation::updatePageMove(Inkscape::Selection *selection) { if (selection && !selection->isEmpty()) { if (!_check_move_relative.get_active()) { - NR::Maybe bbox = selection->bounds(); + Geom::OptRect bbox = selection->bounds(); if (bbox) { - double x = bbox->min()[NR::X]; - double y = bbox->min()[NR::Y]; + double x = bbox->min()[Geom::X]; + double y = bbox->min()[Geom::Y]; _scalar_move_horizontal.setValue(x, "px"); _scalar_move_vertical.setValue(y, "px"); @@ -475,10 +478,10 @@ void Transformation::updatePageScale(Inkscape::Selection *selection) { if (selection && !selection->isEmpty()) { - NR::Maybe bbox = selection->bounds(); + Geom::OptRect bbox = selection->bounds(); if (bbox) { - double w = bbox->extent(NR::X); - double h = bbox->extent(NR::Y); + double w = bbox->dimensions()[Geom::X]; + double h = bbox->dimensions()[Geom::Y]; _scalar_scale_horizontal.setHundredPercent(w); _scalar_scale_vertical.setHundredPercent(h); onScaleXValueChanged(); // to update x/y proportionality if switch is on @@ -505,7 +508,16 @@ void Transformation::updatePageSkew(Inkscape::Selection *selection) { if (selection && !selection->isEmpty()) { - _page_skew.set_sensitive(true); + Geom::OptRect bbox = selection->bounds(); + if (bbox) { + double w = bbox->dimensions()[Geom::X]; + double h = bbox->dimensions()[Geom::Y]; + _scalar_skew_vertical.setHundredPercent(w); + _scalar_skew_horizontal.setHundredPercent(h); + _page_skew.set_sensitive(true); + } else { + _page_skew.set_sensitive(false); + } } else { _page_skew.set_sensitive(false); } @@ -516,9 +528,9 @@ Transformation::updatePageTransform(Inkscape::Selection *selection) { if (selection && !selection->isEmpty()) { if (_check_replace_matrix.get_active()) { - NR::Matrix current (SP_ITEM(selection->itemList()->data)->transform); // take from the first item in selection + Geom::Matrix current (SP_ITEM(selection->itemList()->data)->transform); // take from the first item in selection - NR::Matrix new_displayed = current; + Geom::Matrix new_displayed = current; _scalar_transform_a.setValue(new_displayed[0]); _scalar_transform_b.setValue(new_displayed[1]); @@ -587,13 +599,81 @@ Transformation::applyPageMove(Inkscape::Selection *selection) double x = _scalar_move_horizontal.getValue("px"); double y = _scalar_move_vertical.getValue("px"); - if (_check_move_relative.get_active()) { - sp_selection_move_relative(selection, x, y); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (!prefs->getBool("/dialogs/transformation/applyseparately")) { + // move selection as a whole + if (_check_move_relative.get_active()) { + sp_selection_move_relative(selection, x, y); + } else { + Geom::OptRect bbox = selection->bounds(); + if (bbox) { + sp_selection_move_relative(selection, + x - bbox->min()[Geom::X], y - bbox->min()[Geom::Y]); + } + } } else { - NR::Maybe bbox = selection->bounds(); - if (bbox) { - sp_selection_move_relative(selection, - x - bbox->min()[NR::X], y - bbox->min()[NR::Y]); + + if (_check_move_relative.get_active()) { + // shift each object relatively to the previous one + using Inkscape::Util::GSListConstIterator; + std::list selected; + selected.insert >(selected.end(), selection->itemList(), NULL); + if (selected.empty()) return; + + if (fabs(x) > 1e-6) { + std::vector< BBoxSort > sorted; + for (std::list::iterator it(selected.begin()); + it != selected.end(); + ++it) + { + Geom::OptRect bbox = sp_item_bbox_desktop(*it); + if (bbox) { + sorted.push_back(BBoxSort(*it, *bbox, Geom::X, x > 0? 1. : 0., x > 0? 0. : 1.)); + } + } + //sort bbox by anchors + std::sort(sorted.begin(), sorted.end()); + + double move = x; + for ( std::vector ::iterator it (sorted.begin()); + it < sorted.end(); + it ++ ) + { + sp_item_move_rel(it->item, Geom::Translate(move, 0)); + // move each next object by x relative to previous + move += x; + } + } + if (fabs(y) > 1e-6) { + std::vector< BBoxSort > sorted; + for (std::list::iterator it(selected.begin()); + it != selected.end(); + ++it) + { + Geom::OptRect bbox = sp_item_bbox_desktop(*it); + if (bbox) { + sorted.push_back(BBoxSort(*it, *bbox, Geom::Y, y > 0? 1. : 0., y > 0? 0. : 1.)); + } + } + //sort bbox by anchors + std::sort(sorted.begin(), sorted.end()); + + double move = y; + for ( std::vector ::iterator it (sorted.begin()); + it < sorted.end(); + it ++ ) + { + sp_item_move_rel(it->item, Geom::Translate(0, move)); + // move each next object by x relative to previous + move += y; + } + } + } else { + Geom::OptRect bbox = selection->bounds(); + if (bbox) { + sp_selection_move_relative(selection, + x - bbox->min()[Geom::X], y - bbox->min()[Geom::Y]); + } } } @@ -607,47 +687,48 @@ Transformation::applyPageScale(Inkscape::Selection *selection) double scaleX = _scalar_scale_horizontal.getValue("px"); double scaleY = _scalar_scale_vertical.getValue("px"); - if (prefs_get_int_attribute_limited ("dialogs.transformation", "applyseparately", 0, 0, 1) == 1) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (prefs->getBool("/dialogs/transformation/applyseparately")) { for (GSList const *l = selection->itemList(); l != NULL; l = l->next) { SPItem *item = SP_ITEM(l->data); - NR::scale scale (0,0); + Geom::Scale scale (0,0); // the values are increments! if (_units_scale.isAbsolute()) { - NR::Maybe bbox(sp_item_bbox_desktop(item)); + Geom::OptRect bbox(sp_item_bbox_desktop(item)); if (bbox) { double new_width = scaleX; if (fabs(new_width) < 1e-6) new_width = 1e-6; // not 0, as this would result in a nasty no-bbox object double new_height = scaleY; if (fabs(new_height) < 1e-6) new_height = 1e-6; - scale = NR::scale(new_width / bbox->extent(NR::X), new_height / bbox->extent(NR::Y)); + scale = Geom::Scale(new_width / bbox->dimensions()[Geom::X], new_height / bbox->dimensions()[Geom::Y]); } } else { double new_width = scaleX; if (fabs(new_width) < 1e-6) new_width = 1e-6; double new_height = scaleY; if (fabs(new_height) < 1e-6) new_height = 1e-6; - scale = NR::scale(new_width / 100.0, new_height / 100.0); + scale = Geom::Scale(new_width / 100.0, new_height / 100.0); } sp_item_scale_rel (item, scale); } } else { - NR::Maybe bbox(selection->bounds()); + Geom::OptRect bbox(selection->bounds()); if (bbox) { - NR::Point center(bbox->midpoint()); // use rotation center? - NR::scale scale (0,0); + Geom::Point center(bbox->midpoint()); // use rotation center? + Geom::Scale scale (0,0); // the values are increments! if (_units_scale.isAbsolute()) { double new_width = scaleX; if (fabs(new_width) < 1e-6) new_width = 1e-6; double new_height = scaleY; if (fabs(new_height) < 1e-6) new_height = 1e-6; - scale = NR::scale(new_width / bbox->extent(NR::X), new_height / bbox->extent(NR::Y)); + scale = Geom::Scale(new_width / bbox->dimensions()[Geom::X], new_height / bbox->dimensions()[Geom::Y]); } else { double new_width = scaleX; if (fabs(new_width) < 1e-6) new_width = 1e-6; double new_height = scaleY; if (fabs(new_height) < 1e-6) new_height = 1e-6; - scale = NR::scale(new_width / 100.0, new_height / 100.0); + scale = Geom::Scale(new_width / 100.0, new_height / 100.0); } sp_selection_scale_relative(selection, center, scale); } @@ -662,13 +743,14 @@ Transformation::applyPageRotate(Inkscape::Selection *selection) { double angle = _scalar_rotate.getValue("deg"); - if (prefs_get_int_attribute_limited ("dialogs.transformation", "applyseparately", 0, 0, 1) == 1) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (prefs->getBool("/dialogs/transformation/applyseparately")) { for (GSList const *l = selection->itemList(); l != NULL; l = l->next) { SPItem *item = SP_ITEM(l->data); - sp_item_rotate_rel(item, NR::rotate (angle*M_PI/180.0)); + sp_item_rotate_rel(item, Geom::Rotate (angle*M_PI/180.0)); } } else { - NR::Maybe center = selection->center(); + boost::optional center = selection->center(); if (center) { sp_selection_rotate_relative(selection, *center, angle); } @@ -681,7 +763,8 @@ Transformation::applyPageRotate(Inkscape::Selection *selection) void Transformation::applyPageSkew(Inkscape::Selection *selection) { - if (prefs_get_int_attribute_limited ("dialogs.transformation", "applyseparately", 0, 0, 1) == 1) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (prefs->getBool("/dialogs/transformation/applyseparately")) { for (GSList const *l = selection->itemList(); l != NULL; l = l->next) { SPItem *item = SP_ITEM(l->data); @@ -698,21 +781,21 @@ Transformation::applyPageSkew(Inkscape::Selection *selection) } else { // absolute displacement double skewX = _scalar_skew_horizontal.getValue("px"); double skewY = _scalar_skew_vertical.getValue("px"); - NR::Maybe bbox(sp_item_bbox_desktop(item)); + Geom::OptRect bbox(sp_item_bbox_desktop(item)); if (bbox) { - double width = bbox->extent(NR::X); - double height = bbox->extent(NR::Y); + double width = bbox->dimensions()[Geom::X]; + double height = bbox->dimensions()[Geom::Y]; sp_item_skew_rel (item, skewX/height, skewY/width); } } } } else { // transform whole selection - NR::Maybe bbox = selection->bounds(); - NR::Maybe center = selection->center(); + Geom::OptRect bbox = selection->bounds(); + boost::optional center = selection->center(); if ( bbox && center ) { - double width = bbox->extent(NR::X); - double height = bbox->extent(NR::Y); + double width = bbox->dimensions()[Geom::X]; + double height = bbox->dimensions()[Geom::Y]; if (!_units_skew.isAbsolute()) { // percentage double skewX = _scalar_skew_horizontal.getValue("%"); @@ -747,7 +830,7 @@ Transformation::applyPageTransform(Inkscape::Selection *selection) double e = _scalar_transform_e.getValue(); double f = _scalar_transform_f.getValue(); - NR::Matrix displayed(a, b, c, d, e, f); + Geom::Matrix displayed(a, b, c, d, e, f); if (_check_replace_matrix.get_active()) { for (GSList const *l = selection->itemList(); l != NULL; l = l->next) { @@ -790,17 +873,17 @@ Transformation::onMoveRelativeToggled() //g_message("onMoveRelativeToggled: %f, %f px\n", x, y); - NR::Maybe bbox = selection->bounds(); + Geom::OptRect bbox = selection->bounds(); 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"); + _scalar_move_horizontal.setValue(x - bbox->min()[Geom::X], "px"); + _scalar_move_vertical.setValue( y - bbox->min()[Geom::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"); + _scalar_move_horizontal.setValue(bbox->min()[Geom::X] + x, "px"); + _scalar_move_vertical.setValue( bbox->min()[Geom::Y] + y, "px"); } } @@ -893,10 +976,10 @@ Transformation::onReplaceMatrixToggled() double e = _scalar_transform_e.getValue(); double f = _scalar_transform_f.getValue(); - NR::Matrix displayed (a, b, c, d, e, f); - NR::Matrix current (SP_ITEM(selection->itemList()->data)->transform); // take from the first item in selection + Geom::Matrix displayed (a, b, c, d, e, f); + Geom::Matrix current = SP_ITEM(selection->itemList()->data)->transform; // take from the first item in selection - NR::Matrix new_displayed; + Geom::Matrix new_displayed; if (_check_replace_matrix.get_active()) { new_displayed = current; } else { @@ -930,10 +1013,10 @@ Transformation::onClear() _scalar_move_horizontal.setValue(0); _scalar_move_vertical.setValue(0); } else { - NR::Maybe bbox = selection->bounds(); + Geom::OptRect bbox = selection->bounds(); if (bbox) { - _scalar_move_horizontal.setValue(bbox->min()[NR::X], "px"); - _scalar_move_vertical.setValue(bbox->min()[NR::Y], "px"); + _scalar_move_horizontal.setValue(bbox->min()[Geom::X], "px"); + _scalar_move_vertical.setValue(bbox->min()[Geom::Y], "px"); } } break; @@ -943,8 +1026,8 @@ Transformation::onClear() break; } case PAGE_SCALE: { - _scalar_scale_horizontal.setValue(100); - _scalar_scale_vertical.setValue(100); + _scalar_scale_horizontal.setValue(100, "%"); + _scalar_scale_vertical.setValue(100, "%"); break; } case PAGE_SKEW: { @@ -967,7 +1050,8 @@ Transformation::onClear() void Transformation::onApplySeparatelyToggled() { - prefs_set_int_attribute ("dialogs.transformation", "applyseparately", _check_apply_separately.get_active()? 1 : 0); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/dialogs/transformation/applyseparately", _check_apply_separately.get_active()); } @@ -975,8 +1059,6 @@ Transformation::onApplySeparatelyToggled() } // namespace UI } // namespace Inkscape - - /* Local Variables: mode:c++