summaryrefslogtreecommitdiffstats
path: root/src/actions/actions-canvas-transform.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/actions/actions-canvas-transform.cpp286
1 files changed, 286 insertions, 0 deletions
diff --git a/src/actions/actions-canvas-transform.cpp b/src/actions/actions-canvas-transform.cpp
new file mode 100644
index 0000000..da9cec2
--- /dev/null
+++ b/src/actions/actions-canvas-transform.cpp
@@ -0,0 +1,286 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions for transforming the canvas view. Tied to a particular InkscapeWindow.
+ *
+ * Copyright (C) 2020 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#include <iostream>
+
+#include <giomm.h> // Not <gtkmm.h>! To eventually allow a headless version!
+#include <glibmm/i18n.h>
+
+#include "actions-canvas-transform.h"
+#include "inkscape-application.h"
+#include "inkscape-window.h"
+#include "desktop.h"
+
+#include "object/sp-namedview.h"
+#include "page-manager.h"
+
+#include "ui/tools/freehand-base.h" // SP_DRAW_CONTEXT
+#include "ui/tools/pen-tool.h"
+#include "ui/tools/pencil-tool.h"
+
+#include "ui/widget/canvas.h" // Canvas area
+
+enum {
+ INK_CANVAS_ZOOM_IN,
+ INK_CANVAS_ZOOM_OUT,
+ INK_CANVAS_ZOOM_1_1,
+ INK_CANVAS_ZOOM_1_2,
+ INK_CANVAS_ZOOM_2_1,
+ INK_CANVAS_ZOOM_SELECTION,
+ INK_CANVAS_ZOOM_DRAWING,
+ INK_CANVAS_ZOOM_PAGE,
+ INK_CANVAS_ZOOM_PAGE_WIDTH,
+ INK_CANVAS_ZOOM_CENTER_PAGE,
+ INK_CANVAS_ZOOM_PREV,
+ INK_CANVAS_ZOOM_NEXT,
+
+ INK_CANVAS_ROTATE_CW,
+ INK_CANVAS_ROTATE_CCW,
+ INK_CANVAS_ROTATE_RESET,
+ INK_CANVAS_FLIP_HORIZONTAL,
+ INK_CANVAS_FLIP_VERTICAL,
+ INK_CANVAS_FLIP_RESET
+};
+
+static void
+canvas_zoom_helper(SPDesktop* dt, const Geom::Point& midpoint, double zoom_factor)
+{
+ if (dynamic_cast<Inkscape::UI::Tools::PencilTool *>(dt->event_context) ||
+ dynamic_cast<Inkscape::UI::Tools::PenTool *>(dt->event_context) ) {
+
+ // Zoom around end of unfinished path.
+ std::optional<Geom::Point> zoom_to =
+ dynamic_cast<Inkscape::UI::Tools::FreehandBase*>(dt->event_context)->red_curve_get_last_point();
+ if (zoom_to) {
+ dt->zoom_relative(*zoom_to, zoom_factor);
+ return;
+ }
+ }
+
+ dt->zoom_relative(midpoint, zoom_factor, false);
+}
+
+void
+canvas_transform(InkscapeWindow *win, const int& option)
+{
+ SPDesktop* dt = win->get_desktop();
+ SPDocument *doc = dt->getDocument();
+
+ // The following might be better done elsewhere:
+
+ // Get preference dependent parameters
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ double zoom_inc =
+ prefs->getDoubleLimited("/options/zoomincrement/value", M_SQRT2, 1.01, 10);
+ double rotate_inc =
+ prefs->getDoubleLimited("/options/rotateincrement/value", 15, 1, 90, "°");
+ rotate_inc *= M_PI/180.0;
+
+ // Get document dependent parameters
+ Geom::Rect const canvas = dt->getCanvas()->get_area_world();
+ Geom::Point midpoint = dt->w2d(canvas.midpoint()); // Midpoint of drawing on canvas.
+
+ switch (option) {
+ case INK_CANVAS_ZOOM_IN:
+ canvas_zoom_helper( dt, midpoint, zoom_inc);
+ break;
+
+ case INK_CANVAS_ZOOM_OUT:
+ canvas_zoom_helper( dt, midpoint, 1.0 / zoom_inc); // zoom_inc > 1
+ break;
+
+ case INK_CANVAS_ZOOM_1_1:
+ dt->zoom_realworld( midpoint, 1.0 );
+ break;
+
+ case INK_CANVAS_ZOOM_1_2:
+ dt->zoom_realworld( midpoint, 0.5 );
+ break;
+
+ case INK_CANVAS_ZOOM_2_1:
+ dt->zoom_realworld( midpoint, 2.0 );
+ break;
+
+ case INK_CANVAS_ZOOM_SELECTION:
+ dt->zoom_selection();
+ break;
+
+ case INK_CANVAS_ZOOM_DRAWING:
+ dt->zoom_drawing();
+ break;
+
+ case INK_CANVAS_ZOOM_PAGE:
+ doc->getPageManager().zoomToSelectedPage(dt, false);
+ break;
+
+ case INK_CANVAS_ZOOM_PAGE_WIDTH:
+ doc->getPageManager().zoomToSelectedPage(dt, true);
+ break;
+
+ case INK_CANVAS_ZOOM_CENTER_PAGE:
+ doc->getPageManager().centerToSelectedPage(dt);
+ break;
+
+ case INK_CANVAS_ZOOM_PREV:
+ dt->prev_transform();
+ break;
+
+ case INK_CANVAS_ZOOM_NEXT:
+ dt->next_transform(); // Is this only zoom? Yes!
+ break;
+
+ case INK_CANVAS_ROTATE_CW:
+ dt->rotate_relative_center_point (midpoint, rotate_inc);
+ break;
+
+ case INK_CANVAS_ROTATE_CCW:
+ dt->rotate_relative_center_point (midpoint, -rotate_inc);
+ break;
+
+ case INK_CANVAS_ROTATE_RESET:
+ dt->rotate_absolute_center_point (midpoint, 0);
+ break;
+
+ case INK_CANVAS_FLIP_HORIZONTAL:
+ dt->flip_relative_center_point (midpoint, SPDesktop::FLIP_HORIZONTAL);
+ break;
+
+ case INK_CANVAS_FLIP_VERTICAL:
+ dt->flip_relative_center_point (midpoint, SPDesktop::FLIP_VERTICAL);
+ break;
+
+ case INK_CANVAS_FLIP_RESET:
+ dt->flip_absolute_center_point (midpoint, SPDesktop::FLIP_NONE);
+ break;
+
+ default:
+ std::cerr << "canvas_zoom: unhandled action value!" << std::endl;
+ }
+}
+
+/**
+ * Toggle rotate lock.
+ */
+void
+canvas_rotate_lock(InkscapeWindow *win)
+{
+ auto action = win->lookup_action("canvas-rotate-lock");
+ if (!action) {
+ std::cerr << "canvas_rotate_lock: action missing!" << std::endl;
+ return;
+ }
+
+ auto saction = Glib::RefPtr<Gio::SimpleAction>::cast_dynamic(action);
+ if (!saction) {
+ std::cerr << "canvas_rotate_lock: action not SimpleAction!" << std::endl;
+ return;
+ }
+
+ bool state = false;
+ saction->get_state(state);
+ state = !state;
+ saction->change_state(state);
+
+ // Save value as a preference
+ Inkscape::Preferences *pref = Inkscape::Preferences::get();
+ pref->setBool("/options/rotationlock", state);
+ std::cout << "rotate_lock: set to: " << state << std::endl;
+
+ SPDesktop* dt = win->get_desktop();
+ dt->set_rotation_lock(state);
+}
+
+
+std::vector<std::vector<Glib::ustring>> raw_data_canvas_transform =
+{
+ // clang-format off
+ {"win.canvas-zoom-in", N_("Zoom In"), "Canvas Geometry", N_("Zoom in") },
+ {"win.canvas-zoom-out", N_("Zoom Out"), "Canvas Geometry", N_("Zoom out") },
+ {"win.canvas-zoom-1-1", N_("Zoom 1:1"), "Canvas Geometry", N_("Zoom to 1:1") },
+ {"win.canvas-zoom-1-2", N_("Zoom 1:2"), "Canvas Geometry", N_("Zoom to 1:2") },
+ {"win.canvas-zoom-2-1", N_("Zoom 2:1"), "Canvas Geometry", N_("Zoom to 2:1") },
+ {"win.canvas-zoom-selection", N_("Zoom Selection"), "Canvas Geometry", N_("Zoom to fit selection in window") },
+ {"win.canvas-zoom-drawing", N_("Zoom Drawing"), "Canvas Geometry", N_("Zoom to fit drawing in window") },
+ {"win.canvas-zoom-page", N_("Zoom Page"), "Canvas Geometry", N_("Zoom to fit page in window") },
+ {"win.canvas-zoom-page-width", N_("Zoom Page Width"), "Canvas Geometry", N_("Zoom to fit page width in window") },
+ {"win.canvas-zoom-center-page", N_("Zoom Center Page"), "Canvas Geometry", N_("Center page in window") },
+ {"win.canvas-zoom-prev", N_("Zoom Prev"), "Canvas Geometry", N_("Go back to previous zoom (from the history of zooms)")},
+ {"win.canvas-zoom-next", N_("Zoom Next"), "Canvas Geometry", N_("Go to next zoom (from the history of zooms)")},
+
+ {"win.canvas-rotate-cw", N_("Rotate Clockwise"), "Canvas Geometry", N_("Rotate canvas clockwise") },
+ {"win.canvas-rotate-ccw", N_("Rotate Counter-CW"), "Canvas Geometry", N_("Rotate canvas counter-clockwise") },
+ {"win.canvas-rotate-reset", N_("Reset Rotation"), "Canvas Geometry", N_("Reset canvas rotation") },
+
+ {"win.canvas-flip-horizontal", N_("Flip Horizontal"), "Canvas Geometry", N_("Flip canvas horizontally") },
+ {"win.canvas-flip-vertical", N_("Flip Vertical"), "Canvas Geometry", N_("Flip canvas vertically") },
+ {"win.canvas-flip-reset", N_("Reset Flipping"), "Canvas Geometry", N_("Reset canvas flipping") },
+
+ {"win.canvas-rotate-lock", N_("Lock Rotation"), "Canvas Geometry", N_("Lock canvas rotation") },
+ // clang-format on
+};
+
+void
+add_actions_canvas_transform(InkscapeWindow* win)
+{
+ auto prefs = Inkscape::Preferences::get();
+
+ bool rotate_lock = prefs->getBool("/options/rotationlock");
+
+ SPDesktop* dt = win->get_desktop();
+ if (dt) {
+ dt->set_rotation_lock(rotate_lock);
+ } else {
+ std::cerr << "add_actions_canvas_transform: no desktop!" << std::endl;
+ }
+
+ // clang-format off
+ win->add_action( "canvas-zoom-in", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_ZOOM_IN));
+ win->add_action( "canvas-zoom-out", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_ZOOM_OUT));
+ win->add_action( "canvas-zoom-1-1", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_ZOOM_1_1));
+ win->add_action( "canvas-zoom-1-2", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_ZOOM_1_2));
+ win->add_action( "canvas-zoom-2-1", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_ZOOM_2_1));
+ win->add_action( "canvas-zoom-selection", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_ZOOM_SELECTION));
+ win->add_action( "canvas-zoom-drawing", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_ZOOM_DRAWING));
+ win->add_action( "canvas-zoom-page", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_ZOOM_PAGE));
+ win->add_action( "canvas-zoom-page-width", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_ZOOM_PAGE_WIDTH));
+ win->add_action( "canvas-zoom-center-page",sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_ZOOM_CENTER_PAGE));
+ win->add_action( "canvas-zoom-prev", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_ZOOM_PREV));
+ win->add_action( "canvas-zoom-next", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_ZOOM_NEXT));
+
+ win->add_action( "canvas-rotate-cw", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_ROTATE_CW));
+ win->add_action( "canvas-rotate-ccw", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_ROTATE_CCW));
+ win->add_action( "canvas-rotate-reset", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_ROTATE_RESET));
+
+ win->add_action( "canvas-flip-horizontal", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_FLIP_HORIZONTAL));
+ win->add_action( "canvas-flip-vertical", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_FLIP_VERTICAL));
+ win->add_action( "canvas-flip-reset", sigc::bind<InkscapeWindow*, int>(sigc::ptr_fun(&canvas_transform), win, INK_CANVAS_FLIP_RESET));
+
+ win->add_action_bool( "canvas-rotate-lock",sigc::bind<InkscapeWindow*>(sigc::ptr_fun(&canvas_rotate_lock), win), rotate_lock);
+ // clang-format on
+
+ auto app = InkscapeApplication::instance();
+ if (!app) {
+ std::cerr << "add_actions_canvas_transform: no app!" << std::endl;
+ return;
+ }
+ app->get_action_extra_data().add_data(raw_data_canvas_transform);
+}
+
+
+/*
+ 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 :