summaryrefslogtreecommitdiffstats
path: root/src/ui/toolbar/snap-toolbar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/toolbar/snap-toolbar.cpp')
-rw-r--r--src/ui/toolbar/snap-toolbar.cpp402
1 files changed, 402 insertions, 0 deletions
diff --git a/src/ui/toolbar/snap-toolbar.cpp b/src/ui/toolbar/snap-toolbar.cpp
new file mode 100644
index 0000000..483faf3
--- /dev/null
+++ b/src/ui/toolbar/snap-toolbar.cpp
@@ -0,0 +1,402 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/**
+ * @file
+ * Inkscape Snap toolbar
+ *
+ * @authors Inkscape Authors
+ * Copyright (C) 1999-2019 authors
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+#include "snap-toolbar.h"
+
+#include <glibmm/i18n.h>
+
+#include "attributes.h"
+#include "desktop.h"
+#include "verbs.h"
+
+#include "object/sp-namedview.h"
+
+#include "ui/icon-names.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Toolbar {
+
+SnapToolbar::SnapToolbar(SPDesktop *desktop)
+ : Toolbar(desktop),
+ _freeze(false)
+{
+ // Global snapping control
+ {
+ auto snap_global_verb = Inkscape::Verb::get(SP_VERB_TOGGLE_SNAPPING);
+ _snap_global_item = add_toggle_button(snap_global_verb->get_name(),
+ snap_global_verb->get_tip());
+ _snap_global_item->set_icon_name(INKSCAPE_ICON("snap"));
+ _snap_global_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_GLOBAL));
+ }
+
+ add_separator();
+
+ // Snapping to bounding boxes
+ {
+ _snap_from_bbox_corner_item = add_toggle_button(_("Bounding box"),
+ _("Snap bounding boxes"));
+ _snap_from_bbox_corner_item->set_icon_name(INKSCAPE_ICON("snap"));
+ _snap_from_bbox_corner_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_BBOX));
+ }
+
+ {
+ _snap_to_bbox_path_item = add_toggle_button(_("Bounding box edges"),
+ _("Snap to edges of a bounding box"));
+ _snap_to_bbox_path_item->set_icon_name(INKSCAPE_ICON("snap-bounding-box-edges"));
+ _snap_to_bbox_path_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_BBOX_EDGE));
+ }
+
+ {
+ _snap_to_bbox_node_item = add_toggle_button(_("Bounding box corners"),
+ _("Snap bounding box corners"));
+ _snap_to_bbox_node_item->set_icon_name(INKSCAPE_ICON("snap-bounding-box-corners"));
+ _snap_to_bbox_node_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_BBOX_CORNER));
+ }
+
+ {
+ _snap_to_from_bbox_edge_midpoints_item = add_toggle_button(_("BBox Edge Midpoints"),
+ _("Snap midpoints of bounding box edges"));
+ _snap_to_from_bbox_edge_midpoints_item->set_icon_name(INKSCAPE_ICON("snap-bounding-box-midpoints"));
+ _snap_to_from_bbox_edge_midpoints_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_BBOX_EDGE_MIDPOINT));
+ }
+
+ {
+ _snap_to_from_bbox_edge_centers_item = add_toggle_button(_("BBox Centers"),
+ _("Snapping centers of bounding boxes"));
+ _snap_to_from_bbox_edge_centers_item->set_icon_name(INKSCAPE_ICON("snap-bounding-box-center"));
+ _snap_to_from_bbox_edge_centers_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_BBOX_MIDPOINT));
+ }
+
+ add_separator();
+
+ // Snapping to nodes, paths & handles
+ {
+ _snap_from_node_item = add_toggle_button(_("Nodes"),
+ _("Snap nodes, paths, and handles"));
+ _snap_from_node_item->set_icon_name(INKSCAPE_ICON("snap"));
+ _snap_from_node_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_NODE));
+ }
+
+ {
+ _snap_to_item_path_item = add_toggle_button(_("Paths"),
+ _("Snap to paths"));
+ _snap_to_item_path_item->set_icon_name(INKSCAPE_ICON("snap-nodes-path"));
+ _snap_to_item_path_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_PATH));
+ }
+
+ {
+ _snap_to_path_intersections_item = add_toggle_button(_("Path intersections"),
+ _("Snap to path intersections"));
+ _snap_to_path_intersections_item->set_icon_name(INKSCAPE_ICON("snap-nodes-intersection"));
+ _snap_to_path_intersections_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_PATH_INTERSECTION));
+ }
+
+ {
+ _snap_to_item_node_item = add_toggle_button(_("To nodes"),
+ _("Snap to cusp nodes, incl. rectangle corners"));
+ _snap_to_item_node_item->set_icon_name(INKSCAPE_ICON("snap-nodes-cusp"));
+ _snap_to_item_node_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_NODE_CUSP));
+ }
+
+ {
+ _snap_to_smooth_nodes_item = add_toggle_button(_("Smooth nodes"),
+ _("Snap smooth nodes, incl. quadrant points of ellipses"));
+ _snap_to_smooth_nodes_item->set_icon_name(INKSCAPE_ICON("snap-nodes-smooth"));
+ _snap_to_smooth_nodes_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_NODE_SMOOTH));
+ }
+
+ {
+ _snap_to_from_line_midpoints_item = add_toggle_button(_("Line Midpoints"),
+ _("Snap midpoints of line segments"));
+ _snap_to_from_line_midpoints_item->set_icon_name(INKSCAPE_ICON("snap-nodes-midpoint"));
+ _snap_to_from_line_midpoints_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_LINE_MIDPOINT));
+ }
+
+ add_separator();
+
+ {
+ _snap_from_others_item = add_toggle_button(_("Others"),
+ _("Snap other points (centers, guide origins, gradient handles, etc.)"));
+ _snap_from_others_item->set_icon_name(INKSCAPE_ICON("snap"));
+ _snap_from_others_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_OTHERS));
+ }
+
+ {
+ _snap_to_from_object_centers_item = add_toggle_button(_("Object Centers"),
+ _("Snap centers of objects"));
+ _snap_to_from_object_centers_item->set_icon_name(INKSCAPE_ICON("snap-nodes-center"));
+ _snap_to_from_object_centers_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_OBJECT_MIDPOINT));
+ }
+
+ {
+ _snap_to_from_rotation_center_item = add_toggle_button(_("Rotation Centers"),
+ _("Snap an item's rotation center"));
+ _snap_to_from_rotation_center_item->set_icon_name(INKSCAPE_ICON("snap-nodes-rotation-center"));
+ _snap_to_from_rotation_center_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_ROTATION_CENTER));
+ }
+
+ {
+ _snap_to_from_text_baseline_item = add_toggle_button(_("Text baseline"),
+ _("Snap text anchors and baselines"));
+ _snap_to_from_text_baseline_item->set_icon_name(INKSCAPE_ICON("snap-text-baseline"));
+ _snap_to_from_text_baseline_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_TEXT_BASELINE));
+ }
+
+ add_separator();
+
+ {
+ _snap_to_page_border_item = add_toggle_button(_("Page border"),
+ _("Snap to the page border"));
+ _snap_to_page_border_item->set_icon_name(INKSCAPE_ICON("snap-page"));
+ _snap_to_page_border_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_PAGE_BORDER));
+ }
+
+ {
+ _snap_to_grids_item = add_toggle_button(_("Grids"),
+ _("Snap to grids"));
+ _snap_to_grids_item->set_icon_name(INKSCAPE_ICON("grid-rectangular"));
+ _snap_to_grids_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_GRID));
+ }
+
+ {
+ _snap_to_guides_item = add_toggle_button(_("Guides"),
+ _("Snap guides"));
+ _snap_to_guides_item->set_icon_name(INKSCAPE_ICON("guides"));
+ _snap_to_guides_item->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &SnapToolbar::on_snap_toggled),
+ SP_ATTR_INKSCAPE_SNAP_GUIDE));
+ }
+
+ show_all();
+}
+
+GtkWidget *
+SnapToolbar::create(SPDesktop *desktop)
+{
+ auto tb = Gtk::manage(new SnapToolbar(desktop));
+ return GTK_WIDGET(tb->gobj());
+}
+
+void
+SnapToolbar::update(SnapToolbar *tb)
+{
+ auto nv = tb->_desktop->getNamedView();
+
+ if (nv == nullptr) {
+ g_warning("Namedview cannot be retrieved (in updateSnapToolbox)!");
+ return;
+ }
+
+ // The ..._set_active calls below will toggle the buttons, but this shouldn't lead to
+ // changes in our document because we're only updating the UI;
+ // Setting the "freeze" parameter to true will block the code in toggle_snap_callback()
+ tb->_freeze = true;
+
+ bool const c1 = nv->snap_manager.snapprefs.getSnapEnabledGlobally();
+ tb->_snap_global_item->set_active(c1);
+
+ bool const c2 = nv->snap_manager.snapprefs.isTargetSnappable(SNAPTARGET_BBOX_CATEGORY);
+ tb->_snap_from_bbox_corner_item->set_active(c2);
+ tb->_snap_from_bbox_corner_item->set_sensitive(c1);
+
+ tb->_snap_to_bbox_path_item->set_active(nv->snap_manager.snapprefs.isSnapButtonEnabled(SNAPTARGET_BBOX_EDGE));
+ tb->_snap_to_bbox_path_item->set_sensitive(c1 && c2);
+
+ tb->_snap_to_bbox_node_item->set_active(nv->snap_manager.snapprefs.isSnapButtonEnabled(SNAPTARGET_BBOX_CORNER));
+ tb->_snap_to_bbox_node_item->set_sensitive(c1 && c2);
+
+ tb->_snap_to_from_bbox_edge_midpoints_item->set_active(nv->snap_manager.snapprefs.isSnapButtonEnabled(SNAPTARGET_BBOX_EDGE_MIDPOINT));
+ tb->_snap_to_from_bbox_edge_midpoints_item->set_sensitive(c1 && c2);
+ tb->_snap_to_from_bbox_edge_centers_item->set_active(nv->snap_manager.snapprefs.isSnapButtonEnabled(SNAPTARGET_BBOX_MIDPOINT));
+ tb->_snap_to_from_bbox_edge_centers_item->set_sensitive(c1 && c2);
+
+ bool const c3 = nv->snap_manager.snapprefs.isTargetSnappable(SNAPTARGET_NODE_CATEGORY);
+ tb->_snap_from_node_item->set_active(c3);
+ tb->_snap_from_node_item->set_sensitive(c1);
+
+ tb->_snap_to_item_path_item->set_active(nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_PATH));
+ tb->_snap_to_item_path_item->set_sensitive(c1 && c3);
+ tb->_snap_to_path_intersections_item->set_active(nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_PATH_INTERSECTION));
+ tb->_snap_to_path_intersections_item->set_sensitive(c1 && c3);
+ tb->_snap_to_item_node_item->set_active(nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_NODE_CUSP));
+ tb->_snap_to_item_node_item->set_sensitive(c1 && c3);
+ tb->_snap_to_smooth_nodes_item->set_active(nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_NODE_SMOOTH));
+ tb->_snap_to_smooth_nodes_item->set_sensitive(c1 && c3);
+ tb->_snap_to_from_line_midpoints_item->set_active(nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_LINE_MIDPOINT));
+ tb->_snap_to_from_line_midpoints_item->set_sensitive(c1 && c3);
+
+ bool const c5 = nv->snap_manager.snapprefs.isTargetSnappable(SNAPTARGET_OTHERS_CATEGORY);
+ tb->_snap_from_others_item->set_active(c5);
+ tb->_snap_from_others_item->set_sensitive(c1);
+ tb->_snap_to_from_object_centers_item->set_active(nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_OBJECT_MIDPOINT));
+ tb->_snap_to_from_object_centers_item->set_sensitive(c1 && c5);
+ tb->_snap_to_from_rotation_center_item->set_active(nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_ROTATION_CENTER));
+ tb->_snap_to_from_rotation_center_item->set_sensitive(c1 && c5);
+ tb->_snap_to_from_text_baseline_item->set_active(nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_TEXT_BASELINE));
+ tb->_snap_to_from_text_baseline_item->set_sensitive(c1 && c5);
+ tb->_snap_to_page_border_item->set_active(nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_PAGE_BORDER));
+ tb->_snap_to_page_border_item->set_sensitive(c1);
+ tb->_snap_to_grids_item->set_active(nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_GRID));
+ tb->_snap_to_grids_item->set_sensitive(c1);
+ tb->_snap_to_guides_item->set_active(nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_GUIDE));
+ tb->_snap_to_guides_item->set_sensitive(c1);
+
+ tb->_freeze = false;
+}
+
+void
+SnapToolbar::on_snap_toggled(SPAttributeEnum attr)
+{
+ if(_freeze) return;
+
+ auto dt = _desktop;
+ auto nv = dt->getNamedView();
+
+ if(!nv) {
+ g_warning("No namedview specified in toggle-snap callback");
+ return;
+ }
+
+ auto doc = nv->document;
+ auto repr = nv->getRepr();
+
+ if(!repr) {
+ g_warning("This namedview doesn't have an XML representation attached!");
+ return;
+ }
+
+ DocumentUndo::ScopedInsensitive _no_undo(doc);
+
+ bool v = false;
+
+ switch (attr) {
+ case SP_ATTR_INKSCAPE_SNAP_GLOBAL:
+ dt->toggleSnapGlobal();
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_BBOX:
+ v = nv->snap_manager.snapprefs.isTargetSnappable(Inkscape::SNAPTARGET_BBOX_CATEGORY);
+ sp_repr_set_boolean(repr, "inkscape:snap-bbox", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_BBOX_EDGE:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_BBOX_EDGE);
+ sp_repr_set_boolean(repr, "inkscape:bbox-paths", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_BBOX_CORNER:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_BBOX_CORNER);
+ sp_repr_set_boolean(repr, "inkscape:bbox-nodes", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_NODE:
+ v = nv->snap_manager.snapprefs.isTargetSnappable(Inkscape::SNAPTARGET_NODE_CATEGORY);
+ sp_repr_set_boolean(repr, "inkscape:snap-nodes", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_PATH:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_PATH);
+ sp_repr_set_boolean(repr, "inkscape:object-paths", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_PATH_CLIP:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_PATH_CLIP);
+ sp_repr_set_boolean(repr, "inkscape:snap-path-clip", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_PATH_MASK:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_PATH_MASK);
+ sp_repr_set_boolean(repr, "inkscape:snap-path-mask", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_NODE_CUSP:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_NODE_CUSP);
+ sp_repr_set_boolean(repr, "inkscape:object-nodes", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_NODE_SMOOTH:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_NODE_SMOOTH);
+ sp_repr_set_boolean(repr, "inkscape:snap-smooth-nodes", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_PATH_INTERSECTION:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_PATH_INTERSECTION);
+ sp_repr_set_boolean(repr, "inkscape:snap-intersection-paths", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_OTHERS:
+ v = nv->snap_manager.snapprefs.isTargetSnappable(Inkscape::SNAPTARGET_OTHERS_CATEGORY);
+ sp_repr_set_boolean(repr, "inkscape:snap-others", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_ROTATION_CENTER:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_ROTATION_CENTER);
+ sp_repr_set_boolean(repr, "inkscape:snap-center", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_GRID:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_GRID);
+ sp_repr_set_boolean(repr, "inkscape:snap-grids", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_GUIDE:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_GUIDE);
+ sp_repr_set_boolean(repr, "inkscape:snap-to-guides", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_PAGE_BORDER:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_PAGE_BORDER);
+ sp_repr_set_boolean(repr, "inkscape:snap-page", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_LINE_MIDPOINT:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_LINE_MIDPOINT);
+ sp_repr_set_boolean(repr, "inkscape:snap-midpoints", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_OBJECT_MIDPOINT:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_OBJECT_MIDPOINT);
+ sp_repr_set_boolean(repr, "inkscape:snap-object-midpoints", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_TEXT_BASELINE:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_TEXT_BASELINE);
+ sp_repr_set_boolean(repr, "inkscape:snap-text-baseline", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_BBOX_EDGE_MIDPOINT:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_BBOX_EDGE_MIDPOINT);
+ sp_repr_set_boolean(repr, "inkscape:snap-bbox-edge-midpoints", !v);
+ break;
+ case SP_ATTR_INKSCAPE_SNAP_BBOX_MIDPOINT:
+ v = nv->snap_manager.snapprefs.isSnapButtonEnabled(Inkscape::SNAPTARGET_BBOX_MIDPOINT);
+ sp_repr_set_boolean(repr, "inkscape:snap-bbox-midpoints", !v);
+ break;
+ default:
+ g_warning("toggle_snap_callback has been called with an ID for which no action has been defined");
+ break;
+ }
+
+ doc->setModifiedSinceSave();
+}
+
+}
+}
+}
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :