input.cpp revision 87ea779e2ba0cdee8c0945db55e0504e94fdb0b3
/**
* @file
* Input devices dialog (new) - implementation.
*/
/* Author:
* Jon A. Cruz
*
* Copyright (C) 2008 Author
* Released under GNU GPL. Read the file 'COPYING' for more information.
*/
#include <map>
#include <set>
#include <list>
#include <gtkmm/alignment.h>
#include <gtkmm/cellrenderercombo.h>
#include <gtkmm/checkbutton.h>
#include <gtkmm/comboboxtext.h>
#include <gtkmm/eventbox.h>
#include <gtkmm/liststore.h>
#include <gtkmm/notebook.h>
#include <gtkmm/progressbar.h>
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/treemodel.h>
#include <gtkmm/treemodelcolumn.h>
#include <gtkmm/treestore.h>
#include <gtkmm/treeview.h>
#include "device-manager.h"
#include "preferences.h"
#include "input.h"
/* XPM */
static char const * core_xpm[] = {
"16 16 4 1",
" c None",
". c #808080",
"+ c #000000",
"@ c #FFFFFF",
" ",
" ",
" ",
" .++++++. ",
" +@+@@+@+ ",
" +@+@@+@+ ",
" +.+..+.+ ",
" +@@@@@@+ ",
" +@@@@@@+ ",
" +@@@@@@+ ",
" +@@@@@@+ ",
" +@@@@@@+ ",
" .++++++. ",
" ",
" ",
" "};
/* XPM */
static char const *eraser[] = {
/* columns rows colors chars-per-pixel */
"16 16 5 1",
" c black",
". c green",
"X c #808080",
"o c gray100",
"O c None",
/* pixels */
"OOOOOOOOOOOOOOOO",
"OOOOOOOOOOOOO OO",
"OOOOOOOOOOOO . O",
"OOOOOOOOOOO . OO",
"OOOOOOOOOO . OOO",
"OOOOOOOOO . OOOO",
"OOOOOOOO . OOOOO",
"OOOOOOOXo OOOOOO",
"OOOOOOXoXOOOOOOO",
"OOOOOXoXOOOOOOOO",
"OOOOXoXOOOOOOOOO",
"OOOXoXOOOOOOOOOO",
"OOXoXOOOOOOOOOOO",
"OOXXOOOOOOOOOOOO",
"OOOOOOOOOOOOOOOO",
"OOOOOOOOOOOOOOOO"
};
/* XPM */
static char const *mouse[] = {
/* columns rows colors chars-per-pixel */
"16 16 3 1",
" c black",
". c gray100",
"X c None",
/* pixels */
"XXXXXXXXXXXXXXXX",
"XXXXXXXXXXXXXXXX",
"XXXXXXXXXXXXXXXX",
"XXXXXXXXXXXXXXXX",
"XXXXXXX XXXXXXX",
"XXXXX . XXXXXXX",
"XXXX .... XXXXXX",
"XXXX .... XXXXXX",
"XXXXX .... XXXXX",
"XXXXX .... XXXXX",
"XXXXXX .... XXXX",
"XXXXXX .... XXXX",
"XXXXXXX . XXXXX",
"XXXXXXX XXXXXXX",
"XXXXXXXXXXXXXXXX",
"XXXXXXXXXXXXXXXX"
};
/* XPM */
static char const *pen[] = {
/* columns rows colors chars-per-pixel */
"16 16 3 1",
" c black",
". c gray100",
"X c None",
/* pixels */
"XXXXXXXXXXXXXXXX",
"XXXXXXXXXXXXX XX",
"XXXXXXXXXXXX . X",
"XXXXXXXXXXX . XX",
"XXXXXXXXXX . XXX",
"XXXXXXXXX . XXXX",
"XXXXXXXX . XXXXX",
"XXXXXXX . XXXXXX",
"XXXXXX . XXXXXXX",
"XXXXX . XXXXXXXX",
"XXXX . XXXXXXXXX",
"XXX . XXXXXXXXXX",
"XX . XXXXXXXXXXX",
"XX XXXXXXXXXXXX",
"XXXXXXXXXXXXXXXX",
"XXXXXXXXXXXXXXXX"
};
/* XPM */
static char const *sidebuttons[] = {
/* columns rows colors chars-per-pixel */
"16 16 4 1",
" c black",
". c #808080",
"o c green",
"O c None",
/* pixels */
"OOOOOOOOOOOOOOOO",
"OOOOOOOOOOOOOOOO",
"O..............O",
"O.OOOOOOOOOOOO.O",
"O OOOOOOOO O",
"O o OOOOOOOO o O",
"O o OOOOOOOO o O",
"O OOOOOOOO O",
"O.OOOOOOOOOOOO.O",
"O.OOOOOOOOOOOO.O",
"O.OOOOOOOOOOOO.O",
"O.OOOOOOOOOOOO.O",
"O.OOOOOOOOOOOO.O",
"O..............O",
"OOOOOOOOOOOOOOOO",
"OOOOOOOOOOOOOOOO"
};
/* XPM */
static char const *tablet[] = {
/* columns rows colors chars-per-pixel */
"16 16 3 1",
" c black",
". c gray100",
"X c None",
/* pixels */
"XXXXXXXXXXXXXXXX",
"XXXXXXXXXXXXXXXX",
"X X",
"X ............ X",
"X ............ X",
"X ............ X",
"X ............ X",
"X ............ X",
"X ............ X",
"X ............ X",
"X ............ X",
"X ............ X",
"X ............ X",
"X X",
"XXXXXXXXXXXXXXXX",
"XXXXXXXXXXXXXXXX"
};
/* XPM */
static char const *tip[] = {
/* columns rows colors chars-per-pixel */
"16 16 5 1",
" c black",
". c green",
"X c #808080",
"o c gray100",
"O c None",
/* pixels */
"OOOOOOOOOOOOOOOO",
"OOOOOOOOOOOOOXOO",
"OOOOOOOOOOOOXoXO",
"OOOOOOOOOOOXoXOO",
"OOOOOOOOOOXoXOOO",
"OOOOOOOOOXoXOOOO",
"OOOOOOOOXoXOOOOO",
"OOOOOOO oXOOOOOO",
"OOOOOO . OOOOOOO",
"OOOOO . OOOOOOOO",
"OOOO . OOOOOOOOO",
"OOO . OOOOOOOOOO",
"OO . OOOOOOOOOOO",
"OO OOOOOOOOOOOO",
"OOOOXXXXXOOOOOOO",
"OOOOOOOOOXXXXXOO"
};
/* XPM */
static char const *button_none[] = {
/* columns rows colors chars-per-pixel */
"8 8 3 1",
" c black",
". c #808080",
"X c None",
/* pixels */
"XXXXXXXX",
"XX .. XX",
"X .XX. X",
"X.XX X.X",
"X.X XX.X",
"X .XX. X",
"XX .. XX",
"XXXXXXXX"
};
/* XPM */
static char const *button_off[] = {
/* columns rows colors chars-per-pixel */
"8 8 4 1",
" c black",
". c #808080",
"X c gray100",
"o c None",
/* pixels */
"oooooooo",
"oo. .oo",
"o. XX .o",
"o XXXX o",
"o XXXX o",
"o. XX .o",
"oo. .oo",
"oooooooo"
};
/* XPM */
static char const *button_on[] = {
/* columns rows colors chars-per-pixel */
"8 8 3 1",
" c black",
". c green",
"X c None",
/* pixels */
"XXXXXXXX",
"XX XX",
"X .. X",
"X .... X",
"X .... X",
"X .. X",
"XX XX",
"XXXXXXXX"
};
/* XPM */
static char const * axis_none_xpm[] = {
"24 8 3 1",
" c None",
". c #000000",
"+ c #808080",
" ",
" .++++++++++++++++++. ",
" .+ . .+. ",
" + . . . + ",
" + . . . + ",
" .+. . +. ",
" .++++++++++++++++++. ",
" "};
/* XPM */
static char const * axis_off_xpm[] = {
"24 8 4 1",
" c None",
". c #808080",
"+ c #000000",
"@ c #FFFFFF",
" ",
" .++++++++++++++++++. ",
" .+@@@@@@@@@@@@@@@@@@+. ",
" +@@@@@@@@@@@@@@@@@@@@+ ",
" +@@@@@@@@@@@@@@@@@@@@+ ",
" .+@@@@@@@@@@@@@@@@@@+. ",
" .++++++++++++++++++. ",
" "};
/* XPM */
static char const * axis_on_xpm[] = {
"24 8 3 1",
" c None",
". c #000000",
"+ c #00FF00",
" ",
" .................... ",
" ..++++++++++++++++++.. ",
" .++++++++++++++++++++. ",
" .++++++++++++++++++++. ",
" ..++++++++++++++++++.. ",
" .................... ",
" "};
using Inkscape::InputDevice;
namespace Inkscape {
namespace UI {
namespace Dialog {
{
public:
DeviceModelColumns() { add(toggler), add(expander), add(description); add(thumbnail); add(device); add(mode); }
};
{
}
return mapping;
}
{
}
return mapping;
}
class InputDialogImpl : public InputDialog {
public:
virtual ~InputDialogImpl() {}
private:
{
public:
ConfPanel();
~ConfPanel();
{
public:
virtual ~Blink();
};
static void commitCellModeChange(Glib::ustring const &path, Glib::ustring const &newText, Glib::RefPtr<Gtk::TreeStore> store);
void saveSettings();
void useExtToggled();
};
static DeviceModelColumns &getCols();
void linkComboChanged();
void resyncToSelection();
static void updateDeviceLinks(Glib::RefPtr<InputDevice const> device, Gtk::TreeIter tabletIter, Glib::RefPtr<Gtk::TreeView> tree);
}; // class InputDialogImpl
{
static DeviceModelColumns cols;
return cols;
}
{
}
return pix;
}
// Now that we've defined the *Impl class, we can do the method to aquire one.
{
return *dialog;
}
InputDialog(),
lastDevnameSeen(""),
tabletIter(),
frame2(),
testFrame(_("Test Area")),
treeScroller(),
splitter(),
split2(),
linkCombo(),
topHolder(),
testDetector(),
cfgPanel()
{
{
col++;
if (col > 7) {
col = 0;
row++;
}
}
col = 0;
col++;
if (col > 3) {
col = 0;
row++;
}
}
}
int rowNum = 0;
rowNum++;
linkCombo.set_sensitive(false);
linkConnection = linkCombo.signal_changed().connect(sigc::mem_fun(*this, &InputDialogImpl::linkComboChanged));
rowNum++;
rowNum++;
/*
lbl = Gtk::manage(new Gtk::Label(_("Actual axes count:")));
devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
::Gtk::FILL,
::Gtk::SHRINK);
devDetails.attach(axesCombo, 1, 2, rowNum, rowNum + 1,
::Gtk::SHRINK,
::Gtk::SHRINK);
rowNum++;
*/
rowNum++;
}
rowNum++;
/*
lbl = Gtk::manage(new Gtk::Label(_("Actual button count:")));
devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
::Gtk::FILL,
::Gtk::SHRINK);
devDetails.attach(buttonCombo, 1, 2, rowNum, rowNum + 1,
::Gtk::SHRINK,
::Gtk::SHRINK);
rowNum++;
*/
rowNum++;
// void gdk_input_set_extension_events (GdkWindow *window,
// gint mask,
// GdkExtensionMode mode);
testDetector.add_events(Gdk::POINTER_MOTION_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK |Gdk::PROXIMITY_IN_MASK|Gdk::PROXIMITY_OUT_MASK|Gdk::SCROLL_MASK);
rowNum++;
devDetails.set_sensitive(false);
// gnome-dev-mouse-optical
// input-mouse
// input-tablet
// mouse
//Add the TreeView's view columns:
tree.set_headers_visible(false);
tree.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &InputDialogImpl::resyncToSelection));
Inkscape::DeviceManager::getManager().signalDeviceChanged().connect(sigc::mem_fun(*this, &InputDialogImpl::handleDeviceChange));
Inkscape::DeviceManager::getManager().signalAxesChanged().connect(sigc::mem_fun(*this, &InputDialogImpl::updateDeviceAxes));
Inkscape::DeviceManager::getManager().signalButtonsChanged().connect(sigc::mem_fun(*this, &InputDialogImpl::updateDeviceButtons));
Inkscape::DeviceManager::getManager().signalLinkChanged().connect(sigc::bind(sigc::ptr_fun(&InputDialogImpl::updateDeviceLinks), tabletIter, treePtr));
tree.expand_all();
}
class TabletTmp {
public:
TabletTmp() {}
};
{
bool match = true;
while ( match ) {
match = false;
break;
}
}
if (match) {
pos++;
}
} else {
match = false;
}
}
}
return result;
}
{
std::list<Glib::RefPtr<InputDevice const> > devList = Inkscape::DeviceManager::getManager().getDevices();
// Let's make some tablets!!!
// Phase 1 - figure out which tablets are present
for ( std::list<Glib::RefPtr<InputDevice const> >::iterator it = devList.begin(); it != devList.end(); ++it ) {
if ( dev ) {
}
}
} else {
g_warning("Null device in list");
}
}
// Phase 2 - build a UI for the present devices
// Check to see if we can derive one
for ( std::list<Glib::RefPtr<InputDevice const> >::iterator it2 = it->devices.begin(); it2 != it->devices.end(); ++it2 ) {
}
}
}
// Check if there is an eraser we can link to a pen
for ( std::list<Glib::RefPtr<InputDevice const> >::iterator it2 = it->devices.begin(); it2 != it->devices.end(); ++it2 ) {
for ( std::list<Glib::RefPtr<InputDevice const> >::iterator it3 = it->devices.begin(); it3 != it->devices.end(); ++it3 ) {
break; // only check the first eraser... for now
}
break; // only check the first pen... for now
}
}
}
for ( std::list<Glib::RefPtr<InputDevice const> >::iterator it2 = it->devices.begin(); it2 != it->devices.end(); ++it2 ) {
case GDK_SOURCE_MOUSE:
break;
case GDK_SOURCE_PEN:
} else {
}
break;
case GDK_SOURCE_CURSOR:
break;
case GDK_SOURCE_ERASER:
break;
default:
; // nothing
}
}
}
for ( std::list<Glib::RefPtr<InputDevice const> >::iterator it = devList.begin(); it != devList.end(); ++it ) {
}
}
} else {
g_warning("No devices found");
}
}
tabletIter(),
treeScroller(),
watcher(*this),
useExt(_("_Use pressure-sensitive tablet (requires restart)"), true),
save(_("_Save"), true)
{
public :
};
//Add the TreeView's view columns:
{
if (col) {
}
}
{
rendr->property_has_entry() = false;
if (col) {
rendr->property_editable() = true;
}
}
tree.set_headers_visible(false);
Inkscape::DeviceManager::getManager().signalLinkChanged().connect(sigc::bind(sigc::ptr_fun(&InputDialogImpl::updateDeviceLinks), tabletIter, treePtr));
tree.expand_all();
}
{
}
void InputDialogImpl::ConfPanel::setModeCellString(Gtk::CellRenderer *rndr, Gtk::TreeIter const &iter)
{
if (iter) {
if (combo) {
} else {
}
}
}
}
void InputDialogImpl::ConfPanel::commitCellModeChange(Glib::ustring const &path, Glib::ustring const &newText, Glib::RefPtr<Gtk::TreeStore> store)
{
if (iter) {
}
}
}
void InputDialogImpl::ConfPanel::setCellStateToggle(Gtk::CellRenderer *rndr, Gtk::TreeIter const &iter)
{
if (iter) {
if (toggle) {
if (dev) {
} else {
toggle->set_active(false);
}
}
}
}
void InputDialogImpl::ConfPanel::commitCellStateChange(Glib::ustring const &path, Glib::RefPtr<Gtk::TreeStore> store)
{
if (iter) {
if (dev) {
} else {
}
}
}
}
{
}
{
if (active) {
// As a work-around for a common problem, enable tablet toggles on the calligraphic tool.
// Covered in Launchpad bug #196195.
}
}
}
{
}
{
}
{
}
{
// g_message("OUCH!!!! for %p hits %s", &device, device->getId().c_str());
for (std::vector<Glib::RefPtr<Gtk::TreeStore> >::iterator it = stores.begin(); it != stores.end(); ++it) {
&deviceIter) );
if ( deviceIter ) {
}
}
}
}
{
}
}
}
}
{
}
}
}
}
{
bool stop = false;
if ( result ) {
}
stop = true;
}
return stop;
}
{
bool stop = false;
if ( result ) {
}
stop = true;
}
return stop;
}
void InputDialogImpl::updateDeviceLinks(Glib::RefPtr<InputDevice const> device, Gtk::TreeIter tabletIter, Glib::RefPtr<Gtk::TreeView> tree)
{
// g_message("Links!!!! for %p hits [%s] with link of [%s]", &device, device->getId().c_str(), device->getLink().c_str());
&deviceIter) );
if ( deviceIter ) {
// Found the device concerned. Can proceed.
// is now unlinked
// g_message("Item %s is unlinked", device->getId().c_str());
// Not the child of the tablet. move on up
}
}
} else {
// is linking
// Simple case. Not already linked
&linkIter) );
if ( linkIter ) {
}
}
}
}
}
}
}
void InputDialogImpl::linkComboChanged() {
if (iter) {
if ( dev ) {
if ( linkCombo.get_active_row_number() == 0 ) {
// It is the "None" entry
} else {
std::list<Glib::RefPtr<InputDevice const> > devList = Inkscape::DeviceManager::getManager().getDevices();
for ( std::list<Glib::RefPtr<InputDevice const> >::const_iterator it = devList.begin(); it != devList.end(); ++it ) {
break;
}
}
}
}
}
}
void InputDialogImpl::resyncToSelection() {
bool clear = true;
if (iter) {
if ( dev ) {
devDetails.set_sensitive(true);
linkCombo.set_active(0);
std::list<Glib::RefPtr<InputDevice const> > devList = Inkscape::DeviceManager::getManager().getDevices();
for ( std::list<Glib::RefPtr<InputDevice const> >::const_iterator it = devList.begin(); it != devList.end(); ++it ) {
}
}
}
linkCombo.set_sensitive(true);
} else {
linkCombo.set_sensitive(false);
}
clear = false;
}
}
if (clear) {
}
}
void InputDialogImpl::setupValueAndCombo( gint reported, gint actual, Gtk::Label& label, Gtk::ComboBoxText& combo )
{
combo.clear_items();
}
}
}
{
if ( i == hotButton ) {
} else {
}
} else {
}
}
}
{
{
if (iter) {
dev = 0;
}
}
}
case 0:
case 1:
axesValues[i].set_sensitive(false);
}
break;
case 2:
axesValues[i].set_sensitive(true);
axesValues[i].set_sensitive(true);
axesValues[i].set_fraction( (axesMap[key][i].second- dev->axes[i].min) / (dev->axes[i].max - dev->axes[i].min) );
}
}
break;
case 3:
axesValues[i].set_sensitive(true);
axesValues[i].set_sensitive(true);
axesValues[i].set_fraction( (axesMap[key][i].second- dev->axes[i].min) / (dev->axes[i].max - dev->axes[i].min) );
}
}
}
} else {
}
}
if ( !dev ) {
axesValues[i].set_sensitive(false);
}
}
}
void InputDialogImpl::mapAxesValues( Glib::ustring const& key, guint numAxes, gdouble const * axes, GdkDevice* dev )
{
// 0 == new, 1 == set value, 2 == changed value, 3 == active
case 0:
{
}
break;
case 1:
{
// g_message("Axis %d changed on %s]", axisNum, key.c_str());
}
}
break;
case 2:
{
}
}
break;
case 3:
{
} else {
}
}
}
}
}
// std::map<Glib::ustring, std::map<guint, std::pair<guint, gdouble> > > axesMap;
}
{
case GDK_SOURCE_MOUSE:
key = "M:";
break;
case GDK_SOURCE_CURSOR:
key = "C:";
break;
case GDK_SOURCE_PEN:
key = "P:";
break;
case GDK_SOURCE_ERASER:
key = "E:";
break;
default:
key = "?:";
}
return key;
}
{
int modmod = 0;
case GDK_KEY_PRESS:
case GDK_KEY_RELEASE:
{
// g_message("%d KEY state:0x%08x 0x%04x [%s]", keyEvt->type, keyEvt->state, keyEvt->keyval, name);
}
break;
case GDK_BUTTON_PRESS:
modmod = 1;
// fallthrough
case GDK_BUTTON_RELEASE:
{
// g_message("New button found for %s = %d", key.c_str(), btnEvt->button);
}
}
// g_message("%d BTN state:0x%08x %c %4d [%s] dev:%p [%s] ",
// btnEvt->type, btnEvt->state,
// (modmod ? '+':'-'),
// btnEvt->button, name, btnEvt->device,
// (btnEvt->device ? btnEvt->device->name : "null")
// );
}
break;
case GDK_MOTION_NOTIFY:
{
}
// g_message("%d MOV state:0x%08x [%s] dev:%p [%s] %3.2f %3.2f %3.2f %3.2f %3.2f %3.2f", btnMtn->type, btnMtn->state,
// name, btnMtn->device,
// (btnMtn->device ? btnMtn->device->name : "null"),
// ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 0)) ? btnMtn->axes[0]:0),
// ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 1)) ? btnMtn->axes[1]:0),
// ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 2)) ? btnMtn->axes[2]:0),
// ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 3)) ? btnMtn->axes[3]:0),
// ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 4)) ? btnMtn->axes[4]:0),
// ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 5)) ? btnMtn->axes[5]:0)
// );
}
break;
default:
;// nothing
}
switch (source) {
case GDK_SOURCE_MOUSE:
{
}
break;
case GDK_SOURCE_CURSOR:
{
// g_message("flip to cursor");
}
break;
case GDK_SOURCE_PEN:
{
if (devName == _("pad")) {
// g_message("flip to pad");
} else {
// g_message("flip to pen");
}
}
break;
case GDK_SOURCE_ERASER:
{
// g_message("flip to eraser");
}
break;
// default:
// g_message("gurgle");
}
}
return false;
}
} // end namespace Inkscape
} // end namespace UI
} // end namespace Dialog
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :