IL'dar AKHmetgaleev (AkhIL)
Gerald Young (Yoyobuae)
Cyril Brulebois (KiBi)
+Gerco Ballintijn
Translators:
Copyright 2008 David Roden
Copyright 2008 Daniel Hornung
Copyright 2008 Carlos López
-Copyright 2008 Gerco Ballintijn
+Copyright 2008-2009 Gerco Ballintijn
Some of the icons are placed in the Public Domain by Chris Norman
Some of the icons are placed in the Public Domain by Carlos López González
studio_init_cb.task(_("Init Input Dialog..."));
dialog_input=new Gtk::InputDialog();
dialog_input->get_close_button()->signal_clicked().connect( sigc::mem_fun( *dialog_input, &Gtk::InputDialog::hide ) );
- dialog_input->get_save_button()->signal_clicked().connect( sigc::ptr_fun(studio::App::dialog_not_implemented) );
+ dialog_input->get_save_button()->signal_clicked().connect( sigc::mem_fun( *device_tracker, &DeviceTracker::save_preferences) );
studio_init_cb.task(_("Init auto recovery..."));
auto_recover=new AutoRecover();
**
** \legal
** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2009 Gerco Ballintijn
**
** This package is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License as
*/
/* ========================================================================= */
+// FIXME: The code here doesn't use the GTKmm layer but uses GTK+ directly
+// since the GTKmm wrapper for Gdk::Device is incomplete. When the wrapper
+// gets fixed, this code should be updated accoordingly.
+
/* === H E A D E R S ======================================================= */
#ifdef USING_PCH
#endif
#include "devicetracker.h"
-#include <gdkmm/device.h>
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
#include <synfigapp/main.h>
#include "general.h"
using namespace std;
using namespace etl;
using namespace synfig;
+using namespace synfigapp;
using namespace studio;
/* === M A C R O S ========================================================= */
DeviceTracker::DeviceTracker()
{
- // FIXME: We no longer do this, but we should figure out why this was being done
- // By default, set the input mode on devices to
- // GDK_MODE_SCREEN.
+ GList* device_list;
+ GList* iter;
+ device_list=gdk_devices_list();
+
+ for(iter=device_list;iter;iter=g_list_next(iter))
{
- GList* device_list;
- GList* iter;
- device_list=gdk_devices_list();
-
- for(iter=device_list;iter;iter=g_list_next(iter))
- {
- GdkDevice* device=reinterpret_cast<GdkDevice*>(iter->data);
- //gdk_device_set_mode(device,GDK_MODE_SCREEN);
-
- synfigapp::InputDevice::Handle input_device;
- input_device=synfigapp::Main::add_input_device(device->name,synfigapp::InputDevice::Type(device->source));
- if(input_device->get_type()==synfigapp::InputDevice::TYPE_MOUSE)
- synfigapp::Main::select_input_device(input_device);
+ GdkDevice* device=reinterpret_cast<GdkDevice*>(iter->data);
+
+ synfigapp::InputDevice::Handle input_device;
+ input_device=synfigapp::Main::add_input_device(device->name,synfigapp::InputDevice::Type(device->source));
+ if(input_device->get_type()==synfigapp::InputDevice::TYPE_MOUSE) {
+ input_device->set_mode(synfigapp::InputDevice::MODE_SCREEN);
+ synfigapp::Main::select_input_device(input_device);
}
}
}
DeviceTracker::~DeviceTracker()
{
}
+
+void
+DeviceTracker::save_preferences()
+{
+ GList * device_list = gdk_devices_list();
+ for (GList * itr = device_list; itr; itr = g_list_next(itr))
+ {
+ GdkDevice * gdk_device = reinterpret_cast<GdkDevice*>(itr->data);
+
+ InputDevice::Handle synfig_device = synfigapp::Main::find_input_device(gdk_device->name);
+ if (synfig_device == NULL)
+ continue;
+
+ synfig_device->set_mode(InputDevice::Mode(gdk_device->mode));
+ if (gdk_device->num_axes > 0) {
+ vector<synfigapp::InputDevice::AxisUse> axes;
+ axes.resize(gdk_device->num_axes);
+ for (int i = 0; i < gdk_device->num_axes; i++)
+ axes[i] = InputDevice::AxisUse(gdk_device->axes[i].use);
+ synfig_device->set_axes(axes);
+ }
+
+ if (gdk_device->num_keys > 0) {
+ vector<synfigapp::InputDevice::DeviceKey> keys;
+ keys.resize(gdk_device->num_keys);
+ for (int i = 0; i < gdk_device->num_keys; i++) {
+ keys[i].keyval = gdk_device->keys[i].keyval;
+ keys[i].modifiers = gdk_device->keys[i].modifiers;
+ }
+ synfig_device->set_keys(keys);
+ }
+ }
+}
+
+void
+DeviceTracker::set_device_mode(const synfig::String & id,
+ InputDevice::Mode mode)
+{
+ for (GList * itr = gdk_devices_list(); itr; itr = g_list_next(itr))
+ {
+ GdkDevice * device = reinterpret_cast<GdkDevice*>(itr->data);
+ if (id == device->name)
+ gdk_device_set_mode(device, GdkInputMode(mode));
+ }
+}
+
+void
+DeviceTracker::set_device_axes(const synfig::String & id,
+ const std::vector<synfigapp::InputDevice::AxisUse> axes)
+{
+ for (GList * itr = gdk_devices_list(); itr; itr = g_list_next(itr))
+ {
+ GdkDevice * device = reinterpret_cast<GdkDevice*>(itr->data);
+ if (id == device->name) {
+ for (int axis = 0; axis < (int) axes.size(); axis++)
+ gdk_device_set_axis_use(device, axis, GdkAxisUse(axes[axis]));
+ }
+ }
+}
+
+void
+DeviceTracker::set_device_keys(const synfig::String & id,
+ const std::vector<synfigapp::InputDevice::DeviceKey> keys)
+{
+ for (GList * itr = gdk_devices_list(); itr; itr = g_list_next(itr))
+ {
+ GdkDevice * device = reinterpret_cast<GdkDevice*>(itr->data);
+ if (id == device->name) {
+ for (int key = 0; key < (int) keys.size(); key++)
+ gdk_device_set_key(device, key, keys[key].keyval,
+ GdkModifierType(keys[key].modifiers));
+ }
+ }
+}
/* === H E A D E R S ======================================================= */
+#include <synfig/string.h>
+#include <synfigapp/inputdevice.h>
+
/* === M A C R O S ========================================================= */
/* === T Y P E D E F S ===================================================== */
DeviceTracker();
~DeviceTracker();
-}; // END of class ToolTracker
+ void save_preferences();
+
+ static void set_device_mode(const synfig::String & id,
+ synfigapp::InputDevice::Mode mode);
+ static void set_device_axes(const synfig::String & id,
+ const std::vector<synfigapp::InputDevice::AxisUse> axes);
+ static void set_device_keys(const synfig::String & id,
+ const std::vector<synfigapp::InputDevice::DeviceKey> keys);
+}; // END of class DeviceTracker
}; // END of namespace studio
#include <cstdio>
#include <ETL/stringf>
#include "main.h"
+#include <gtkmm/devicetracker.h>
#include "general.h"
using namespace etl;
using namespace synfig;
using namespace synfigapp;
+using namespace studio;
/* === M A C R O S ========================================================= */
return true;
}
+ if(key=="mode")
+ {
+ get_mode_value(value);
+ return true;
+ }
+ if(key=="axes")
+ {
+ get_axes_value(value);
+ return true;
+ }
+ if(key=="keys")
+ {
+ get_keys_value(value);
+ return true;
+ }
return Settings::get_value(key, value);
}
+ void get_mode_value(synfig::String & value) const
+ {
+ if (input_device->get_mode() == InputDevice::MODE_SCREEN)
+ value = "screen";
+ else if (input_device->get_mode() == InputDevice::MODE_WINDOW)
+ value = "window";
+ else
+ value = "disabled";
+ }
+
+ void get_axes_value(synfig::String & value) const
+ {
+ vector<InputDevice::AxisUse> axes = input_device->get_axes();
+ value = strprintf("%u", axes.size());
+ vector<InputDevice::AxisUse>::const_iterator itr;
+ for (itr = axes.begin(); itr != axes.end(); itr++)
+ value += strprintf(" %u", (unsigned int) *itr);
+ }
+
+ void get_keys_value(synfig::String & value) const
+ {
+ vector<InputDevice::DeviceKey> keys = input_device->get_keys();
+ value = strprintf("%u", keys.size());
+ vector<InputDevice::DeviceKey>::const_iterator itr;
+ for (itr = keys.begin(); itr != keys.end(); itr++)
+ value += strprintf(" %u %u", itr->keyval, itr->modifiers);
+ }
+
virtual bool set_value(const synfig::String& key,const synfig::String& value)
{
if(key=="state")
input_device->set_background_color(synfig::Color(r,g,b,a));
return true;
}
+ if(key=="mode")
+ {
+ set_mode_value(value);
+ return true;
+ }
+ if(key=="axes")
+ {
+ set_axes_value(value);
+ return true;
+ }
+ if(key=="keys")
+ {
+ set_keys_value(value);
+ return true;
+ }
return Settings::set_value(key, value);
}
+ void set_mode_value(const synfig::String & value)
+ {
+ InputDevice::Mode mode;
+ if (value == "screen")
+ mode = InputDevice::MODE_SCREEN;
+ else if (value == "window")
+ mode = InputDevice::MODE_WINDOW;
+ else
+ mode = InputDevice::MODE_DISABLED;
+
+ input_device->set_mode(mode);
+ DeviceTracker::set_device_mode(input_device->get_id(), mode);
+ }
+
+ void set_axes_value(const synfig::String & value)
+ {
+ std::vector<InputDevice::AxisUse> axes;
+
+ unsigned pos = value.find(' ', 0);
+ if (pos < value.size()) {
+ int num_axes = atoi(value.substr(0, pos).c_str());
+ axes.resize(num_axes);
+
+ for (int axis = 0; axis < num_axes; axis++) {
+ int last = pos;
+ pos = value.find(' ', pos + 1);
+ axes[axis] = InputDevice::AxisUse(atoi(value.substr(last, pos).c_str()));
+ }
+ }
+
+ input_device->set_axes(axes);
+ DeviceTracker::set_device_axes(input_device->get_id(), axes);
+ }
+
+ void set_keys_value(const synfig::String & value)
+ {
+ std::vector<InputDevice::DeviceKey> keys;
+
+ unsigned pos = value.find(' ', 0);
+ if (pos < value.size()) {
+ int num_keys = atoi(value.substr(0, pos).c_str());
+ keys.resize(num_keys);
+
+ for (int key = 0; key < num_keys; key++) {
+ int last = pos;
+ pos = value.find(' ', pos + 1);
+ keys[key].keyval = (unsigned int) atol(value.substr(last, pos).c_str());
+ last = pos;
+ pos = value.find(' ', pos + 1);
+ keys[key].modifiers = (unsigned int) atol(value.substr(last, pos).c_str());
+ }
+ }
+
+ input_device->set_keys(keys);
+ DeviceTracker::set_device_keys(input_device->get_id(), keys);
+ }
+
virtual KeyList get_key_list()const
{
KeyList ret(Settings::get_key_list());
ret.push_back("bline_width");
ret.push_back("blend_method");
ret.push_back("opacity");
+ ret.push_back("mode");
+ ret.push_back("axes");
+ ret.push_back("keys");
return ret;
}
};
background_color_(Color::white()),
bline_width_(Distance(1,Distance::SYSTEM_POINTS)),
opacity_(1.0f),
- blend_method_(Color::BLEND_COMPOSITE)
+ blend_method_(Color::BLEND_COMPOSITE),
+ mode_(MODE_DISABLED)
{
device_settings=new DeviceSettings(this);
Main::settings().add_domain(device_settings,"input_device."+id_);
/* === H E A D E R S ======================================================= */
+#include <vector>
#include <synfig/color.h>
#include <synfig/vector.h>
#include <synfig/distance.h>
class Settings;
+/*! \class InputDevice inputdevice.h "synfigapp/inputdevice.h"
+** \brief This class provides a device independent representation the state
+** of an input device.
+** \see studio::DeviceTracker
+** \see synfigapp::Settings
+**
+** The represenation includes both the GDK state (e.g., mode) and synfigstudio
+** state (e.g., foreground color). An object of this class can be saved and
+** restored using its Settings object, provided by the settings method.
+*/
class InputDevice : public etl::shared_object
{
public:
TYPE_CURSOR
};
+ enum Mode
+ {
+ MODE_DISABLED,
+ MODE_SCREEN,
+ MODE_WINDOW
+ };
+
+ enum AxisUse
+ {
+ AXIS_IGNORE,
+ AXIS_X,
+ AXIS_Y,
+ AXIS_PRESSURE,
+ AXIS_XTILT,
+ AXIS_YTILT,
+ AXIS_WHEEL,
+ AXIS_LAST
+ };
+
+ struct DeviceKey
+ {
+ unsigned int keyval;
+ unsigned int modifiers;
+ };
+
typedef etl::handle<InputDevice> Handle;
private:
synfig::Distance bline_width_;
synfig::Real opacity_;
synfig::Color::BlendMethod blend_method_;
+ Mode mode_;
+ std::vector<AxisUse> axes_;
+ std::vector<DeviceKey> keys_;
DeviceSettings* device_settings;
const synfig::Real& get_opacity()const { return opacity_; }
const synfig::Color::BlendMethod& get_blend_method()const { return blend_method_; }
Type get_type()const { return type_; }
+ Mode get_mode()const { return mode_; }
+ const std::vector<AxisUse> & get_axes()const { return axes_; }
+ const std::vector<DeviceKey> & get_keys()const { return keys_; }
void set_state(const synfig::String& x) { state_=x; }
void set_foreground_color(const synfig::Color& x) { foreground_color_=x; }
void set_blend_method(const synfig::Color::BlendMethod& x) { blend_method_=x; }
void set_opacity(const synfig::Real& x) { opacity_=x; }
void set_type(Type x) { type_=x; }
+ void set_mode(Mode x) { mode_=x; }
+ void set_axes(const std::vector<AxisUse>& x) { axes_=x; }
+ void set_keys(const std::vector<DeviceKey>& x) { keys_=x; }
Settings& settings();
const Settings& settings()const;