Jump to content

Drag (and Drop) Image Across GUI


3lbuniverse
 Share

Recommended Posts

I just want to be able to move pictures inside a gui and be able to "drop" those pictures into a different, stationary picture. It's basically doing what I want but it is ROUGH. In this example, I have two logo pictures from the autoit example file that are dragable by the mouse. If they are drug over the merlin picture from the autoit example file, the logos are deleted. 


The gui borders are the main problem. They are a mess. If I drag the picture off the gui, it stops the picture, which is fine if I drag the picture back into the gui without releasing the mouse button. But if I release the mouse button outside the window, or even when the image is touching the border, it loses track of the image and I can't move it again. Also, the borders act weird if I move the mouse quickly.


What's going on there? How do I fix it? Is there a better way to approach this whole thing? Some of you are wizards with your DLLs and your other magic things and could probably do something like this in 6 lines of code!

Edit: I realized I should try to do more comments on my code if I want someone to look through it and help me, so I added some. Hope that makes it easier!

Edit 2: I was trying to deal with the problem of what happens when a user drags an image off the gui, it didn't occur to me until an hour or so ago that I could just use MouseMove to create a barrier to prevent the mouse from ever leaving the gui in the 1st place if it is dragging an image. Works fine now but the whole thing is still pretty rough.

If anyone has any ideas on how to clean this up, make it more efficient or wants to blow my mind with a different approach to this thing altogether, I'd still be thrilled to hear from you! Thank you!

 

#include <GUIConstantsEx.au3>
Opt("MouseCoordMode", 0) ;1=absolute, 0=relative, 2=client

$WindowWidth = 1000
$WindowHeight = 700

$Window = GUICreate("Feed Merlin The Logos",$WindowWidth,$WindowHeight)

$PicxTopLeft = 100
$PicyTopLeft = 550
$PicLength = 100
$PicHeight = 50
$2PicxTopLeft = 800
$2PicyTopLeft = 550
$2PicLength = 100
$2PicHeight = 50
$DestinationPicTopLeftX = 450
$DestinationPicTopLeftY = 10
$DestinationPicLength = 100
$DestinationPicHeight = 100

$IsFoodEaten1 = False
$IsFoodEaten2 = False

;2Pictures Dragable with Mouse
$Food = GUICtrlCreatePic("C:\Program Files (x86)\AutoIt3\Examples\GUI\logo4.gif",$PicxTopLeft,$PicyTopLeft,$PicLength,$PicHeight)
$Food2 = GUICtrlCreatePic("C:\Program Files (x86)\AutoIt3\Examples\GUI\mslogo.jpg",$2PicxTopLeft,$2PicyTopLeft,$2PicLength,$2PicHeight)

;Stationary Destination Picture that "Eats" the Dragable pictures if they are moved over this and the mouse button is released.
$HungryWizard = GUICtrlCreatePic("C:\Program Files (x86)\AutoIt3\Examples\GUI\merlin.GIF",$DestinationPicTopLeftX,$DestinationPicTopLeftY,$DestinationPicLength,$DestinationPicHeight)

GUISetState()

While 1
        $msgpath = GUIGetMsg()

Select
    Case $msgpath = $GUI_EVENT_PRIMARYDOWN

$mouse = MouseGetPos()

$mouse[0] -= 3
$mouse[1] -= 25

;Sets boundaries for dragable pictures
$LeftBottomY = $PicyTopLeft + $PicHeight
$RightTopX = $PicxTopLeft + $PicLength

$2LeftBottomY = $2PicyTopLeft + $2PicHeight
$2RightTopX = $2PicxTopLeft + $2PicLength

;Compares mouses current position to 2 dragable pictures to see if mouse is over it
;The code is just repeated twice for each picture, not very efficient yet, I know
    Select
        Case $mouse[0] >= $PicxTopLeft And $mouse[0] <= $RightTopX And $mouse[1] >= $PicyTopLeft And $mouse[1] <= $LeftBottomY

;offsets picture from mouse grab point to keep stable
$xoffset = $mouse[0] - $PicxTopLeft
$yoffset = $mouse[1] - $PicyTopLeft

While 1
    $msg = GUIGetMsg()

        $mouse = MouseGetPos()

$mouse[0] = $mouse[0] - $xoffset - 3
$mouse[1] = $mouse[1] - $yoffset - 25

;Moves Picture around as it is dragged by the mouse with the left button still clicked
If $mouse[0] > 3 And $mouse[0] < $WindowWidth - 25 And $mouse[1] > 0 And $mouse[1] < $WindowHeight - 25 Then GUICtrlSetPos($Food,$mouse[0],$mouse[1])

;Checks if mouse button is released and if the mouse is currently over the stationary destination picture, deletes the picture control if it is...
Select
    Case $msg = $GUI_EVENT_PRIMARYUP And $mouse[0] + $xoffset > $DestinationPicTopLeftX And $mouse[0] + $xoffset < $DestinationPicTopLeftX + $DestinationPicLength And _
         $mouse[1] + $yoffset > $DestinationPicTopLeftY And $mouse[1] + $yoffset < $DestinationPicTopLeftY + $DestinationPicHeight

        $IsFoodEaten1 = True
        GUICtrlDelete($Food)
        ExitLoop

    Case $msg = $GUI_EVENT_PRIMARYUP

;Suppose to keep the pictures position if the mouse is off the gui when the button is released
Select
    Case $mouse[0] > 3 And $mouse[0] < $WindowWidth - 25 And $mouse[1] > 0 And $mouse[1] < $WindowHeight - 25

$PicxTopLeft = $mouse[0]
$PicyTopLeft = $mouse[1]

EndSelect

ExitLoop

EndSelect

Sleep(10)
WEnd


        Case $mouse[0] >= $2PicxTopLeft And $mouse[0] <= $2RightTopX And $mouse[1] >= $2PicyTopLeft And $mouse[1] <= $2LeftBottomY

;offsets picture from mouse grab point to keep stable
$xoffset = $mouse[0] - $2PicxTopLeft
$yoffset = $mouse[1] - $2PicyTopLeft

While 1
    $msg = GUIGetMsg()

        $mouse = MouseGetPos()

$mouse[0] = $mouse[0] - $xoffset - 3
$mouse[1] = $mouse[1] - $yoffset - 25

;Moves Picture around as it is dragged by the mouse with the left button still clicked
If $mouse[0] > 3 And $mouse[0] < $WindowWidth - 25 And $mouse[1] > 0 And $mouse[1] < $WindowHeight - 25 Then GUICtrlSetPos($Food2,$mouse[0],$mouse[1])

;Checks if mouse button is released and if the mouse is currently over the stationary destination picture, deletes the picture control if it is...
Select
    Case $msg = $GUI_EVENT_PRIMARYUP And $mouse[0] + $xoffset > $DestinationPicTopLeftX And $mouse[0] + $xoffset < $DestinationPicTopLeftX + $DestinationPicLength And _
         $mouse[1] + $yoffset > $DestinationPicTopLeftY And $mouse[1] + $yoffset < $DestinationPicTopLeftY + $DestinationPicHeight

        $IsFoodEaten2 = True
        GUICtrlDelete($Food2)
        ExitLoop

    Case $msg = $GUI_EVENT_PRIMARYUP

;Suppose to keep the pictures position if the mouse is off the gui when the button is released
Select
    Case $mouse[0] > 3 And $mouse[0] < $WindowWidth - 25 And $mouse[1] > 0 And $mouse[1] < $WindowHeight - 25

$2PicxTopLeft = $mouse[0]
$2PicyTopLeft = $mouse[1]

EndSelect

ExitLoop

EndSelect

Sleep(10)
WEnd

    EndSelect
    EndSelect

    If $msgpath = $GUI_EVENT_CLOSE Or ($IsFoodEaten1 = True And $IsFoodEaten2 = True) Then Exit

Sleep(10)
WEnd

GUIDelete()


 

Edited by 3lbuniverse
Link to comment
Share on other sites

  • 2 weeks later...

martin, has an example I used: https://www.autoitscript.com/forum/topic/144357-drag-a-control/?do=findComment&comment=1018427

His example runs.  Mine won't, but it drags like this:

; Adapted from: Author: martin
; https://www.autoitscript.com/forum/topic/144357-drag-a-control/?do=findComment&comment=1018427
Func toolbar_drag_control($aCC_GUI_control, $aCC_GUI_binding_control, ByRef $control)

    ; MouseCoordMode
    Opt("MouseCoordMode", $eMouseCoordMode_relavive)

    ; Activate the Binding Window for relative mouse coords
    WinActivate($aCC_GUI_control[$eCC_GUI_control_GUI_binding])

    $aControl_start_pos = ControlGetPos($ghGui_troller, "", $control)

    Do
        $msg = GUIGetMsg()

        ; Are we moving?
        $cInfo = GUIGetCursorInfo($ghGui_troller)
        $aPos = ControlGetPos($ghGui_troller, "", $control)
        $iSubtractX = $cInfo[0] - $aPos[0]
        $iSubtractY = $cInfo[1] - $aPos[1]
        Sleep(200)
        $cInfo = GUIGetCursorInfo($ghGui_troller)
        $cInfo = GUIGetCursorInfo($ghGui_troller)
        ControlMove($ghGui_troller, "", $control, $cInfo[0] - $iSubtractX, $cInfo[1] - $iSubtractY)
    Until _IsPressed(1) = 0

    $aMouse_pos = MouseGetPos()

    Local $dropped_id = -1

    ; Check if over action combo
    For $i = 0 To $gCC_binding_max - 1
        $aControl_Pos = ControlGetPos($aCC_GUI_control[$eCC_GUI_control_GUI_binding], "", $aCC_GUI_binding_control[$i][$eCC_GUI_binding_control_action_pressed_combo])
        If $aMouse_pos[0] >= $aControl_Pos[0] And $aMouse_pos[0] <= $aControl_Pos[0] + $aControl_Pos[2] Then
            If $aMouse_pos[1] >= $aControl_Pos[1] And $aMouse_pos[1] <= $aControl_Pos[1] + $aControl_Pos[3] Then
                $dropped_id = $i
                ExitLoop
            EndIf
        EndIf
    Next

    ; Reset toolbar control
    ControlMove($ghGui_troller, "", $control, $aControl_start_pos[0], $aControl_start_pos[1])

    Return $dropped_id

EndFunc; toolbar_drag_control()

I like your example.  When I have more time I'll see if I can learn from it.

At the moment I can't tell which is better method, I have a lot on my mind.  Yours is pretty cool.

Link to comment
Share on other sites

  • 1 month later...

This might be another way:

Global $hMain

$hMain = GUICreate("Images Move",800,600)
$hPic1 = GUICtrlCreatePic("C:\Program Files (x86)\AutoIt3\Examples\GUI\logo4.gif",10,10,168,68)
$hPic2 = GUICtrlCreatePic("C:\Program Files (x86)\AutoIt3\Examples\GUI\mslogo.jpg",200,200,255,40)
GUISetState(@SW_SHOW,$hMain)

Do
   $aData = GUIGetCursorInfo($hMain)
   If $aData[2] Then
      If $aData[4] Then DropCtrl($aData[4])
   EndIf
   Sleep(10)
Until GUIGetMsg() = -3


Func DropCtrl($hCtrl)
   Local $aPos = ControlGetPos($hMain,'',$hCtrl)
   Local $aMouse = MouseGetPos()
   Local $iX = $aMouse[0] - $aPos[0]
   Local $iY = $aMouse[1] - $aPos[1]
   Do
      $aData = GUIGetCursorInfo($hMain)
      $aMouse = MouseGetPos()
      GUICtrlSetPos($hCtrl,$aMouse[0]-$iX,$aMouse[1]-$iY,$aPos[2],$aPos[3])
      Sleep(10)
   Until Not $aData[2]
EndFunc

 

When the words fail... music speaks.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...