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