Author |
Topic |
|
mousemagician
6 Posts |
Posted - 06/21/2013 : 11:18:15
|
Gesture area/size/length based actions.
Still new to S+ and all hooked up in trying to find something nice to do i found that (ab-)using the size of a gesture to change it's behavior is quite useful especially for actions that work on a linear scale. E.g. "turn volume up", "scroll a few pages".
So i came up with first two methods to gauge the gesture size:
------------ ### Global Lua ### ------------ function myGetGestureDiagonal(t,r,b,l,step) -- calculates the diagonal of the gesture bounding area -- returns 1+number of steps as approximate gesture scale local diagonal = math.sqrt((t-b)^2+(r-l)^2) return math.floor(diagonal/step)+1 end
function myGetGestureArea(t,r,b,l,step) -- calculate total area of gesture rectangle -- returns 1+number of steps as approximate gesture scale return math.floor(math.abs((t-b)*(r-l))/step)+1 end ------------ ### Global Lua ### ------------
These should theoretically work fine on multi-monitor, even if some screens have negative coordinates. Both functions need to be passed the parameters of the gesture bounding box (gbt,gbr,gbb,gbl) as first four parameters. The step parameter then devides the diagonal/area to produce a more meaningful number. For example my gestures usually have a diagonal of about 100-200 pixels and an area of 10000-20000 square pixels, so for myGetGestureDiagonal i use step=150, which means that every time i draw the gesture 150 pixels larger, the number returned by myGetGestureDiagonal would grow by one. So for a standard gesture it returns 1, for a gesture larger than 150px it returns 2, etc. For myGetGestureArea a step size of 15000 would probably be appropriate. I personally prefer to use the diagonal because it's more "stable", aka it has approximately the same values for one-dimensional gestures like straight lines, and two-dimensional gestures, like letters, so it's easier to get a feeling of how large you have to draw to trigger the next step.
Here's some examples which i use as actions:
---ACTION1:SET VOLUME---
-- set the volume according to gesture diagonal
d = myGetGestureArea(gbt,gbr,gbb,gbl,15000)
acSetVolume(d*10, 0) -- set volume, increase by 10 per step
-- display a small number of the resulting volume change near the cursor
fontsize=24
acDisplayText("[Vol=" .. d*10 .. "]", "Arial", fontsize, 0, 200, 0, 500, gex-fontsize, gey-fontsize)
---ACTION2:QUICK NAVIGATE---
-- navigate several pages back, one page per step
d = myGetGestureDiagonal(gbt,gbr,gbb,gbl,150)
for i=1,d,1 do
-- <for customizing delete acSendKeys and acDelay and put your stuff here>
acSendKeys("{BROWSERBACK}") -- presses this button once per step
acDelay(50) -- most applications require a few ms to process keypresses
end
-- and display a small hint again
fontsize=24
acDisplayText("[=" .. d .. "]", "Arial", fontsize, 0, 200, 0, 500, gex-fontsize, gey-fontsize)
---ACTION3:CASE BY CASE EXAMPLE---
-- of course you can also use this to do entirely different things for different sizes
d = myGetGestureDiagonal(gbt,gbr,gbb,gbl,150)
if d == 1 then
-- catch a magic butterfly
elseif d == 2 then
-- sudo make sandwich
elseif d <= 4 then
-- run out of in-jokes
elseif d <=42 then
-- destroy earth
end
Hope you enjoy these and get rid of having to draw the same gesture 10 times in a row ^_^. |
Edited by - mousemagician on 07/05/2013 06:14:49 |
|
XilE
10 Posts |
Posted - 07/02/2013 : 02:50:43
|
Thank you!! This is a perfect way to stop accidental triggering without actually having to set a modifier key. However the = did not work for me I had to use it as ==
Like my orig close tab was this. ---------------------------- acConsumePhysicalInput(1) acActivateWindow(nil, gsx, gsy, 0) acMouseClick(1919, 0, 2, 1, 1) acMouseMove(gex, gey) acConsumePhysicalInput(0) ------------------------------- I know it can be done with a hotkey, but with my FF add-on it works better my way. ----------------------- d = myGetGestureDiagonal(gbt,gbr,gbb,gbl,200) if d == 1 then acDelay(1) elseif d == 2 then acConsumePhysicalInput(1) acActivateWindow(nil, gsx, gsy, 0) acMouseClick(1919, 0, 2, 1, 1) acMouseMove(gex, gey) acConsumePhysicalInput(0) elseif d >= 3 then acConsumePhysicalInput(1) acActivateWindow(nil, gsx, gsy, 0) acMouseClick(1919, 0, 2, 1, 1) acMouseMove(gex, gey) acConsumePhysicalInput(0) end ----------------------------
Anyways thanks again :) this is going to be very useful for Photoshop and some AutoHotkey triggers as well. :P |
Edited by - XilE on 07/02/2013 03:51:12 |
|
|
mousemagician
6 Posts |
Posted - 07/05/2013 : 06:21:20
|
Nice to know you find it this useful. I'm not exactly sure what you're trying to do/click from reading your script. E.g. the acDelay(1) is a total mystery to me and the lower two elseif blocks seem to be the same. If you're trying to just have "click if gesture larger than 200" then you could replace the lower block of your code with just:
d = myGetGestureDiagonal(gbt,gbr,gbb,gbl,200)
if d >= 2 then
acConsumePhysicalInput(1)
acActivateWindow(nil, gsx, gsy, 0)
acMouseClick(1919, 0, 2, 1, 1)
acMouseMove(gex, gey)
acConsumePhysicalInput(0)
end
Which automagically does nothing if the gesture was too short ;) (PS:Corrected the original post which erroneously stated if d = x instead of if d == x. Thanks for the hint) |
Edited by - mousemagician on 07/05/2013 06:22:41 |
|
|
|
Topic |
|
|
|