Detect drag then "shake" a file as a trigger for an action.

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Epoch
Posts: 41
Joined: 04 Jun 2021, 11:09

Detect drag then "shake" a file as a trigger for an action.

20 Sep 2022, 12:34

Is it possible to have AHK detect dragging then "shaking" a file? I am working on a "dropper" GUI where the idea is to start dragging a file, then come up with a trigger to fire up the GUI in question, where I'd finally let the drag go and drop the file into specific parts of the GUI, corresponding to different "Open with x program" actions.
I initially thought dragging the file all the way to the right as a trigger, but I think giving it 3-4 right-left swings would be more convenient, provided it works as expected, i.e not firing up with usual drag 'n drop routines such as moving files, not messing with the GUI's dropper function and "destroy"/cancel the entire action if I stop dragging without dropping the file in the GUI.
The "shake" trigger I have in mind is something like this:
79amPMQ8BU.gif
79amPMQ8BU.gif (73.06 KiB) Viewed 402 times
Any ideas? Thanks in advance!
User avatar
pizzapizze
Posts: 44
Joined: 08 May 2019, 15:38

Re: Detect drag then "shake" a file as a trigger for an action.

20 Sep 2022, 17:32

Hi, I made a little script for you. It is triggered when you drag and shake something, it doesnt detect if its in particular a file under your cursor though. I tried it and it works fine.
Between the MARKER comments, you can insert what you want to do if its triggered.

You can also tune the

Code: Select all

min_shake_dist

Code: Select all

min_shakes

Code: Select all

time_to_shake
variables.

Code: Select all

CoordMode, mouse, Screen
min_shake_dist := 80
min_shakes := 6
time_to_shake := 2500

~LButton UP::timedout := True
~LButton::
timedout := False
SetTimer, timeout, off
SetTimer, timeout, %time_to_shake%

shakes := 0
MouseGetPos, initial_x
xr := initial_x
xl := initial_x
While (GetKeyState("LButton") && !timedout)
{
    MouseGetPos, x

    if (x > x2)
    {
        direction := "right"
        xr := x
    }
    if (x < x2)
    {
        direction := "left"
        xl := x
    }

    x2 := x

    if (direction = "right")
        if (xr > (xl + min_shake_dist))
            if (last_shake != "right")
            {
                shakes++
                last_shake := "right"
            }

    if (direction = "left")
        if (xl < (xr - min_shake_dist))
            if (last_shake != "left")
            {
                shakes++
                last_shake := "left"
            }

    if (shakes >= min_shakes)
    {
        ; MARKER
        MsgBox drop the files.
        ; MARKER
        Break
    }
    sleep 10
}

Return

timeout:
SetTimer, timeout, off
timedout := True
Return
Epoch
Posts: 41
Joined: 04 Jun 2021, 11:09

Re: Detect drag then "shake" a file as a trigger for an action.

22 Sep 2022, 13:41

pizzapizze wrote:
20 Sep 2022, 17:32
Hi, I made a little script for you. It is triggered when you drag and shake something, it doesnt detect if its in particular a file under your cursor though. I tried it and it works fine.
Between the MARKER comments, you can insert what you want to do if its triggered.

You can also tune the

Code: Select all

min_shake_dist

Code: Select all

min_shakes

Code: Select all

time_to_shake
variables.

Code: Select all

CoordMode, mouse, Screen
min_shake_dist := 80
min_shakes := 6
time_to_shake := 2500

~LButton UP::timedout := True
~LButton::
timedout := False
SetTimer, timeout, off
SetTimer, timeout, %time_to_shake%

shakes := 0
MouseGetPos, initial_x
xr := initial_x
xl := initial_x
While (GetKeyState("LButton") && !timedout)
{
    MouseGetPos, x

    if (x > x2)
    {
        direction := "right"
        xr := x
    }
    if (x < x2)
    {
        direction := "left"
        xl := x
    }

    x2 := x

    if (direction = "right")
        if (xr > (xl + min_shake_dist))
            if (last_shake != "right")
            {
                shakes++
                last_shake := "right"
            }

    if (direction = "left")
        if (xl < (xr - min_shake_dist))
            if (last_shake != "left")
            {
                shakes++
                last_shake := "left"
            }

    if (shakes >= min_shakes)
    {
        ; MARKER
        MsgBox drop the files.
        ; MARKER
        Break
    }
    sleep 10
}

Return

timeout:
SetTimer, timeout, off
timedout := True
Return
Thanks so much, it's working great, especially with the tuning options. I've tried messing with different positions in the X Axis, attempting initially to come up with a script on my own, but it soon became apparent it wasn't such an easy task, which also explains why I am not able to follow a big part of your script...
Really appreciate the time you dedicated to put this together!
it doesnt detect if its in particular a file under your cursor though.
Since this can be useful in order to minimize the chance of the GUI showing up when I don't drag a file, I came up with the idea of using the always excellent FindText to search for (as a condition for the script to continue) the bottom-right corner of the blue square appearing when you drag a file:

Code: Select all

Text:="|<>*217$9.0k60k60k60k60k60kC1rwz00U"
if (ok:=FindText(X, Y, 846-150000, 1043-150000, 846+150000, 1043+150000, 0, 0, Text))
2dRjKrFgbo_cr.png
2dRjKrFgbo_cr.png (1.7 KiB) Viewed 326 times
I suppose there are more efficient ways to deal with this, but if there are, they demand a higher level of AHK wizardry I don't posses, so unless someone has a better idea, I guess that would do for now, especially since it seems to work fine.






Ideally, I'd like a different GUI popping up, based on the file type (extension - let's say .txt and .mp4) so I get different programs suggested for different file types.
This seems to work alone, but not when I try to combine it with your script:

Code: Select all

Clipboard = 
Send ^c
ClipWait
splitpath, clipboard,,, ext

{
	if % ext = "txt"
		{
			msgbox TXT
;		Run "C:\Windows\System32\notepad.exe" "%clipboard%"
		Return
		}
	else if % ext = "mp4"
		{
		msgbox MP4
;		Run, C:\Program Files (x86)\VideoReDoTVSuite 6.63.7.835b\VideoReDo6.exe %clipboard%
		Return
		}
}

Tried placing it in different places in the script, even outside the MARKER area, but it just doesn't work, usually results in preventing the GUI from showing up altogether.
This is my current working script, maybe you (or anyone else?) have an idea (using the EXT trick from above or something completely different) of how to make it distinguish different filetypes for launching different GUIs?
Also, I suppose someone might want to "shake" things up to do whatever in the future, so I guess this can be helpful. :)
Thanks again!

Code: Select all

#IfWinActive ahk_exe Explorer.EXE

CoordMode, mouse, Screen
min_shake_dist := 100
min_shakes := 6
time_to_shake := 1300

~LButton UP::timedout := True
~LButton::
timedout := False
SetTimer, timeout, off
SetTimer, timeout, %time_to_shake%

shakes := 0
MouseGetPos, initial_x
xr := initial_x
xl := initial_x
While (GetKeyState("LButton") && !timedout)
{
	
Text:="|<>*217$9.0k60k60k60k60k60kC1rwz00U" ; Checking whether a file is actually being dragged using Findtext
if (ok:=FindText(X, Y, 846-150000, 1043-150000, 846+150000, 1043+150000, 0, 0, Text))
		
	
    MouseGetPos, x

    if (x > x2)
    {
        direction := "right"
        xr := x
    }
    if (x < x2)
    {
        direction := "left"
        xl := x
    }

    x2 := x

    if (direction = "right")
        if (xr > (xl + min_shake_dist))
            if (last_shake != "right")
            {
                shakes++
                last_shake := "right"
            }

    if (direction = "left")
        if (xl < (xr - min_shake_dist))
            if (last_shake != "left")
            {
                shakes++
                last_shake := "left"
            }

    if (shakes >= min_shakes)
    {
        ; MARKER
	   
Gui, Dropper: New ; Launching Dropper GUI
Gui, Dropper: Font, s10 w700
Gui, Dropper: Add, Text, y80 vText1, Drag the files here
Gui, Dropper: Show, w200 h200 Center, Dropper

return

DropperGuiDropFiles:
DroppedFile:=A_GuiEvent
    
 WinActivate ahk_class CabinetWClass ; Focusing on Windows Explorer to complete the "run with x program" task
 WinWaitActive ahk_class CabinetWClass
 sleep 20
 Clipboard =
Send ^c
sleep 20
ClipWait 
sleep 20
Run, C:\Program Files (x86)\VideoReDoTVSuite 6.63.7.835b\VideoReDo6.exe %clipboard%
Gui, Dropper: Destroy	  

return

        ; MARKER
        Break
    }
    sleep 10
}

Return

timeout:
SetTimer, timeout, off
timedout := True
Return

	#IfWinActive 


Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: AlFlo and 72 guests