Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
context-fns.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
/*
5 * Authors: see git history
6 *
7 * Copyright (C) 2018 Authors
8 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
9 */
10#include <glibmm/i18n.h>
11
12#include "context-fns.h"
13
14#include "desktop.h"
15#include "layer-manager.h"
16#include "message-context.h"
17#include "message-stack.h"
18#include "snap.h"
19
21
22#include "object/sp-namedview.h"
24
25#include "ui/modifiers.h"
26#include "ui/tools/tool-base.h"
27
28static const double midpt_1_goldenratio = (1 + goldenratio) / 2;
29static const double midpt_goldenratio_2 = (goldenratio + 2) / 2;
30
31/* FIXME: could probably use a template here */
32
43{
44 auto layer = desktop->layerManager().currentLayer();
45
46 if ( !layer || desktop->itemIsHidden(layer) ) {
48 _("<b>Current layer is hidden</b>. Unhide it to be able to draw on it."));
49 return false;
50 }
51
52 if ( layer->isLocked() ) {
54 _("<b>Current layer is locked</b>. Unlock it to be able to draw on it."));
55 return false;
56 }
57
58 return true;
59}
60
61
72{
73 auto layer = desktop->layerManager().currentLayer();
74
75 if ( !layer || desktop->itemIsHidden(layer) ) {
77 _("<b>Current layer is hidden</b>. Unhide it to be able to draw on it."));
78 return false;
79 }
80
81 if ( layer->isLocked() ) {
83 _("<b>Current layer is locked</b>. Unlock it to be able to draw on it."));
84 return false;
85 }
86
87 return true;
88}
89
90
92 Geom::Point const &pt, Geom::Point const &center, int state)
93{
95 Geom::Point p[2];
96
97 auto confine = Modifiers::Modifier::get(Modifiers::Type::TRANS_CONFINE)->active(state);
98 auto off_center = Modifiers::Modifier::get(Modifiers::Type::TRANS_OFF_CENTER)->active(state);
99 /* Check if Alt key is pressed */
100 auto rect_edge = Modifiers::Modifier::get(Modifiers::Type::TRANS_INCREMENT)->active(state);
101
102 auto &m = desktop->getNamedView()->snap_manager;
103 m.setup(desktop, false, item);
104 Inkscape::SnappedPoint snappoint;
105
106 if (confine) {
107 /* We are constrained to producing integer-ratio rectangles */
108
109 /* Vector from the centre of the box to the point we are dragging to */
110 Geom::Point delta = pt - center;
111
112 if (!rect_edge) {
113 /* Round it so that we have an integer-ratio (or golden ratio) box */
114 if (fabs(delta[Geom::X]) > fabs(delta[Geom::Y]) && (delta[Geom::Y] != 0.0)) {
115 double ratio = delta[Geom::X] / delta[Geom::Y];
116 double ratioabs = fabs (ratio);
117 double sign = (ratio < 0 ? -1 : 1);
118 if (midpt_1_goldenratio < ratioabs && ratioabs < midpt_goldenratio_2) {
120 } else {
121 delta[Geom::X] = floor(ratio + 0.5) * delta[Geom::Y];
122 }
123 } else if (delta[Geom::X] != 0.0) {
124 double ratio = delta[Geom::Y] / delta[Geom::X];
125 double ratioabs = fabs(ratio);
126 double sign = (ratio < 0 ? -1 : 1);
127 if (midpt_1_goldenratio < ratioabs && ratioabs < midpt_goldenratio_2) {
129 } else {
131 }
132 }
133 } else {
134 /* Since Alt+Ctrl is pressed we make mouse pointer lie on square with origin as one corner */
135 double ratio = delta[Geom::Y] / delta[Geom::X];
136 double sign = (ratio < 0 ? -1 : 1);
137 if (fabs(delta[Geom::X]) > fabs(delta[Geom::Y]) && (delta[Geom::Y] != 0.0)) {
139 } else if (delta[Geom::X] != 0.0) {
141 }
142 }
143
144 /* p[1] is the dragged point with the integer-ratio constraint */
145 p[1] = center + delta;
146
147 if (off_center) {
148
149 // Our origin is the centre point rather than the corner point;
150 // this means that corner-point movements are bound to each other.
151
152 /* p[0] is the opposite corner of our box */
153 p[0] = center - delta;
154
156
157 /* Try to snap p[0] (the opposite corner) along the constraint vector */
160
161 /* Try to snap p[1] (the dragged corner) along the constraint vector */
164
165 /* Choose the best snap and update points accordingly */
166 if (s[0].getSnapDistance() < s[1].getSnapDistance()) {
167 if (s[0].getSnapped()) {
168 p[0] = s[0].getPoint();
169 p[1] = 2 * center - s[0].getPoint();
170 snappoint = s[0];
171 }
172 } else {
173 if (s[1].getSnapped()) {
174 p[0] = 2 * center - s[1].getPoint();
175 p[1] = s[1].getPoint();
176 snappoint = s[1];
177 }
178 }
179 } else {
180
181 /* Our origin is the opposite corner. Snap the drag point along the constraint vector */
182 p[0] = center;
183 snappoint = m.constrainedSnap(Inkscape::SnapCandidatePoint(p[1], Inkscape::SNAPSOURCE_NODE_HANDLE),
185 if (snappoint.getSnapped()) {
186 p[1] = snappoint.getPoint();
187 }
188 }
189
190 } else if (off_center) {
191 // Our origin is the centre point rather than the corner point;
192 // this means that corner-point movements are bound to each other.
193
194 p[1] = pt;
195 p[0] = 2 * center - p[1];
196
198
201
202 if (s[0].getSnapDistance() < s[1].getSnapDistance()) {
203 if (s[0].getSnapped()) {
204 p[0] = s[0].getPoint();
205 p[1] = 2 * center - s[0].getPoint();
206 snappoint = s[0];
207 }
208 } else {
209 if (s[1].getSnapped()) {
210 p[0] = 2 * center - s[1].getPoint();
211 p[1] = s[1].getPoint();
212 snappoint = s[1];
213 }
214 }
215
216 } else {
217
218 /* There's no constraint on the corner point, so just snap it to anything */
219 p[0] = center;
220 p[1] = pt;
222 if (snappoint.getSnapped()) {
223 p[1] = snappoint.getPoint();
224 }
225 }
226
227 if (snappoint.getSnapped()) {
229 }
230
231 p[0] *= desktop->dt2doc();
232 p[1] *= desktop->dt2doc();
233
234 m.unSetup();
235
236 return Geom::Rect(Geom::Point(MIN(p[0][Geom::X], p[1][Geom::X]), MIN(p[0][Geom::Y], p[1][Geom::Y])),
237 Geom::Point(MAX(p[0][Geom::X], p[1][Geom::X]), MAX(p[0][Geom::Y], p[1][Geom::Y])));
238}
239
240
241
242/*
243 Local Variables:
244 mode:c++
245 c-file-style:"stroustrup"
246 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
247 indent-tabs-mode:nil
248 fill-column:99
249 End:
250*/
251// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Two-dimensional point that doubles as a vector.
Definition point.h:66
Axis aligned, non-empty rectangle.
Definition rect.h:92
void remove_snaptarget(bool only_if_presnap=false)
void set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap=false)
SPGroup * currentLayer() const
Returns current top layer.
A convenience class for working with MessageStacks.
void flash(MessageType type, char const *message)
pushes a message onto the stack for a brief period of time without disturbing our "current" message
A class which holds a stack of displayed messages.
MessageId flash(MessageType type, char const *message)
Temporarily pushes a message onto the stack.
Class to store data for points which are snap candidates, either as a source or as a target.
Class describing the result of an attempt to snap.
Geom::Point getPoint() const
Geom::Coord getSnapDistance() const
To do: update description of desktop.
Definition desktop.h:149
bool itemIsHidden(SPItem const *item) const
Definition desktop.cpp:264
Geom::Affine const & dt2doc() const
Definition desktop.cpp:1343
Inkscape::Display::SnapIndicator * getSnapIndicator() const
Definition desktop.h:193
SPNamedView * getNamedView() const
Definition desktop.h:191
Inkscape::LayerManager & layerManager()
Definition desktop.h:287
Base class for visual SVG elements.
Definition sp-item.h:109
SnapManager snap_manager
void setup(SPDesktop const *desktop, bool snapindicator=true, SPObject const *item_to_ignore=nullptr, std::vector< Inkscape::SnapCandidatePoint > *unselected_nodes=nullptr)
Convenience shortcut when there is only one item to ignore.
Definition snap.cpp:663
static const double midpt_1_goldenratio
static const double midpt_goldenratio_2
constexpr double goldenratio
Definition context-fns.h:19
Editable view implementation.
@ Y
Definition coord.h:48
@ X
Definition coord.h:48
auto floor(Geom::Rect const &rect)
Definition geom.h:131
SPItem * item
Interface for locally managing a current status message.
Raw stack of active status messages.
@ SNAPSOURCE_NODE_HANDLE
Definition snap-enums.h:43
Geom::Rect snap_rectangular_box(SPDesktop const *desktop, SPItem *item, Geom::Point const &pt, Geom::Point const &center, int state)
@ ERROR_MESSAGE
Definition message.h:29
@ WARNING_MESSAGE
Definition message.h:28
bool have_viable_layer(SPDesktop *desktop, MessageContext *message)
Check to see if the current layer is both unhidden and unlocked.
static double sign(double const x)
Returns -1 or 1 according to the sign of x.
Provides a class that shows a temporary indicator on the canvas of where the snap was,...
int delta
SPDesktop * desktop