From kde-commits Thu Mar 31 21:14:16 2011 From: =?utf-8?q?J=C3=B6rg_Ehrichs?= Date: Thu, 31 Mar 2011 21:14:16 +0000 To: kde-commits Subject: =?utf-8?q?=5Bwacomtablet=5D_src/kcmodule=3A_pad/touch_mapping_ta?= Message-Id: <20110331211416.9FCA3A60AE () git ! kde ! org> X-MARC-Message: https://marc.info/?l=kde-commits&m=130160611101124 Git commit 07f7f48ed6206914007d996f2e1aed17b1bb2bf7 by Jörg Ehrichs. Committed on 31/03/2011 at 21:45. Pushed by jehrichs into branch 'master'. pad/touch mapping tab added. First version of graphical tablet representation for easy calibration M +1 -0 src/kcmodule/CMakeLists.txt M +87 -148 src/kcmodule/padmapping.cpp M +5 -4 src/kcmodule/padmapping.h M +218 -347 src/kcmodule/padmapping.ui A +382 -0 src/kcmodule/tabletarea.cpp [License: GPL (v2+)] A +79 -0 src/kcmodule/tabletarea.h [License: GPL (v2+)] M +12 -0 src/kcmodule/tabletwidget.cpp M +1 -0 src/kcmodule/tabletwidget.h http://commits.kde.org/wacomtablet/07f7f48ed6206914007d996f2e1aed17b1bb2bf7 diff --git a/src/kcmodule/CMakeLists.txt b/src/kcmodule/CMakeLists.txt index 970764b..946a76f 100644 --- a/src/kcmodule/CMakeLists.txt +++ b/src/kcmodule/CMakeLists.txt @@ -14,6 +14,7 @@ set( kcm_tablet_SRCS tabletwidget.cpp calibrationdialog.cpp touchwidget.cpp + tabletarea.cpp ) kde4_add_ui_files( kcm_tablet_SRCS diff --git a/src/kcmodule/padmapping.cpp b/src/kcmodule/padmapping.cpp index be575da..dc89e1d 100644 --- a/src/kcmodule/padmapping.cpp +++ b/src/kcmodule/padmapping.cpp @@ -21,6 +21,8 @@ #include "profilemanagement.h" #include "calibrationdialog.h" +#include "tabletarea.h" + //KDE includes #include #include @@ -61,74 +63,74 @@ PadMapping::~PadMapping() delete m_ui; } -void PadMapping::saveToProfile() +void PadMapping::setTool( int tool ) { - // save current calibration area to the right temp rect - if( m_ui->toolCombobox->currentIndex() == 0 ) { - m_stylusArea.setX( m_ui->topX->value() ); - m_stylusArea.setY( m_ui->topY->value() ); - m_stylusArea.setWidth( m_ui->bottomX->value() ); - m_stylusArea.setHeight( m_ui->bottomY->value() ); + m_tool = tool; + + m_tabletArea = new TabletArea(); + + QString toolName; + if( tool == 0 ) { + QDBusReply stylusName = m_deviceInterface->call( QLatin1String( "stylusName" ) ); + toolName = stylusName.value(); } - else { - m_touchArea.setX( m_ui->topX->value() ); - m_touchArea.setY( m_ui->topY->value() ); - m_touchArea.setWidth( m_ui->bottomX->value() ); - m_touchArea.setHeight( m_ui->bottomY->value() ); + else if( tool == 1 ) { + QDBusReply touchName = m_deviceInterface->call( QLatin1String( "touchName" ) ); + toolName = touchName.value(); } - // read in from stylus. - // values for stylus/eraser/touch will be the same - KConfigGroup stylusConfig = m_profileManagement->configGroup( QLatin1String( "stylus" ) ); - KConfigGroup eraserConfig = m_profileManagement->configGroup( QLatin1String( "eraser" ) ); + m_tabletArea->setTool( toolName ); + m_ui->tabletAreaBox->layout()->addWidget( m_tabletArea ); - stylusConfig.writeEntry( QLatin1String( "Rotate" ), m_ui->rotationComboBox->currentIndex() ); - eraserConfig.writeEntry( QLatin1String( "Rotate" ), m_ui->rotationComboBox->currentIndex() ); + connect( m_tabletArea, SIGNAL( selectedArea( QString ) ), this, SLOT( profileChanged() ) ); +} - if( !m_ui->screenComboBox->currentText().isEmpty() ) { - stylusConfig.writeEntry( QLatin1String( "MapToOutput" ), m_ui->screenComboBox->currentText() ); - eraserConfig.writeEntry( QLatin1String( "MapToOutput" ), m_ui->screenComboBox->currentText() ); - } +void PadMapping::saveToProfile() +{ + if( m_tool == 0 ) { + // read in from stylus. + // values for stylus/eraser/touch will be the same + KConfigGroup stylusConfig = m_profileManagement->configGroup( QLatin1String( "stylus" ) ); + KConfigGroup eraserConfig = m_profileManagement->configGroup( QLatin1String( "eraser" ) ); - if( m_ui->xrandrRotationCheckBox->isChecked() ) { - stylusConfig.writeEntry( QLatin1String( "RotateWithScreen" ), "true" ); - eraserConfig.writeEntry( QLatin1String( "RotateWithScreen" ), "true" ); - } - else { - stylusConfig.writeEntry( QLatin1String( "RotateWithScreen" ), "false" ); - eraserConfig.writeEntry( QLatin1String( "RotateWithScreen" ), "false" ); - } + stylusConfig.writeEntry( QLatin1String( "Rotate" ), m_ui->rotationComboBox->currentIndex() ); + eraserConfig.writeEntry( QLatin1String( "Rotate" ), m_ui->rotationComboBox->currentIndex() ); - if( m_ui->workingAreaBox->isChecked() ) { - stylusConfig.writeEntry( QLatin1String( "0ChangeArea" ), "true" ); - eraserConfig.writeEntry( QLatin1String( "0ChangeArea" ), "true" ); - } - else { - stylusConfig.writeEntry( QLatin1String( "0ChangeArea" ), "false" ); - eraserConfig.writeEntry( QLatin1String( "0ChangeArea" ), "false" ); - } + if( m_ui->xrandrRotationCheckBox->isChecked() ) { + stylusConfig.writeEntry( QLatin1String( "RotateWithScreen" ), "true" ); + eraserConfig.writeEntry( QLatin1String( "RotateWithScreen" ), "true" ); + } + else { + stylusConfig.writeEntry( QLatin1String( "RotateWithScreen" ), "false" ); + eraserConfig.writeEntry( QLatin1String( "RotateWithScreen" ), "false" ); + } - stylusConfig.writeEntry( QLatin1String( "Area" ), QString::fromLatin1( "%1 %2 %3 %4" ) - .arg( m_stylusArea.x() ).arg( m_stylusArea.y() ) - .arg( m_stylusArea.width() ).arg( m_stylusArea.height() ) ); - eraserConfig.writeEntry( QLatin1String( "Area" ), QString::fromLatin1( "%1 %2 %3 %4" ) - .arg( m_stylusArea.x() ).arg( m_stylusArea.y() ) - .arg( m_stylusArea.width() ).arg( m_stylusArea.height() ) ); + if( !m_ui->screenComboBox->currentText().isEmpty() || m_ui->screenComboBox->currentIndex() != 0 ) { + stylusConfig.writeEntry( QLatin1String( "MapToOutput" ), m_ui->screenComboBox->currentText() ); + eraserConfig.writeEntry( QLatin1String( "MapToOutput" ), m_ui->screenComboBox->currentText() ); + } - stylusConfig.sync(); - eraserConfig.sync(); + if( m_ui->fullTablet->isChecked() ) { + stylusConfig.writeEntry( QLatin1String( "0ChangeArea" ), "true" ); + eraserConfig.writeEntry( QLatin1String( "0ChangeArea" ), "true" ); + } + else { + stylusConfig.writeEntry( QLatin1String( "0ChangeArea" ), "false" ); + eraserConfig.writeEntry( QLatin1String( "0ChangeArea" ), "false" ); + } - // if we have a touch device, update these values too - QDBusReply touchName = m_deviceInterface->call( QLatin1String( "touchName" ) ); + stylusConfig.writeEntry( QLatin1String( "Area" ), m_tabletArea->getSelectedAreaString() ); + eraserConfig.writeEntry( QLatin1String( "Area" ), m_tabletArea->getSelectedAreaString() ); - QString validName = touchName.value(); - if( !validName.isEmpty() ) { + stylusConfig.sync(); + eraserConfig.sync(); + } + else if( m_tool == 1 ) { + // read in from stylus. + // values for stylus/eraser/touch will be the same KConfigGroup touchConfig = m_profileManagement->configGroup( QLatin1String( "touch" ) ); - touchConfig.writeEntry( QLatin1String( "Rotate" ), m_ui->rotationComboBox->currentIndex() ); - if( !m_ui->screenComboBox->currentText().isEmpty() ) { - touchConfig.writeEntry( QLatin1String( "MapToOutput" ), m_ui->screenComboBox->currentText() ); - } + touchConfig.writeEntry( QLatin1String( "Rotate" ), m_ui->rotationComboBox->currentIndex() ); if( m_ui->xrandrRotationCheckBox->isChecked() ) { touchConfig.writeEntry( QLatin1String( "RotateWithScreen" ), "true" ); @@ -137,16 +139,18 @@ void PadMapping::saveToProfile() touchConfig.writeEntry( QLatin1String( "RotateWithScreen" ), "false" ); } - if( m_ui->workingAreaBox->isChecked() ) { + if( !m_ui->screenComboBox->currentText().isEmpty() || m_ui->screenComboBox->currentIndex() != 0 ) { + touchConfig.writeEntry( QLatin1String( "MapToOutput" ), m_ui->screenComboBox->currentText() ); + } + + if( m_ui->fullTablet->isChecked() ) { touchConfig.writeEntry( QLatin1String( "0ChangeArea" ), "true" ); } else { touchConfig.writeEntry( QLatin1String( "0ChangeArea" ), "false" ); } - touchConfig.writeEntry( QLatin1String( "Area" ), QString::fromLatin1( "%1 %2 %3 %4" ) - .arg( m_touchArea.x() ).arg( m_touchArea.y() ) - .arg( m_touchArea.width() ).arg( m_touchArea.height() ) ); + touchConfig.writeEntry( QLatin1String( "Area" ), m_tabletArea->getSelectedAreaString() ); touchConfig.sync(); } @@ -155,63 +159,32 @@ void PadMapping::saveToProfile() void PadMapping::loadFromProfile() { // read in from stylus. - // values for stylus/eraser/touch will be the same - KConfigGroup stylusConfig = m_profileManagement->configGroup( QLatin1String( "stylus" ) ); - - m_ui->rotationComboBox->setCurrentIndex( stylusConfig.readEntry( QLatin1String( "Rotate" ) ).toInt() ); + // values for stylus/eraser will be the same + KConfigGroup config; - if( stylusConfig.readEntry( QLatin1String( "RotateWithScreen" ) ) == QLatin1String( "true" ) ) { - m_ui->xrandrRotationCheckBox->setChecked( true ); + if( m_tool == 0 ) { + config = m_profileManagement->configGroup( QLatin1String( "stylus" ) ); } - - int index = m_ui->screenComboBox->findText( stylusConfig.readEntry( QLatin1String( "MapToOutput" ) ) ); - m_ui->screenComboBox->setCurrentIndex( index ); - - - if( stylusConfig.readEntry( QLatin1String( "0ChangeArea" ) ) == QLatin1String( "true" ) ) { - m_ui->workingAreaBox->setChecked( true ); + else { + config = m_profileManagement->configGroup( QLatin1String( "touch" ) ); } - // check if we have a touch tool available - // this means we want to calibrate the tablet area in two different ways - QDBusReply touchName = m_deviceInterface->call( QLatin1String( "touchName" ) ); - - QString validName = touchName.value(); - if( !validName.isEmpty() ) { - KConfigGroup touchConfig = m_profileManagement->configGroup( QLatin1String( "touch" ) ); - - QString workingArea = touchConfig.readEntry( QLatin1String( "Area" ) ); - QStringList waList = workingArea.split( QLatin1String( " " ) ); - - if( waList.size() != 4 ) { - kDebug() << "Error while parsing touch Area settings. Entry must have 4 ints seperated by a space. For example: 0 0 100 100"; - return; - } + m_ui->rotationComboBox->setCurrentIndex( config.readEntry( QLatin1String( "Rotate" ) ).toInt() ); - m_touchArea.setX( waList.at( 0 ).toInt() ); - m_touchArea.setY( waList.at( 1 ).toInt() ); - m_touchArea.setWidth( waList.at( 2 ).toInt() ); - m_touchArea.setHeight( waList.at( 3 ).toInt() ); + if( config.readEntry( QLatin1String( "RotateWithScreen" ) ) == QLatin1String( "true" ) ) { + m_ui->xrandrRotationCheckBox->setChecked( true ); } - QString workingArea = stylusConfig.readEntry( QLatin1String( "Area" ) ); - QStringList waList = workingArea.split( QLatin1String( " " ) ); + int index = m_ui->screenComboBox->findText( config.readEntry( QLatin1String( "MapToOutput" ) ) ); + m_ui->screenComboBox->setCurrentIndex( index ); - if( waList.size() != 4 ) { - kDebug() << "Error while parsing Area settings. Entry must have 4 ints seperated by a space. For example: 0 0 100 100"; - return; + if( config.readEntry( QLatin1String( "0ChangeArea" ) ) == QLatin1String( "true" ) ) { + m_ui->partOfTablet->setChecked( true ); } - m_stylusArea.setX( waList.at( 0 ).toInt() ); - m_stylusArea.setY( waList.at( 1 ).toInt() ); - m_stylusArea.setWidth( waList.at( 2 ).toInt() ); - m_stylusArea.setHeight( waList.at( 3 ).toInt() ); + QString workingArea = config.readEntry( QLatin1String( "Area" ) ); - // default to stylus/areaser area - m_ui->topX->setValue( m_stylusArea.x() ); - m_ui->topY->setValue( m_stylusArea.y() ); - m_ui->bottomX->setValue( m_stylusArea.width() ); - m_ui->bottomY->setValue( m_stylusArea.height() ); + m_tabletArea->setSelection( workingArea ); } void PadMapping::profileChanged() @@ -232,17 +205,6 @@ void PadMapping::reloadWidget() } m_ui->screenComboBox->blockSignals( false ); XRRFreeScreenResources( sr ); - - // check if the connected tabled has touch features - // hides the tool selection box if no touch is available - // helps to reduce the ui clutter for "normal" tablets - QDBusReply touchName = m_deviceInterface->call( QLatin1String( "touchName" ) ); - - QString validName = touchName.value(); - if( validName.isEmpty() ) { - m_ui->toolLabel->hide(); - m_ui->toolCombobox->hide(); - } } void PadMapping::showCalibrationDialog() @@ -263,13 +225,14 @@ void PadMapping::showCalibrationDialog() } QString toolName; - if( m_ui->toolCombobox->currentIndex() == 0 ) { + + if( m_tool == 0 ) { QDBusReply stylusName = m_deviceInterface->call( QLatin1String( "stylusName" ) ); toolName = stylusName.value(); } else { - QDBusReply touchName = m_deviceInterface->call( QLatin1String( "touchName" ) ); - toolName = touchName.value(); + QDBusReply stylusName = m_deviceInterface->call( QLatin1String( "touchName" ) ); + toolName = stylusName.value(); } CalibrationDialog cdlg( toolName ); @@ -277,11 +240,13 @@ void PadMapping::showCalibrationDialog() cdlg.exec(); QRect newCalibration = cdlg.calibratedArea(); - m_ui->topX->setValue( newCalibration.x() ); - m_ui->topY->setValue( newCalibration.y() ); - m_ui->bottomX->setValue( newCalibration.width() ); - m_ui->bottomY->setValue( newCalibration.height() ); + QString area = QString::fromLatin1( "%1 %2 %3 %4" ) + .arg( newCalibration.x() ) + .arg( newCalibration.y() ) + .arg( newCalibration.width() ) + .arg( newCalibration.height() ); + m_tabletArea->setSelection( area ); if( oldstate ) { config.writeEntry( QLatin1String( "Enabled" ), true ); @@ -293,29 +258,3 @@ void PadMapping::showCalibrationDialog() QDBusConnection::sessionBus().send( message ); } } - -void PadMapping::switchCalibrationTool() -{ - if( m_ui->toolCombobox->currentIndex() == 1 ) { - m_stylusArea.setX( m_ui->topX->value() ); - m_stylusArea.setY( m_ui->topY->value() ); - m_stylusArea.setWidth( m_ui->bottomX->value() ); - m_stylusArea.setHeight( m_ui->bottomY->value() ); - - m_ui->topX->setValue( m_touchArea.x()); - m_ui->topY->setValue( m_touchArea.y()); - m_ui->bottomX->setValue( m_touchArea.width()); - m_ui->bottomY->setValue( m_touchArea.height()); - } - else { - m_touchArea.setX( m_ui->topX->value() ); - m_touchArea.setY( m_ui->topY->value() ); - m_touchArea.setWidth( m_ui->bottomX->value() ); - m_touchArea.setHeight( m_ui->bottomY->value() ); - - m_ui->topX->setValue( m_stylusArea.x()); - m_ui->topY->setValue( m_stylusArea.y()); - m_ui->bottomX->setValue( m_stylusArea.width()); - m_ui->bottomY->setValue( m_stylusArea.height()); - } -} diff --git a/src/kcmodule/padmapping.h b/src/kcmodule/padmapping.h index 0a1dd52..e3de104 100644 --- a/src/kcmodule/padmapping.h +++ b/src/kcmodule/padmapping.h @@ -31,6 +31,7 @@ class QDBusInterface; namespace Wacom { class ProfileManagement; +class TabletArea; /** * This class implements the widget to change the pad mapping @@ -55,6 +56,8 @@ public: */ ~PadMapping(); + void setTool(int tool); + /** * Saves all values to the current profile */ @@ -85,8 +88,6 @@ public slots: */ void showCalibrationDialog(); - void switchCalibrationTool(); - signals: /** * Used to inform the main widget that unsaved changes in the current profile are available. @@ -98,8 +99,8 @@ private: QDBusInterface *m_deviceInterface; /**< Connection to the tablet daemon DBus /Device Interface */ ProfileManagement *m_profileManagement; /**< Handler for the profile config connection */ - QRect m_stylusArea; /**< Calibrated area for the stylus/eraser tool */ - QRect m_touchArea; /**< Calibrated area for the touch tool */ + int m_tool; + TabletArea *m_tabletArea; }; } diff --git a/src/kcmodule/padmapping.ui b/src/kcmodule/padmapping.ui index 3546be2..78cb426 100644 --- a/src/kcmodule/padmapping.ui +++ b/src/kcmodule/padmapping.ui @@ -6,8 +6,8 @@ 0 0 - 375 - 348 + 413 + 342 @@ -16,302 +16,206 @@ - + - - - Orientation - - - - - - - - Rotation: - - - rotationComboBox - - - - - - - Select the rotation of the tablet device. - - - - none - - - - - couter clockwise - - - - - clockwise - - - - - half - - - - - - - - If enabled the tablet is automatically rotated together with the screen - - - Rotate tablet with screen - - - - - - - Map to output: - - - screenComboBox - - - - - - - Select the XRandR display which will be used to map the tablet area on it. - - - - - - - - - - - - If enabled, the working area can be changed. - If disabled the default values from xorg are used - - - Adjust Working Area - - - true - - - - - - 10 - - - - - Select Tool: - - - toolCombobox - - - - - - - - Stylus/Eraser - - - - - Touch - - - - - - - - Opens a fullscreen window to calibrate the tablet. - - - Calibrate Tablet - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - X-Coordinate of the top left point - - - -99999 + + + + + + + Orientation + + + + + + Rotation: - - 99999 + + rotationComboBox - - + + - Y-Coordinate of the top right point - - - -99999 - - - 99999 + Select the rotation of the tablet device. + + + none + + + + + couter clockwise + + + + + clockwise + + + + + half + + - - - - Qt::Vertical + + + + If enabled the tablet is automatically rotated together with the screen - - - 20 - 40 - + + Rotate with screen - + - - - - Qt::Vertical + + + + + + + Screen Area + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + 10 + + + -1 + + + 8 + + + + + Map to output - - - 20 - 40 - + + true - + - - + + - Height of the used tablet area - - - -99999 - - - 99999 + Select the XRandR display which will be used to map the tablet area on it. + + + --- + + - - - - Qt::Horizontal - - - - 40 - 20 - + + + + Part of the Screen - + - - - - Width of the tablet area - - - 99999 + + + + + + + Tablet Area + + + + + + Full tablet - - 0 + + true - - - - QFrame::Box - + + - Working -Area + Part of the Tablet - - Qt::AlignCenter + + + + + + Force Proportions - - - - - Qt::Horizontal - - - - 161 - 147 - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - + + + + + + + + Opens a fullscreen window to calibrate the tablet. + + + Calibrate + + + + + + + + + + + Tablet Area + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 59 + + + - KIntSpinBox - QSpinBox -
knuminput.h
-
- KPushButton QPushButton
kpushbutton.h
@@ -326,177 +230,145 @@ Area rotationComboBox - currentIndexChanged(int) + currentIndexChanged(QString) PadMapping profileChanged() - 231 - 56 + 78 + 44 - 264 - 19 + 1 + 39 - topY - valueChanged(int) + xrandrRotationCheckBox + toggled(bool) PadMapping profileChanged() - 74 - 235 + 25 + 79 - 254 - 61 + 2 + 80 - bottomY - valueChanged(int) + radioButton + toggled(bool) PadMapping profileChanged() - 272 - 303 + 27 + 139 - 223 - 120 + 2 + 139 - bottomX - valueChanged(int) + radioButton_2 + toggled(bool) PadMapping profileChanged() - 206 - 330 + 29 + 171 - 87 - 110 + 1 + 172 - topX - valueChanged(int) + screenComboBox + currentIndexChanged(int) PadMapping profileChanged() - 140 - 208 - - - 40 - 77 - - - - - calibrateButton - clicked() - PadMapping - showCalibrationDialog() - - - 320 - 178 + 166 + 138 - 84 - 306 + 0 + 118 - screenComboBox - currentIndexChanged(QString) + fullTablet + toggled(bool) PadMapping profileChanged() - 179 - 111 + 22 + 238 2 - 47 + 237 - workingAreaBox - clicked() + partOfTablet + toggled(bool) PadMapping profileChanged() - 185 - 165 + 26 + 261 - 374 - 78 + 3 + 267 - xrandrRotationCheckBox - clicked() + checkBox + toggled(bool) PadMapping profileChanged() - 244 - 83 - - - 374 - 44 - - - - - toolCombobox - currentIndexChanged(int) - PadMapping - switchCalibrationTool() - - - 127 - 168 + 26 + 287 2 - 167 + 302 - toolCombobox - currentIndexChanged(int) + calibrateButton + clicked() PadMapping - profileChanged() + showCalibrationDialog() - 117 - 155 + 47 + 319 - 2 - 124 + -2 + 336 @@ -504,6 +376,5 @@ Area profileChanged() showCalibrationDialog() - switchCalibrationTool() diff --git a/src/kcmodule/tabletarea.cpp b/src/kcmodule/tabletarea.cpp new file mode 100644 index 0000000..cb629e7 --- /dev/null +++ b/src/kcmodule/tabletarea.cpp @@ -0,0 +1,382 @@ +/* + * Copyright 2011 Jörg Ehrichs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "tabletarea.h" + +#include +#include +#include +#include +#include + +#include + +#include + +// X11 includes +#include +#include +#include +#include + +using namespace Wacom; + +const qreal handleSize = 6; +const int tabletGap = 20; + +TabletArea::TabletArea( QWidget *parent ) : + QWidget( parent ) +{ + setMouseTracking( true ); + + setMinimumWidth( 300 + 2 * tabletGap ); + setMaximumWidth( 300 + 2 * tabletGap ); +} + +void TabletArea::setTool( QString toolName ) +{ + m_toolName = toolName; + setupWidget(); +} + +QRect TabletArea::getOriginalArea() +{ + return m_origialArea.toRect(); +} + +QString TabletArea::getOriginalAreaString() +{ + int x = ( m_origialArea.x()); + int y = ( m_origialArea.y() ); + int width = m_origialArea.width(); + int height = m_origialArea.height(); + + QString area = QString::fromLatin1( "%1 %2 %3 %4" ).arg( x ).arg( y ).arg( width ).arg( height ); + + return area; +} + +QRect TabletArea::getSelectedArea() +{ + QRect area; + area.setX( m_selectedArea.x() / m_scaling ); + area.setY( m_selectedArea.y() / m_scaling ); + area.setWidth( m_selectedArea.width() / m_scaling ); + area.setHeight( m_selectedArea.height() / m_scaling ); + + return area; +} + +QString TabletArea::getSelectedAreaString() +{ + int x = ( m_selectedArea.x() - tabletGap ) / m_scaling; + int y = ( m_selectedArea.y() - tabletGap ) / m_scaling; + int width = m_selectedArea.width() / m_scaling; + int height = m_selectedArea.height() / m_scaling; + + QString area = QString::fromLatin1( "%1 %2 %3 %4" ).arg( x ).arg( y ).arg( width ).arg( height ); + + return area; +} + +void TabletArea::resetSelection() +{ + m_selectedArea = QRect( rect().x() + tabletGap, + rect().y() + tabletGap, + rect().width() - 2 * tabletGap, + rect().height() - 2 * tabletGap ); + + updateDragHandle(); + update(); +} + +void TabletArea::setSelection( QString area ) +{ + QStringList list = area.split( QLatin1String(" ") ); + + m_selectedArea.setX( list.at( 0 ).toInt() * m_scaling + tabletGap ); + m_selectedArea.setY( list.at( 1 ).toInt() * m_scaling + tabletGap ); + m_selectedArea.setWidth( list.at( 2 ).toInt() * m_scaling ); + m_selectedArea.setHeight( list.at( 3 ).toInt() * m_scaling ); + + updateDragHandle(); + update(); +} + +void TabletArea::paintEvent( QPaintEvent *event ) +{ + Q_UNUSED( event ); + + QPainter painter( this ); + painter.setRenderHint( QPainter::Antialiasing ); + + QPen pen; + pen.setWidth( 1 ); + pen.setColor( Qt::red ); + painter.setPen( pen ); + painter.setBrush( Qt::gray ); + painter.drawRect( m_selectedArea ); + + painter.setPen( Qt::black ); + painter.setBrush( Qt::transparent ); + painter.drawRect( rect().x() + tabletGap, + rect().y() + tabletGap, + rect().width() - 2 * tabletGap, + rect().height() - 2 * tabletGap ); + + painter.setPen( pen ); + + // draw drag handles + painter.setBrush( Qt::red ); + painter.drawRect( m_dragHandleLeft ); + painter.drawRect( m_dragHandleRight ); + painter.drawRect( m_dragHandleTop ); + painter.drawRect( m_dragHandleBottom ); + + // draw area info in the middle + painter.setPen(Qt::black); + painter.drawText(rect().width()/2 - 50, rect().height()/2 -15, getOriginalAreaString()); + painter.setPen(Qt::darkRed); + painter.drawText(rect().width()/2 - 50, rect().height()/2 +15, getSelectedAreaString()); +} + +void TabletArea::mouseMoveEvent( QMouseEvent *event ) +{ + if( !m_dragMode ) { + if( m_dragHandleLeft.contains( event->pos() ) + || m_dragHandleRight.contains( event->pos() ) ) { + + setCursor( Qt::SizeHorCursor ); + + } + else if( m_dragHandleTop.contains( event->pos() ) + || m_dragHandleBottom.contains( event->pos() ) ) { + + setCursor( Qt::SizeVerCursor ); + + } + else { + setCursor( Qt::ArrowCursor ); + } + } + + if( m_dragMode ) { + switch( m_mode ) { + case 1: + if( event->x() > 0 && event->x() < width() ) { + m_selectedArea.setX( event->x() ); + } + break; + case 2: + if( event->x() > 0 && event->x() < width() ) { + + m_selectedArea.setWidth( event->x() - m_selectedArea.x() ); + } + break; + case 3: + if( event->y() > 0 && event->y() < height() ) { + m_selectedArea.setY( event->y() ); + } + break; + case 4: + if( event->y() > 0 && event->y() < height() ) { + qreal newHeight = event->y() - m_selectedArea.y(); + + if( newHeight > m_origialArea.height() * m_scaling ) { + newHeight = m_origialArea.height() * m_scaling; + } + m_selectedArea.setHeight( newHeight ); + } + break; + case 5: + if( event->x() > 0 && event->x() < width() + && event->y() > 0 && event->y() < height() ) { + + qreal newX = m_selectedArea.x() + event->pos().x() - m_dragPoint.x(); + + if( newX >= 0 && newX + m_selectedArea.width() < rect().width() ) { + m_selectedArea.setX( newX ); + m_selectedArea.setWidth( m_selectedArea.width() + event->pos().x() - m_dragPoint.x() ); + } + + qreal newXY = m_selectedArea.y() + event->pos().y() - m_dragPoint.y(); + + if( newXY >= 0 && newXY + m_selectedArea.height() < rect().height() ) { + m_selectedArea.setY( newXY ); + m_selectedArea.setHeight( m_selectedArea.height() + event->pos().y() - m_dragPoint.y() ); + } + m_dragPoint = event->pos(); + } + break; + } + + // cap tablet width / height + if( m_selectedArea.height() > m_origialArea.height() * m_scaling ) { + m_selectedArea.setHeight( m_origialArea.height() * m_scaling ); + } + + if( m_selectedArea.width() > m_origialArea.width() * m_scaling ) { + m_selectedArea.setWidth( m_origialArea.width() * m_scaling ); + } + + updateDragHandle(); + update(); + + emit selectedArea( getSelectedAreaString() ); + } +} + +void TabletArea::mousePressEvent( QMouseEvent *event ) +{ + if( !m_dragMode ) { + m_mode = 0; + if( m_dragHandleLeft.contains( event->pos() ) ) { + m_dragMode = true; + m_mode = 1; + } + else if( m_dragHandleRight.contains( event->pos() ) ) { + m_dragMode = true; + m_mode = 2; + } + else if( m_dragHandleTop.contains( event->pos() ) ) { + m_dragMode = true; + m_mode = 3; + } + else if( m_dragHandleBottom.contains( event->pos() ) ) { + m_dragMode = true; + m_mode = 4; + } + else if( m_selectedArea.contains( event->pos() ) ) { + m_dragMode = true; + m_mode = 5; + setCursor( Qt::SizeAllCursor ); + + m_dragPoint = event->pos(); + } + } +} + +void TabletArea::mouseReleaseEvent( QMouseEvent *event ) +{ + Q_UNUSED(event); + + m_dragMode = false; + m_mode = 0; +} + +void TabletArea::setupWidget() +{ + // original area from xinput + getMaxTabletArea(); + + m_scaling = ( width() - 2 * tabletGap ) / m_origialArea.width(); + + setMaximumHeight( m_origialArea.height() * m_scaling + 2 * tabletGap ); + setMinimumHeight( m_origialArea.height() * m_scaling + 2 * tabletGap ); + + m_selectedArea = QRect( rect().x() + tabletGap, + rect().y() + tabletGap, + rect().width() - 2 * tabletGap, + rect().height() - 2 * tabletGap ); + + updateDragHandle(); + update(); +} + +void TabletArea::updateDragHandle() +{ + m_dragHandleLeft.setX( m_selectedArea.x() - handleSize / 2 ); + m_dragHandleLeft.setY( m_selectedArea.y() + m_selectedArea.height() / 2 - handleSize / 2 ); + m_dragHandleLeft.setWidth( handleSize ); + m_dragHandleLeft.setHeight( handleSize ); + + m_dragHandleRight.setX( m_selectedArea.x() + m_selectedArea.width() - handleSize / 2 ); + m_dragHandleRight.setY( m_selectedArea.y() + m_selectedArea.height() / 2 - handleSize / 2 ); + m_dragHandleRight.setWidth( handleSize ); + m_dragHandleRight.setHeight( handleSize ); + + m_dragHandleTop.setX( m_selectedArea.x() + m_selectedArea.width() / 2 - handleSize / 2 ); + m_dragHandleTop.setY( m_selectedArea.y() - handleSize / 2 ); + m_dragHandleTop.setWidth( handleSize ); + m_dragHandleTop.setHeight( handleSize ); + + m_dragHandleBottom.setX( m_selectedArea.x() + m_selectedArea.width() / 2 - handleSize / 2 ); + m_dragHandleBottom.setY( m_selectedArea.y() + m_selectedArea.height() - handleSize / 2 ); + m_dragHandleBottom.setWidth( handleSize ); + m_dragHandleBottom.setHeight( handleSize ); +} + +void TabletArea::getMaxTabletArea() +{ + int ndevices; + XDevice *dev = NULL; + Display *dpy = QX11Info::display(); + + XDeviceInfo *info = XListInputDevices( dpy, &ndevices ); + for( int i = 0; i < ndevices; i++ ) { + if( info[i].name == m_toolName.toLatin1() ) { + dev = XOpenDevice( dpy, info[i].id ); + break; + } + } + + Atom prop, type; + int format; + unsigned char *data = NULL; + unsigned char *dataOld = NULL; + unsigned long nitems, bytes_after; + long *ldata; + + prop = XInternAtom( dpy, "Wacom Tablet Area", True ); + + XGetDeviceProperty( dpy, dev, prop, 0, 1000, False, AnyPropertyType, + &type, &format, &nitems, &bytes_after, &dataOld ); + + XGetDeviceProperty( dpy, dev, prop, 0, 1000, False, AnyPropertyType, + &type, &format, &nitems, &bytes_after, &data ); + + ldata = ( long * )data; + + // first reset to default values + ldata[0] = -1; + ldata[1] = -1; + ldata[2] = -1; + ldata[3] = -1; + + XChangeDeviceProperty( dpy, dev, prop, type, format, + PropModeReplace, data, nitems ); + + // Now get the defaults + XGetDeviceProperty( dpy, dev, prop, 0, 1000, False, AnyPropertyType, + &type, &format, &nitems, &bytes_after, &data ); + + ldata = ( long * )data; + m_origialArea.setX( ldata[0] ); + m_origialArea.setX( ldata[1] ); + m_origialArea.setWidth( ldata[2] ); + m_origialArea.setHeight( ldata[3] ); + + // and apply the old values again + XChangeDeviceProperty( dpy, dev, prop, type, format, + PropModeReplace, dataOld, nitems ); + + XFlush( dpy ); + + free( data ); + XFreeDeviceList( info ); + XCloseDevice( QX11Info::display(), dev ); +} diff --git a/src/kcmodule/tabletarea.h b/src/kcmodule/tabletarea.h new file mode 100644 index 0000000..b05e7e0 --- /dev/null +++ b/src/kcmodule/tabletarea.h @@ -0,0 +1,79 @@ +/* + * Copyright 2011 Jörg Ehrichs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef TABLETAREA_H +#define TABLETAREA_H + +#include +#include +#include + +namespace Wacom { + +class TabletArea : public QWidget +{ + Q_OBJECT +public: + explicit TabletArea(QWidget *parent = 0); + + void setTool(QString toolName); + + QRect getOriginalArea(); + QString getOriginalAreaString(); + QRect getSelectedArea(); + QString getSelectedAreaString(); + + void resetSelection(); + void setSelection(QString area); + + protected: + void paintEvent(QPaintEvent *event); + void mouseMoveEvent ( QMouseEvent * event ); + void mousePressEvent ( QMouseEvent * event ); + void mouseReleaseEvent ( QMouseEvent * event ); + +signals: + void selectedArea(QString area); + + private: + + /** + * @brief Get tablet width/height from xinput + */ + void getMaxTabletArea(); + void setupWidget(); + void updateDragHandle(); + + QString m_toolName; + + QRectF m_origialArea; // [tablet units] + qreal m_scaling; // scaling factor between tablet/widget units + QRectF m_selectedArea; // [widget units] + + QRectF m_dragHandleLeft; + QRectF m_dragHandleRight; + QRectF m_dragHandleTop; + QRectF m_dragHandleBottom; + + bool m_dragMode; + int m_mode; + QPoint m_dragPoint; + +}; + +} +#endif // TABLETAREA_H diff --git a/src/kcmodule/tabletwidget.cpp b/src/kcmodule/tabletwidget.cpp index 4489877..818c722 100644 --- a/src/kcmodule/tabletwidget.cpp +++ b/src/kcmodule/tabletwidget.cpp @@ -59,6 +59,7 @@ TabletWidget::~TabletWidget() delete m_generalPage; delete m_padButtonPage; delete m_padMappingPage; + delete m_touchMappingPage; delete m_penPage; delete m_touchPage; } @@ -77,6 +78,9 @@ void TabletWidget::init() m_generalPage = new GeneralWidget( m_deviceInterface, m_profileManagement ); m_padButtonPage = new PadButtonWidget( m_profileManagement ); m_padMappingPage = new PadMapping( m_deviceInterface, m_profileManagement ); + m_padMappingPage->setTool( 0 ); + m_touchMappingPage = new PadMapping( m_deviceInterface, m_profileManagement ); + m_touchMappingPage->setTool( 1 ); m_penPage = new PenWidget( m_profileManagement ); m_touchPage = new TouchWidget( m_profileManagement ); m_ui->setupUi( this ); @@ -88,6 +92,7 @@ void TabletWidget::init() connect( m_ui->profileSelector, SIGNAL( currentIndexChanged( const QString ) ), SLOT( switchProfile( const QString ) ) ); connect( m_padButtonPage, SIGNAL( changed() ), SLOT( profileChanged() ) ); connect( m_padMappingPage, SIGNAL( changed() ), SLOT( profileChanged() ) ); + connect( m_touchMappingPage, SIGNAL( changed() ), SLOT( profileChanged() ) ); connect( m_penPage, SIGNAL( changed() ), SLOT( profileChanged() ) ); connect( m_touchPage, SIGNAL( changed() ), SLOT( profileChanged() ) ); connect( m_generalPage, SIGNAL( changed() ), SLOT( profileChanged() ) ); @@ -125,6 +130,7 @@ void TabletWidget::loadTabletInformation() m_generalPage->reloadWidget(); m_padButtonPage->reloadWidget(); m_padMappingPage->reloadWidget(); + m_touchMappingPage->reloadWidget(); m_penPage->reloadWidget(); m_touchPage->reloadWidget(); @@ -169,6 +175,9 @@ void TabletWidget::loadTabletInformation() } m_ui->deviceTabWidget->addTab( m_padMappingPage, i18n( "Pad Mapping" ) ); + if( !touchName.isEmpty() ) { + m_ui->deviceTabWidget->addTab( m_touchMappingPage, i18n( "Touch Mapping" ) ); + } // switch to the current active profile QDBusReply profile = m_tabletInterface->call( QLatin1String( "profile" ) ); @@ -220,6 +229,7 @@ void TabletWidget::saveProfile() m_generalPage->saveToProfile(); m_padButtonPage->saveToProfile(); m_padMappingPage->saveToProfile(); + m_touchMappingPage->saveToProfile(); m_penPage->saveToProfile(); m_touchPage->saveToProfile(); @@ -252,6 +262,7 @@ void TabletWidget::switchProfile( const QString &profile ) m_generalPage->loadFromProfile(); m_padButtonPage->loadFromProfile(); m_padMappingPage->loadFromProfile(); + m_touchMappingPage->loadFromProfile(); m_penPage->loadFromProfile(); m_touchPage->loadFromProfile(); @@ -266,6 +277,7 @@ void TabletWidget::reloadProfile() m_generalPage->loadFromProfile(); m_padButtonPage->loadFromProfile(); m_padMappingPage->loadFromProfile(); + m_touchMappingPage->loadFromProfile(); m_penPage->loadFromProfile(); m_touchPage->loadFromProfile(); diff --git a/src/kcmodule/tabletwidget.h b/src/kcmodule/tabletwidget.h index 9aace59..4d2b7fc 100644 --- a/src/kcmodule/tabletwidget.h +++ b/src/kcmodule/tabletwidget.h @@ -155,6 +155,7 @@ private: GeneralWidget *m_generalPage; /**< Widget that shows some basic information about the tablet */ PadButtonWidget *m_padButtonPage; /**< Widget for the pad button settings */ PadMapping *m_padMappingPage; /**< Widget for the pad rotation and working area */ + PadMapping *m_touchMappingPage; /**< Widget for the touch rotation and working area */ PenWidget *m_penPage; /**< Widget for the pen settings (stylus/eraser) */ TouchWidget *m_touchPage; /**< Widget for the touch settings */ bool m_profileChanged; /**< True if the profile was changed and not saved yet */