 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Lexikos
Joined: 17 Oct 2006 Posts: 2526 Location: Australia, Qld
|
Posted: Fri Nov 23, 2007 5:30 am Post subject: Lex' Mouse Gestures |
|
|
Lex' Mouse Gestures
Yet another mouse gestures script! I wrote this one (at least) several months ago, after trying various mouse gesture scripts and applications. For some I did not like the configuration methods, and for others I did not like the way gesture recognition worked.
This script allows gestures similar to the All-in-One Gestures addon for Firefox, since that is what I was used to.
I had been intending to rewrite the script and add more features, but... I'm too lazy.
Gestures are triggered by holding the gesture key (default is right mouse button), drawing a sequence of "strokes" (line segments) then releasing the gesture key.
Features:
- Allows an arbitrary number of directions ("zones"), though 4 is the most practical and efficient.
- Allows any number of "strokes" in a gesture.
- Gestures either execute a label or send keystrokes.
- Wheel gestures (gesture key + wheel up/down.)
- Various options controlling gesture recognition. See Gestures Default.ahk for more information.
- Custom normal and suspended tray icons.
- Win + Gesture key enables/disables gestures, and indicates the current status by playing a sound from Wurt Simplicity.
- Note that it ignores the length of each stroke (excluding m_LowThreshold and m_HighThreshold), so two consecutive strokes cannot be in the same zone. For instance, Gesture_L_L is not valid, since it would be recognized as Gesture_L.
Script Structure:
Gestures.ahk contains the "gesture engine," while Gestures Default.ahk contains the default settings and any gestures which are implemented in script (vs pure keystrokes.) Gestures.ini is used to override settings, or define pure keystroke gestures.
When a gesture is executed, the script builds a label/variable name in the format:%c_GesturePrefix%_%zone1%_%zone2%_%zoneN% For example:This represents left, then up. c_GesturePrefix is defined in Gestures Default.ahk, and is "Gesture" by default. It could be used by a label-associated gesture to easily switch between a "set" of gestures. (The script doesn't use this capability yet.)
If a variable exists of the relevant name, the variable's contents are sent as keystrokes.
If no variable exists, but a label does, the label is executed.
Default Gestures:
Implemented in Gestures Default.ahk as labels:
- Gesture_L (left) - Back - !{Left}, ^-, or Browser_Back depending on the active window.
- Gesture_R (right) - Forward.
- Gesture_D_R (down, then right) - Close the active window. A three second delay is implemented to allow cancelling by pressing Escape.
- Gesture_R_D_L_U (right, down, left, up) - Reload the script.
- Gesture_L_D_R_U (left, down, right, up) - Edit Gestures.ini.
- Gesture_L_D (left, down) - Minimize active window.
- Gesture_R_U (right, up) - Maximize active window.
- Gesture_R_L (right, left) or
Gesture_L_R (left, right) - Undo recent minimize, restore active window, or restore the "top-most" minimized window.
- Gesture_L_D_U (left, down, up) or
Gesture_U_L_D_U (up, left, down, up) - Restore the "top-most" minimized window. (Since the above gesture prefers to restore the active window if maximized.)
- Gesture_R_L_R_L (right, left, right, left) or
Gesture_L_R_L_R (left, right, left, right) - Enter "window move" mode. Click or press Enter to confirm window location. Press Escape to cancel. (This really just activates "Move" from the window's system menu.)
- Gesture_Default - Pressing the gesture key without moving the mouse executes Gesture_Default. If the gesture key is a mouse button, it simulates a click+drag from the gesture start point to the current mouse location, otherwise it sends a keystroke. Gesture_Default is also executed if the gesture is cancelled via m_Timeout and m_DefaultOnTimeout is non-zero.
Implemented in Gestures.ini as pure keystroke assignments:
- Gesture_WheelUp (gesture key + wheel up) - Ctrl+Shift+Tab.
- Gesture_WheelDown (gesture key + wheel down) - Ctrl+Tab.
- Gesture_L_U (left, up) - Up one level in Explorer/a file dialog.
- Gesture_U (up) - Launch_App1 (usually My Computer.)
- Gesture_D (down) - Launch_App2 (usually Calculator.)
- Gesture_D_U (down, up) - Browser_Home.
- Gesture_D_L (down, left) - ^F4 (usually close tab/document.)
- Gesture_D_R_L (down, right, left) - !F4 (close window without delay.)
Download
(Includes script, default ini, tray icons and wurt sounds used by the script.) |
|
| Back to top |
|
 |
Andreone
Joined: 20 Jul 2007 Posts: 257 Location: Paris, France
|
Posted: Fri Nov 23, 2007 10:30 am Post subject: |
|
|
This is a really nice script and very useful
Thank you |
|
| Back to top |
|
 |
catweazle Guest
|
Posted: Thu Jan 03, 2008 9:06 pm Post subject: |
|
|
Did you consider rendering "mouse trails" on the screen to show the gesture as it's being composed (as per all-in-one gestures)? I think this would be a useful addition.
Some time ago I added very basic trail support (rendering multiple tiny windows) to one of the earlier mouse gesture scripts (see below), although it could probably be improved by rendering lines directly to the screen.
| Code: |
;
; mg.ahk - Mouse gestures with right button.
;
; Jason Hood, 15 August to 9 September, 2004.
;
; Adapted from mousegesture.ahk from:
; http://lukewarm.s41.xrea.com/AutoHotkey/myscripts/
;
;#NoTrayIcon
Menu Tray, Tip, Mouse Gestures
SetMouseDelay -1
SetDefaultMouseSpeed 0
mg_active = 0
timeout = 50 ; approx. half a second
sensitivity = 10 ; this many pixels required before being accepted
; Show a tooltip indicating the current gesture; uncomment to hide it.
;mg_showtips = hide
;mg_showtrails = hide
; Ignore unknown gestures (no right click); uncomment to do the click.
;mg_rclick = yes
; Define the recognised gestures (each of these should have an _Action label).
; Any number of directions is allowed, so, for example, an "S" (or "5") gesture
; could be created with "LDRDL".
gestures = -L-R-U-D-UD-DR-RU-DL-DR-LDR-DU-DURD-DLU-
; Window titles to exclude.
excluded = Pixia,Firefox,Virtual Machine Remote Control,Remote Desktop,Potter
; Window titles which automatically disable the gestures (it can't quite handle
; simultaneous left/right presses correctly).
disabled = Minesweeper,Cheat Mine,Potter
; Initialise variables for the actions and exit.
;goto action_init
SetWinDelay,0
CoordMode,Mouse,Screen
; Initialise variables to support mouse pointer trails
trail=50
delay=20
;trans=255
image=C:\4x4_red.bmp
; Create small 4x4 windows to represent mouse pointer trails
Loop,%trail%
{
Gui,%A_Index%:+Owner +AlwaysOnTop -Resize -SysMenu -MinimizeBox -MaximizeBox +Disabled -Caption -Border -ToolWindow
Gui,%A_Index%:Margin,0,0
Gui,%A_Index%:Add,Picture,,%image%
Gui,%A_Index%:Show,X-50 Y-50 W4 H4 NoActivate,MouseTrail%A_Index%
;WinSet,TransColor,FFFFFF %trans%,MouseTrail%A_Index%
;trans-=25
}
; Hotkeys for script control.
#g::Suspend
+#g::Reload
^#g::Edit
!#g::ExitApp
;------------------------------------------------------------------------------
DR_Action:
; Close the active window.
WinClose A
return
DL_Action:
; Minimize the active window.
; WinMinimize A
; WinGetClass, GestureInitiatedWindow, ahk_id %winid%
;
; ;MsgBox, "Active" %GestureInitiatedWindow%
;
; If GestureInitiatedWindow in Progman
; {
;; MsgBox, "Clicked root"
; If LastMinimized <>
; {
; WinRestore
; }
; }
; Else
; {
; PostMessage, 0x112, 0xF020,,, A ; 0x112 = WM_SYSCOMMAND, 0xF020 = SC_MINIMIZE
; LastMinimized = %winid%
; }
PostMessage, 0x112, 0xF020,,, A ; 0x112 = WM_SYSCOMMAND, 0xF020 = SC_MINIMIZE
return
; -----------------------------------------------------------------------------
D_Action:
WinGetClass, ActiveClass, A
If ActiveClass in ExploreWClass,CabinetWClass
{
ControlGetText, Dir, Edit1, A
;WinGetTitle, Dir, A
;Run, explore %Dir%
If Dir = My Documents
Dir = %A_MyDocuments%
Else If Dir = My Computer
Dir = %A_MyComputer%
Else If Dir = Desktop
Dir = %A_Desktop%
Run, explorer /n `, %Dir%
}
return
; -----------------------------------------------------------------------------
U_Action:
WinGetClass, ActiveClass, A
If ActiveClass in ExploreWClass,IEFrame,CabinetWClass
{
WinGetTitle, Title, A
Send, {Backspace}
}
return
UD_Action:
; Strg+N erzeugt im Explorer oder Dateidialog einen neuen Ordner
~^M:: ; Strg+M (~ = native)
WinGetClass, ActiveClass, A ; Klasse des aktiven Fensters
If ActiveClass in ExploreWClass,CabinetWClass ; Wenn Explorer-Fenster ...
{
Send, !F
Send, w
Send, f
}
IfWinActive, ahk_class #32770 ; Ist Dateidialog?
{
PostMessage, 0x111, 40962 ; Direkten Befehl für neuer Ordner senden
}
return
RU_Action:
WinGet state, MinMax, A
If state = 1 ; maximized (or minimized)
WinRestore,A
else ; normal window
WinMaximize,A
return
L_Action:
WinGetClass, ActiveClass, A
If ActiveClass in ExploreWClass,IEFrame,CabinetWClass,wndclass_desked_gsk
Send, !{Left}
return
R_Action:
WinGetClass, ActiveClass, A
If ActiveClass in ExploreWClass,IEFrame,CabinetWClass,wndclass_desked_gsk
Send, !{Right}
return
LDR_Action:
Run, C:\
return
DU_Action:
if (A_ComputerName = "CATWEAZLE")
url = http://www.google.co.uk
else
url = http://ra/johnc
Run,%url%
return
DURD_Action:
Run,%userprofile%\My Documents
return
DLU_Action:
Send, #d
return
;------------------------------------------------------------------------------
;MButton::
; mb = M
;goto MouseButton
;LButton::
; mb = L
;MouseButton:
; If mg_active = 1
; {
; IfEqual mg_showtips,, Tooltip
; mg_executed = 1
; mg_str = %mb%B
; goto %mg_str%_Action
; }
; ; I like to use middle button as left double-click.
; If mb = M
; {
; MouseClick L,,, 2
; return
; }
; NOTE: This function is needed for excluded windows (e.g., Firefox) to be handled correctly
ButtonWait:
;FileAppend mg_active %mg_active% `n, C:\debug.txt
;IfEqual,mg_active,0,Return
MouseClick %mb%,,,,,D
loop
{
GetKeyState st, %mb%Button, P
IfEqual st, U, break
Sleep 10
}
MouseClick %mb%,,,,,U
return
;WheelUp::
; mg_str = WU
;goto Wheel
;
;WheelDown::
; mg_str = WD
;
;Wheel:
; If mg_active = 1
; {
; IfEqual mg_showtips,, Tooltip
; mg_executed = 1
; goto %mg_str%_Action
; }
; MouseClick %mg_str%
;return
^+RButton::
Loop,%trail%
{
WinSet,Top,,MouseTrail%index%
}
MsgBox, raised gesture windows
return
;^RButton::
+RButton::
RButton::
; Loop,%trail%
; {
; WinSet,Top,,MouseTrail%index%
; }
MouseGetPos,,, id
WinGetTitle mg_title, ahk_id %id%
If mg_title contains %disabled%
Suspend
else
{
If mg_title contains %excluded%
;If !GetKeyState("Control")
If !GetKeyState("LShift")
{
mb = R
goto ButtonWait
}
mg_active = 1
mg_executed = 0
mg_rheld = 0
mg_str =
mg_idletime = 0
mg_rclick =
;IfEqual mg_showtips,, ToolTip %A_Space%
MouseGetPos px, py, winid
px2 = %px%
py2 = %py%
loop
{
GetKeyState sh, Shift, P
If sh = D
{
mg_rclick = yes
;MsgBox, shift down
}
GetKeyState st, RButton, P
If st = U ; the button has been released
{
IfEqual mg_showtips,, ToolTip
IfEqual mg_showtrails,, GoSub, ClearTrails
If mg_rheld = 0
{
mg_active = 0
IfEqual mg_showtrails,, GoSub, ClearTrails
If mg_executed = 0
If mg_str =
MouseClick R
else IfInString gestures, -%mg_str%-
gosub %mg_str%_Action
else IfNotEqual mg_rclick,,MouseClick, R
}
else IfNotEqual mg_rclick,,MouseClick,R,,,,,U
; else
; MouseClick R,,,,,U
return
}
else If mg_idletime < %timeout%
; button still pressed, within timeout since last direction change
{
MouseGetPos dx, dy
dx -= %px2%
dy -= %py2%
If dx > %sensitivity%
mg_dir = R
else If dx < -%sensitivity%
mg_dir = L
else If dy > %sensitivity%
mg_dir = D
else If dy < -%sensitivity%
mg_dir = U
If mg_dir <>
{
StringRight,right,mg_str,1
IfNotInString, right, %mg_dir%
{
mg_str = %mg_str%%mg_dir%
}
IfEqual mg_showtips,, ToolTip %mg_str%
MouseGetPos px2, py2
mg_idletime = 0
mg_dir =
}
else
mg_idletime++
}
else ; timeout has expired
{
IfEqual mg_showtips,,ToolTip Gesture Expired
If mg_rheld = 0
If mg_executed = 0
{
MouseGetPos px2, py2
If px2 <> %px%
If py2 <> %py%
{
IfEqual mg_showtips,, ToolTip
IfEqual mg_showtrails,, GoSub, ClearTrails
If mg_rclick <>
{
MouseClick R, %px%, %py%,,,D
MouseMove %px2%, %py2%
}
mg_rheld = 1
mg_active = 0
}
}
}
If (mg_active)
IfEqual mg_showtrails,, GoSub, DrawTrails
Sleep delay
}
}
mb = R
goto ButtonWait
DrawTrails:
;FileAppend index %index% trail %trail% `n, C:\debug.txt
If (index > trail)
{
;FileAppend greater %index% `n, C:\debug.txt
index = 1
}
;FileAppend index %index% `n, C:\debug.txt
MouseGetPos,x,y
x+=5
y+=5
WinMove,MouseTrail%index%,,%x%,%y%
index += 1
Return
ClearTrails:
Loop,%trail%
{
WinMove,MouseTrail%A_Index%,,-10,-10
;WinSet,Top,,MouseTrail%index%
}
Return
|
|
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3622 Location: Belgrade
|
Posted: Thu Jan 03, 2008 9:45 pm Post subject: |
|
|
Thank you _________________
 |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2526 Location: Australia, Qld
|
Posted: Fri Jan 04, 2008 4:18 am Post subject: |
|
|
| catweazle wrote: | Did you consider rendering "mouse trails" on the screen to show the gesture as it's being composed (as per all-in-one gestures)? I think this would be a useful addition.
| I find trails distracting rather than useful. The tactile response of the mouse is effective enough, IMO. Eventually the movements become so natural you don't need to think about which way you're moving the mouse. |
|
| Back to top |
|
 |
juan Guest
|
Posted: Sat Jan 26, 2008 8:38 pm Post subject: |
|
|
thankyou, really nice script, I´m now using it
I added the current gesture to tooltip for one second, just for a litle feedback
bye |
|
| Back to top |
|
 |
juan Guest
|
Posted: Sat Jan 26, 2008 8:51 pm Post subject: |
|
|
I´m a litle newbe to do it my self, what do you think about adding to gestures .ini something like
[mp3 @ C:\.* - xplorer²]
Gesture_D_U = !{F4}
["- Mozilla Firefox"]
Gesture_D_U = {Browser_Home}
[else]
Gesture_D_U = {something_else}
or something better, like using the classname to, it would be great
thanks againg, i´m enjoying your script
and sorry about my english |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2526 Location: Australia, Qld
|
Posted: Sun Jan 27, 2008 2:35 am Post subject: |
|
|
I've been planning to revise Gestures for a long time, especially for context-sensitive gestures, but since I very rarely edit my gestures, other projects have taken precedence.
Note that you can script any gesture by adding it to either ahk file:
| Code: | Gesture_D_U:
SetTitleMatchMode, RegEx
ifWinActive, mp3 @ C:\\.* \- xplorer² ; assuming ".*" was meant as a wildcard
Send !{F4}
else ifWinActive, \- Mozilla Firefox ahk_class MozillaUIWindowClass
Send {Browser_Home}
else
Send {Launch_App1}
return
| Be sure to remove Gesture_D_U from your ini file, if present. |
|
| Back to top |
|
 |
Juan Guest
|
Posted: Sun Jan 27, 2008 4:13 pm Post subject: |
|
|
| thanks lexikos, that´s the way i´m doing it now, i think your script is very good, if you find the time please revise it a litle, I´ll try for my self, thanks again and see you |
|
| Back to top |
|
 |
jpsala
Joined: 21 Jan 2008 Posts: 7
|
Posted: Sun Jan 27, 2008 10:05 pm Post subject: |
|
|
Hi lexikos, I made some modifications, if you find some time have a look and make the necesary conrrections, take a look at gestures.ini
now you can have the same hotkey for diferent windows
Gesture_D = doSomething<win>Scite<=>- SciTE
Gesture_D = doSomethingElse<win>Firefox<=>- Mozilla Firefox
| Code: |
;
; AutoHotkey Version: 1.0.46.09 +
; Language: English
; Platform: Win XP, 2003, Vista, and probably 2000
; Author: Steve Gray, aka Lexikos
;
; Script Function:
; Mouse gestures.
; - Allows abitrary number of directions (zones).
; - Allows any number of movements/strokes in a sequence.
; - Custom script (label) execution OR variable-based key-stroke simulation.
; - Variable-based key-strokes and options can be set via Gestures.ini
; (setting a variable-based gesture overrides any associated labels/custom scripts)
;
gosub Gestures_Default_Init
; guardo los nombres de las variables
RunDebugView()
; Read gesture definitions from Gestures.ini
G_LoadGestures( A_ScriptDir . "\Gestures.ini" )
; save the name of the gestures in vars
vars := getVars()
c_PI := 3.141592653589793
c_halfPI := 1.5707963267948965 ; Pi/2
c_Degrees := 57.29578 ; 180/Pi (degrees per radian)
#NoEnv
SendMode Input
#SingleInstance force
#KeyHistory 20
CoordMode, Mouse, Screen
SetTitleMatchMode, 2
; custom tray icon (also called by ToggleGestureSuspend)
G_SetTrayIcon(true)
; Hook "Suspend Hotkeys" messages to update the tray icon.
; Note: This has the odd side-effect of "disabling" the tray menu
; if the script is paused from the tray menu.
OnMessage(0x111, "WM_COMMAND")
Menu, TRAY, Tip, Mouse Gestures
Menu, TRAY, Add
Menu, TRAY, Add, Edit &Gestures, EditGestures
Menu, TRAY, Add, Edit &Default Gestures, EditGestures2
Menu, TRAY, Add, Edit &this script, EditThisScript
; RAlt or %m_GestureKey%, whichever was used last
m_LastGestureKey := m_GestureKey
; m_Stroke%i% will be set to the actual strokes (starting at m_Stroke1)
m_StrokeCount = 0
m_WaitForRelease := false
m_PassKeyUp := false
m_ClosingWindow := 0
; Use code similar to this to disable gestures on a per-application basis:
; GroupAdd, Blacklist, Firefox ahk_class MozillaUIWindowClass
; Hotkey, IfWinNotActive, ahk_group Blacklist
; register the hotkey
Hotkey, %m_GestureKey%, GestureKey_Down
Hotkey, #%m_GestureKey%, ToggleGestureSuspend
; extra key
if ( m_GestureKey2 && m_GestureKey2 != m_GestureKey )
{
Hotkey, %m_GestureKey2%, GestureKey_Down
Hotkey, #%m_GestureKey2%, ToggleGestureSuspend
}
if !m_GestureKey2
m_GestureKey2 := m_GestureKey
; see also: GestureKey_Down for GetKeyState(...)
GroupAdd, WinCloseGroup, ahk_class ConsoleWindowClass
GroupAdd, WinCloseGroup, ahk_class AutoHotkey
return
Gestures_Default_Init:
#Include %A_ScriptDir%\Gestures Default.ahk
return
EditGestures:
Run, C:\tools\wscite\SciTE.exe "%A_ScriptDir%\Gestures.ini",, UseErrorLevel
if ErrorLevel = ERROR
Run, C:\tools\wscite\SciTE.exe "%A_ScriptDir%\Gestures.ini"
return
EditGestures2:
Run, C:\tools\wscite\SciTE.exe "%A_ScriptDir%\Gestures Default.ahk",, UseErrorLevel
if ErrorLevel = ERROR
Run, C:\tools\wscite\SciTE.exe "%A_ScriptDir%\Gestures Default.ahk"
return
EditThisScript:
Run, C:\tools\wscite\SciTE.exe %A_ScriptFullPath%,, UseErrorLevel
if ErrorLevel = ERROR
Run, C:\tools\wscite\SciTE.exe "%A_ScriptDir%\Gestures Default.ahk"
return
; Wheel Gestures: Gesture key + Wheel sends keystrokes as defined by
; Gesture_WheelUp and Gesture_WheelDown in Gestures.ini.
WheelUp::
WheelDown::
gesture := c_GesturePrefix ? c_GesturePrefix : "Gesture"
if (m_WaitForRelease && %gesture%_%A_ThisHotkey%)
{ ; holding gesture button && this wheel gesture has a defined action
m_ScrolledWheel := true
m_ExitLoop := true
Send % %gesture%_%A_ThisHotkey%
} else
Send {%A_ThisHotkey%}
return
/********** XBUTTON HOTKEYS - included in the script for (my) convenience.
*/
XButton2 & LButton::MinimizeActiveWindow() ;WinMinimize, A
XButton2 & RButton::
ifWinActive, ahk_group WinCloseGroup
WinClose, A
else
Send !{F4}
return
; Task-switch with XButton1( + Wheel).
XButton1 & WheelUp::AltTab
XButton1 & WheelDown::ShiftAltTab
XButton1::Send !{Tab}
; Document/tab-switch with XButton2( + Wheel)
XButton2 & WheelUp::Send ^+{tab}
XButton2 & WheelDown::Send ^{tab}
XButton2::Send ^{Tab}
MinimizeActiveWindow()
{
global
lastMinTime := A_TickCount
lastMinID := WinExist("A")
; unlike WinMinimize, using WM_SYSCOMMAND, SC_MINIMIZE
; causes the system-wide "Minimize" sound to be played
PostMessage, 0x112, 0xF020
}
; Press Win + Gesture button to enable/disable gestures.
ToggleGestureSuspend:
Suspend, Toggle
G_SetTrayIcon(!A_IsSuspended)
; wurt from: http://addons.miranda-im.org/details.php?action=viewfile&id=1512
if A_IsSuspended
SoundPlay, %A_ScriptDir%\wurt_disabled.wav
else
SoundPlay, %A_ScriptDir%\wurt_enabled.wav
return
; Press Escape to cancel the current gesture (before releasing the gesture button.)
CancelGesture:
Hotkey, Escape, CancelGesture, Off
m_ExitLoop := true
return
GestureKey_Up:
m_WaitForRelease := false
Hotkey, IfWinActive
Hotkey, *%m_LastGestureKey% Up, GestureKey_Up, Off
Hotkey, Escape, CancelGesture, Off
; record for later use
MouseGetPos, m_EndX, m_EndY
if ( m_PassKeyUp )
{
Send {%m_LastGestureKey% Up}
m_PassKeyUp := false
}
return
GestureKey_Down:
if ( !GetKeyState(m_GestureKey, "P") && !GetKeyState(m_GestureKey2, "P") )
return
if ( m_WaitForRelease )
return
m_WaitForRelease := true
m_ExitLoop := false
Hotkey, IfWinActive
m_LastGestureKey := A_ThisHotkey
Hotkey, *%m_LastGestureKey% Up, GestureKey_Up, On
Hotkey, Escape, CancelGesture, On
waitCounter := 0
startX := -1
startY := -1
totalDistance := 0
zone := 0
lastZone := -1
m_StrokeCount := 0
; get starting mouse position
MouseGetPos, lastX, lastY
; record for later use
m_StartX := lastX
m_StartY := lastY
Loop
{
; wait for mouse to move
Sleep, m_Interval
if ( m_ExitLoop )
{
if m_ScrolledWheel
KeyWait, %m_LastGestureKey%
return
}
; increment waitCounter by timer interval
; (may not be entirely accurate if the script is lagging...)
waitCounter += m_Interval
if ( !m_StrokeCount && m_InitialTimeout && waitCounter > m_InitialTimeout )
{
if ( GetKeyState(m_LastGestureKey, "P") )
{
if m_LastGestureKey in LButton,MButton,RButton
{
; convert key name to a "button" (silly how MouseClick won't accept "LButton")
StringLeft, btn, m_LastGestureKey, 1
; remember position
MouseGetPos, m_EndX, m_EndY
; move to point where gesture started, then click
MouseClick, %btn%, m_StartX, m_StartY, , 0, D
; move back into place
MouseMove, m_EndX, m_EndY, 0
btn =
}
else
{
Send {%m_LastGestureKey%}
}
; pass GestureKey Up on to active window
m_PassKeyUp := true
}
return
}
if ( !GetKeyState(m_GestureKey, "P") && !GetKeyState(m_GestureKey2, "P") )
{ ; use location mouse was released at
x := m_EndX
y := m_EndY
}
else ; get current mouse position
MouseGetPos, x, y
offsetX := x - lastX
offsetY := y - lastY
; check if mouse has moved
if ( offsetX!=0 || offsetY!=0 )
{
; calculate distance and angle from previous position
distance := G_GetLength(offsetX, offsetY)
if ( distance > m_LowThreshold )
{
angle := G_GetAngle(offsetX, offsetY)
angle *= c_Degrees
lastX := x
lastY := y
; get zone of angle
if ( m_StrokeCount > 0 || m_InitialZoneCount < 2 )
zone := G_GetZone(angle, m_ZoneCount)
else
zone := G_GetZone(angle, m_InitialZoneCount)
if ( zone == -1 )
{
;DEBUG
;MsgBox, 64, DEBUG, Gesture stroke went off-course! (Exceeded zone tolerance `%%m_Tolerance%.), 5
SoundPlay, *-1
return
}
if ( lastZone != zone )
{
totalDistance := distance
; add stroke zone to the pseudo-array
++m_StrokeCount
m_Stroke%m_StrokeCount% := zone
lastZone := zone
; reset timeout counter
waitCounter := 0
}
else
{
totalDistance += distance
}
if ( m_HighThreshold > 0 && totalDistance > m_HighThreshold )
{
;DEBUG
;MsgBox, 64, DEBUG, Gesture stroke exceeded maximum stroke length: %totalDistance% / %m_HighThreshold%., 5
SoundPlay, *-1
Sleep, 150
SoundPlay, *-1
return
}
}
}
; end loop when gesture key is released
if ( !GetKeyState(m_GestureKey, "P") && !GetKeyState(m_GestureKey2, "P") )
break
}
; cancel gesture if the mouse was immobile for too long after the last gesture
if ( m_Timeout > 0 && waitCounter > m_Timeout )
{
;DEBUG
SoundPlay, *-1
;MsgBox, 64, DEBUG, Gesture timeout- %waitCounter% / %m_Timeout%, 5
if ( m_DefaultOnTimeout )
{
gesture = Gesture_Default
if ( %gesture% )
SendEvent % %gesture%
else if ( IsLabel(gesture) )
gosub %gesture%
}
return
}
gesture := c_GesturePrefix ? c_GesturePrefix : "Gesture"
Loop %m_StrokeCount%
{
; get the zone of this stroke
zone := m_Stroke%A_Index%
; get descriptive label for zone, if possible
if ( A_Index == 1 && m_InitialZoneCount >= 2 )
zoneText := c_Zone%m_InitialZoneCount%_%zone%
else
zoneText := c_Zone%m_ZoneCount%_%zone%
gesture .= "_"
if ( zoneText )
gesture .= zoneText
else
gesture .= zone
}
if ( m_StrokeCount == 0 )
gesture = Gesture_Default
; if gesture points to a variable, send its contents as keystrokes
wins := getWins(gesture . "_ID_", vars)
if (wins <> "")
{
nWin := 0
Loop, Parse, wins, ß
{
if ( SubStr(A_LoopField,1, StrLen(gesture)) == gesture)
{
;gesture := substr(A_LoopField,1,instr(A_LoopField,"_ID_")-1)
sid := substr(A_LoopField,instr(A_LoopField,"_ID_")+4,instr(A_LoopField,"[")-instr(A_LoopField,"_ID_")-4)
win := substr(A_LoopField,InStr(A_LoopField,"<=>")+4,500)
comando := substr(A_LoopField,instr(A_LoopField,"]: ")+3,instr(A_LoopField,"<win>")-instr(A_LoopField,"]: ")-3)
nWin += 1
SetTitleMatchMode, 2
outputdebug, x%win%x
if (WinActive(win))
{
ToolTip %gesture% ID %sid% inWin %win%
SetTimer, RemoveToolTip, 2500
send, %comando%
exit
}
}
}
ToolTip, No %gesture% in any of your %nWin% window definitions
SetTimer, RemoveToolTip, 1500
exit
}
;Gesture_D_ID_a[42 of 63]: comandoScite<win>a<=>ahk_class SciTEWindow
;Gesture_D_ID_b[53 of 63]: comandoFirefox<win>b<=>ahk_class MozillaUIWindowClass
else if ( %gesture% )
{
StringReplace, comando, %gesture%, <win>, Ì
StringSplit, command, comando, Ì, %A_Space%%A_Tab%
if (command0 == 2)
{
SetTitleMatchMode, regex
if WinActive( command2 )
Send % %command1%
Else
gesture := gesture . " no window " . command2
}
else
Send % %gesture%
} ; else if gesture has a label (e.g Gesture_D_R = down, then right), go to it
else if ( IsLabel(gesture) )
{
gosub %gesture%
}
else
gesture := gesture . " no existe"
; MsgBox, , , Unknown gesture with %m_StrokeCount% strokes:`n %gesture%, 2
if (gesture<>"Gesture_Default")
{
ToolTip %gesture%
SetTimer, RemoveToolTip, 1500
}
return
; get angle of {x,y} from positive x-axis, relative to {0,0}
; return value is in RADIANS
G_GetAngle( x, y )
{
global c_PI, c_halfPI
; if {0,0}, angle can be any real value
if ( x==0 && y==0 )
return 0
if ( x > 0 )
{
if ( y >= 0 )
return ATan(y/x)
;y < 0
return ATan(y/x) + 2*c_PI
}
else if ( x < 0 )
{
return ATan(y/x) + c_PI
}
else ; x == 0
{
if ( y > 0 )
return c_halfPI
;y < 0
return -c_halfPI
}
}
; get distance of {x,y} from {0,0}
G_GetLength( x, y )
{
return Sqrt(x*x + y*y)
}
; get the zone of an angle
; angle: specified in degrees
; zoneCount: number of zones (zone centers are at (360/zoneCount) degree intervals)
G_GetZone( angle, zoneCount )
{
local degPerZone
local zone
local tolerance
if ( zoneCount < 2 )
{ ; show debug error message
MsgBox, 16, ERROR, Invalid zoneCount (%zoneCount%) passed to G_GetZone()., 5
return 0
}
if ( angle < 0 ) {
Loop { ; while ( angle < 0 ) would be nice...
angle += 360
if ( angle >= 0 )
break
}
}
; calculate zone size
degPerZone := 360 / zoneCount
; calculate zone - Round() finds the nearest zone (nearest integer)
zone := Mod( Round(angle/degPerZone), zoneCount )
; calculate maximum tolerance
tolerance := degPerZone/2.0
; calculate real tolerance from user-defined tolerance (percentage)
if ( m_Tolerance < 100 )
tolerance *= Abs(m_Tolerance)/100.0
if ( zone == 0 && angle > 180 )
angle -= 360
; return -1 if angle is not within tolerance of the nearest zone
if ( Abs(angle-(zone*degPerZone)) >= tolerance )
zone := -1
return zone
}
G_LoadGestures( filename )
{
; declaring one or more local variables forces newly created variables to be global in scope
local line, varname
; declare a local array (0=array length, 1=first item)
local lineParts0
; these must be explicitly declared local
; (as of AHK 1.0.46.10, StringSplit creates them as local variables either way
; because lineParts0 is local, but references to 'lineParts1' in script refer
; to GLOBAL variables...)
local lineParts1, lineParts2
Loop, Read, %filename%
{
; ignore comments
StringLeft, line, A_LoopReadLine, 1
if ( line = ";" )
continue
; replace " = " with uncommon delimiter
StringReplace, line, A_LoopReadLine, %A_Space%=%A_Space%,
; split the string into (hopefully) two parts: variable, keys to send
StringSplit, lineParts, line, , %A_Space%%A_Tab%
if ( lineParts0 == 2 )
{ ; first search for a window ( <win> )
StringReplace, comando, lineParts2, <win>, Ì
StringSplit, command, comando, Ì, %A_Space%%A_Tab%
if (command0 == 2)
{ ; if there´s one, separate the id and the window
StringReplace, comando, command2, <=>, Ì
StringSplit, command, comando, Ì, %A_Space%%A_Tab%
%lineParts1%_ID_%command1% := lineParts2
%lineParts1%%_ID_%WIN := command2
}
else
{
if ( StrLen(lineParts1) > 0 )
{
; allow underscores by removing them from comparison
StringReplace, varname, lineParts1, _, , All
; check if variable name is alphanumeric
if varname is alnum
%lineParts1% := lineParts2
}
else
{
MsgBox empty variable name on line %A_Index%
}
}
}
}
}
WM_COMMAND(wParam, lParam)
{
static IsPaused, IsSuspended
Critical
id := wParam & 0xFFFF
if id in 65305,65404,65306,65403
{ ; "Suspend Hotkeys" or "Pause Script"
if id in 65306,65403 ; pause
IsPaused := ! IsPaused
else ; at this point, A_IsSuspended has not yet been toggled.
IsSuspended := ! A_IsSuspended
G_SetTrayIcon(!(IsPaused or IsSuspended))
}
}
G_SetTrayIcon(is_enabled)
{
icon := is_enabled ? "gestures.ico" : "nogestures.ico"
icon = %A_ScriptDir%\%icon%
; avoid an error message if the icon doesn't exist
IfExist, %icon%
Menu, TRAY, Icon, %icon%,, 1
}
RemoveToolTip:
SetTimer, RemoveToolTip, Off
ToolTip
return
getVars() {
DetectHiddenWindows, On
IfEqual Section,, SetEnv Section, Key
HidWin := WinExist(A_ScriptFullPath " - AutoHotkey v")
OldPar := DllCall("GetParent", UInt,HidWin)
GUI +LastFound
DllCall("SetParent", UInt,HidWin, UInt,WinExist("ahk_class Shell_TrayWnd"))
WinMenuSelectItem ahk_id %HidWin%,,View, Variables
Sleep 0
ControlGetText str, Edit1, ahk_id %HidWin%
WinHide ahk_id %HidWin%
DllCall("SetParent", UInt,HidWin, UInt,OldPar)
Out1 := ""
Loop, Parse, str, `n, `r
{
if SubStr(A_LoopField, 1, 8) == "Gesture_"
Out1 .= A_LoopField . "ß"
}
Return Out1
}
getWins(var, vars)
{
out := ""
Loop, Parse, vars, ß
{
if ( SubStr(A_LoopField,1, StrLen(var)) == var)
out := out . A_LoopField . "ß"
}
return out
}
RunDebugView(){
debuggerpath .= "c:\programme\autohotkey\DebugView\Dbgview.exe"
debuggerTitel := "DebugView on \\" . A_ComputerName . " (local)"
IfExist, %debuggerpath%
ifwinNotexist, %debuggerTitel%
Run, %debuggerpath%
}
|
| Code: |
; Syntax:
; %c_GesturePrefix%_%zone1%_%zone2%_%zoneN% = keys (in Send-compatible format)
Gesture_WheelUp = ^+{Tab}
Gesture_WheelDown = ^{Tab}
Gesture_L_U = !{Up}
Gesture_D_U = {Browser_Home}
Gesture_DR_R = !{g}
Gesture_D_R = ^{F4}
Gesture_D_R_L = !{F4}
Gesture_L_DR = {Browser_Back}
Gesture_D_UR = ^{End}
Gesture_U_DR = ^{Home}
Gesture_U_UR = #c
Gesture_D = comandoScite<win>Scite<=>- SciTE
; with this text; ahk_class SciTEWindow, instead of the title doesnt work, y tried with regex too. Maibe you can see what is wrong
Gesture_D = comandoFirefox<win>Firefox<=>- Mozilla Firefox
; Override Options specified in "Gestures Default.ahk"
m_GestureKey = RButton
m_GestureKey2 =
|
Thanks a lot!
Juan |
|
| Back to top |
|
 |
automaticman
Joined: 27 Oct 2006 Posts: 320
|
Posted: Fri Feb 22, 2008 12:21 pm Post subject: |
|
|
Thanks for sharing. I didn't "download" and try it out yet. As I prefer inputting mostly with the keys I'm not sure if I would use these gestures "often". Then I would have to leave the keyboard and move the mouse. But in contrary it might be useful if I already switched over to the mouse (because I had to) then those gestures might free me from jumping back to the keyboard just to fire some hotkeys.
I don't know how your solution works but interesting would be also having one "multiplication gesture", when triggered, opening a GUI with buttons in it like: DoThis, DoThat, AplicationXDoThis, ApplicationYDoThat which you can press and the GUI disappears again (similar to nDroid's GUI maybe). This would give us a multiplicative operation on gestures using
+ gesture + click on gui
as input mechanism. (Similar to this idea is enterpad here. Our enterpad would be the GUI.)
Maybe I should reactivate my Wacom tablet to try out these gestures.
+ The next step could be a ZUI enterpad, we wouldn't be limited to a given window size. We could zoom in/out into various regions and so have 1000's of hotkey/automation buttons in front of us.  |
|
| Back to top |
|
 |
jpsala
Joined: 21 Jan 2008 Posts: 7
|
Posted: Fri Feb 22, 2008 2:35 pm Post subject: |
|
|
yep, I like your ideas but don´t have the energy, nor the knowledge of autohotkey to do it, I hope someone can do it.
I don´t use the mouse either, but when surfing and researching the keyboard, with some minor exceptions, like gmail, is useless.
Thanks for the feedback
[ Moderator!: Please do not top-post., ie dont quote the entire previous post unneccessarily. This is not practiced in our forum. ] |
|
| Back to top |
|
 |
automaticman
Joined: 27 Oct 2006 Posts: 320
|
Posted: Fri Feb 22, 2008 2:40 pm Post subject: |
|
|
This package seems not to include gestures for copy
paste
cut
delete
undo and these are among the most general operations used all over applications.
+ Principle: Increasing it's power by increasing it's quantitative impact. |
|
| Back to top |
|
 |
jpsala
Joined: 21 Jan 2008 Posts: 7
|
Posted: Fri Feb 22, 2008 2:54 pm Post subject: |
|
|
| no, you can make your own gestures easily, just take a look at the files and the examples and youll be making yours in no time, if you come up with some idea tell me, good luck |
|
| Back to top |
|
 |
automaticman
Joined: 27 Oct 2006 Posts: 320
|
Posted: Fri Feb 22, 2008 2:58 pm Post subject: |
|
|
| I would apply gestures more to general operations as written above than "small space operations". |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|