aea4e6220054ae14c5b0e870098005b09f3bb72f
[synfig.git] / synfig-studio / src / synfigapp / inputdevice.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file inputdevice.cpp
3 **      \brief Template File
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
10 **      This package is free software; you can redistribute it and/or
11 **      modify it under the terms of the GNU General Public License as
12 **      published by the Free Software Foundation; either version 2 of
13 **      the License, or (at your option) any later version.
14 **
15 **      This package is distributed in the hope that it will be useful,
16 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 **      General Public License for more details.
19 **      \endlegal
20 */
21 /* ========================================================================= */
22
23 /* === H E A D E R S ======================================================= */
24
25 #ifdef USING_PCH
26 #       include "pch.h"
27 #else
28 #ifdef HAVE_CONFIG_H
29 #       include <config.h>
30 #endif
31
32 #include "inputdevice.h"
33 #include "settings.h"
34 #include <cstdio>
35 #include <ETL/stringf>
36 #include "main.h"
37
38 #include "general.h"
39
40 #endif
41
42 /* === U S I N G =========================================================== */
43
44 using namespace std;
45 using namespace etl;
46 using namespace synfig;
47 using namespace synfigapp;
48
49 /* === M A C R O S ========================================================= */
50
51 /* === G L O B A L S ======================================================= */
52
53 class DeviceSettings : public Settings
54 {
55         InputDevice* input_device;
56 public:
57         DeviceSettings(InputDevice* input_device):
58                 input_device(input_device) { }
59
60
61         virtual bool get_value(const synfig::String& key, synfig::String& value)const
62         {
63                 try
64                 {
65                         SETTINGS_LOCALE_SAFE_AND_BACKUP
66                         if(key=="state")
67                         {
68                                 value=input_device->get_state();
69                                 return true;
70                         }
71                         if(key=="bline_width")
72                         {
73                                 value=strprintf("%s",input_device->get_bline_width().get_string().c_str());
74                                 return true;
75                         }
76                         if(key=="opacity")
77                         {
78                                 value=strprintf("%f",(float)input_device->get_opacity());
79                                 return true;
80                         }
81                         if(key=="blend_method")
82                         {
83                                 value=strprintf("%i",(int)input_device->get_blend_method());
84                                 return true;
85                         }
86                         if(key=="outline_color")
87                         {
88                                 Color c(input_device->get_outline_color());
89                                 value=strprintf("%f %f %f %f",(float)c.get_r(),(float)c.get_g(),(float)c.get_b(),(float)c.get_a());
90
91                                 return true;
92                         }
93                         if(key=="fill_color")
94                         {
95                                 Color c(input_device->get_fill_color());
96                                 value=strprintf("%f %f %f %f",(float)c.get_r(),(float)c.get_g(),(float)c.get_b(),(float)c.get_a());
97
98                                 return true;
99                         }
100                         if(key=="mode")
101                         {
102                                 get_mode_value(value);
103                                 return true;
104                         }
105                         if(key=="axes")
106                         {
107                                 get_axes_value(value);
108                                 return true;
109                         }
110                         if(key=="keys")
111                         {
112                                 get_keys_value(value);
113                                 return true;
114                         }
115                         SETTINGS_LOCALE_RESTORE
116                 }
117                 catch(...)
118                 {
119                         synfig::warning("DeviceSettings: Caught exception when attempting to get value.");
120                 }
121                 return Settings::get_value(key, value);
122         }
123
124         void get_mode_value(synfig::String & value) const
125         {
126                 if (input_device->get_mode() == InputDevice::MODE_SCREEN)
127                         value = "screen";
128                 else if (input_device->get_mode() == InputDevice::MODE_WINDOW)
129                         value = "window";
130                 else
131                         value = "disabled";
132         }
133
134         void get_axes_value(synfig::String & value) const
135         {
136                 vector<InputDevice::AxisUse> axes = input_device->get_axes();
137                 value = strprintf("%u", axes.size());
138                 vector<InputDevice::AxisUse>::const_iterator itr;
139                 for (itr = axes.begin(); itr != axes.end(); itr++)
140                         value += strprintf(" %u", (unsigned int) *itr);
141         }
142
143         void get_keys_value(synfig::String & value) const
144         {
145                 vector<InputDevice::DeviceKey> keys = input_device->get_keys();
146                 value = strprintf("%u", keys.size());
147                 vector<InputDevice::DeviceKey>::const_iterator itr;
148                 for (itr = keys.begin(); itr != keys.end(); itr++)
149                         value += strprintf(" %u %u", itr->keyval, itr->modifiers);
150         }
151
152         virtual bool set_value(const synfig::String& key,const synfig::String& value)
153         {
154                 try
155                 {
156                         SETTINGS_LOCALE_SAFE_AND_BACKUP
157                         if(key=="state")
158                         {
159                                 input_device->set_state(value);
160                                 return true;
161                         }
162                         if(key=="bline_width")
163                         {
164                                 input_device->set_bline_width(synfig::Distance(value));
165                                 return true;
166                         }
167                         if(key=="opacity")
168                         {
169                                 input_device->set_opacity(atof(value.c_str()));
170                                 return true;
171                         }
172                         if(key=="blend_method")
173                         {
174                                 input_device->set_blend_method(Color::BlendMethod(atoi(value.c_str())));
175                                 return true;
176                         }
177                         if(key=="outline_color")
178                         {
179                                 float r=0,g=0,b=0,a=1;
180                                 if(!strscanf(value,"%f %f %f %f",&r,&g,&b,&a))
181                                         return false;
182                                 input_device->set_outline_color(synfig::Color(r,g,b,a));
183                                 return true;
184                         }
185                         if(key=="fill_color")
186                         {
187                                 float r=0,g=0,b=0,a=1;
188                                 if(!strscanf(value,"%f %f %f %f",&r,&g,&b,&a))
189                                         return false;
190                                 input_device->set_fill_color(synfig::Color(r,g,b,a));
191                                 return true;
192                         }
193                         if(key=="mode")
194                         {
195                                 set_mode_value(value);
196                                 return true;
197                         }
198                         if(key=="axes")
199                         {
200                                 set_axes_value(value);
201                                 return true;
202                         }
203                         if(key=="keys")
204                         {
205                                 set_keys_value(value);
206                                 return true;
207                         }
208                         SETTINGS_LOCALE_RESTORE
209                 }
210                 catch(...)
211                 {
212                         synfig::warning("DeviceSettings: Caught exception when attempting to set value.");
213                 }
214                 return Settings::set_value(key, value);
215         }
216
217         void set_mode_value(const synfig::String & value)
218         {
219                 InputDevice::Mode mode;
220                 if (value == "screen")
221                         mode = InputDevice::MODE_SCREEN;
222                 else if (value == "window")
223                         mode = InputDevice::MODE_WINDOW;
224                 else
225                         mode = InputDevice::MODE_DISABLED;
226
227                 input_device->set_mode(mode);
228         }
229
230         void set_axes_value(const synfig::String & value)
231         {
232                 std::vector<InputDevice::AxisUse> axes;
233
234                 unsigned pos = value.find(' ', 0);
235                 if (pos < value.size()) {
236                         int num_axes = atoi(value.substr(0, pos).c_str());
237                         axes.resize(num_axes);
238
239                         for (int axis = 0; axis < num_axes; axis++) {
240                                 int last = pos;
241                                 pos = value.find(' ', pos + 1);
242                                 axes[axis] = InputDevice::AxisUse(atoi(value.substr(last, pos).c_str()));
243                         }
244                 }
245
246                 input_device->set_axes(axes);
247         }
248
249         void set_keys_value(const synfig::String & value)
250         {
251                 std::vector<InputDevice::DeviceKey> keys;
252
253                 unsigned pos = value.find(' ', 0);
254                 if (pos < value.size()) {
255                         int num_keys = atoi(value.substr(0, pos).c_str());
256                         keys.resize(num_keys);
257
258                         for (int key = 0; key < num_keys; key++) {
259                                 int last = pos;
260                                 pos = value.find(' ', pos + 1);
261                                 keys[key].keyval = (unsigned int) atol(value.substr(last, pos).c_str());
262                                 last = pos;
263                                 pos = value.find(' ', pos + 1);
264                                 keys[key].modifiers = (unsigned int) atol(value.substr(last, pos).c_str());
265                         }
266                 }
267
268                 input_device->set_keys(keys);
269         }
270
271         virtual KeyList get_key_list()const
272         {
273                 KeyList ret(Settings::get_key_list());
274                 ret.push_back("outline_color");
275                 ret.push_back("fill_color");
276                 ret.push_back("state");
277                 ret.push_back("bline_width");
278                 ret.push_back("blend_method");
279                 ret.push_back("opacity");
280                 ret.push_back("mode");
281                 ret.push_back("axes");
282                 ret.push_back("keys");
283                 return ret;
284         }
285 };
286
287 /* === P R O C E D U R E S ================================================= */
288
289 /* === M E T H O D S ======================================================= */
290
291 InputDevice::InputDevice(const synfig::String id_, Type type_):
292         id_(id_),
293         type_(type_),
294         state_((type_==TYPE_PEN)?"draw":"normal"),
295         outline_color_(Color::black()),
296         fill_color_(Color::white()),
297         bline_width_(Distance(1,Distance::SYSTEM_POINTS)),
298         opacity_(1.0f),
299         blend_method_(Color::BLEND_BY_LAYER),
300         mode_(MODE_DISABLED)
301 {
302         device_settings=new DeviceSettings(this);
303         Main::settings().add_domain(device_settings,"input_device."+id_);
304 }
305
306 InputDevice::~InputDevice()
307 {
308         Main::settings().remove_domain("input_device."+id_);
309         delete device_settings;
310 }
311
312 Settings&
313 InputDevice::settings()
314 {
315         return *device_settings;
316 }
317
318 const Settings&
319 InputDevice::settings()const
320 {
321         return *device_settings;
322 }