Apply patch #17: Implement a Fill/Outline system in place of Foreground/Background...
[synfig.git] / synfig-studio / trunk / 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 #include <gtkmm/devicetracker.h>
38
39 #include "general.h"
40
41 #endif
42
43 /* === U S I N G =========================================================== */
44
45 using namespace std;
46 using namespace etl;
47 using namespace synfig;
48 using namespace synfigapp;
49 using namespace studio;
50
51 /* === M A C R O S ========================================================= */
52
53 /* === G L O B A L S ======================================================= */
54
55 class DeviceSettings : public Settings
56 {
57         InputDevice* input_device;
58 public:
59         DeviceSettings(InputDevice* input_device):
60                 input_device(input_device) { }
61
62
63         virtual bool get_value(const synfig::String& key, synfig::String& value)const
64         {
65                 if(key=="state")
66                 {
67                         value=input_device->get_state();
68                         return true;
69                 }
70                 if(key=="bline_width")
71                 {
72                         value=strprintf("%s",input_device->get_bline_width().get_string().c_str());
73                         return true;
74                 }
75                 if(key=="opacity")
76                 {
77                         value=strprintf("%f",(float)input_device->get_opacity());
78                         return true;
79                 }
80                 if(key=="blend_method")
81                 {
82                         value=strprintf("%i",(int)input_device->get_blend_method());
83                         return true;
84                 }
85                 if(key=="outline_color")
86                 {
87                         Color c(input_device->get_outline_color());
88                         value=strprintf("%f %f %f %f",(float)c.get_r(),(float)c.get_g(),(float)c.get_b(),(float)c.get_a());
89
90                         return true;
91                 }
92                 if(key=="fill_color")
93                 {
94                         Color c(input_device->get_fill_color());
95                         value=strprintf("%f %f %f %f",(float)c.get_r(),(float)c.get_g(),(float)c.get_b(),(float)c.get_a());
96
97                         return true;
98                 }
99                 if(key=="mode")
100                 {
101                         get_mode_value(value);
102                         return true;
103                 }
104                 if(key=="axes")
105                 {
106                         get_axes_value(value);
107                         return true;
108                 }
109                 if(key=="keys")
110                 {
111                         get_keys_value(value);
112                         return true;
113                 }
114
115                 return Settings::get_value(key, value);
116         }
117
118         void get_mode_value(synfig::String & value) const
119         {
120                 if (input_device->get_mode() == InputDevice::MODE_SCREEN)
121                         value = "screen";
122                 else if (input_device->get_mode() == InputDevice::MODE_WINDOW)
123                         value = "window";
124                 else
125                         value = "disabled";
126         }
127
128         void get_axes_value(synfig::String & value) const
129         {
130                 vector<InputDevice::AxisUse> axes = input_device->get_axes();
131                 value = strprintf("%u", axes.size());
132                 vector<InputDevice::AxisUse>::const_iterator itr;
133                 for (itr = axes.begin(); itr != axes.end(); itr++)
134                         value += strprintf(" %u", (unsigned int) *itr);
135         }
136
137         void get_keys_value(synfig::String & value) const
138         {
139                 vector<InputDevice::DeviceKey> keys = input_device->get_keys();
140                 value = strprintf("%u", keys.size());
141                 vector<InputDevice::DeviceKey>::const_iterator itr;
142                 for (itr = keys.begin(); itr != keys.end(); itr++)
143                         value += strprintf(" %u %u", itr->keyval, itr->modifiers);
144         }
145
146         virtual bool set_value(const synfig::String& key,const synfig::String& value)
147         {
148                 if(key=="state")
149                 {
150                         input_device->set_state(value);
151                         return true;
152                 }
153                 if(key=="bline_width")
154                 {
155                         input_device->set_bline_width(synfig::Distance(value));
156                         return true;
157                 }
158                 if(key=="opacity")
159                 {
160                         input_device->set_opacity(atof(value.c_str()));
161                         return true;
162                 }
163                 if(key=="blend_method")
164                 {
165                         input_device->set_blend_method(Color::BlendMethod(atoi(value.c_str())));
166                         return true;
167                 }
168                 if(key=="outline_color")
169                 {
170                         float r=0,g=0,b=0,a=1;
171                         if(!strscanf(value,"%f %f %f %f",&r,&g,&b,&a))
172                                 return false;
173                         input_device->set_outline_color(synfig::Color(r,g,b,a));
174                         return true;
175                 }
176                 if(key=="fill_color")
177                 {
178                         float r=0,g=0,b=0,a=1;
179                         if(!strscanf(value,"%f %f %f %f",&r,&g,&b,&a))
180                                 return false;
181                         input_device->set_fill_color(synfig::Color(r,g,b,a));
182                         return true;
183                 }
184                 if(key=="mode")
185                 {
186                         set_mode_value(value);
187                         return true;
188                 }
189                 if(key=="axes")
190                 {
191                         set_axes_value(value);
192                         return true;
193                 }
194                 if(key=="keys")
195                 {
196                         set_keys_value(value);
197                         return true;
198                 }
199
200                 return Settings::set_value(key, value);
201         }
202
203         void set_mode_value(const synfig::String & value)
204         {
205                 InputDevice::Mode mode;
206                 if (value == "screen")
207                         mode = InputDevice::MODE_SCREEN;
208                 else if (value == "window")
209                         mode = InputDevice::MODE_WINDOW;
210                 else
211                         mode = InputDevice::MODE_DISABLED;
212
213                 input_device->set_mode(mode);
214                 DeviceTracker::set_device_mode(input_device->get_id(), mode);
215         }
216
217         void set_axes_value(const synfig::String & value)
218         {
219                 std::vector<InputDevice::AxisUse> axes;
220
221                 unsigned pos = value.find(' ', 0);
222                 if (pos < value.size()) {
223                         int num_axes = atoi(value.substr(0, pos).c_str());
224                         axes.resize(num_axes);
225
226                         for (int axis = 0; axis < num_axes; axis++) {
227                                 int last = pos;
228                                 pos = value.find(' ', pos + 1);
229                                 axes[axis] = InputDevice::AxisUse(atoi(value.substr(last, pos).c_str()));
230                         }
231                 }
232
233                 input_device->set_axes(axes);
234                 DeviceTracker::set_device_axes(input_device->get_id(), axes);
235         }
236
237         void set_keys_value(const synfig::String & value)
238         {
239                 std::vector<InputDevice::DeviceKey> keys;
240
241                 unsigned pos = value.find(' ', 0);
242                 if (pos < value.size()) {
243                         int num_keys = atoi(value.substr(0, pos).c_str());
244                         keys.resize(num_keys);
245
246                         for (int key = 0; key < num_keys; key++) {
247                                 int last = pos;
248                                 pos = value.find(' ', pos + 1);
249                                 keys[key].keyval = (unsigned int) atol(value.substr(last, pos).c_str());
250                                 last = pos;
251                                 pos = value.find(' ', pos + 1);
252                                 keys[key].modifiers = (unsigned int) atol(value.substr(last, pos).c_str());
253                         }
254                 }
255
256                 input_device->set_keys(keys);
257                 DeviceTracker::set_device_keys(input_device->get_id(), keys);
258         }
259
260         virtual KeyList get_key_list()const
261         {
262                 KeyList ret(Settings::get_key_list());
263                 ret.push_back("outline_color");
264                 ret.push_back("fill_color");
265                 ret.push_back("state");
266                 ret.push_back("bline_width");
267                 ret.push_back("blend_method");
268                 ret.push_back("opacity");
269                 ret.push_back("mode");
270                 ret.push_back("axes");
271                 ret.push_back("keys");
272                 return ret;
273         }
274 };
275
276 /* === P R O C E D U R E S ================================================= */
277
278 /* === M E T H O D S ======================================================= */
279
280 InputDevice::InputDevice(const synfig::String id_, Type type_):
281         id_(id_),
282         type_(type_),
283         state_((type_==TYPE_PEN)?"draw":"normal"),
284         outline_color_(Color::black()),
285         fill_color_(Color::white()),
286         bline_width_(Distance(1,Distance::SYSTEM_POINTS)),
287         opacity_(1.0f),
288         blend_method_(Color::BLEND_COMPOSITE),
289         mode_(MODE_DISABLED)
290 {
291         device_settings=new DeviceSettings(this);
292         Main::settings().add_domain(device_settings,"input_device."+id_);
293 }
294
295 InputDevice::~InputDevice()
296 {
297         Main::settings().remove_domain("input_device."+id_);
298         delete device_settings;
299 }
300
301 Settings&
302 InputDevice::settings()
303 {
304         return *device_settings;
305 }
306
307 const Settings&
308 InputDevice::settings()const
309 {
310         return *device_settings;
311 }