File indexing completed on 2024-05-12 16:34:30

0001 /* This file is part of the KDE project
0002  * Copyright (c) 2008 Jan Hambrecht <jaham@gmx.net>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Library General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2 of the License, or (at your option) any later version.
0008  *
0009  * This library is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012  * Library General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU Library General Public License
0015  * along with this library; see the file COPYING.LIB.  If not, write to
0016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018  */
0019 
0020 #include "SpaceNavigatorDevice.h"
0021 #include "SpaceNavigatorPollingThread.h"
0022 #include "SpaceNavigatorEvent.h"
0023 #include "SpaceNavigatorDebug.h"
0024 
0025 #include <KoToolManager.h>
0026 #include <KoCanvasController.h>
0027 
0028 #include <spnav.h>
0029 #include <math.h>
0030 
0031 #define SpaceNavigatorDevice_ID "SpaceNavigator"
0032 
0033 SpaceNavigatorDevice::SpaceNavigatorDevice( QObject * parent )
0034 : KoInputDeviceHandler( parent, SpaceNavigatorDevice_ID ), m_thread( new SpaceNavigatorPollingThread( this ) )
0035 {
0036     qRegisterMetaType<Qt::MouseButtons>( "Qt::MouseButtons" );
0037     qRegisterMetaType<Qt::MouseButton>( "Qt::MouseButton" );
0038     connect( m_thread, SIGNAL(moveEvent(int,int,int,int,int,int,Qt::MouseButtons)),
0039             this, SLOT(slotMoveEvent(int,int,int,int,int,int,Qt::MouseButtons)));
0040     connect( m_thread, SIGNAL(buttonEvent(int,int,int,int,int,int,Qt::MouseButtons,Qt::MouseButton,int)),
0041             this, SLOT(slotButtonEvent(int,int,int,int,int,int,Qt::MouseButtons,Qt::MouseButton,int)));
0042 }
0043 
0044 SpaceNavigatorDevice::~SpaceNavigatorDevice()
0045 {
0046 }
0047 
0048 bool SpaceNavigatorDevice::start()
0049 {
0050     if( m_thread->isRunning() )
0051         return true;
0052 
0053     m_thread->start();
0054 
0055     return true;
0056 }
0057 
0058 bool SpaceNavigatorDevice::stop()
0059 {
0060     if( ! m_thread->isRunning() )
0061         return true;
0062 
0063     m_thread->stop();
0064 
0065     if( ! m_thread->wait( 500 ) )
0066         m_thread->terminate();
0067 
0068     spnav_close();
0069 
0070     return true;
0071 }
0072 
0073 void SpaceNavigatorDevice::slotMoveEvent( int x, int y, int z, int rx, int ry, int rz, Qt::MouseButtons buttons )
0074 {
0075     SpaceNavigatorEvent e( KoInputDeviceHandlerEvent::PositionChanged );
0076     e.setPosition( x, y, z );
0077     e.setRotation( rx, ry, rz );
0078     e.setButton( Qt::NoButton );
0079     e.setButtons( buttons );
0080     KoToolManager::instance()->injectDeviceEvent( &e );
0081 
0082     if( ! e.isAccepted() )
0083     {
0084         // no tool wants the event, so do some standard actions
0085         KoCanvasController * controller = KoToolManager::instance()->activeCanvasController();
0086         // check if the z-movement is dominant
0087         if( qAbs(z) > qAbs(x) && qAbs(z) > qAbs(y) )
0088         {
0089             // zoom
0090             controller->zoomBy( controller->preferredCenter().toPoint(), pow(1.01,-z/10) );
0091         }
0092         else
0093         {
0094             // pan
0095             controller->pan( QPoint( -x, -y ) );
0096         }
0097     }
0098 }
0099 
0100 void SpaceNavigatorDevice::slotButtonEvent( int x, int y, int z, int rx, int ry, int rz, Qt::MouseButtons buttons, Qt::MouseButton button, int type )
0101 {
0102     SpaceNavigatorEvent e( static_cast<KoInputDeviceHandlerEvent::Type>( type ) );
0103     e.setPosition( x, y, z );
0104     e.setRotation( rx, ry, rz );
0105     e.setButton( button );
0106     e.setButtons( buttons );
0107     KoToolManager::instance()->injectDeviceEvent( &e );
0108 }