Code

LPE: add RandomParam type.
[inkscape.git] / src / live_effects / parameter / random.cpp
1 #define INKSCAPE_LIVEPATHEFFECT_PARAMETER_RANDOM_CPP\r
2 \r
3 /*\r
4  * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
5  *\r
6  * Released under GNU GPL, read the file 'COPYING' for more information\r
7  */\r
8 \r
9 #include "live_effects/parameter/random.h"\r
10 #include "live_effects/effect.h"\r
11 #include "svg/svg.h"\r
12 #include "libnr/nr-values.h"\r
13 \r
14 #include <gtkmm.h>\r
15 #include "ui/widget/random.h"\r
16 \r
17 #include "svg/stringstream.h"\r
18 \r
19 #include "verbs.h"\r
20 \r
21 #define noLPERANDOMPARAM_DEBUG\r
22 \r
23 namespace Inkscape {\r
24 \r
25 namespace LivePathEffect {\r
26 \r
27 \r
28 RandomParam::RandomParam( const Glib::ustring& label, const Glib::ustring& tip,\r
29                       const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,\r
30                       Effect* effect, gdouble default_value, long default_seed)\r
31     : Parameter(label, tip, key, wr, effect)\r
32 {\r
33     defvalue = default_value;\r
34     value = defvalue;\r
35     min = -NR_HUGE;\r
36     max = NR_HUGE;\r
37     integer = false;\r
38     regrandom = NULL;\r
39 \r
40     defseed = default_seed;\r
41     startseed = defseed;\r
42     seed = startseed;\r
43 }\r
44 \r
45 RandomParam::~RandomParam()\r
46 {\r
47     if (regrandom)\r
48         delete regrandom;\r
49 }\r
50 \r
51 bool\r
52 RandomParam::param_readSVGValue(const gchar * strvalue)\r
53 {\r
54     double newval, newstartseed;\r
55     gchar** stringarray = g_strsplit (strvalue, ";", 2);\r
56     unsigned int success = sp_svg_number_read_d(stringarray[0], &newval);\r
57     if (success == 1) {\r
58         success += sp_svg_number_read_d(stringarray[1], &newstartseed);\r
59         if (success == 2) {\r
60             param_set_value(newval, newstartseed);\r
61         } else {\r
62             param_set_value(newval, defseed);\r
63         }\r
64         g_strfreev(stringarray);\r
65         return true;\r
66     }\r
67     g_strfreev(stringarray);\r
68     return false;\r
69 }\r
70 \r
71 gchar *\r
72 RandomParam::param_writeSVGValue() const\r
73 {\r
74     Inkscape::SVGOStringStream os;\r
75     os << value << ';' << startseed;\r
76     gchar * str = g_strdup(os.str().c_str());\r
77     return str;\r
78 }\r
79 \r
80 void\r
81 RandomParam::param_set_default() \r
82 {\r
83     param_set_value(defvalue, defseed);\r
84 }\r
85 \r
86 void\r
87 RandomParam::param_set_value(gdouble val, long newseed) \r
88 {\r
89     value = val;\r
90     if (integer)\r
91         value = round(value);\r
92     if (value > max)\r
93         value = max;\r
94     if (value < min)\r
95         value = min;\r
96 \r
97     startseed = setup_seed(newseed);\r
98     seed = startseed;\r
99 \r
100     if (regrandom)\r
101         regrandom->setValue(value, startseed);\r
102 }\r
103 \r
104 void\r
105 RandomParam::param_set_range(gdouble min, gdouble max) \r
106 {\r
107     this->min = min;\r
108     this->max = max;\r
109     if (regrandom)\r
110         regrandom->getR()->setRange(min, max);\r
111 \r
112     param_set_value(value, startseed); // reset value, to check whether it is in range\r
113 }\r
114 \r
115 void\r
116 RandomParam::param_make_integer(bool yes)\r
117 {\r
118     integer = yes;\r
119     if (regrandom) {\r
120         regrandom->getR()->setDigits(0);\r
121         regrandom->getR()->setIncrements(1, 10);\r
122     }\r
123 }\r
124 \r
125 void\r
126 RandomParam::resetRandomizer()\r
127 {\r
128     seed = startseed;\r
129 }\r
130 \r
131 \r
132 Gtk::Widget *\r
133 RandomParam::param_getWidget()\r
134 {\r
135     // TODO: add  a button to set a different startseed\r
136     if (!regrandom) {\r
137         regrandom = new Inkscape::UI::Widget::RegisteredRandom();\r
138         regrandom->init(param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc());\r
139         regrandom->setValue(value, startseed);\r
140         if (integer)\r
141             param_make_integer();\r
142 \r
143         regrandom->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change random parameter"));\r
144     }\r
145     return dynamic_cast<Gtk::Widget *> (regrandom->getR());\r
146 }\r
147 \r
148 RandomParam::operator gdouble()\r
149 {\r
150     return rand() * value;\r
151 };\r
152 \r
153 /* RNG stolen from /display/nr-filter-turbulence.cpp */\r
154 #define RAND_m 2147483647 /* 2**31 - 1 */\r
155 #define RAND_a 16807 /* 7**5; primitive root of m */\r
156 #define RAND_q 127773 /* m / a */\r
157 #define RAND_r 2836 /* m % a */\r
158 #define BSize 0x100\r
159 \r
160 long\r
161 RandomParam::setup_seed(long lSeed)\r
162 {\r
163   if (lSeed <= 0) lSeed = -(lSeed % (RAND_m - 1)) + 1;\r
164   if (lSeed > RAND_m - 1) lSeed = RAND_m - 1;\r
165   return lSeed;\r
166 }\r
167 \r
168 // generates random number between 0 and 1\r
169 gdouble\r
170 RandomParam::rand()\r
171 {\r
172   long result;\r
173   result = RAND_a * (seed % RAND_q) - RAND_r * (seed / RAND_q);\r
174   if (result <= 0) result += RAND_m;\r
175   seed = result;\r
176 \r
177   gdouble dresult = (gdouble)(result % BSize) / BSize;\r
178   return dresult;\r
179 }\r
180 \r
181 \r
182 } /* namespace LivePathEffect */\r
183 } /* namespace Inkscape */\r
184 \r
185 /*\r
186   Local Variables:\r
187   mode:c++\r
188   c-file-style:"stroustrup"\r
189   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
190   indent-tabs-mode:nil\r
191   fill-column:99\r
192   End:\r
193 */\r
194 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r