 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
barty
Joined: 30 Aug 2009 Posts: 10
|
Posted: Sun Sep 06, 2009 7:57 pm Post subject: Key gestures? |
|
|
Hi
I'd like a way to do "key gestures", to fire action on certain pattern of key input.
example: it's great that I can easily map RCtrl by itself to an action. But I want to be able to do something like
a) quickly tapping rctrl, do X
b) double tapping rctrl, do Y
c) if rctrl held down for 1-2 sec and let go, do nothing.
d) if rctrl held down for > 3 sec, do Z
b) may be tricky, but the rest should be very doable.
I'm handicapped so I'm always looking out for ways to do a lot of different actions while hitting as few key combinations as possible. Also, certain keys are easier for me to hit so I want to "overload" them.
I'd appreciate any pointers . thanks in advance. |
|
| Back to top |
|
 |
AnttiV
Joined: 14 Aug 2009 Posts: 237 Location: Finland
|
Posted: Sun Sep 06, 2009 9:40 pm Post subject: |
|
|
Just a quick note, I'm trying to tackle this script I have time-based clicking working, now I just have to check if you press the button quickly, and how many times. I'll post results when I get something working  |
|
| Back to top |
|
 |
SoLong&Thx4AllTheFish
Joined: 27 May 2007 Posts: 4999
|
|
| Back to top |
|
 |
AnttiV
Joined: 14 Aug 2009 Posts: 237 Location: Finland
|
Posted: Sun Sep 06, 2009 10:43 pm Post subject: |
|
|
Thanks HugoV, I managed to make my code a bit more readable with that example. (I was going with a similiar code, but that was shorter).
But, here:
| Code: | #SingleInstance Force
#Persistent
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
TimeToAllow := 1000 ; allow 1000ms (one second) for second click, adjust this as needed!
RControl::
SetTimer, CountMe, 10
Counter := 0
Loop, 300
{
Sleep, 10
Counter++
GetKeyState, KeyState, RControl, P
If KeyState=U
Break
}
If Counter = 300 ; held down 3 sec
{
MsgBox, You held RControl down for 3 sec.
}
If Counter < 100 ; held down under 1 sec
{
Pushed++ ; count clicks
}
Return
CountMe:
Timer += 10
GetKeyState, KeyState, RControl, P
If Timer > %TimeToAllow% ; Allowed time passed
{
If KeyState=U ; do nothing if key is still held down
{
If Pushed = 1
{
MsgBox, You pressed RControl once in %TimeToAllow%ms.
}
Else If Pushed = 2
{
MsgBox, You Pressed RControl twice in %TimeToAllow%ms.
}
Else
{
MsgBox, You Pressed RControl more than twice in %TimeToAllow%ms.
}
}
Pushed := 0 ; Allowed time passed, reset clicks
Timer := 0 ; reset timer
SetTimer, CountMe ,Off ; turn counter off
}
Return |
This (at least seems to) works for me. adjust the TimeToAllow variable as you like. It's the time the script waits for you to press multiple times, and fires off the code only after that time is passed. I left it at 1 second, but as low as 200ms should be ok. (I couldn't click faster, and the script seemed to fail if set to 100ms.) In my opinion, 300-500ms seems like the sweet spot.
Anyways, see if this is what you want and let me know  |
|
| Back to top |
|
 |
barty
Joined: 30 Aug 2009 Posts: 10
|
Posted: Mon Sep 07, 2009 6:13 pm Post subject: |
|
|
here's what I came up with. It's a little convoluted but I think it works
code:
| Code: |
LastLength := 0
; return how long current key was held down
TapLength() {
t := A_TickCount
key := RegExReplace(A_ThisHotKey,"[\*\~\$\#\+\!\^]")
Loop {
Sleep, 10
GetKeyState, KeyState, %key%, P
If KeyState=U
Break
}
return (A_TickCount - t)
}
; return true if key was tapped cnt times
Tapped( cnt) {
return TapCount(cnt)=cnt
}
; count number of taps of current key up to max
; if number of taps reaches max, return immediately rather than wait for another tap
; on exit, LastLength contains how msec long last tap was held down
TapCount(max = 9999)
{
global LastLength
key := RegExReplace(A_ThisHotKey,"[\*\~\$\#\+\!\^]")
cnt := 0
loop {
LastLength := TapLength()
; key held down too long?
if (LastLength > 300)
return cnt
cnt++
; got what we wanted?
if (cnt>=max)
return cnt
l := A_TickCount
; wait next key
KeyWait %key%, D T0.2
LastLength := A_TickCount - l
; key did not come?
if (ErrorLevel)
return cnt
}
}
|
usage examples:
| Code: |
~RControl::
cnt := TapCount(2)
/*
if (cnt>0)
msgbox tapped %cnt% times
else
msgbox held down %LastLength% msec
*/
if cnt = 1
Send {F3}
else
if cnt = 2
Send ^f
return
~RShift::
if Tapped(1)
Send {Esc}
return
|
I have 2 subtly different ways of using this:
1) I use Tapped(n) when I want to fire an action IMMEDIATELY on reaching a specific # of taps.
2) I use TabCount() when I want to do different things based on number of taps.
Note that I need to use ~RControl to pass along normal control + key.
There's a flaw with this and I haven't figured out a workaround. If I hit rshift+A and let go very quickly, both shift+A and the hotkey action I defined above will fire. This isn't a real problem for me since I'm not a touch typist, but the problem is there. |
|
| Back to top |
|
 |
SoLong&Thx4AllTheFish
Joined: 27 May 2007 Posts: 4999
|
|
| 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
|