X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fui%2Fdialog%2Falign-and-distribute.cpp;h=3203816d36f96850cdd956bade4456b46d03c163;hb=c647aff4da60b280974a1d5eceda738b5a0ab389;hp=e83907f492cb5b2e8ccb91ab132ba2382cb7b380;hpb=8b9a820756fdf348239872236be2257f854e094a;p=inkscape.git diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index e83907f49..3203816d3 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -1,7 +1,7 @@ -/** - * \brief Align and Distribute dialog - * - * Authors: +/** @file + * @brief Align and Distribute dialog - implementation + */ +/* Authors: * Bryce W. Harrington * Aubanel MONNIER * Frank Felfe @@ -39,7 +39,7 @@ #include "desktop-handles.h" #include "macros.h" #include "sp-item-transform.h" -#include "prefs-utils.h" +#include "preferences.h" #include "enums.h" #include "sp-text.h" @@ -122,6 +122,9 @@ private : Inkscape::Selection *selection = sp_desktop_selection(desktop); if (!selection) return; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool sel_as_group = prefs->getBool("/dialogs/align/sel-as-groups"); + using Inkscape::Util::GSListConstIterator; std::list selected; selected.insert >(selected.end(), selection->itemList(), NULL); @@ -151,9 +154,14 @@ private : ); //remove the master from the selection SPItem * thing = *master; - selected.erase(master); + // TODO: either uncomment or remove the following commented lines, depending on which + // behaviour of moving objects makes most sense; also cf. discussion at + // https://bugs.launchpad.net/inkscape/+bug/255933 + /*if (!sel_as_group) { */ + selected.erase(master); + /*}*/ //Compute the anchor point - boost::optional b = sp_item_bbox_desktop (thing); + Geom::OptRect b = sp_item_bbox_desktop (thing); if (b) { mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X], a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]); @@ -170,7 +178,7 @@ private : case AlignAndDistribute::DRAWING: { - boost::optional b = sp_item_bbox_desktop + Geom::OptRect b = sp_item_bbox_desktop ( (SPItem *) sp_document_root (sp_desktop_document (desktop)) ); if (b) { mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X], @@ -183,7 +191,7 @@ private : case AlignAndDistribute::SELECTION: { - boost::optional b = selection->bounds(); + Geom::OptRect b = selection->bounds(); if (b) { mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X], a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]); @@ -204,30 +212,35 @@ private : // a selected original, they will be unmoved too, possibly contrary to user's // expecation. However this is a minor point compared to making align/distribute always // work as expected, and "unmoved" is the default option anyway. - int saved_compensation = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); - prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); + int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); + prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); bool changed = false; - //Move each item in the selected list + Geom::OptRect b; + if (sel_as_group) + b = selection->bounds(); + + //Move each item in the selected list separately for (std::list::iterator it(selected.begin()); it != selected.end(); it++) { sp_document_ensure_up_to_date(sp_desktop_document (desktop)); - boost::optional b = sp_item_bbox_desktop (*it); + if (!sel_as_group) + b = sp_item_bbox_desktop (*it); if (b) { Geom::Point const sp(a.sx0 * b->min()[Geom::X] + a.sx1 * b->max()[Geom::X], - a.sy0 * b->min()[Geom::Y] + a.sy1 * b->max()[Geom::Y]); + a.sy0 * b->min()[Geom::Y] + a.sy1 * b->max()[Geom::Y]); Geom::Point const mp_rel( mp - sp ); if (LInfty(mp_rel) > 1e-9) { - sp_item_move_rel(*it, NR::translate(mp_rel)); + sp_item_move_rel(*it, Geom::Translate(mp_rel)); changed = true; } } } // restore compensation setting - prefs_set_int_attribute("options.clonecompensation", "value", saved_compensation); + prefs->setInt("/options/clonecompensation/value", saved_compensation); if (changed) { sp_document_done ( sp_desktop_document (desktop) , SP_VERB_DIALOG_ALIGN_DISTRIBUTE, @@ -318,17 +331,18 @@ private : it != selected.end(); ++it) { - boost::optional bbox = sp_item_bbox_desktop(*it); + Geom::OptRect bbox = sp_item_bbox_desktop(*it); if (bbox) { - sorted.push_back(BBoxSort(*it, to_2geom(*bbox), _orientation, _kBegin, _kEnd)); + sorted.push_back(BBoxSort(*it, *bbox, _orientation, _kBegin, _kEnd)); } } //sort bbox by anchors std::sort(sorted.begin(), sorted.end()); // see comment in ActionAlign above - int saved_compensation = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); - prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); + prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); unsigned int len = sorted.size(); bool changed = false; @@ -353,7 +367,7 @@ private : if (!NR_DF_TEST_CLOSE (pos, it->bbox.min()[_orientation], 1e-6)) { Geom::Point t(0.0, 0.0); t[_orientation] = pos - it->bbox.min()[_orientation]; - sp_item_move_rel(it->item, NR::translate(t)); + sp_item_move_rel(it->item, Geom::Translate(t)); changed = true; } pos += it->bbox[_orientation].extent(); @@ -378,14 +392,14 @@ private : Geom::Point t(0.0, 0.0); t[_orientation] = pos - it.anchor; //translate - sp_item_move_rel(it.item, NR::translate(t)); + sp_item_move_rel(it.item, Geom::Translate(t)); changed = true; } } } // restore compensation setting - prefs_set_int_attribute("options.clonecompensation", "value", saved_compensation); + prefs->setInt("/options/clonecompensation/value", saved_compensation); if (changed) { sp_document_done ( sp_desktop_document (desktop), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, @@ -427,9 +441,9 @@ private : if (!SP_IS_NODE_CONTEXT (event_context)) return ; if (_distribute) - SP_NODE_CONTEXT (event_context)->shape_editor->distribute((NR::Dim2)_orientation); + event_context->shape_editor->distribute((Geom::Dim2)_orientation); else - SP_NODE_CONTEXT (event_context)->shape_editor->align((NR::Dim2)_orientation); + event_context->shape_editor->align((Geom::Dim2)_orientation); } }; @@ -485,8 +499,9 @@ private : if (!_dialog.getDesktop()) return; // see comment in ActionAlign above - int saved_compensation = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); - prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); + prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); // xGap and yGap are the minimum space required between bounding rectangles. double const xGap = removeOverlapXGap.get_value(); @@ -495,7 +510,7 @@ private : xGap, yGap); // restore compensation setting - prefs_set_int_attribute("options.clonecompensation", "value", saved_compensation); + prefs->setInt("/options/clonecompensation/value", saved_compensation); sp_document_done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Remove overlaps")); @@ -519,13 +534,14 @@ private : if (!_dialog.getDesktop()) return; // see comment in ActionAlign above - int saved_compensation = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); - prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); + prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); graphlayout(sp_desktop_selection(_dialog.getDesktop())->itemList()); // restore compensation setting - prefs_set_int_attribute("options.clonecompensation", "value", saved_compensation); + prefs->setInt("/options/clonecompensation/value", saved_compensation); sp_document_done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Arrange connector network")); @@ -549,13 +565,14 @@ private : if (!_dialog.getDesktop()) return; // see comment in ActionAlign above - int saved_compensation = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); - prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); + prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); unclump ((GSList *) sp_desktop_selection(_dialog.getDesktop())->itemList()); // restore compensation setting - prefs_set_int_attribute("options.clonecompensation", "value", saved_compensation); + prefs->setInt("/options/clonecompensation/value", saved_compensation); sp_document_done (sp_desktop_document (_dialog.getDesktop()), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Unclump")); @@ -590,7 +607,7 @@ private : //Check 2 or more selected objects if (selected.size() < 2) return; - boost::optional sel_bbox = selection->bounds(); + Geom::OptRect sel_bbox = selection->bounds(); if (!sel_bbox) { return; } @@ -599,33 +616,34 @@ private : // nor drift on sequential randomizations. Discard cache on global (or better active // desktop's) selection_change signal. if (!_dialog.randomize_bbox) { - _dialog.randomize_bbox = to_2geom(*sel_bbox); + _dialog.randomize_bbox = *sel_bbox; } // see comment in ActionAlign above - int saved_compensation = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); - prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); + prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); for (std::list::iterator it(selected.begin()); it != selected.end(); ++it) { sp_document_ensure_up_to_date(sp_desktop_document (desktop)); - boost::optional item_box = sp_item_bbox_desktop (*it); + Geom::OptRect item_box = sp_item_bbox_desktop (*it); if (item_box) { // find new center, staying within bbox - double x = _dialog.randomize_bbox->min()[Geom::X] + (*item_box).extent(Geom::X)/2 + - g_random_double_range (0, (*_dialog.randomize_bbox)[Geom::X].extent() - (*item_box).extent(Geom::X)); - double y = _dialog.randomize_bbox->min()[Geom::Y] + (*item_box).extent(Geom::Y)/2 + - g_random_double_range (0, (*_dialog.randomize_bbox)[Geom::Y].extent() - (*item_box).extent(Geom::Y)); + double x = _dialog.randomize_bbox->min()[Geom::X] + (*item_box)[Geom::X].extent() /2 + + g_random_double_range (0, (*_dialog.randomize_bbox)[Geom::X].extent() - (*item_box)[Geom::X].extent()); + double y = _dialog.randomize_bbox->min()[Geom::Y] + (*item_box)[Geom::Y].extent()/2 + + g_random_double_range (0, (*_dialog.randomize_bbox)[Geom::Y].extent() - (*item_box)[Geom::Y].extent()); // displacement is the new center minus old: - NR::Point t = NR::Point (x, y) - 0.5*(item_box->max() + item_box->min()); - sp_item_move_rel(*it, NR::translate(t)); + Geom::Point t = Geom::Point (x, y) - 0.5*(item_box->max() + item_box->min()); + sp_item_move_rel(*it, Geom::Translate(t)); } } // restore compensation setting - prefs_set_int_attribute("options.clonecompensation", "value", saved_compensation); + prefs->setInt("/options/clonecompensation/value", saved_compensation); sp_document_done (sp_desktop_document (desktop), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Randomize positions")); @@ -694,7 +712,7 @@ private : { if (SP_IS_TEXT (*it) || SP_IS_FLOWTEXT (*it)) { Inkscape::Text::Layout const *layout = te_get_layout(*it); - Geom::Point base = layout->characterAnchorPoint(layout->begin()) * from_2geom(sp_item_i2d_affine(*it)); + Geom::Point base = layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(*it); if (base[Geom::X] < b_min[Geom::X]) b_min[Geom::X] = base[Geom::X]; if (base[Geom::Y] < b_min[Geom::Y]) b_min[Geom::Y] = base[Geom::Y]; if (base[Geom::X] > b_max[Geom::X]) b_max[Geom::X] = base[Geom::X]; @@ -719,7 +737,7 @@ private : Geom::Point base = sorted[i]._base; Geom::Point t(0.0, 0.0); t[_orientation] = b_min[_orientation] + step * i - base[_orientation]; - sp_item_move_rel(item, NR::translate(t)); + sp_item_move_rel(item, Geom::Translate(t)); changed = true; } @@ -735,10 +753,10 @@ private : { if (SP_IS_TEXT (*it) || SP_IS_FLOWTEXT (*it)) { Inkscape::Text::Layout const *layout = te_get_layout(*it); - Geom::Point base = layout->characterAnchorPoint(layout->begin()) * from_2geom(sp_item_i2d_affine(*it)); + Geom::Point base = layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(*it); Geom::Point t(0.0, 0.0); t[_orientation] = b_min[_orientation] - base[_orientation]; - sp_item_move_rel(*it, NR::translate(t)); + sp_item_move_rel(*it, Geom::Translate(t)); changed = true; } } @@ -762,7 +780,7 @@ void on_tool_changed(Inkscape::Application */*inkscape*/, SPEventContext */*cont void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, AlignAndDistribute *daad) { - daad->randomize_bbox = boost::optional(); + daad->randomize_bbox = Geom::OptRect(); } ///////////////////////////////////////////////////////// @@ -771,7 +789,7 @@ void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selecti AlignAndDistribute::AlignAndDistribute() - : UI::Widget::Panel ("", "dialogs.align", SP_VERB_DIALOG_ALIGN_DISTRIBUTE), + : UI::Widget::Panel ("", "/dialogs/align", SP_VERB_DIALOG_ALIGN_DISTRIBUTE), randomize_bbox(), _alignFrame(_("Align")), _distributeFrame(_("Distribute")), @@ -783,8 +801,10 @@ AlignAndDistribute::AlignAndDistribute() _removeOverlapTable(1, 5, false), _graphLayoutTable(1, 5, false), _nodesTable(1, 4, true), - _anchorLabel(_("Relative to: ")) + _anchorLabel(_("Relative to: ")), + _selgrpLabel(_("Treat selection as group: ")) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); //Instanciate the align buttons addAlignButton("al_left_out", @@ -904,13 +924,19 @@ AlignAndDistribute::AlignAndDistribute() _combo.append_text(_("Drawing")); _combo.append_text(_("Selection")); - _combo.set_active(prefs_get_int_attribute("dialogs.align", "align-to", 6)); + _combo.set_active(prefs->getInt("/dialogs/align/align-to", 6)); _combo.signal_changed().connect(sigc::mem_fun(*this, &AlignAndDistribute::on_ref_change)); _anchorBox.pack_start(_anchorLabel); _anchorBox.pack_start(_combo); + _selgrpBox.pack_start(_selgrpLabel); + _selgrpBox.pack_start(_selgrp); + _selgrp.set_active(prefs->getBool("/dialogs/align/sel-as-groups")); + _selgrp.signal_toggled().connect(sigc::mem_fun(*this, &AlignAndDistribute::on_selgrp_toggled)); + _alignBox.pack_start(_anchorBox); + _alignBox.pack_start(_selgrpBox); _alignBox.pack_start(_alignTable); _alignFrame.add(_alignBox); @@ -935,7 +961,7 @@ AlignAndDistribute::AlignAndDistribute() // Connect to the global selection change, to invalidate cached randomize_bbox g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (on_selection_changed), this); - randomize_bbox = boost::optional(); + randomize_bbox = Geom::OptRect(); show_all_children(); @@ -953,8 +979,15 @@ AlignAndDistribute::~AlignAndDistribute() } void AlignAndDistribute::on_ref_change(){ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/dialogs/align/align-to", _combo.get_active_row_number()); + + //Make blink the master +} - prefs_set_int_attribute("dialogs.align", "align-to", _combo.get_active_row_number()); +void AlignAndDistribute::on_selgrp_toggled(){ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/dialogs/align/sel-as-groups", _selgrp.get_active()); //Make blink the master } @@ -1073,9 +1106,9 @@ std::list::iterator AlignAndDistribute::find_master( std::list::iterator it = list.begin(); it != list.end(); it++) { - boost::optional b = sp_item_bbox_desktop (*it); + Geom::OptRect b = sp_item_bbox_desktop (*it); if (b) { - gdouble dim = (*b).extent(horizontal ? Geom::X : Geom::Y); + gdouble dim = (*b)[horizontal ? Geom::X : Geom::Y].extent(); if (dim > max) { max = dim; master = it; @@ -1090,9 +1123,9 @@ std::list::iterator AlignAndDistribute::find_master( std::list::iterator it = list.begin(); it != list.end(); it++) { - boost::optional b = sp_item_bbox_desktop (*it); + Geom::OptRect b = sp_item_bbox_desktop (*it); if (b) { - gdouble dim = (*b).extent(horizontal ? Geom::X : Geom::Y); + gdouble dim = (*b)[horizontal ? Geom::X : Geom::Y].extent(); if (dim < max) { max = dim; master = it;