2014-03-28 02:50:40 +01:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
using System.Text ;
using System.Runtime.InteropServices ;
using DS4Library ;
namespace DS4Control
{
public class ButtonMouse : ITouchpadBehaviour
{
private int deviceNum ;
private bool leftButton , middleButton , rightButton ;
private DS4State s = new DS4State ( ) ;
private bool buttonLock ; // Toggled with a two-finger touchpad push, we accept and absorb button input without any fingers on a touchpad, helping with drag-and-drop.
private DS4Device dev = null ;
2014-03-29 06:29:08 +01:00
private readonly MouseCursor cursor ;
private readonly MouseWheel wheel ;
2014-03-28 02:50:40 +01:00
public ButtonMouse ( int deviceID , DS4Device d )
{
deviceNum = deviceID ;
dev = d ;
2014-03-29 06:29:08 +01:00
cursor = new MouseCursor ( deviceNum ) ;
wheel = new MouseWheel ( deviceNum ) ;
2014-03-28 02:50:40 +01:00
}
public override string ToString ( )
{
return "Button Mode" ;
}
public void touchesMoved ( object sender , TouchpadEventArgs arg )
{
2014-03-29 06:29:08 +01:00
cursor . touchesMoved ( arg ) ;
wheel . touchesMoved ( arg ) ;
dev . getCurrentState ( s ) ;
2014-03-28 02:50:40 +01:00
synthesizeMouseButtons ( false ) ;
}
2014-03-29 06:29:08 +01:00
public void touchUnchanged ( object sender , EventArgs unused )
2014-03-28 02:50:40 +01:00
{
2014-03-29 06:29:08 +01:00
dev . getCurrentState ( s ) ;
if ( buttonLock | | s . Touch1 | | s . Touch2 )
2014-03-28 02:50:40 +01:00
synthesizeMouseButtons ( false ) ;
}
public void touchesBegan ( object sender , TouchpadEventArgs arg )
{
2014-03-29 06:29:08 +01:00
cursor . touchesBegan ( arg ) ;
wheel . touchesBegan ( arg ) ;
dev . getCurrentState ( s ) ;
2014-03-28 02:50:40 +01:00
synthesizeMouseButtons ( false ) ;
}
public void touchesEnded ( object sender , TouchpadEventArgs arg )
{
2014-03-29 06:29:08 +01:00
dev . getCurrentState ( s ) ;
2014-03-28 02:50:40 +01:00
if ( ! buttonLock )
synthesizeMouseButtons ( true ) ;
}
private void synthesizeMouseButtons ( bool justRelease )
{
bool previousLeftButton = leftButton , previousMiddleButton = middleButton , previousRightButton = rightButton ;
if ( justRelease )
{
leftButton = middleButton = rightButton = false ;
}
else
{
leftButton = s . L1 | | s . R1 | | s . DpadLeft | | s . Square ;
middleButton = s . DpadUp | | s . DpadDown | | s . Triangle | | s . Cross ;
rightButton = s . DpadRight | | s . Circle ;
s . L1 = s . R1 = s . DpadLeft = s . Square = s . DpadUp = s . DpadDown = s . Triangle = s . Cross = s . DpadRight = s . Circle = false ;
}
if ( leftButton ! = previousLeftButton )
InputMethods . MouseEvent ( leftButton ? InputMethods . MOUSEEVENTF_LEFTDOWN : InputMethods . MOUSEEVENTF_LEFTUP ) ;
if ( middleButton ! = previousMiddleButton )
InputMethods . MouseEvent ( middleButton ? InputMethods . MOUSEEVENTF_MIDDLEDOWN : InputMethods . MOUSEEVENTF_MIDDLEUP ) ;
if ( rightButton ! = previousRightButton )
InputMethods . MouseEvent ( rightButton ? InputMethods . MOUSEEVENTF_RIGHTDOWN : InputMethods . MOUSEEVENTF_RIGHTUP ) ;
}
// touch area stuff
private bool leftDown , rightDown , upperDown ;
private bool isLeft ( Touch t )
{
return t . hwX < 1920 * 2 / 5 ;
}
private bool isRight ( Touch t )
{
return t . hwX > = 1920 * 3 / 5 ;
}
public void touchButtonUp ( object sender , TouchpadEventArgs arg )
{
if ( upperDown )
{
2014-03-31 08:43:21 +02:00
mapTouchPad ( DS4Controls . TouchUpper , true ) ;
2014-03-28 02:50:40 +01:00
upperDown = false ;
}
if ( leftDown )
{
2014-03-31 08:43:21 +02:00
mapTouchPad ( DS4Controls . TouchButton , true ) ;
2014-03-28 02:50:40 +01:00
leftDown = false ;
}
if ( rightDown )
{
2014-03-31 08:43:21 +02:00
mapTouchPad ( DS4Controls . TouchMulti , true ) ;
2014-03-28 02:50:40 +01:00
rightDown = false ;
}
dev . setRumble ( 0 , 0 ) ;
}
public void touchButtonDown ( object sender , TouchpadEventArgs arg )
{
byte leftRumble , rightRumble ;
if ( arg . touches = = null ) //No touches, finger on upper portion of touchpad
{
2014-03-31 08:43:21 +02:00
mapTouchPad ( DS4Controls . TouchUpper , false ) ;
2014-03-28 02:50:40 +01:00
upperDown = true ;
leftRumble = rightRumble = 127 ;
}
else if ( arg . touches . Length = = 1 )
{
if ( isLeft ( arg . touches [ 0 ] ) )
{
2014-03-31 08:43:21 +02:00
mapTouchPad ( DS4Controls . TouchButton , false ) ;
2014-03-28 02:50:40 +01:00
leftDown = true ;
leftRumble = 63 ;
rightRumble = 0 ;
}
else if ( isRight ( arg . touches [ 0 ] ) )
{
2014-03-31 08:43:21 +02:00
mapTouchPad ( DS4Controls . TouchMulti , false ) ;
2014-03-28 02:50:40 +01:00
rightDown = true ;
leftRumble = 0 ;
rightRumble = 63 ;
}
else
{
2014-03-29 06:29:08 +01:00
leftRumble = rightRumble = 0 ; // Ignore ambiguous pushes.
2014-03-28 02:50:40 +01:00
}
}
else
{
buttonLock = ! buttonLock ;
leftRumble = rightRumble = ( byte ) ( buttonLock ? 255 : 63 ) ;
}
dev . setRumble ( rightRumble , leftRumble ) ; // sustain while pressed
}
bool mapTouchPad ( DS4Controls padControl , bool release )
{
ushort key = Global . getCustomKey ( padControl ) ;
if ( key = = 0 )
return false ;
else
{
DS4KeyType keyType = Global . getCustomKeyType ( padControl ) ;
if ( ! release )
if ( keyType . HasFlag ( DS4KeyType . ScanCode ) )
InputMethods . performSCKeyPress ( key ) ;
else InputMethods . performKeyPress ( key ) ;
else
if ( ! keyType . HasFlag ( DS4KeyType . Repeat ) )
if ( keyType . HasFlag ( DS4KeyType . ScanCode ) )
InputMethods . performSCKeyRelease ( key ) ;
else InputMethods . performKeyRelease ( key ) ;
return true ;
}
}
public DS4State getDS4State ( )
{
return s ;
}
}
}