New "Align and Distribute" action button / Center on vertical and horizontal axes
Steps to reproduce:
- open Inkscape
- open the Align and Distribute dialog
- draw some shapes
- align them both vertically and horizontally
What happened?
Very often it's needed to align objects vertically and horizontally.
Currently this requires pressing two different buttons, one to center the objects vertically and another one to center them horizontally.
What should have happened?
It'd be nice to have such a shortcut to do it just by clicking on a single button.
I have added this feature to my custom version. It look like this (icon design is just my suggestion)
Attached to this issue there is a copy of each file I've changed/added.
To give you an idea, next are the patch code for the two most relevant files:
diff --git a/src/ui/dialog/align-and-distribute.h b/src/ui/dialog/align-and-distribute.h
index 175ebdc217..2001627675 100644
--- a/src/ui/dialog/align-and-distribute.h
+++ b/src/ui/dialog/align-and-distribute.h
@@ -49,6 +49,7 @@ public:
static AlignAndDistribute &getInstance() { return *new AlignAndDistribute(); }
Gtk::Grid &align_table(){return _alignTable;}
+ Gtk::Grid &align_center_buttons_table(){return _alignCenterButtonsTable;}
Gtk::Grid &distribute_table(){return _distributeTable;}
Gtk::Grid &rearrange_table(){return _rearrangeTable;}
Gtk::Grid &removeOverlap_table(){return _removeOverlapTable;}
@@ -64,12 +65,16 @@ protected:
void on_node_ref_change();
void on_selgrp_toggled();
void on_oncanvas_toggled();
- void addDistributeButton(const Glib::ustring &id, const Glib::ustring tiptext,
- guint row, guint col, bool onInterSpace,
+ void addDistributeButton(const Glib::ustring &id, const Glib::ustring tiptext,
+ guint row, guint col, bool onInterSpace,
Geom::Dim2 orientation, float kBegin, float kEnd);
- void addAlignButton(const Glib::ustring &id, const Glib::ustring tiptext,
- guint row, guint col);
- void addNodeButton(const Glib::ustring &id, const Glib::ustring tiptext,
+ void addAlignButton(const Glib::ustring &id, const Glib::ustring tiptext,
+ guint row, guint col,
+ int verb_id, Gtk::Grid &parent_table);
+ void addAlignMultiButton(const Glib::ustring &id, const Glib::ustring tiptext,
+ guint row, guint col,
+ const std::vector<int> &verbs, Gtk::Grid &parent_table);
+ void addNodeButton(const Glib::ustring &id, const Glib::ustring tiptext,
guint col, Geom::Dim2 orientation, bool distribute);
void addRemoveOverlapsButton(const Glib::ustring &id,
const Glib::ustring tiptext,
@@ -86,9 +91,9 @@ protected:
void addExchangePositionsClockwiseButton(const Glib::ustring &id,
const Glib::ustring tiptext,
guint row, guint col);
- void addUnclumpButton(const Glib::ustring &id, const Glib::ustring tiptext,
+ void addUnclumpButton(const Glib::ustring &id, const Glib::ustring tiptext,
guint row, guint col);
- void addRandomizeButton(const Glib::ustring &id, const Glib::ustring tiptext,
+ void addRandomizeButton(const Glib::ustring &id, const Glib::ustring tiptext,
guint row, guint col);
void addBaselineButton(const Glib::ustring &id, const Glib::ustring tiptext,
guint row, guint col, Gtk::Grid &table, Geom::Dim2 orientation, bool distribute);
@@ -96,10 +101,11 @@ protected:
std::list<Action *> _actionList;
UI::Widget::Frame _alignFrame, _distributeFrame, _rearrangeFrame, _removeOverlapFrame, _nodesFrame;
- Gtk::Grid _alignTable, _distributeTable, _rearrangeTable, _removeOverlapTable, _nodesTable;
+ Gtk::Grid _alignTable, _alignCenterButtonsTable, _distributeTable, _rearrangeTable, _removeOverlapTable, _nodesTable;
Gtk::HBox _anchorBox;
Gtk::HBox _selgrpBox;
Gtk::VBox _alignBox;
+ Gtk::VBox _alignCenterButtonsBox;
Gtk::VBox _alignBoxNode;
Gtk::HBox _alignTableBox;
Gtk::HBox _distributeTableBox;
@@ -169,11 +175,12 @@ public :
ActionAlign(const Glib::ustring &id,
const Glib::ustring &tiptext,
guint row, guint column,
+ Gtk::Grid &parent_table, /**< Grid where placing this action button; it should be either _alignTable or _alignCenterButtonsTable */
AlignAndDistribute &dialog,
- guint coeffIndex):
+ const std::vector<guint> &coeff_indexes): /**< A vector of coefficients to suport multi-verb buttons, such as "Center on the h and v axes" */
Action(id, tiptext, row, column,
- dialog.align_table(), dialog),
- _index(coeffIndex),
+ parent_table, dialog),
+ _indexes(coeff_indexes),
_dialog(dialog)
{}
@@ -191,13 +198,15 @@ private :
SPDesktop *desktop = _dialog.getDesktop();
if (!desktop) return;
- do_action(desktop, _index);
+ for (auto index: _indexes) {
+ do_action(desktop, index);
+ }
}
static void do_action(SPDesktop *desktop, int index);
static void do_node_action(Inkscape::UI::Tools::NodeTool *nt, int index);
- guint _index;
+ std::vector<guint> _indexes; /**< Multi-buttons contain more than one coefficient (i.e. verb) */
AlignAndDistribute &_dialog;
static const Coeffs _allCoeffs[19];
diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp
index c112f965d8..5f5aa05b06 100644
--- a/src/ui/dialog/align-and-distribute.cpp
+++ b/src/ui/dialog/align-and-distribute.cpp
@@ -867,7 +867,7 @@ private :
default:
g_assert_not_reached ();
break;
- };
+ };
if(focus) {
if (SP_IS_TEXT (focus) || SP_IS_FLOWTEXT (focus)) {
@@ -933,6 +933,7 @@ AlignAndDistribute::AlignAndDistribute()
_removeOverlapFrame(_("Remove overlaps")),
_nodesFrame(_("Nodes")),
_alignTable(),
+ _alignCenterButtonsTable(),
_distributeTable(),
_rearrangeTable(),
_removeOverlapTable(),
@@ -945,34 +946,51 @@ AlignAndDistribute::AlignAndDistribute()
//Instantiate the align buttons
addAlignButton(INKSCAPE_ICON("align-horizontal-right-to-anchor"),
_("Align right edges of objects to the left edge of the anchor"),
- 0, 0);
+ 0, 0, SP_VERB_ALIGN_HORIZONTAL_RIGHT_TO_ANCHOR,
+ align_table());
addAlignButton(INKSCAPE_ICON("align-horizontal-left"),
_("Align left edges"),
- 0, 1);
+ 0, 1, SP_VERB_ALIGN_HORIZONTAL_LEFT,
+ align_table());
addAlignButton(INKSCAPE_ICON("align-horizontal-center"),
_("Center on vertical axis"),
- 0, 2);
+ 0, 0, SP_VERB_ALIGN_HORIZONTAL_CENTER,
+ align_center_buttons_table());
addAlignButton(INKSCAPE_ICON("align-horizontal-right"),
_("Align right sides"),
- 0, 3);
+ 0, 3, SP_VERB_ALIGN_HORIZONTAL_RIGHT,
+ align_table());
addAlignButton(INKSCAPE_ICON("align-horizontal-left-to-anchor"),
_("Align left edges of objects to the right edge of the anchor"),
- 0, 4);
+ 0, 4, SP_VERB_ALIGN_HORIZONTAL_LEFT_TO_ANCHOR,
+ align_table());
addAlignButton(INKSCAPE_ICON("align-vertical-bottom-to-anchor"),
_("Align bottom edges of objects to the top edge of the anchor"),
- 1, 0);
+ 1, 0, SP_VERB_ALIGN_VERTICAL_BOTTOM_TO_ANCHOR,
+ align_table());
addAlignButton(INKSCAPE_ICON("align-vertical-top"),
_("Align top edges"),
- 1, 1);
+ 1, 1, SP_VERB_ALIGN_VERTICAL_TOP,
+ align_table());
addAlignButton(INKSCAPE_ICON("align-vertical-center"),
_("Center on horizontal axis"),
- 1, 2);
+ 2, 0, SP_VERB_ALIGN_VERTICAL_CENTER,
+ align_center_buttons_table());
addAlignButton(INKSCAPE_ICON("align-vertical-bottom"),
_("Align bottom edges"),
- 1, 3);
+ 1, 3, SP_VERB_ALIGN_VERTICAL_BOTTOM,
+ align_table());
addAlignButton(INKSCAPE_ICON("align-vertical-top-to-anchor"),
_("Align top edges of objects to the bottom edge of the anchor"),
- 1, 4);
+ 1, 4, SP_VERB_ALIGN_VERTICAL_TOP_TO_ANCHOR,
+ align_table());
+
+ addAlignMultiButton(INKSCAPE_ICON("align-horizontal-and-vertical-centers"),
+ _("Center on vertical and horizontal axes"),
+ 1, 0,
+ {SP_VERB_ALIGN_HORIZONTAL_CENTER,
+ SP_VERB_ALIGN_VERTICAL_CENTER},
+ align_center_buttons_table());
//Baseline aligns
addBaselineButton(INKSCAPE_ICON("align-horizontal-baseline"),
@@ -1110,6 +1128,9 @@ AlignAndDistribute::AlignAndDistribute()
_oncanvas.signal_toggled().connect(sigc::mem_fun(*this, &AlignAndDistribute::on_oncanvas_toggled));
// Right align the buttons
+ _alignCenterButtonsBox.pack_start(_alignCenterButtonsTable);
+ _alignTable.attach(_alignCenterButtonsBox, 2, 0, 1, 2);
+
_alignTableBox.pack_end(_alignTable, false, false);
_distributeTableBox.pack_end(_distributeTable, false, false);
_rearrangeTableBox.pack_end(_rearrangeTable, false, false);
@@ -1223,14 +1244,31 @@ void AlignAndDistribute::setMode(bool nodeEdit)
_getContents()->queue_resize();
}
+
void AlignAndDistribute::addAlignButton(const Glib::ustring &id, const Glib::ustring tiptext,
- guint row, guint col)
+ guint row, guint col, int verb_id, Gtk::Grid &parent_table)
+{
+ addAlignMultiButton(id, tiptext, row, col, {verb_id}, parent_table);
+}
+
+void AlignAndDistribute::addAlignMultiButton(const Glib::ustring &id, const Glib::ustring tiptext,
+ guint row, guint col,
+ const std::vector<int> &verbs,
+ Gtk::Grid &parent_table)
{
+ std::vector<guint> coeff_indexes{};
+
+ for (auto &verb_id : verbs)
+ {
+ coeff_indexes.push_back(static_cast<guint>(ActionAlign::verb_to_coeff(verb_id)));
+ }
+
_actionList.push_back(
new ActionAlign(
id, tiptext, row, col,
- *this , col + row * 5));
+ parent_table, *this, coeff_indexes));
}
+
void AlignAndDistribute::addDistributeButton(const Glib::ustring &id, const Glib::ustring tiptext,
guint row, guint col, bool onInterSpace,
Geom::Dim2 orientation, float kBegin, float kEnd)
It has been tested only on Linux Gnome 3.30.2
If you consider this a feature worth to add to the next release of Inkscape, and require me to do something else, please tell me. Thank you!
Inkscape Version and Operating System:
- Inkscape Version: 1.0alpha (f7d4648084, 2019-03-06, custom)
- Operating System: Linux Debian
- Operating System version: 10 (buster)
Copies of the files changed or added: