GetMouseGesture() - as simple as mouse gestures can get! [updated]

Post your working scripts, libraries and tools
CyL0N
Posts: 211
Joined: 27 Sep 2018, 09:58

GetMouseGesture() - as simple as mouse gestures can get! [updated]

05 Oct 2018, 20:48

I know there's more than plenty of mouse gesture scripts, but they all tend to have one thing in common, they're bloated, my implementation is a tiny function that returns mouse gestures per designated hotkey...

Code: Select all

UDL(){	;function defined gesture example for example below
	MsgBox
}

~Ctrl::		;gesture hotkey, i imagine most would use a mousekey for gestures,ctrl is simply an example suitable for testing as i've got radial menu running...
GetMouseGesture(True)
While GetKeyState(LTrim(A_ThisHotkey,"~")){
	ToolTip % MG := GetMouseGesture()
	Sleep 150
}
IsFunc(MG) ? %MG%() : ""	;example allows creation of gestures by defining functions that comprise U,D,R,L as function name,with no upper limit on the extent of the gesture,i.e UDUDUDUDL for ex.
ToolTip
GetMouseGesture(True)
Return


GetMouseGesture(reset := false){
	Static
	mousegetpos,xpos2, ypos2
	dx:=xpos2-xpos1,dy:=ypos1-ypos2
	,( abs(dy) >= abs(dx) ? (dy > 0 ? (track:="u") : (track:="d")) : (dx > 0 ? (track:="r") : (track:="l")) )	;track is up or down, left or right
	,abs(dy)<4 and abs(dx)<4 ? (track := "") : ""	;not tracking at all if no significant change in x or y
	,xpos1:=xpos2,ypos1:=ypos2
	,track<>SubStr(gesture, 0, 1) ? (gesture := gesture . track) : ""	;ignore track if not changing since previous track
	,gesture := reset ? "" : gesture
	Return gesture
}

I've Added a Function to extend the functionality of this function here: MouseQuadrant

Code: Select all

~Ctrl::		;gesture hotkey, i imagine most would use a mousekey for gestures,ctrl is simply an example suitable for testing as i've got radial menu running...
	GetMouseGesture(True)
	While GetKeyState(LTrim(A_ThisHotkey,"~")){
		ToolTip % MG := GetMouseGesture()
		Sleep 150
	}
	;left <= 20% of screen width, right >= 80% of screen width, top <= 20% of screen height, bottom >= 80% of screen height
	MQ := SubStr(MouseQuadrant(20,80,20,80),1,1)	;take only the first letter of the quadrant,for simplified function names...
	IsFunc(MG "_" MQ) ? %MG%_%MQ%() : (IsFunc(MG) ? %MG%() : "")	;example allows creation of gestures by defining functions that comprise U,D,R,L as function name,with no upper limit on the extent of the gesture,i.e UDUDUDUDL for ex.
	ToolTip
	GetMouseGesture(True)
Return


UDL(){
	MsgBox % "Function Run,if no function was defined for specific quadrant. Or Quadrant Has No Assigned Function.`n`n CurrentQuadrant:`n`t" MouseQuadrant(20,80,20,80)
}

UDL_T(){	;function defined gesture example for example below
	MsgBox Gesture On Top
}

UDL_L(){	;function defined gesture example for example below
	MsgBox Gesture To The LEFT
}

UDL_R(){	;function defined gesture example for example below
	MsgBox Gesture To The Right
}


;returns if screen is on top,bottom,center,left,right area of screen given the defined scope in percent of each area...see example.
/*
					Top
	___________________________________
	L	|						|	R
	E	|						|	y
	F	|		C E N T E R		|	T
	T	|						|
	____|_______________________|______
					Bottom
*/
;defined scopes are in 'percent',i.e left scope means anything below defined % is designated left,right scope is anything above defined %...
MouseQuadrant(leftScope,rightScope,topScope,bottomScope,coordMode:="screen"){	;coordMode should either be 'window' or 'screen'
	CoordMode, Mouse, % coordMode
	MouseGetPos, mX, mY, mHwnd, mCtrl
	WinGetPos, wX, wY, wW, hH, A
	
	If (mX <= leftScope/100*(coordMode = "screen" ? A_ScreenWidth : wW) && mY >= topScope/100*(coordMode = "screen" ? A_ScreenHeight : hH) && mY <= bottomScope/100*(coordMode = "screen" ? A_ScreenHeight : hH))
		Return "LEFT"
	Else If (mX >= rightScope/100*(coordMode = "screen" ? A_ScreenWidth : wW) && mY >= topScope/100*(coordMode = "screen" ? A_ScreenHeight : hH) && mY <= bottomScope/100*(coordMode = "screen" ? A_ScreenHeight : hH))
		Return "RIGHT"
	Else If (mY <= topScope/100*(coordMode = "screen" ? A_ScreenHeight : hH))
		Return "TOP"
	Else If (mY >= bottomScope/100*(coordMode = "screen" ? A_ScreenHeight : hH))
		Return "BOTTOM"
	Else
		Return "CENTER"
	
}


GetMouseGesture(reset := false){
	Static
	mousegetpos,xpos2, ypos2
	dx:=xpos2-xpos1,dy:=ypos1-ypos2
	,( abs(dy) >= abs(dx) ? (dy > 0 ? (track:="u") : (track:="d")) : (dx > 0 ? (track:="r") : (track:="l")) )	;track is up or down, left or right
	,abs(dy)<4 and abs(dx)<4 ? (track := "") : ""	;not tracking at all if no significant change in x or y
	,xpos1:=xpos2,ypos1:=ypos2
	,track<>SubStr(gesture, 0, 1) ? (gesture := gesture . track) : ""	;ignore track if not changing since previous track
	,gesture := reset ? "" : gesture
	Return gesture
}
Last edited by CyL0N on 09 Dec 2018, 11:22, edited 2 times in total.
live ? long & prosper : regards
User avatar
Thoughtfu1Tux
Posts: 101
Joined: 31 May 2018, 23:26

Re: GetMouseGesture() - as simple as mouse gestures can get!

07 Oct 2018, 03:29

Awesome script!

I actually use Raidial Menu as the main part of my daily workflow.
Did you replace the Gestures in Radial Menu with this function? The ability to do more than 3 gestures before timing out would be really great to increase the flexibility of my RadialMenu.

If you did, I'd love to hear how you went at doing it!
CyL0N
Posts: 211
Joined: 27 Sep 2018, 09:58

Re: GetMouseGesture() - as simple as mouse gestures can get!

07 Oct 2018, 05:03

Thoughtfu1Tux wrote:Awesome script!

I actually use Raidial Menu as the main part of my daily workflow.
Did you replace the Gestures in Radial Menu with this function? The ability to do more than 3 gestures before timing out would be really great to increase the flexibility of my RadialMenu.

If you did, I'd love to hear how you went at doing it!
Thanks! ;)

Radial Menu is my jam as well, and infact that was exactly what inspired this script,i ran out of gestures,crazy as that may be.
But instead of replacing the built in function,which i didn't want to replace so i don't have problems when RM gets updated,i added GetMouseGesture() to the 'RM\MyCodes\My Functions.ahk' file in RM and added a custom hotkey, MButton to 'RM\MyCodes\My Hotkeys.ahk' and i can add new gesture functions to the 'RM\MyCodes\My Hotkeys.ahk' file and so long as i use my hotkey they execute all the same,and unlike the main RM gesture key RButton moving down isn't restricted so it opens up newer gestures that are otherwise unavailable as down gesture is reserved in RM.

A few of my default(RButton) RM gestures for the curious few:
  • RD - hide window-onlyOneAtATime
    RU - restore hidden window

    LD - alt-tab menu
    LU - reading lines

    LUR - display time & date
    RUL - Reminders

    U - play/pause/refresh/save(np2)/enter(npp,codequicktester)/esc(HUD CapsLock Launcher)/parentDir(explorer) - CONTEXTUAL
    UD - ESCAPE
    UDU - cut/copy/paste button menu
    LDR - close active window/ close browser tab/ close explorer tab - shape is a 'C' - CONTEXTUAL

    URU - shortcut menu
    URD - recent items
    UR - navigator / ConvertSelected.ToOption Menu(includes Record options)
    URL - metashortcut
    UL - favourites menu
    ULR - tray menu

    UDL - wifi disconnect
    UDR - wifi connect

    ULU - reload radial menu
    ULD - HUD Capslock shell
    UDU - secondary radial menu

    LR - backspace
    L - 'reserved'
    R - 'reserved'
    RL - Volume Presets
live ? long & prosper : regards
Banayat
Posts: 10
Joined: 08 Jul 2018, 14:29

Re: GetMouseGesture() - as simple as mouse gestures can get!

21 Oct 2018, 07:01

I still don't understand your example at all. No matter what gesture I set up everything has been executed :wtf: :lol:
While GetKeyState(LTrim(A_ThisHotkey,"~")
Also, why is that "~" implemented?

Could you please explain more how to create a gesture? :P
burque505
Posts: 1305
Joined: 22 Jan 2017, 19:37

Re: GetMouseGesture() - as simple as mouse gestures can get!

21 Oct 2018, 08:34

Really nice coding, CyLON :clap:

@Banayat, maybe this example will help.
Run it, hold down the Control key. Move the mouse, up, down, then left. "udl" should appear in the tooltip.
Release the Control key. Firefox should load the AHK page.
Hold down the Control key. Move the mouse, up, down, then right. "udr" should appear in the tooltip.
Release the Control key. A MsgBox will appear.

Code: Select all

SetTitleMatchMode, 2

UDL(){	;function defined gesture example for example below
	;MsgBox up down left
	Run, firefox.exe https://autohotkey.com
	SplashTextOn, 100, 100, Loading, Loading ...
	sleep, 1000
	SplashTextOff
}
return

UDR() {
msgbox Up down right
}
return

;For this example, press and hold Control. Then, move the mouse up, down, left, in that order.
;When you see the tooltip read "udl", release the Control key. Firefox should load the AHK page.
~Ctrl::		;gesture hotkey, i imagine most would use a mousekey for gestures,ctrl is simply an example suitable for testing as i've got radial menu running...
GetMouseGesture(True)
While GetKeyState(LTrim(A_ThisHotkey,"~")){
	ToolTip % MG := GetMouseGesture()
	Sleep 150
}
IsFunc(MG) ? %MG%() : ""	;example allows creation of gestures by defining functions that comprise U,D,R,L as function name,with no upper limit on the extent of the gesture,i.e UDUDUDUDL for ex.
ToolTip
GetMouseGesture(True)
Return


GetMouseGesture(reset := false){
	Static
	mousegetpos,xpos2, ypos2
	dx:=xpos2-xpos1,dy:=ypos1-ypos2
	,( abs(dy) >= abs(dx) ? (dy > 0 ? (track:="u") : (track:="d")) : (dx > 0 ? (track:="r") : (track:="l")) )	;track is up or down, left or right
	,abs(dy)<4 and abs(dx)<4 ? (track := "") : ""	;not tracking at all if no significant change in x or y
	,xpos1:=xpos2,ypos1:=ypos2
	,track<>SubStr(gesture, 0, 1) ? (gesture := gesture . track) : ""	;ignore track if not changing since previous track
	,gesture := reset ? "" : gesture
	Return gesture
}

Escape::ExitApp
Regards,
burque505
CyL0N
Posts: 211
Joined: 27 Sep 2018, 09:58

Re: GetMouseGesture() - as simple as mouse gestures can get!

21 Oct 2018, 14:11

@burque505, Thanks dude.


Banayat wrote:
21 Oct 2018, 07:01
I still don't understand your example at all. No matter what gesture I set up everything has been executed :wtf: :lol:
While GetKeyState(LTrim(A_ThisHotkey,"~")
Also, why is that "~" implemented?

Could you please explain more how to create a gesture? :P
I think burque's example was more than sufficient, but to answer your other questions, ~ signifies that the the script won't 'Block' the hotkey it creates,so that it can be used by other applications, While GetKeyState(LTrim(A_ThisHotkey,"~") simply abstracts all mouse movement while the key is held,with LTrim() being used to prun the ~ modifier we added to the hotkey.
live ? long & prosper : regards
tuzi
Posts: 11
Joined: 27 Apr 2016, 23:40

Re: GetMouseGesture() - as simple as mouse gestures can get!

08 Dec 2018, 10:38

great work!it help me a lot!i just come on here to say thank you!!! :D :D :D
CyL0N
Posts: 211
Joined: 27 Sep 2018, 09:58

Re: GetMouseGesture() - as simple as mouse gestures can get!

09 Dec 2018, 11:18

tuzi wrote:
08 Dec 2018, 10:38
great work!it help me a lot!i just come on here to say thank you!!! :D :D :D
Your Most Welcome,glad you found it useful...

You might find this useful too, MouseQuadrant,
the second example specifically, i extended this function a while back,but forgot to post it... I've updated this OP with the example from that topic.

Cheers.
live ? long & prosper : regards
User avatar
hasantr
Posts: 496
Joined: 05 Apr 2016, 14:18
Location: İstanbul

Re: GetMouseGesture() - as simple as mouse gestures can get! [updated]

18 Dec 2018, 08:19

This is really awesome. Very comfortable. I just didn't know how to use RButton. If you do not have a defined Gesture but the contex menu can be opened at that time. But the contex menu opens every time I try.
CyL0N
Posts: 211
Joined: 27 Sep 2018, 09:58

Re: GetMouseGesture() - as simple as mouse gestures can get! [updated]

18 Dec 2018, 23:52

hasantr wrote:
18 Dec 2018, 08:19
This is really awesome. Very comfortable. I just didn't know how to use RButton. If you do not have a defined Gesture but the contex menu can be opened at that time. But the contex menu opens every time I try.
I'm glad you like it...
Here's how you would use RButton, when you CLICK RButton, it' will pop a context menu as usual, but if you HOLD it, it will treat the press as a gesture...

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.


UDL(){	;function defined gesture example for example below
	MsgBox
}

RButton::		;gesture hotkey, i imagine most would use a mousekey for gestures,ctrl is simply an example suitable for testing as i've got radial menu running...
KeyWait, %A_ThisHotkey%, T0.1	;to identify if hotkey was pressed or held...
If ErrorLevel{
	;hotkey is being held down so treat it as a gesture...
	GetMouseGesture(True)
	While GetKeyState(LTrim(A_ThisHotkey,"~"), "P"){
		ToolTip % MG := GetMouseGesture()
		Sleep 150
	}
	IsFunc(MG) ? %MG%() : ""	;example allows creation of gestures by defining functions that comprise U,D,R,L as function name,with no upper limit on the extent of the gesture,i.e UDUDUDUDL for ex.
	ToolTip
	GetMouseGesture(True)
}Else
	Send  {%A_ThisHotkey%}	;if ordinary press, just let the press,passthrough...
Return


GetMouseGesture(reset := false){
	Static
	mousegetpos,xpos2, ypos2
	dx:=xpos2-xpos1,dy:=ypos1-ypos2
	,( abs(dy) >= abs(dx) ? (dy > 0 ? (track:="u") : (track:="d")) : (dx > 0 ? (track:="r") : (track:="l")) )	;track is up or down, left or right
	,abs(dy)<4 and abs(dx)<4 ? (track := "") : ""	;not tracking at all if no significant change in x or y
	,xpos1:=xpos2,ypos1:=ypos2
	,track<>SubStr(gesture, 0, 1) ? (gesture := gesture . track) : ""	;ignore track if not changing since previous track
	,gesture := reset ? "" : gesture
	Return gesture
}

Cheers.
live ? long & prosper : regards
ethanross1a
Posts: 16
Joined: 18 Sep 2019, 18:36

Re: GetMouseGesture() - as simple as mouse gestures can get! [updated]

11 Oct 2019, 19:39

Awsome work. but the rightclick still gets executed. how do you prevent that?
blue83
Posts: 117
Joined: 11 Apr 2018, 06:38

Re: GetMouseGesture() - as simple as mouse gestures can get! [updated]

16 Oct 2019, 07:44

Or maybe this example:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.


c::		;gesture hotkey, i imagine most would use a mousekey for gestures,ctrl is simply an example suitable for testing as i've got radial menu running...
var := ""
var := "something"
ToolTip % MG := GetMouseGesture()
Return


GetMouseGesture(reset := false){
	global
	mousegetpos,xpos2, ypos2
	dx:=xpos2-xpos1,dy:=ypos1-ypos2
	,( abs(dy) >= abs(dx) ? (dy > 0 ? (track:="u") : (track:="d")) : (dx > 0 ? (track:="r") : (track:="l")) )	;track is up or down, left or right
	,abs(dy)<4 and abs(dx)<4 ? (track := "") : ""	;not tracking at all if no significant change in x or y
	,xpos1:=xpos2,ypos1:=ypos2
	Return var
}

F8:: ExitApp
vinnygc
Posts: 1
Joined: 01 Jul 2020, 20:04

Re: GetMouseGesture() - as simple as mouse gestures can get! [updated]

01 Jul 2020, 20:27

Dude, this is nice, and clean! Hat's off to you mate :)
I'm new to AHK, only came across it looking for alternatives to StrokeIt, so this was exactly what I was looking for.
Additionally, I've extended your GetMouseGesture() function to include diagonal directions (N,E,W,S - North, East, West, South - compass tilted diagonally to the right):

Code: Select all

GetMouseGesture(reset := false){
	Static
	mousegetpos,xpos2, ypos2
	dx:=xpos2-xpos1,dy:=ypos1-ypos2
	,dx>0 ? (dy > 0 ? (track:="N") : (track:="E")) : (dy > 0? (track:="W") : (track:="S")) ; track is N,E,W,S - compass, tilted right
	,abs(dy) >= 2.4142*abs(dx) ? (dy > 0 ? (track:="U") : (track:="D")) : "" ;track is up or down
	,abs(dx) >= 2.4142*abs(dy) ? (dx > 0 ? (track:="R") : (track:="L")) : "" ;track is left or right
	,abs(dy)<4 and abs(dx)<4 ? (track := "") : ""	;not tracking at all if no significant change in x or y
	,xpos1:=xpos2,ypos1:=ypos2
	,track<>SubStr(gesture, 0, 1) ? (gesture := gesture . track) : ""	;ignore track if not changing since previous track
	,gesture := reset ? "" : gesture
	Return gesture
}
Allows greater variety in gestures (eg, alphabetic characters like 'M' with diagonal strokes: UEND). The '2.4142' is how narrow the window for vertical/horizontal directions are ( ~ tan(3*pi/8), so angles split equally here).
Cheers dude!

Return to “Scripts and Functions”

Who is online

Users browsing this forum: Rafaews and 87 guests