From 7e1b3e8ecf46144d377f338b075967baa4b08ba6 Mon Sep 17 00:00:00 2001 From: gballintijn Date: Sun, 12 Apr 2009 13:59:11 +0000 Subject: [PATCH] Fix #1677510 (part 1): Added the capability of saving and restoring the input devices configuration (i.e., tablet configuration). git-svn-id: https://synfig.svn.sourceforge.net/svnroot/synfig@2360 1f10aa63-cdf2-0310-b900-c93c546f37ac --- synfig-studio/trunk/AUTHORS | 1 + synfig-studio/trunk/README | 2 +- synfig-studio/trunk/src/gtkmm/app.cpp | 2 +- synfig-studio/trunk/src/gtkmm/devicetracker.cpp | 111 ++++++++++++++++--- synfig-studio/trunk/src/gtkmm/devicetracker.h | 13 ++- synfig-studio/trunk/src/synfigapp/inputdevice.cpp | 123 +++++++++++++++++++++- synfig-studio/trunk/src/synfigapp/inputdevice.h | 45 ++++++++ 7 files changed, 276 insertions(+), 21 deletions(-) diff --git a/synfig-studio/trunk/AUTHORS b/synfig-studio/trunk/AUTHORS index abdd35e..5c60ae2 100644 --- a/synfig-studio/trunk/AUTHORS +++ b/synfig-studio/trunk/AUTHORS @@ -19,6 +19,7 @@ Timo Paulssen (timonator) IL'dar AKHmetgaleev (AkhIL) Gerald Young (Yoyobuae) Cyril Brulebois (KiBi) +Gerco Ballintijn Translators: diff --git a/synfig-studio/trunk/README b/synfig-studio/trunk/README index 1db6ecf..6bd0973 100644 --- a/synfig-studio/trunk/README +++ b/synfig-studio/trunk/README @@ -33,7 +33,7 @@ Copyright 2008 Gerald Young 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 diff --git a/synfig-studio/trunk/src/gtkmm/app.cpp b/synfig-studio/trunk/src/gtkmm/app.cpp index ee4459b..58d6c61 100644 --- a/synfig-studio/trunk/src/gtkmm/app.cpp +++ b/synfig-studio/trunk/src/gtkmm/app.cpp @@ -1272,7 +1272,7 @@ App::App(int *argc, char ***argv): 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(); diff --git a/synfig-studio/trunk/src/gtkmm/devicetracker.cpp b/synfig-studio/trunk/src/gtkmm/devicetracker.cpp index 6d2d516..2f661dd 100644 --- a/synfig-studio/trunk/src/gtkmm/devicetracker.cpp +++ b/synfig-studio/trunk/src/gtkmm/devicetracker.cpp @@ -6,6 +6,7 @@ ** ** \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 @@ -20,6 +21,10 @@ */ /* ========================================================================= */ +// 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 @@ -30,7 +35,8 @@ #endif #include "devicetracker.h" -#include +#include +#include #include #include "general.h" @@ -42,6 +48,7 @@ using namespace std; using namespace etl; using namespace synfig; +using namespace synfigapp; using namespace studio; /* === M A C R O S ========================================================= */ @@ -54,23 +61,19 @@ using namespace studio; 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(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(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); } } } @@ -78,3 +81,77 @@ DeviceTracker::DeviceTracker() 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(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 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 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(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 axes) +{ + for (GList * itr = gdk_devices_list(); itr; itr = g_list_next(itr)) + { + GdkDevice * device = reinterpret_cast(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 keys) +{ + for (GList * itr = gdk_devices_list(); itr; itr = g_list_next(itr)) + { + GdkDevice * device = reinterpret_cast(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)); + } + } +} diff --git a/synfig-studio/trunk/src/gtkmm/devicetracker.h b/synfig-studio/trunk/src/gtkmm/devicetracker.h index 5113e26..c3608de 100644 --- a/synfig-studio/trunk/src/gtkmm/devicetracker.h +++ b/synfig-studio/trunk/src/gtkmm/devicetracker.h @@ -27,6 +27,9 @@ /* === H E A D E R S ======================================================= */ +#include +#include + /* === M A C R O S ========================================================= */ /* === T Y P E D E F S ===================================================== */ @@ -41,7 +44,15 @@ public: 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 axes); + static void set_device_keys(const synfig::String & id, + const std::vector keys); +}; // END of class DeviceTracker }; // END of namespace studio diff --git a/synfig-studio/trunk/src/synfigapp/inputdevice.cpp b/synfig-studio/trunk/src/synfigapp/inputdevice.cpp index f575469..110f0cd 100644 --- a/synfig-studio/trunk/src/synfigapp/inputdevice.cpp +++ b/synfig-studio/trunk/src/synfigapp/inputdevice.cpp @@ -34,6 +34,7 @@ #include #include #include "main.h" +#include #include "general.h" @@ -45,6 +46,7 @@ using namespace std; using namespace etl; using namespace synfig; using namespace synfigapp; +using namespace studio; /* === M A C R O S ========================================================= */ @@ -94,10 +96,53 @@ public: 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 axes = input_device->get_axes(); + value = strprintf("%u", axes.size()); + vector::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 keys = input_device->get_keys(); + value = strprintf("%u", keys.size()); + vector::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") @@ -136,10 +181,82 @@ public: 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 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 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()); @@ -149,6 +266,9 @@ public: 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; } }; @@ -165,7 +285,8 @@ InputDevice::InputDevice(const synfig::String id_, Type type_): 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_); diff --git a/synfig-studio/trunk/src/synfigapp/inputdevice.h b/synfig-studio/trunk/src/synfigapp/inputdevice.h index 2ea0e10..e8c41a1 100644 --- a/synfig-studio/trunk/src/synfigapp/inputdevice.h +++ b/synfig-studio/trunk/src/synfigapp/inputdevice.h @@ -27,6 +27,7 @@ /* === H E A D E R S ======================================================= */ +#include #include #include #include @@ -45,6 +46,16 @@ namespace synfigapp { 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: @@ -56,6 +67,31 @@ 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 Handle; private: @@ -67,6 +103,9 @@ private: synfig::Distance bline_width_; synfig::Real opacity_; synfig::Color::BlendMethod blend_method_; + Mode mode_; + std::vector axes_; + std::vector keys_; DeviceSettings* device_settings; @@ -82,6 +121,9 @@ public: 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 & get_axes()const { return axes_; } + const std::vector & 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; } @@ -90,6 +132,9 @@ public: 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& x) { axes_=x; } + void set_keys(const std::vector& x) { keys_=x; } Settings& settings(); const Settings& settings()const; -- 2.7.4