Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
gradient-drag.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2#ifndef SEEN_GRADIENT_DRAG_H
3#define SEEN_GRADIENT_DRAG_H
4
5/*
6 * On-canvas gradient dragging
7 *
8 * Authors:
9 * bulia byak <bulia@users.sf.net>
10 * Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
11 * Jon A. Cruz <jon@joncruz.org>
12 * Tavmjong Bah <tavmjong@free.fr>
13 *
14 * Copyright (C) 2012 Authors
15 * Copyright (C) 2007 Johan Engelen
16 * Copyright (C) 2005 Authors
17 *
18 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
19 */
20
21#include <cstddef>
22#include <sigc++/sigc++.h>
23#include <vector>
24#include <set>
25#include <gdk/gdk.h>
26#include <glib.h>
27#include <glibmm/ustring.h>
28
29#include <2geom/point.h>
30
31#include "object/sp-gradient.h" // TODO refactor enums to external .h file
34
35class SPKnot;
36
37class SPDesktop;
38class SPCSSAttr;
40class SPMeshGradient;
41class SPItem;
42class SPObject;
44class SPStop;
45
46namespace Inkscape {
47namespace Colors {
48class Color;
49}
50class Selection;
51class CanvasItemCurve;
52struct KeyPressEvent;
53} // namespace Inkscape
54
62 virtual ~GrDraggable();
63
66 gint point_i; // the stop number of this point ( = 0 POINT_LG_BEGIN and POINT_RG_CENTER)
68
70
71 bool mayMerge(GrDraggable *da2);
72
73 inline int equals(GrDraggable *other) {
74 return ((item == other->item) && (point_type == other->point_type) && (point_i == other->point_i) && (fill_or_stroke == other->fill_or_stroke));
75 }
76};
77
78class GrDrag;
79
85struct GrDragger {
87 virtual ~GrDragger();
88
90
92
93 // position of the knot, desktop coords
95 // position of the knot before it began to drag; updated when released
97
98 std::vector<GrDraggable *> draggables;
99
100 void addDraggable(GrDraggable *draggable);
101
102 void updateKnotShape();
103 void updateTip();
104
105 void select();
106 void deselect();
107 bool isSelected();
108
109 /* Given one GrDraggable, these all update other draggables belonging to same GrDragger */
110 void moveThisToDraggable(SPItem *item, GrPointType point_type, gint point_i, Inkscape::PaintTarget fill_or_stroke, bool write_repr);
111 void moveOtherToDraggable(SPItem *item, GrPointType point_type, gint point_i, Inkscape::PaintTarget fill_or_stroke, bool write_repr);
112 void updateMidstopDependencies(GrDraggable *draggable, bool write_repr);
113 void updateDependencies(bool write_repr);
114
115 /* Update handles/tensors when mesh corner moved */
117
118 /* Following are for highlighting mesh handles when corner node is selected. */
120 void highlightNode(SPMeshNode *node, bool highlight, Geom::Point corner_pos, int index);
121 void highlightCorner(bool highlight);
122
123 bool mayMerge(GrDragger *other);
124 bool mayMerge(GrDraggable *da2);
125
128 bool isA(SPItem *item, GrPointType point_type, gint point_i, Inkscape::PaintTarget fill_or_stroke);
129
130 void fireDraggables(bool write_repr, bool scale_radial = false, bool merging_focus = false);
131
132protected:
133 void updateControlSizes();
134
135private:
136 sigc::connection _moved_connection;
137 sigc::connection _clicked_connection;
139 sigc::connection _mousedown_connection;
140 sigc::connection _ungrabbed_connection;
141};
142
143
148class GrDrag {
149public: // FIXME: make more of this private!
150
152 virtual ~GrDrag();
153
154 bool isNonEmpty() {return !draggers.empty();}
155 bool hasSelection() {return !selected.empty();}
156 guint numSelected() {return selected.size();}
157 guint numDraggers() {return draggers.size();}
158
160 return (selected.empty()? 0 : (*(selected.begin()))->draggables.size() );
161 }
162
164 return (selected.empty() ? 0 : ((*(selected.begin()))->draggables[0]->point_type));
165 }
166
167 // especially the selection must be private, fix gradient-context to remove direct access to it
168 std::set<GrDragger *> selected; // list of GrDragger*
169 void setSelected(GrDragger *dragger, bool add_to_selection = false, bool override = true);
170 void setDeselected(GrDragger *dragger);
171 void deselectAll();
172 void selectAll();
173 void selectByCoords(std::vector<Geom::Point> coords);
174 void selectByStop(SPStop *stop, bool add_to_selection = true, bool override = true);
175 void selectRect(Geom::Rect const &r);
176
177 void addColorToDragger(GrDragger &dragger, const char *color);
178 void dropColorOnCorrespondingRegion(const char *color, Geom::Point p);
179 bool dropColor(SPItem *item, gchar const *c, Geom::Point p);
180
181 SPStop *addStopNearPoint(SPItem *item, Geom::Point mouse_p, double tolerance);
182
183 void deleteSelected(bool just_one = false);
184
186
188
191
192 void grabKnot(GrDragger *dragger, gint x, gint y, guint32 etime);
193 void grabKnot(SPItem *item, GrPointType point_type, gint point_i, Inkscape::PaintTarget fill_or_stroke, gint x, gint y, guint32 etime);
194
196
198
199 // lists of edges of selection bboxes, to snap draggers to
200 std::vector<double> hor_levels;
201 std::vector<double> vert_levels;
202
203 std::vector<GrDragger *> draggers;
204
206 {
209 bool is_fill = true; // Fill or stroke, used by meshes.
210 int corner0 = -1; // For meshes
211 int corner1 = -1; // For meshes
212 };
213 std::vector<ItemCurve> item_curves;
214
215 void updateDraggers();
216 void refreshDraggers();
217 void updateLines();
218 void updateLevels();
219
220 bool mouseOver();
221
222 void selected_move_nowrite(double x, double y, bool scale_radial);
223 void selected_move(double x, double y, bool write_repr = true, bool scale_radial = false);
224 void selected_move_screen(double x, double y);
225
227
230
232
233private:
234 void deselect_all();
235
236 void addLine( SPItem *item, Geom::Point p1, Geom::Point p2, Inkscape::PaintTarget fill_or_stroke);
238 int corner0, int corner1, int handle0, int handle1, Inkscape::PaintTarget fill_or_stroke);
239
240 GrDragger *addDragger(GrDraggable *draggable);
241
246
247 bool styleSet( const SPCSSAttr *css, bool switch_style);
248
249 Glib::ustring makeStopSafeColor( gchar const *str, bool &isNull );
250
252 sigc::connection sel_changed_connection;
253 sigc::connection sel_modified_connection;
254
255 sigc::connection style_set_connection;
256 sigc::connection style_query_connection;
257};
258
259#endif // SEEN_GRADIENT_DRAG_H
260/*
261 Local Variables:
262 mode:c++
263 c-file-style:"stroustrup"
264 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
265 indent-tabs-mode:nil
266 fill-column:99
267 End:
268*/
269// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
Cartesian point / 2D vector and related operations.
uint32_t Color
std::unique_ptr< T, CanvasItemUnlinkDeleter > CanvasItemPtr
Smart pointer used to hold CanvasItems, like std::unique_ptr.
Two-dimensional point that doubles as a vector.
Definition point.h:66
Axis aligned, non-empty rectangle.
Definition rect.h:92
This is the root class of the gradient dragging machinery.
GrDragger * addDragger(GrDraggable *draggable)
If there already exists a dragger within MERGE_DIST of p, add the draggable to it; otherwise create n...
void updateDraggers()
Regenerates the draggers list from the current selection; is called when selection is changed or modi...
void deselect_all()
Deselect all stops/draggers (private).
void refreshDraggers()
Refresh draggers, moving and toggling visibility as necessary.
bool hasSelection()
guint singleSelectedDraggerSingleDraggableType()
GrDragger * select_prev()
Select the knot previous from the last selected one and deselect all other selected.
void updateLines()
Regenerates the lines list from the current selection; is called on each move of a dragger,...
bool isNonEmpty()
Inkscape::Colors::Color getColor()
virtual ~GrDrag()
void deselectAll()
Deselect all stops/draggers (public; emits signal).
void addColorToDragger(GrDragger &dragger, const char *color)
void selectByStop(SPStop *stop, bool add_to_selection=true, bool override=true)
Select draggers by stop.
std::vector< double > vert_levels
void addLine(SPItem *item, Geom::Point p1, Geom::Point p2, Inkscape::PaintTarget fill_or_stroke)
Create a line from p1 to p2 and add it to the curves list.
bool local_change
void setDeselected(GrDragger *dragger)
Deselect a dragger.
guint singleSelectedDraggerNumDraggables()
bool dropColor(SPItem *item, gchar const *c, Geom::Point p)
void addDraggersRadial(SPRadialGradient *rg, SPItem *item, Inkscape::PaintTarget fill_or_stroke)
Add draggers for the radial gradient rg on item.
void addCurve(SPItem *item, Geom::Point p0, Geom::Point p1, Geom::Point p2, Geom::Point p3, int corner0, int corner1, int handle0, int handle1, Inkscape::PaintTarget fill_or_stroke)
Create a curve from p0 to p3 and add it to the curves list.
GrDragger * select_next()
Select the knot next to the last selected one and deselect all other selected.
bool styleSet(const SPCSSAttr *css, bool switch_style)
SPStop * addStopNearPoint(SPItem *item, Geom::Point mouse_p, double tolerance)
void selected_move_nowrite(double x, double y, bool scale_radial)
void grabKnot(GrDragger *dragger, gint x, gint y, guint32 etime)
Artificially grab the knot of this dragger; used by the gradient context.
bool key_press_handler(Inkscape::KeyPressEvent const &event)
Handle arrow key events.
bool mouseOver()
Returns true if at least one of the draggers' knots has the mouse hovering above it.
void addDraggersMesh(SPMeshGradient *mg, SPItem *item, Inkscape::PaintTarget fill_or_stroke)
Add draggers for the mesh gradient mg on item.
Inkscape::Selection * selection
void selectByCoords(std::vector< Geom::Point > coords)
Select all stops/draggers that match the coords.
Glib::ustring makeStopSafeColor(gchar const *str, bool &isNull)
sigc::connection style_query_connection
void selected_move_screen(double x, double y)
guint numSelected()
std::set< GrDragger * > selected
void dropColorOnCorrespondingRegion(const char *color, Geom::Point p)
std::vector< double > hor_levels
std::vector< ItemCurve > item_curves
void refreshDraggersMesh(SPMeshGradient *mg, SPItem *item, Inkscape::PaintTarget fill_or_stroke)
Refresh draggers, moving and toggling visibility as necessary.
SPDesktop * desktop
sigc::connection sel_changed_connection
void deleteSelected(bool just_one=false)
void selected_reverse_vector()
sigc::connection style_set_connection
void updateLevels()
Regenerates the levels list from the current selection.
void selectAll()
Select all stops/draggers.
void selected_move(double x, double y, bool write_repr=true, bool scale_radial=false)
bool keep_selection
void setSelected(GrDragger *dragger, bool add_to_selection=false, bool override=true)
Select a dragger.
void selectRect(Geom::Rect const &r)
Select all stops/draggers that fall within the rect.
sigc::connection sel_modified_connection
guint numDraggers()
std::vector< GrDragger * > draggers
GrDragger * getDraggerFor(GrDraggable *d)
Select the dragger which has the given draggable.
void addDraggersLinear(SPLinearGradient *lg, SPItem *item, Inkscape::PaintTarget fill_or_stroke)
Add draggers for the linear gradient lg on item.
The set of selected SPObjects for a given document and layer model.
Definition selection.h:80
To do: update description of desktop.
Definition desktop.h:149
Base class for visual SVG elements.
Definition sp-item.h:109
Desktop-bound visual control object.
Definition knot.h:51
Linear gradient.
Mesh gradient.
SPObject is an abstract base class of all of the document nodes at the SVG document level.
Definition sp-object.h:160
Radial gradient.
Gradient stop.
Definition sp-stop.h:31
std::shared_ptr< Css const > css
double c[8][4]
unsigned int guint32
SPItem * item
Inkscape::XML::Node * node
Helper class to stream background task notifications as a series of messages.
GrPointType
Definition sp-gradient.h:46
MeshNodeOperation
CanvasItemPtr< Inkscape::CanvasItemCurve > curve
This class represents a single draggable point of a gradient.
GrPointType point_type
SPObject * getServer()
int equals(GrDraggable *other)
bool mayMerge(GrDraggable *da2)
virtual ~GrDraggable()
Inkscape::PaintTarget fill_or_stroke
SPItem * item
This class holds together a visible on-canvas knot and a list of draggables that need to be moved whe...
void updateTip()
Updates the statusbar tip of the dragger knot, based on its draggables.
std::vector< GrDraggable * > draggables
void updateDependencies(bool write_repr)
Moves all draggables that depend on this one.
void moveOtherToDraggable(SPItem *item, GrPointType point_type, gint point_i, Inkscape::PaintTarget fill_or_stroke, bool write_repr)
GrDragger * getMgCorner()
Find mesh corner corresponding to given dragger.
void highlightCorner(bool highlight)
Highlight handles for mesh corner corresponding to this dragger.
void updateControlSizes()
SPKnot * knot
sigc::connection _doubleclicked_connection
void fireDraggables(bool write_repr, bool scale_radial=false, bool merging_focus=false)
Act upon all draggables of the dragger, setting them to the dragger's point.
GrDrag * parent
void addDraggable(GrDraggable *draggable)
Adds a draggable to the dragger.
sigc::connection _mousedown_connection
void highlightNode(SPMeshNode *node, bool highlight, Geom::Point corner_pos, int index)
Highlight mesh node.
void updateMidstopDependencies(GrDraggable *draggable, bool write_repr)
Moves all midstop draggables that depend on this one.
void deselect()
Draw this dragger as normal (deselected).
sigc::connection _clicked_connection
void moveMeshHandles(Geom::Point pc_old, MeshNodeOperation op)
Update mesh handles when mesh corner is moved.
bool mayMerge(GrDragger *other)
void updateKnotShape()
Adds a draggable to the dragger.
sigc::connection _moved_connection
Geom::Point point_original
bool isA(GrPointType point_type)
Checks if the dragger has a draggable with this point_type.
virtual ~GrDragger()
void select()
Draw this dragger as selected.
void moveThisToDraggable(SPItem *item, GrPointType point_type, gint point_i, Inkscape::PaintTarget fill_or_stroke, bool write_repr)
Moves this dragger to the point of the given draggable, acting upon all other draggables.
sigc::connection _ungrabbed_connection
Geom::Point point
A key has been pressed.
int index