Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
actions-transform.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Gio::Actions for selection tied to the application and without GUI.
4 *
5 * Copyright (C) 2018 Tavmjong Bah
6 *
7 * The contents of this file may be used under the GNU General Public License Version 2 or later.
8 *
9 */
10
11#include "actions-transform.h"
12
13#include <giomm.h> // Not <gtkmm.h>! To eventually allow a headless version!
14#include <glibmm/i18n.h>
15
16#include "actions-helper.h"
17#include "desktop.h"
18#include "document-undo.h"
20#include "inkscape-window.h"
21#include "preferences.h"
22#include "selection.h" // Selection
23#include "page-manager.h"
24#include "ui/icon-names.h"
25
26void
27transform_translate(const Glib::VariantBase& value, InkscapeApplication *app)
28{
29 Glib::Variant<Glib::ustring> s = Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring> >(value);
30
31 std::vector<Glib::ustring> tokens = Glib::Regex::split_simple(",", s.get());
32 if (tokens.size() != 2) {
33 show_output("action:transform_translate: requires two comma separated numbers");
34 return;
35 }
36 double dx = 0;
37 double dy = 0;
38
39 try {
40 dx = std::stod(tokens[0]);
41 dy = std::stod(tokens[1]);
42 } catch (...) {
43 show_output("action:transform-move: invalid arguments");
44 return;
45 }
46
47 auto selection = app->get_active_selection();
48 selection->move(dx, dy);
49
50 // Needed to update repr (is this the best way?).
51 Inkscape::DocumentUndo::done(app->get_active_document(), "ActionTransformTranslate", "");
52}
53
54void
55transform_scale(const Glib::VariantBase& value, InkscapeApplication *app)
56{
57 auto scale = (Glib::VariantBase::cast_dynamic<Glib::Variant<double>>(value)).get();
59}
60
61void
62transform_grow(const Glib::VariantBase& value, InkscapeApplication *app)
63{
64 auto scale = (Glib::VariantBase::cast_dynamic<Glib::Variant<double>>(value)).get();
66}
67
68void
69transform_grow_step(const Glib::VariantBase& value, InkscapeApplication *app)
70{
72
73 auto scale = (Glib::VariantBase::cast_dynamic<Glib::Variant<double>>(value)).get();
74 app->get_active_selection()->scaleAnchored(scale * prefs->getDoubleLimited("/options/defaultscale/value", 2, 0, 1000));
75}
76
77void
78transform_grow_screen(const Glib::VariantBase& value, InkscapeWindow *win)
79{
80 auto scale = (Glib::VariantBase::cast_dynamic<Glib::Variant<double>>(value)).get();
81 auto desktop = win->get_desktop();
83}
84
85void
86transform_rotate(const Glib::VariantBase& value, InkscapeApplication *app)
87{
88 auto angle = (Glib::VariantBase::cast_dynamic<Glib::Variant<double>>(value)).get();
90}
91
92void
93transform_rotate_step(const Glib::VariantBase& value, InkscapeApplication *app)
94{
96
97 auto angle = (Glib::VariantBase::cast_dynamic<Glib::Variant<double>>(value)).get();
98 app->get_active_selection()->rotateAnchored(angle / prefs->getInt("/options/rotationsnapsperpi/value", 12));
99}
100
101void
102transform_rotate_screen(const Glib::VariantBase& value, InkscapeWindow *win)
103{
104 auto angle = (Glib::VariantBase::cast_dynamic<Glib::Variant<double>>(value)).get();
105 auto desktop = win->get_desktop();
106
108}
109
110
111void
113{
114 auto selection = app->get_active_selection();
115 selection->removeTransform();
116
117 // Needed to update repr (is this the best way?).
118 Inkscape::DocumentUndo::done(app->get_active_document(), "ActionTransformRemoveTransform", "");
119}
120
122{
123 auto selection = app->get_active_selection();
124 selection->reapplyAffine();
125 Inkscape::DocumentUndo::maybeDone(app->get_active_document(), "reapply-transform", _("Reapply Transforms"),
126 INKSCAPE_ICON("tool-pointer"));
127}
128
129void page_rotate(const Glib::VariantBase& value, InkscapeApplication *app)
130{
131 auto document = app->get_active_document();
132 Glib::Variant<int> i = Glib::VariantBase::cast_dynamic<Glib::Variant<int> >(value);
133 document->getPageManager().rotatePage(i.get());
134 Inkscape::DocumentUndo::done(document, "Rotate Page", INKSCAPE_ICON("tool-pages"));
135}
136
137const Glib::ustring SECTION = NC_("Action Section", "Transform");
138
139// SHOULD REALLY BE SELECTION LEVEL ACTIONS
140std::vector<std::vector<Glib::ustring>> raw_data_transform = {
141 // clang-format off
142 {"app.transform-translate", N_("Translate"), SECTION, N_("Translate selected objects (dx,dy)")},
143 {"app.transform-rotate", N_("Rotate"), SECTION, N_("Rotate selected objects by degrees")},
144 {"app.transform-scale", N_("Scale"), SECTION, N_("Scale selected objects by scale factor")},
145 {"app.transform-grow", N_("Grow/Shrink"), SECTION, N_("Grow/shrink selected objects")},
146 {"app.transform-grow-step", N_("Grow/Shrink Step"), SECTION, N_("Grow/shrink selected objects by multiple of step value")},
147 {"app.transform-grow-screen", N_("Grow/Shrink Screen"), SECTION, N_("Grow/shrink selected objects relative to zoom level")},
148 {"app.transform-rotate", N_("Rotate"), SECTION, N_("Rotate selected objects")},
149 {"app.transform-rotate-step", N_("Rotate Step"), SECTION, N_("Rotate selected objects by multiple of step value")},
150 {"app.transform-rotate-screen", N_("Rotate Screen"), SECTION, N_("Rotate selected objects relative to zoom level")},
151
152 {"app.transform-remove", N_("Remove Transforms"), SECTION, N_("Remove any transforms from selected objects")},
153 {"app.transform-reapply", N_("Reapply Transforms"), SECTION, N_("Reapply the last transformation to the selection")},
154 {"app.page-rotate", N_("Rotate Page 90°"), SECTION, N_("Rotate page by 90-degree rotation steps")},
155 // clang-format on
156};
157
158std::vector<std::vector<Glib::ustring>> hint_data_transform =
159{
160 // clang-format off
161 {"app.transform-translate", N_("Enter two comma-separated numbers, e.g. 50,-2.5")},
162 {"app.transform-rotate", N_("Enter angle (in degrees) for clockwise rotation")},
163 {"app.transform-scale", N_("Enter scaling factor, e.g. 1.5")},
164 {"app.transform-grow", N_("Enter positive or negative number to grow/shrink selection")},
165 {"app.transform-grow-step", N_("Enter positive or negative number to grow or shrink selection relative to preference step value")},
166 {"app.transform-grow-screen", N_("Enter positive or negative number to grow or shrink selection relative to zoom level")},
167 {"app.page-rotate", N_("Enter number of 90-degree rotation steps")},
168 // clang-format on
169};
170
171void
173{
174 // If these ever get moved to the Inkscape::Selection object, the screen and app based ones can be combined again.
175 Glib::VariantType Bool( Glib::VARIANT_TYPE_BOOL);
176 Glib::VariantType Int( Glib::VARIANT_TYPE_INT32);
177 Glib::VariantType Double(Glib::VARIANT_TYPE_DOUBLE);
178 Glib::VariantType String(Glib::VARIANT_TYPE_STRING);
179
180 auto *gapp = app->gio_app();
181
182 // clang-format off
183 gapp->add_action_with_parameter( "transform-translate", String, sigc::bind(sigc::ptr_fun(&transform_translate), app));
184 gapp->add_action_with_parameter( "transform-rotate", Double, sigc::bind(sigc::ptr_fun(&transform_rotate), app));
185 gapp->add_action_with_parameter( "transform-scale", Double, sigc::bind(sigc::ptr_fun(&transform_scale), app));
186 gapp->add_action_with_parameter( "transform-grow", Double, sigc::bind(sigc::ptr_fun(&transform_grow), app));
187 gapp->add_action_with_parameter( "transform-grow-step", Double, sigc::bind(sigc::ptr_fun(&transform_grow_step), app));
188 gapp->add_action_with_parameter( "transform-rotate", Double, sigc::bind(sigc::ptr_fun(&transform_rotate), app));
189 gapp->add_action_with_parameter( "transform-rotate-step", Double, sigc::bind(sigc::ptr_fun(&transform_rotate_step), app));
190 gapp->add_action( "transform-remove", sigc::bind(sigc::ptr_fun(&transform_remove), app));
191 gapp->add_action( "transform-reapply", sigc::bind(sigc::ptr_fun(&transform_reapply), app));
192 gapp->add_action_with_parameter( "page-rotate", Int, sigc::bind(sigc::ptr_fun(&page_rotate), app));
193 // clang-format on
194
197}
198
199void
201{
202 Glib::VariantType Double(Glib::VARIANT_TYPE_DOUBLE);
203
204 win->add_action_with_parameter( "transform-grow-screen", Double, sigc::bind(sigc::ptr_fun(&transform_grow_screen), win));
205 win->add_action_with_parameter( "transform-rotate-screen", Double, sigc::bind(sigc::ptr_fun(&transform_rotate_screen), win));
206
207 // action data already added above by app actions.
208}
209
210/*
211 Local Variables:
212 mode:c++
213 c-file-style:"stroustrup"
214 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
215 indent-tabs-mode:nil
216 fill-column:99
217 End:
218*/
219// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
double scale
Definition aa.cpp:228
void show_output(Glib::ustring const &data, bool const is_cerr)
std::vector< std::vector< Glib::ustring > > hint_data_transform
void transform_translate(const Glib::VariantBase &value, InkscapeApplication *app)
const Glib::ustring SECTION
void transform_rotate_screen(const Glib::VariantBase &value, InkscapeWindow *win)
void transform_reapply(InkscapeApplication *app)
void page_rotate(const Glib::VariantBase &value, InkscapeApplication *app)
void transform_grow_screen(const Glib::VariantBase &value, InkscapeWindow *win)
void transform_scale(const Glib::VariantBase &value, InkscapeApplication *app)
void transform_remove(InkscapeApplication *app)
void transform_rotate_step(const Glib::VariantBase &value, InkscapeApplication *app)
void transform_grow(const Glib::VariantBase &value, InkscapeApplication *app)
std::vector< std::vector< Glib::ustring > > raw_data_transform
void transform_rotate(const Glib::VariantBase &value, InkscapeApplication *app)
void transform_grow_step(const Glib::VariantBase &value, InkscapeApplication *app)
void add_actions_transform(InkscapeApplication *app)
void add_data(std::vector< std::vector< Glib::ustring > > const &raw_data)
void add_data(std::vector< std::vector< Glib::ustring > > &raw_data)
InkActionExtraData & get_action_extra_data()
Gio::Application * gio_app()
The Gio application instance, never NULL.
SPDocument * get_active_document()
InkActionHintData & get_action_hint_data()
Inkscape::Selection * get_active_selection()
SPDesktop * get_desktop()
static void done(SPDocument *document, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
static void maybeDone(SPDocument *document, const gchar *keyconst, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
void move(double dx, double dy)
void reapplyAffine()
Reapply the same transform again.
void rotatePage(int turns)
Rotate the selected page by the given number of 90 degree rotations.
Preference storage class.
Definition preferences.h:66
static Preferences * get()
Access the singleton Preferences object.
int getInt(Glib::ustring const &pref_path, int def=0)
Retrieve an integer.
double getDoubleLimited(Glib::ustring const &pref_path, double def=0.0, double min=DBL_MIN, double max=DBL_MAX, Glib::ustring const &unit="")
Retrieve a limited floating point value.
void rotateAnchored(double angle_degrees, double zoom=1.0)
Rotate the selection, anchoring it against the center, or a selected anchor.
void scaleAnchored(double amount, bool fixed=true)
Scale the selection, anchoring it against the center, or a selected anchor.
double current_zoom() const
Definition desktop.h:335
Inkscape::Selection * getSelection() const
Definition desktop.h:188
Inkscape::PageManager & getPageManager()
Definition document.h:162
Editable view implementation.
TODO: insert short description here.
Macro for icon names used in Inkscape.
Inkscape - An SVG editor.
Singleton class to access the preferences file in a convenient way.
SPDesktop * desktop