Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
parameter.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
4 *
5 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
6 */
7
8#include "parameter.h"
9
10#include <utility>
11
12#include <glibmm/i18n.h>
13
14#include "inkscape.h"
15#include "preferences.h"
16#include "selection.h"
17
19#include "display/curve.h"
20#include "live_effects/effect.h"
22#include "object/sp-lpe-item.h"
23#include "svg/stringstream.h"
24#include "svg/svg.h"
25#include "ui/icon-names.h"
26#include "xml/node.h"
27
28#define noLPEREALPARAM_DEBUG
29
31
32Parameter::Parameter(Glib::ustring label, Glib::ustring tip, Glib::ustring key, Inkscape::UI::Widget::Registry *wr,
33 Effect *effect)
34 : param_key(std::move(key))
35 , param_wr(wr)
36 , param_label(std::move(label))
37 , oncanvas_editable(false)
38 , widget_is_visible(true)
39 , widget_is_enabled(true)
40 , param_tooltip(std::move(tip))
41 , param_effect(effect)
42{
43}
44
51
52void Parameter::param_write_to_repr(const char *svgd)
53{
54 if (param_effect->getRepr()) {
56 }
57}
58
63
65{
66 if (param_effect) {
67 return param_effect->effectType();
68 }
69 return INVALID_LPE;
70};
71
72/*
73 * sometimes for example on ungrouping or loading documents we need to relay in stored value instead the volatile
74 * version in the parameter
75 */
77{
78 if (auto const val = param_effect->getRepr()->attribute(param_key.c_str())) {
80 }
81}
82
83void Parameter::param_higlight(bool highlight)
84{
85 SPDesktop *desktop = SP_ACTIVE_DESKTOP;
86 if (desktop) {
87 if (!highlight && ownerlocator) {
89 ownerlocator = nullptr;
90 }
91 if (highlight) {
92 std::vector<SPLPEItem *> lpeitems = param_effect->getCurrrentLPEItems();
93 if (lpeitems.size() == 1 && param_effect->is_visible) {
94 SPCurve c;
95 std::vector<Geom::PathVector> cs; // = param_effect->getCanvasIndicators(lpeitems[0]);
96 Geom::OptRect bbox = lpeitems[0]->documentVisualBounds();
97
99 std::vector<SPObject *> satellites = param_get_satellites();
100 for (auto iter : satellites) {
101 auto satelliteitem = cast<SPItem>(iter);
102 if (satelliteitem) {
103 bbox.unionWith(lpeitems[0]->documentVisualBounds());
104 }
105 }
106 }
108 if (bbox) {
109 Geom::Path p = Geom::Path(*bbox);
110 out.push_back(p);
111 }
112 cs.push_back(out);
113 for (auto &p2 : cs) {
114 p2 *= desktop->dt2doc();
115 c.append(p2);
116 }
117 if (!c.is_empty()) {
119 auto tmpitem = new Inkscape::CanvasItemBpath(desktop->getCanvasTemp(), c.get_pathvector(), true);
120 tmpitem->set_stroke(0x0000ff9a);
121 tmpitem->set_fill(0x0, SP_WIND_RULE_NONZERO); // No fill
123 }
124 }
125 }
126 }
127}
128
133
135{
136 SPDesktop *desktop = SP_ACTIVE_DESKTOP;
137 if (desktop) {
139 if (selection) {
140 std::vector<SPObject *> satellites = param_get_satellites();
143 sigc::mem_fun(*this, &Parameter::change_selection));
144 }
145 }
146 }
147}
148
150{
153 // maybe we remove desktop by change with selection get from actions-helper
154 // but this function call param_higlight with also need
155 // desktop to update helper canvas item
156 if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) {
157 std::vector<SPLPEItem *> lpeitems = param_effect->getCurrrentLPEItems();
158 if (lpeitems.size() == 1){
160 param_higlight(false);
162 if (selection) {
163 std::vector<SPObject *> satellites = param_get_satellites();
165 if (selection->singleItem()) {
167 return;
168 }
169 // we always start hiding helper path
170 for (auto iter : satellites) {
171 // if selection is current ref we highlight original sp_lpe_item to
172 // give visual feedback to the user to know what's the LPE item that generated the selection
173 if (iter && selection->includes(iter, true) && param_effect->getLPEObj()->getId() && lpeitems[0]->getId()) {
174 auto rootsatellites = cast<SPItem>(iter)->rootsatellites;
175 Glib::ustring lpeid = Glib::ustring(param_effect->getLPEObj()->getId());
176 Glib::ustring itemid = Glib::ustring(lpeitems[0]->getId());
177 std::pair<Glib::ustring, Glib::ustring> rootsatellite = std::make_pair(itemid, lpeid);
178 if (! (std::find(rootsatellites.begin(), rootsatellites.end(), rootsatellite) != rootsatellites.end()) ) {
179 cast<SPItem>(iter)->rootsatellites.push_back(rootsatellite);
180 }
181 param_higlight(true);
182 break;
183 }
184 }
185 }
186 }
187 } else {
188 param_higlight(false);
189 }
190 }
191 }
192}
193
194/*
195 * we get satellites of parameter, virtual function overided by some parameter with linked satellites
196 */
197std::vector<SPObject *> Parameter::param_get_satellites()
198{
199 std::vector<SPObject *> objs;
200 return objs;
201};
202
203/*###########################################
204 * REAL PARAM
205 */
206ScalarParam::ScalarParam(const Glib::ustring &label, const Glib::ustring &tip, const Glib::ustring &key,
207 Inkscape::UI::Widget::Registry * const wr, Effect * const effect,
208 double const default_value)
209 : Parameter(label, tip, key, wr, effect)
210 , value(default_value)
213 , integer(false)
214 , defvalue(default_value)
215 , digits(2)
216 , inc_step(0.1)
217 , inc_page(1)
218 , add_slider(false)
219 , _set_undo(true)
220 , _no_leading_zeros(false)
221 , _width_chars(-1)
222{
223}
224
225bool ScalarParam::param_readSVGValue(char const * const strvalue)
226{
227 double newval;
228 unsigned int success = sp_svg_number_read_d(strvalue, &newval);
229 if (success == 1) {
230 param_set_value(newval);
231 return true;
232 }
233 return false;
234}
235
237{
239 os << value;
240 return os.str();
241}
242
244{
246 os << defvalue;
247 return os.str();
248}
249
251
252void ScalarParam::param_update_default(double const default_value) { defvalue = default_value; }
253
254void ScalarParam::param_update_default(char const * const default_value)
255{
256 double newval;
257 unsigned int success = sp_svg_number_read_d(default_value, &newval);
258 if (success == 1) {
259 param_update_default(newval);
260 }
261}
262
264{
265 // Check if proportional stroke-width scaling is on
267 bool transform_stroke = prefs ? prefs->getBool("/options/transform/stroke", true) : true;
268 if (transform_stroke || set) {
269 param_set_value(value * postmul.descrim());
270 write_to_SVG();
271 }
272}
273
274void ScalarParam::param_set_value(double const val)
275{
276 value = val;
277 if (integer)
278 value = round(value);
279 if (value > max)
280 value = max;
281 if (value < min)
282 value = min;
283}
284
285void ScalarParam::param_set_range(double const min, double const max)
286{
287 // if you look at client code, you'll see that many effects
288 // has a tendency to set an upper range of Geom::infinity().
289 // Once again, in gtk2, this is not a problem. But in gtk3,
290 // widgets get allocated the amount of size they ask for,
291 // leading to excessively long widgets.
293 this->min = min;
294 } else {
295 this->min = -SCALARPARAM_G_MAXDOUBLE;
296 }
298 this->max = max;
299 } else {
300 this->max = SCALARPARAM_G_MAXDOUBLE;
301 }
302 param_set_value(value); // reset value to see whether it is in ranges
303}
304
306{
307 integer = yes;
308 digits = 0;
309 inc_step = 1;
310 inc_page = 10;
311}
312
316
318 _width_chars = width_chars;
319}
320
321void ScalarParam::param_set_undo(bool set_undo) { _set_undo = set_undo; }
322
324{
325 if (widget_is_visible) {
326 auto const rsu = Gtk::make_managed<UI::Widget::RegisteredScalar>(
328 rsu->setValue(value);
329 rsu->setDigits(digits);
330 rsu->setIncrements(inc_step, inc_page);
331 rsu->setRange(min, max);
332 rsu->setProgrammatically = false;
333 if (_no_leading_zeros) {
334 rsu->setNoLeadingZeros();
335 }
336 if (_width_chars > 0) {
337 rsu->setWidthChars(_width_chars);
338 }
339 if (add_slider) {
340 rsu->addSlider();
341 }
342 if (_set_undo) {
343 rsu->set_undo_parameters(_("Change scalar parameter"), INKSCAPE_ICON("dialog-path-effects"));
344 }
345 return rsu;
346 } else {
347 return nullptr;
348 }
349}
350
351void ScalarParam::param_set_digits(unsigned digits) { this->digits = digits; }
352
354{
355 inc_step = step;
356 inc_page = page;
357}
358
359} // namespace Inkscape::LivePathEffect
360
361/*
362 Local Variables:
363 mode:c++
364 c-file-style:"stroustrup"
365 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
366 indent-tabs-mode:nil
367 fill-column:99
368 End:
369*/
370// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
uint64_t page
Definition canvas.cpp:171
3x3 matrix representing an affine transformation.
Definition affine.h:70
Coord descrim() const
Calculate the descriminant.
Definition affine.cpp:434
void unionWith(CRect const &b)
Enlarge the rectangle to contain the argument.
Axis-aligned rectangle that can be empty.
Definition rect.h:203
Sequence of subpaths.
Definition pathvector.h:122
void push_back(Path const &path)
Append a path at the end.
Definition pathvector.h:172
Sequence of contiguous curves, aka spline.
Definition path.h:353
RAII-style mechanism for creating a temporary undo-insensitive context.
Inkscape::XML::Node * getRepr()
Definition effect.cpp:1934
bool isOnClipboard()
The lpe is on clipboard.
Definition effect.cpp:1248
std::vector< SPLPEItem * > getCurrrentLPEItems() const
Definition effect.cpp:1187
EffectType effectType() const
Definition effect.cpp:1182
LivePathEffectObject * getLPEObj()
Definition effect.h:151
virtual bool param_readSVGValue(char const *strvalue)=0
Inkscape::Display::TemporaryItem * ownerlocator
Definition parameter.h:111
Parameter(Glib::ustring label, Glib::ustring tip, Glib::ustring key, Inkscape::UI::Widget::Registry *wr, Effect *effect)
Definition parameter.cpp:32
Inkscape::UI::Widget::Registry * param_wr
Definition parameter.h:99
virtual ParamType paramType() const =0
sigc::scoped_connection selection_changed_connection
Definition parameter.h:94
void param_write_to_repr(const char *svgd)
Definition parameter.cpp:52
virtual std::vector< SPObject * > param_get_satellites()
void change_selection(Inkscape::Selection *selection)
virtual Glib::ustring param_getSVGValue() const =0
void param_higlight(bool highlight)
Definition parameter.cpp:83
void param_set_digits(unsigned digits)
void param_transform_multiply(Geom::Affine const &postmul, bool set) override
void param_set_range(double min, double max)
bool param_readSVGValue(char const *strvalue) override
void param_set_increments(double step, double page)
void param_update_default(double default_value)
Glib::ustring param_getDefaultSVGValue() const override
void param_set_width_chars(int width_chars)
Gtk::Widget * param_newWidget() override
ScalarParam(const Glib::ustring &label, const Glib::ustring &tip, const Glib::ustring &key, Inkscape::UI::Widget::Registry *wr, Effect *effect, double default_value=1.0)
Glib::ustring param_getSVGValue() const override
SPItem * singleItem()
Returns a single selected item.
Preference storage class.
Definition preferences.h:66
bool getBool(Glib::ustring const &pref_path, bool def=false)
Retrieve a Boolean value.
static Preferences * get()
Access the singleton Preferences object.
std::string str() const
The set of selected SPObjects for a given document and layer model.
Definition selection.h:80
bool includes(XML::Node *repr, bool anyAncestor=false)
Returns true if the given item is selected.
Definition selection.h:140
sigc::connection connectChangedFirst(sigc::slot< void(Selection *)> slot)
Similar to connectChanged, but will be run first.
Definition selection.h:188
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
Definition node.cpp:25
virtual char const * attribute(char const *key) const =0
Get the string representation of a node's attribute.
Wrapper around a Geom::PathVector object.
Definition curve.h:26
To do: update description of desktop.
Definition desktop.h:149
SPDocument * getDocument() const
Definition desktop.h:189
Inkscape::Display::TemporaryItem * add_temporary_canvasitem(Inkscape::CanvasItem *item, int lifetime_msecs, bool move_to_bottom=true)
One should not keep a reference to the SPCanvasItem, the temporary item code will delete the object f...
Definition desktop.cpp:229
Inkscape::CanvasItemGroup * getCanvasTemp() const
Definition desktop.h:202
Geom::Affine const & dt2doc() const
Definition desktop.cpp:1343
Inkscape::Selection * getSelection() const
Definition desktop.h:188
void remove_temporary_canvasitem(Inkscape::Display::TemporaryItem *tempitem)
It is perfectly safe to call this function while the object has already been deleted due to a timeout...
Definition desktop.cpp:242
char const * getId() const
Returns the objects current ID string.
double c[8][4]
Macro for icon names used in Inkscape.
constexpr double SCALARPARAM_G_MAXDOUBLE
Definition parameter.h:27
Glib::ustring label
MultiDegree< n > max(MultiDegree< n > const &p, MultiDegree< n > const &q)
Returns the maximal degree appearing in the two arguments for each variables.
Definition sbasisN.h:158
Piecewise< SBasis > min(SBasis const &f, SBasis const &g)
Return the more negative of the two functions pointwise.
Live Path Effects code.
STL namespace.
static cairo_user_data_key_t key
Singleton class to access the preferences file in a convenient way.
Base class for live path effect items.
@ SP_WIND_RULE_NONZERO
Definition style-enums.h:24
unsigned int sp_svg_number_read_d(gchar const *str, double *val)
TODO: insert short description here.
SPDesktop * desktop
Interface for XML nodes.