Revision: 2360 http://synfig.svn.sourceforge.net/synfig/?rev=2360&view=rev Author: gballintijn Date: 2009-04-12 13:59:11 +0000 (Sun, 12 Apr 2009)
Log Message: ----------- Fix #1677510 (part 1): Added the capability of saving and restoring the input devices configuration (i.e., tablet configuration). Modified Paths: -------------- synfig-studio/trunk/AUTHORS synfig-studio/trunk/README synfig-studio/trunk/src/gtkmm/app.cpp synfig-studio/trunk/src/gtkmm/devicetracker.cpp synfig-studio/trunk/src/gtkmm/devicetracker.h synfig-studio/trunk/src/synfigapp/inputdevice.cpp synfig-studio/trunk/src/synfigapp/inputdevice.h Modified: synfig-studio/trunk/AUTHORS =================================================================== --- synfig-studio/trunk/AUTHORS 2009-04-12 12:48:42 UTC (rev 2359) +++ synfig-studio/trunk/AUTHORS 2009-04-12 13:59:11 UTC (rev 2360) @@ -19,6 +19,7 @@ IL'dar AKHmetgaleev (AkhIL) Gerald Young (Yoyobuae) Cyril Brulebois (KiBi) +Gerco Ballintijn Translators: Modified: synfig-studio/trunk/README =================================================================== --- synfig-studio/trunk/README 2009-04-12 12:48:42 UTC (rev 2359) +++ synfig-studio/trunk/README 2009-04-12 13:59:11 UTC (rev 2360) @@ -33,7 +33,7 @@ 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 Modified: synfig-studio/trunk/src/gtkmm/app.cpp =================================================================== --- synfig-studio/trunk/src/gtkmm/app.cpp 2009-04-12 12:48:42 UTC (rev 2359) +++ synfig-studio/trunk/src/gtkmm/app.cpp 2009-04-12 13:59:11 UTC (rev 2360) @@ -1272,7 +1272,7 @@ 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(); Modified: synfig-studio/trunk/src/gtkmm/devicetracker.cpp =================================================================== --- synfig-studio/trunk/src/gtkmm/devicetracker.cpp 2009-04-12 12:48:42 UTC (rev 2359) +++ synfig-studio/trunk/src/gtkmm/devicetracker.cpp 2009-04-12 13:59:11 UTC (rev 2360) @@ -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 <gdkmm/device.h> +#include <gdk/gdk.h> +#include <gtk/gtk.h> #include <synfigapp/main.h> #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 @@ 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(); + GdkDevice* device=reinterpret_cast<GdkDevice*>(iter->data); - 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); + 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() { } + +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)); + } + } +} Modified: synfig-studio/trunk/src/gtkmm/devicetracker.h =================================================================== --- synfig-studio/trunk/src/gtkmm/devicetracker.h 2009-04-12 12:48:42 UTC (rev 2359) +++ synfig-studio/trunk/src/gtkmm/devicetracker.h 2009-04-12 13:59:11 UTC (rev 2360) @@ -27,6 +27,9 @@ /* === 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 ===================================================== */ @@ -41,8 +44,16 @@ 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 /* === E N D =============================================================== */ Modified: synfig-studio/trunk/src/synfigapp/inputdevice.cpp =================================================================== --- synfig-studio/trunk/src/synfigapp/inputdevice.cpp 2009-04-12 12:48:42 UTC (rev 2359) +++ synfig-studio/trunk/src/synfigapp/inputdevice.cpp 2009-04-12 13:59:11 UTC (rev 2360) @@ -34,6 +34,7 @@ #include <cstdio> #include <ETL/stringf> #include "main.h" +#include <gtkmm/devicetracker.h> #include "general.h" @@ -45,6 +46,7 @@ using namespace etl; using namespace synfig; using namespace synfigapp; +using namespace studio; /* === M A C R O S ========================================================= */ @@ -94,10 +96,53 @@ 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") @@ -136,10 +181,82 @@ 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()); @@ -149,6 +266,9 @@ 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 @@ 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_); Modified: synfig-studio/trunk/src/synfigapp/inputdevice.h =================================================================== --- synfig-studio/trunk/src/synfigapp/inputdevice.h 2009-04-12 12:48:42 UTC (rev 2359) +++ synfig-studio/trunk/src/synfigapp/inputdevice.h 2009-04-12 13:59:11 UTC (rev 2360) @@ -27,6 +27,7 @@ /* === H E A D E R S ======================================================= */ +#include <vector> #include <synfig/color.h> #include <synfig/vector.h> #include <synfig/distance.h> @@ -45,6 +46,16 @@ 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 @@ 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: @@ -67,6 +103,9 @@ 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; @@ -82,6 +121,9 @@ 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; } @@ -90,6 +132,9 @@ 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; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ This SF.net email is sponsored by: High Quality Requirements in a Collaborative Environment. Download a free trial of Rational Requirements Composer Now! http://p.sf.net/sfu/www-ibm-com _______________________________________________ Synfig-devl mailing list Synfig-devl@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/synfig-devl