summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
authorMarc Jeanmougin <marc@jeanmougin.fr>2016-03-13 23:50:24 +0000
committerMarc Jeanmougin <marcjeanmougin@free.fr>2016-03-13 23:50:24 +0000
commitd7b1e066fa7c7d9e6a83d688fe48c5f06620bf10 (patch)
tree3a0c0d0d59acbfdf97735223c482df2b968a1026 /src/ui
parentTranslations. Danish translation update. (diff)
downloadinkscape-d7b1e066fa7c7d9e6a83d688fe48c5f06620bf10.tar.gz
inkscape-d7b1e066fa7c7d9e6a83d688fe48c5f06620bf10.zip
"Relative to" option for node alignment.
- Node tool has those new "relative to" alignment options : last selected, first selected, current behaviour (middle), max value(rightmost/topmost) or min value(leftmost/bottommost). - Verbs: --If the node tool is active and whole objects are selected (no individual node is), works as usual for objects; --Else, align horizontal/vertical (SP_VERB_ALIGN_HORIZONTAL_CENTER) honor the "relative to" settings, SP_VERB_ALIGN_HORIZONTAL_LEFT (ctrl+alt+pavnum4) aligns vertically on the leftmost node (same behavior as SP_VERB_ALIGN_HORIZONTAL_LEFT when the setting is "align relative to min value"), and so on with all alignment verbs Fixed bugs: - https://launchpad.net/bugs/171287 (bzr r14703)
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/dialog/align-and-distribute.cpp76
-rw-r--r--src/ui/dialog/align-and-distribute.h11
-rw-r--r--src/ui/tool/control-point-selection.cpp29
-rw-r--r--src/ui/tool/control-point-selection.h3
4 files changed, 116 insertions, 3 deletions
diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp
index 5a16ecce8..8f87932b8 100644
--- a/src/ui/dialog/align-and-distribute.cpp
+++ b/src/ui/dialog/align-and-distribute.cpp
@@ -42,6 +42,7 @@
#include "ui/icon-names.h"
#include "ui/tools/node-tool.h"
#include "ui/tool/multi-path-manipulator.h"
+#include "ui/tool/control-point-selection.h"
#include "verbs.h"
#include "widgets/icon.h"
#include "sp-root.h"
@@ -88,6 +89,42 @@ Action::Action(const Glib::ustring &id,
}
+void ActionAlign::do_node_action(Inkscape::UI::Tools::NodeTool *nt, int verb)
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ int prev_pref = prefs->getInt("/dialogs/align/align-nodes-to");
+ switch(verb){
+ case SP_VERB_ALIGN_HORIZONTAL_LEFT:
+ prefs->setInt("/dialogs/align/align-nodes-to", MIN_NODE );
+ nt->_multipath->alignNodes(Geom::Y);
+ break;
+ case SP_VERB_ALIGN_HORIZONTAL_CENTER:
+ nt->_multipath->alignNodes(Geom::Y);
+ break;
+ case SP_VERB_ALIGN_HORIZONTAL_RIGHT:
+ prefs->setInt("/dialogs/align/align-nodes-to", MAX_NODE );
+ nt->_multipath->alignNodes(Geom::Y);
+ break;
+ case SP_VERB_ALIGN_VERTICAL_TOP:
+ prefs->setInt("/dialogs/align/align-nodes-to", MAX_NODE );
+ nt->_multipath->alignNodes(Geom::X);
+ break;
+ case SP_VERB_ALIGN_VERTICAL_CENTER:
+ nt->_multipath->alignNodes(Geom::X);
+ break;
+ case SP_VERB_ALIGN_VERTICAL_BOTTOM:
+ prefs->setInt("/dialogs/align/align-nodes-to", MIN_NODE );
+ nt->_multipath->alignNodes(Geom::X);
+ break;
+ case SP_VERB_ALIGN_VERTICAL_HORIZONTAL_CENTER:
+ nt->_multipath->alignNodes(Geom::X);
+ nt->_multipath->alignNodes(Geom::Y);
+ break;
+ default:return;
+ }
+ prefs->setInt("/dialogs/align/align-nodes-to", prev_pref );
+}
+
void ActionAlign::do_action(SPDesktop *desktop, int index)
{
Inkscape::Selection *selection = desktop->getSelection();
@@ -187,6 +224,14 @@ ActionAlign::Coeffs const ActionAlign::_allCoeffs[11] = {
void ActionAlign::do_verb_action(SPDesktop *desktop, int verb)
{
+ Inkscape::UI::Tools::ToolBase *event_context = desktop->getEventContext();
+ if (INK_IS_NODE_TOOL(event_context)) {
+ Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(event_context);
+ if(!nt->_selected_nodes->empty()){
+ do_node_action(nt, verb);
+ return;
+ }
+ }
do_action(desktop, verb_to_coeff(verb));
}
@@ -871,6 +916,9 @@ static void on_tool_changed(AlignAndDistribute *daad)
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
if (desktop && desktop->getEventContext())
daad->setMode(tools_active(desktop) == TOOLS_NODES);
+ else
+ daad->setMode(false);
+
}
static void on_selection_changed(AlignAndDistribute *daad)
@@ -905,6 +953,7 @@ AlignAndDistribute::AlignAndDistribute()
_nodesTable(1, 4, true),
#endif
_anchorLabel(_("Relative to: ")),
+ _anchorLabelNode(_("Relative to: ")),
_selgrpLabel(_("_Treat selection as group: "), 1)
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -1043,9 +1092,20 @@ AlignAndDistribute::AlignAndDistribute()
_combo.set_active(prefs->getInt("/dialogs/align/align-to", 6));
_combo.signal_changed().connect(sigc::mem_fun(*this, &AlignAndDistribute::on_ref_change));
+ _comboNode.append(_("Last selected"));
+ _comboNode.append(_("First selected"));
+ _comboNode.append(_("Middle of selection"));
+ _comboNode.append(_("Min value"));
+ _comboNode.append(_("Max value"));
+ _comboNode.set_active(prefs->getInt("/dialogs/align/align-nodes-to", 2));
+ _comboNode.signal_changed().connect(sigc::mem_fun(*this, &AlignAndDistribute::on_node_ref_change));
+
_anchorBox.pack_end(_combo, false, false);
_anchorBox.pack_end(_anchorLabel, false, false);
+ _anchorBoxNode.pack_end(_comboNode, false, false);
+ _anchorBoxNode.pack_end(_anchorLabelNode, false, false);
+
_selgrpLabel.set_mnemonic_widget(_selgrp);
_selgrpBox.pack_end(_selgrp, false, false);
_selgrpBox.pack_end(_selgrpLabel, false, false);
@@ -1063,11 +1123,15 @@ AlignAndDistribute::AlignAndDistribute()
_alignBox.pack_start(_selgrpBox);
_alignBox.pack_start(_alignTableBox);
+ _alignBoxNode.pack_start(_anchorBoxNode, false, false);
+ _alignBoxNode.pack_start(_nodesTableBox);
+
+
_alignFrame.add(_alignBox);
_distributeFrame.add(_distributeTableBox);
_rearrangeFrame.add(_rearrangeTableBox);
_removeOverlapFrame.add(_removeOverlapTableBox);
- _nodesFrame.add(_nodesTableBox);
+ _nodesFrame.add(_alignBoxNode);
Gtk::Box *contents = _getContents();
contents->set_spacing(4);
@@ -1078,7 +1142,7 @@ AlignAndDistribute::AlignAndDistribute()
contents->pack_start(_distributeFrame, true, true);
contents->pack_start(_rearrangeFrame, true, true);
contents->pack_start(_removeOverlapFrame, true, true);
- contents->pack_start(_nodesFrame, true, true);
+ contents->pack_start(_nodesFrame, true, false);
//Connect to the global tool change signal
_toolChangeConn = INKSCAPE.signal_eventcontext_set.connect(sigc::hide<0>(sigc::bind(sigc::ptr_fun(&on_tool_changed), this)));
@@ -1124,6 +1188,13 @@ void AlignAndDistribute::on_ref_change(){
//Make blink the master
}
+void AlignAndDistribute::on_node_ref_change(){
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setInt("/dialogs/align/align-nodes-to", _comboNode.get_active_row_number());
+
+ //Make blink the master
+}
+
void AlignAndDistribute::on_selgrp_toggled(){
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->setInt("/dialogs/align/sel-as-groups", _selgrp.get_active());
@@ -1149,6 +1220,7 @@ void AlignAndDistribute::setMode(bool nodeEdit)
((_rearrangeFrame).*(mSel))();
((_removeOverlapFrame).*(mSel))();
((_nodesFrame).*(mNode))();
+ _getContents()->queue_resize();
}
void AlignAndDistribute::addAlignButton(const Glib::ustring &id, const Glib::ustring tiptext,
diff --git a/src/ui/dialog/align-and-distribute.h b/src/ui/dialog/align-and-distribute.h
index d337775cf..f8cc61af2 100644
--- a/src/ui/dialog/align-and-distribute.h
+++ b/src/ui/dialog/align-and-distribute.h
@@ -18,6 +18,7 @@
#include <list>
#include "ui/widget/panel.h"
#include "ui/widget/frame.h"
+
#include <gtkmm/frame.h>
#include <gtkmm/comboboxtext.h>
#include <gtkmm/label.h>
@@ -35,6 +36,9 @@ class SPItem;
namespace Inkscape {
namespace UI {
+namespace Tools{
+class NodeTool;
+}
namespace Dialog {
class Action;
@@ -68,6 +72,7 @@ public:
protected:
void on_ref_change();
+ void on_node_ref_change();
void on_selgrp_toggled();
void addDistributeButton(const Glib::ustring &id, const Glib::ustring tiptext,
guint row, guint col, bool onInterSpace,
@@ -114,15 +119,19 @@ protected:
Gtk::HBox _anchorBox;
Gtk::HBox _selgrpBox;
Gtk::VBox _alignBox;
+ Gtk::VBox _alignBoxNode;
Gtk::HBox _alignTableBox;
Gtk::HBox _distributeTableBox;
Gtk::HBox _rearrangeTableBox;
Gtk::HBox _removeOverlapTableBox;
Gtk::HBox _nodesTableBox;
Gtk::Label _anchorLabel;
+ Gtk::Label _anchorLabelNode;
Gtk::Label _selgrpLabel;
Gtk::CheckButton _selgrp;
Gtk::ComboBoxText _combo;
+ Gtk::HBox _anchorBoxNode;
+ Gtk::ComboBoxText _comboNode;
SPDesktop *_desktop;
DesktopTracker _deskTrack;
@@ -150,6 +159,7 @@ class Action {
public :
enum AlignTarget { LAST=0, FIRST, BIGGEST, SMALLEST, PAGE, DRAWING, SELECTION };
+ enum AlignTargetNode { LAST_NODE=0, FIRST_NODE, MID_NODE, MIN_NODE, MAX_NODE };
Action(const Glib::ustring &id,
const Glib::ustring &tiptext,
guint row, guint column,
@@ -213,6 +223,7 @@ private :
}
static void do_action(SPDesktop *desktop, int index);
+ static void do_node_action(Inkscape::UI::Tools::NodeTool *nt, int index);
guint _index;
AlignAndDistribute &_dialog;
diff --git a/src/ui/tool/control-point-selection.cpp b/src/ui/tool/control-point-selection.cpp
index 998f74ee0..f36ad7374 100644
--- a/src/ui/tool/control-point-selection.cpp
+++ b/src/ui/tool/control-point-selection.cpp
@@ -19,6 +19,8 @@
#include "ui/tool/transform-handle-set.h"
#include "ui/tool/node.h"
+
+
#include <gdk/gdkkeysyms.h>
namespace Inkscape {
@@ -82,6 +84,7 @@ std::pair<ControlPointSelection::iterator, bool> ControlPointSelection::insert(c
}
found = _points.insert(x).first;
+ _points_list.push_back(x);
x->updateState();
_pointChanged(x, true);
@@ -97,6 +100,7 @@ std::pair<ControlPointSelection::iterator, bool> ControlPointSelection::insert(c
void ControlPointSelection::erase(iterator pos)
{
SelectableControlPoint *erased = *pos;
+ _points_list.remove(*pos);
_points.erase(pos);
erased->updateState();
_pointChanged(erased, false);
@@ -219,8 +223,11 @@ void ControlPointSelection::transform(Geom::Affine const &m)
/** Align control points on the specified axis. */
void ControlPointSelection::align(Geom::Dim2 axis)
{
+ enum AlignTargetNode { LAST_NODE=0, FIRST_NODE, MID_NODE, MIN_NODE, MAX_NODE };
if (empty()) return;
Geom::Dim2 d = static_cast<Geom::Dim2>((axis + 1) % 2);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+
Geom::OptInterval bound;
for (iterator i = _points.begin(); i != _points.end(); ++i) {
@@ -229,7 +236,27 @@ void ControlPointSelection::align(Geom::Dim2 axis)
if (!bound) { return; }
- double new_coord = bound->middle();
+ double new_coord;
+ switch (AlignTargetNode(prefs->getInt("/dialogs/align/align-nodes-to", 2))){
+ case FIRST_NODE:
+ new_coord=(_points_list.front())->position()[d];
+ break;
+ case LAST_NODE:
+ new_coord=(_points_list.back())->position()[d];
+ break;
+ case MID_NODE:
+ new_coord=bound->middle();
+ break;
+ case MIN_NODE:
+ new_coord=bound->min();
+ break;
+ case MAX_NODE:
+ new_coord=bound->max();
+ break;
+ default:
+ return;
+ }
+
for (iterator i = _points.begin(); i != _points.end(); ++i) {
Geom::Point pos = (*i)->position();
pos[d] = new_coord;
diff --git a/src/ui/tool/control-point-selection.h b/src/ui/tool/control-point-selection.h
index 2d812c0a3..f122a468d 100644
--- a/src/ui/tool/control-point-selection.h
+++ b/src/ui/tool/control-point-selection.h
@@ -12,6 +12,7 @@
#ifndef SEEN_UI_TOOL_CONTROL_POINT_SELECTION_H
#define SEEN_UI_TOOL_CONTROL_POINT_SELECTION_H
+#include <list>
#include <memory>
#include <boost/optional.hpp>
#include <stddef.h>
@@ -140,6 +141,8 @@ private:
double _rotationRadius(Geom::Point const &);
set_type _points;
+ //the purpose of this list is to keep track of first and last selected
+ std::list<SelectableControlPoint *> _points_list;
set_type _all_points;
INK_UNORDERED_MAP<SelectableControlPoint *, Geom::Point> _original_positions;
INK_UNORDERED_MAP<SelectableControlPoint *, Geom::Affine> _last_trans;