Jump to content

Drag and drop items (labels) vertically among themselves


Go to solution Solved by ioa747,

Recommended Posts

Posted (edited)

Hello friends!

I've been struggling for a couple of hours, maybe because I'm not good at math. I need the labels to be draggable horizontally. I managed to make it work so that when dragging a point upwards, the top point replaces the bottom one (dragging a point downwards - I'll do that later, it's not important, the main thing is to understand the principle). But it only works properly if I do it very slowly. If I move the point quickly, it malfunctions.

Can you please advise on how to make it work even when the point is dragged upwards quickly? I think the general idea of what I want to achieve is clear.

I must say - I'm SORRY for the code, it's a draft, I'm just trying to understand how to make this work. But I'm pretty tired, so the code is a bit messy.

Please, if you have the time and willingness to help - I would be very grateful just for a hint.

ps: sorry for my English

#include <GUIConstantsEx.au3>
#include <ColorConstants.au3>
#include <StaticConstants.au3>
#include <WinAPIGdiDC.au3>
#include <Misc.au3>
#include <WinAPIConv.au3>

$hGUI = GUICreate('Dragging items vertically (this is a draft)', 800, 500)
GUISetBkColor(0x00FF00) ; background color is green

For $i = 1 To 5 ;Creating test items (labels)
    $label = GUICtrlCreateLabel("Label " & $i, 0, (40 * ($i - 1)) + 0, 760, 40, BitOR($SS_SUNKEN, $SS_CENTER))
    GUICtrlSetBkColor($label, 0xFF0000)
    GUICtrlSetColor($label, 0xFFFFFF)
    GUICtrlSetFont($label, 14, 700, 'Tahoma')
Next

$SERVICE_INFO = GUICtrlCreateLabel('', 20, 260, 800, 200)

GUISetState(@SW_SHOW, $hGUI)

;AutoItSetOption("MouseCoordMode",2)

While Sleep(5)
    If _IsPressed('01') Then
        $aCInfo = GUIGetCursorInfo($hGUI)
        If $aCInfo[4] Then
            ;The current Y position of the draggable item
            ;$sText&= 'The current Y position of the mouse relative to the window: ' & _
            ;       MouseGetPos(1) - WinGetPos($hGUI)[1] - 38 - 20 ;To retrieve the Y coordinate relative to the window (not the desktop)

            $sText = ''
            $sText &= 'The current Y coordinate of the mouse: ' & $aCInfo[1] & @CRLF
            ;Let's find out the Y coordinate of the point currently under the mouse
            ;Let's round the number down
            $a = Floor($aCInfo[1] / 40)
            ;Find the Y coordinate of the point
            $a = 40 * $a
            $sText &= 'The Y coordinate of the point under the mouse cursor: ' & $a & @CRLF

            GUICtrlSetData($SERVICE_INFO, $sText)
            $id2 = 0
            While _IsPressed('01')
                ;Dragging the point with the mouse
                $iY = (MouseGetPos(1) - WinGetPos($hGUI)[1]) - 32
                $iY = $iY - ($aCInfo[1] - $a) - 5
                ControlMove($hGUI, '', $aCInfo[4], Default, $iY)

                ;Dragging the higher point with the mouse
                ;To find the ID of the higher point
                ;Finding the Y-coordinate of the higher point
                $coord_y_vverx = $a - 40

                $sText = 'Top point Y-coordinate (upper): ' & $coord_y_vverx & @CRLF & _
                        'Top point Y-coordinate (lower): ' & $a & @CRLF & _
                        'The Y-coordinate of the dragged point (relative to the window): ' & $iY & @CRLF & _
                        'How much should the top point be lowered (relative to the window): ' & $a - $iY & @CRLF

                If $coord_y_vverx = $iY Then ExitLoop

                GUICtrlSetData($SERVICE_INFO, $sText)

                ;Let's find out the ID of the top point
                $id = ControlGetHandle($hGUI, "", "[CLASS:Static; Y:" & $coord_y_vverx & "]")

                If Not $id2 Then $id2 = $id

                ;Lowering the top point
                $coord_y_vverx1 = $coord_y_vverx + ($a - $iY)
                ControlMove($hGUI, '', $id2, Default, $coord_y_vverx1)

            WEnd
        EndIf
    EndIf

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

 

Edited by SEKOMD
Link to comment
Share on other sites

#include <GUIConstantsEx.au3>
#include <ColorConstants.au3>
#include <StaticConstants.au3>
#include <WinAPIGdiDC.au3>
#include <Misc.au3>
#include <WinAPIConv.au3>

$hGUI = GUICreate('Dragging items vertically (this is a draft)', 800, 500)
GUISetBkColor(0x00FF00) ; background color is green

Global $aLabels[6][9]
$aLabels[0][0] = UBound($aLabels) -1
For $n = 1 To $aLabels[0][0] ;Creating test items (labels)
    $aLabels[$n][3] = 40
    $aLabels[$n][2] = ($aLabels[$n][3] * ($n - 1)) + 2
    $aLabels[$n][1] = "Label " & $n
    $aLabels[$n][0] = GUICtrlCreateLabel($aLabels[$n][1], 2, $aLabels[$n][2], 760, $aLabels[$n][3] - 2, BitOR($SS_SUNKEN, $SS_CENTER))
    GUICtrlSetBkColor(-1, 0xFF0000)
    GUICtrlSetColor(-1, 0xFFFFFF)
    GUICtrlSetFont(-1, 14, 700, 'Tahoma')
    ConsoleWrite($n & @TAB & $aLabels[$n][2] & @CRLF)
Next

$SERVICE_INFO = GUICtrlCreateLabel('', 20, 260, 800, 200)

GUISetState(@SW_SHOW, $hGUI)

While 1 ; Sleep(5)

    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case 0, -11, -9, -10, -7, -8
            ContinueLoop
        Case $GUI_EVENT_CLOSE
            Exit
        Case Else
            ConsoleWrite($nMsg & ' ')
            For $n = 1 To $aLabels[0][0]
                If $aLabels[$n][0] = $nMsg Then
                    ConsoleWrite(@CRLF & '! ' & $nMsg & @CRLF)
                    f_DoTheThing($aLabels, $nMsg) ; replace the label data instead of moving the label ?
                EndIf
            Next

    EndSwitch
WEnd

Func f_DoTheThing($aArray, $nMsg)
    While _IsPressed('01')
        Sleep(20)
        $aCInfo = GUIGetCursorInfo($hGUI)
        ToolTip($aCInfo[4])
    WEnd
    ToolTip("")
EndFunc

replace the label data instead of moving the label ? :) 

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

I haven't considered that, but data replacement is not exactly what is needed. What is required is the ability to easily change positions/order of items (labels).

In theory, I believe I can solve this task... but honestly, I admit that it seems incredibly difficult to me for some reason. I'll have to invent some algorithms and calculate the coordinates of the current item, the item above, the past items, and then assign them new Y coordinates...

Link to comment
Share on other sites

Posted (edited)
25 minutes ago, argumentum said:

..am watching a movie so, no code :ржу не могу:
But move the label after the cursor is in in the next label position. Otherwise, while dragging the label, it will always be the same label under the cursor ;) 

I already have good progress towards a successfully functioning layout.

Edited by SEKOMD
Link to comment
Share on other sites

Posted (edited)

This is all a rough draft. But it's working, I'm close to the goal! I even implemented auto-alignment.

In fact, it can be said that this draft will already help solve my problem. Now, if I drag an label up, the items change correctly, I even implemented auto-docking of items. I just need to do the same for shifting an item down.

The main thing is to tidy up the code quickly before I forget what is what :)

#include <GUIConstantsEx.au3>
#include <ColorConstants.au3>
#include <StaticConstants.au3>
#include <WinAPIGdiDC.au3>
#include <Misc.au3>
#include <WinAPIConv.au3>

$hGUI = GUICreate('Dragging items vertically (this is a draft)', 800, 500)
GUISetBkColor(0x00FF00) ; background color is green

For $i = 1 To 5 ;Creating test items (labels)
    $label = GUICtrlCreateLabel("Label " & $i, 0, (40 * ($i - 1)) + 0, 760, 40, BitOR($SS_SUNKEN, $SS_CENTER))
    GUICtrlSetBkColor($label, 0xFF0000)
    GUICtrlSetColor($label, 0xFFFFFF)
    GUICtrlSetFont($label, 14, 700, 'Tahoma')
Next

$SERVICE_INFO = GUICtrlCreateLabel('', 20, 260, 800, 400)

GUISetState(@SW_SHOW, $hGUI)

;AutoItSetOption("MouseCoordMode",2)

While Sleep(5)
    While _IsPressed('01')
        $aCInfo = GUIGetCursorInfo($hGUI)
        If $aCInfo[4] Then
            ;The current Y position of the draggable item
            ;$sText&= 'The current Y position of the mouse relative to the window: ' & _
            ;       MouseGetPos(1) - WinGetPos($hGUI)[1] - 38 - 20 ;To retrieve the Y coordinate relative to the window (not the desktop)

            $sText = ''
            $sText &= 'The current Y coordinate of the mouse: ' & $aCInfo[1] & @CRLF
            ;Let's find out the Y coordinate of the point currently under the mouse
            ;Let's round the number down
            $a = Floor($aCInfo[1] / 40)
            ;Find the Y coordinate of the point
            $a = 40 * $a
            $sText &= 'The Y coordinate of the point under the mouse cursor: ' & $a & @CRLF

            GUICtrlSetData($SERVICE_INFO, $sText)
            $id2 = 0
            While _IsPressed('01')
                ;Dragging the point with the mouse
                $iY = (MouseGetPos(1) - WinGetPos($hGUI)[1]) - 32
                $iY = $iY - ($aCInfo[1] - $a) - 5
                ControlMove($hGUI, '', $aCInfo[4], Default, $iY)

                ;Dragging the higher point with the mouse
                ;To find the ID of the higher point
                ;Finding the Y-coordinate of the higher point
                $coord_y_vverx = $a - 40

                $sText = 'Top point Y-coordinate (upper): ' & $coord_y_vverx & @CRLF & _
                        'Top point Y-coordinate (lower): ' & $a & @CRLF & _
                        'The Y-coordinate of the dragged point (relative to the window): ' & $iY & @CRLF & _
                        'How much should the top point be lowered (relative to the window): ' & $a - $iY & @CRLF

                If $coord_y_vverx >= $iY Then ExitLoop

                ;GUICtrlSetData($SERVICE_INFO, $sText)

                ;Let's find out the ID of the top point
                $id = ControlGetHandle($hGUI, "", "[CLASS:Static; Y:" & $coord_y_vverx & "]")

                If Not $id2 Then $id2 = $id

                ;Lowering the top point
                $coord_y_vverx1 = $coord_y_vverx + ($a - $iY)
                ControlMove($hGUI, '', $id2, Default, $coord_y_vverx1)

                $sText = ''
                $sText = 'Target coordinate: ' & $coord_y_vverx & @CRLF
                $sText &=  'Dragged items Y coordinate: ' & $iY
                GUICtrlSetData($SERVICE_INFO, $sText)
                GUICtrlSetBkColor($aCInfo[4], 0x00FF00)

                if ($iY-$coord_y_vverx)<20 Then
                    ControlMove($hGUI, '', $aCInfo[4], Default, $coord_y_vverx)
                    ;===========
                    ControlMove($hGUI, '', $id2, Default, $a)
                EndIf

                Sleep(50)

            WEnd
        EndIf
    WEnd

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

 

Edited by SEKOMD
Link to comment
Share on other sites

Posted (edited)

Something like this?

#include <WinAPISysWin.au3>
#include <Array.au3>

Global $hGUI, $iNumOfLabels = 10, $iLabelHeight = 30
Global $aLabel[$iNumOfLabels]

$hGUI = GUICreate('Test', 400, 500)
For $Index = 0 To $iNumOfLabels - 1
    $aLabel[$Index] = GUICtrlCreateLabel('Label ' & $Index + 1, 10, 10 + $Index * 40, 300, $iLabelHeight, 0x1200)
Next
GUISetState(@SW_SHOW)

Do
    DragEvent()
Until GUIGetMsg() = -3  ; GUI_EVENT_CLOSE

Func DragEvent()
    Local Static $iAdjPos = Int($iLabelHeight / 2)
    Local $iCtrl = Null
    Local $aInfo = GUIGetCursorInfo($hGUI)
    If Not $aInfo[2] Then Return SetError(1, 0, False)
    For $Index = 0 To $iNumOfLabels - 1
        If $aLabel[$Index] = $aInfo[4] Then
            $iCtrl = $aInfo[4]
            ExitLoop
        EndIf
    Next
    If $iCtrl = Null Then Return SetError(2, 0, False)
    Do
        $aInfo = GUIGetCursorInfo($hGUI)
        ControlMove($hGUI, '', $iCtrl, 10, $aInfo[1] - $iAdjPos)
        Sleep(10)
    Until Not $aInfo[2]
    Local $aPos[$iNumOfLabels][2]
    For $Index = 0 To $iNumOfLabels - 1
        $aPos[$Index][0] = $aLabel[$Index]
        $aPos[$Index][1] = ControlGetPos($hGUI, '', $aLabel[$Index])[1]
    Next
    _ArraySort($aPos, Default, Default, Default, 1)
    For $Index = 0 To $iNumOfLabels - 1
        ControlMove($hGUI, '', $aPos[$Index][0], 10, 10 + $Index * 40)
    Next
    _WinAPI_InvalidateRect($hGUI)
EndFunc

 

Edited by Andreik

When the words fail... music speaks.

Link to comment
Share on other sites

No, that's not quite it. I need the items to smoothly move between each other vertically, similar to how you can smoothly move open tabs in Chrome horizontally.

Link to comment
Share on other sites

Posted (edited)

If I had yesterday, when I started it, the script of @Andreik my script would be better and smaller

; https://www.autoitscript.com/forum/topic/211959-drag-and-drop-items-labels-vertically-among-themselves/?do=findComment&comment=1534550
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

#include <StaticConstants.au3>
#include <Misc.au3>
#include <WinAPIGdi.au3>
#include <WinAPISysWin.au3>
#include <Array.au3>

Global $iStep = 40
Global $hGUI = GUICreate('Dragging items vertically (this is a draft)', 800, $iStep * 12)
GUISetBkColor(0x00FF00) ; background color is green
Global $aLabel[10][2]
$aLabel[0][0] = 9

For $i = 1 To $aLabel[0][0] ;Creating test items (labels)
    $aLabel[$i][1] = ($iStep * ($i - 1))
    $aLabel[$i][0] = GUICtrlCreateLabel("Label " & $i, 0, $aLabel[$i][1], 760, $iStep, BitOR($SS_SUNKEN, $SS_CENTER))
    GUICtrlSetBkColor(-1, 0xFF0000)
    GUICtrlSetColor(-1, 0xFFFFFF)
    GUICtrlSetFont(-1, 14, 700, 'Tahoma')
Next

GUISetState(@SW_SHOW, $hGUI)

Opt("MouseCoordMode", 2) ;1=absolute, 0=relative, 2=client

;**********************************
While 1
    Switch GUIGetMsg()
        Case -3 ;$GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
    _IsDragging()
    Sleep(10)
WEnd
;**********************************
Exit

;--------------------------------------------------------------------------------------------------------------------------------
Func _IsDragging()

    If _IsPressed('01') And WinActive($hGUI) Then
        Local $bDragging = False
        Local $hTimer = TimerInit()
        While _IsPressed('01')

            ; If _IsPressed for more than 400 ms
            If TimerDiff($hTimer) > 400 Then
                Local $aCtrl, $ActiveCtrl, $iCursorId, $iStartPos, $iEndPos, $iOffset

                ;find the active $aLabel
                If Not $ActiveCtrl Then
                    $aCtrl = GUIGetCursorInfo($hGUI)
                    ;check if $ActiveCtrl = $aLabel
                    For $i = 1 To $aLabel[0][0]
                        If $aLabel[$i][0] = $aCtrl[4] Then
                            $ActiveCtrl = $aCtrl[4]
                            $bDragging = True
                            $iStartPos = MouseGetPos(1)
                            $iOffset = $iStartPos - $aLabel[$i][1]
                            $iCursorId = MouseGetCursor()
                            GUISetCursor(11, 1, $hGUI)
                            GUICtrlSetBkColor($ActiveCtrl, 0xCC0000) ;0xFF0000
                            ConsoleWrite("- Start Dragging, " & GUICtrlRead($ActiveCtrl))
                            ConsoleWrite(", at PosY:" & $iStartPos & @CRLF)
                        EndIf
                    Next
                    If Not $ActiveCtrl Then ExitLoop
                EndIf

                ControlMove($hGUI, '', $ActiveCtrl, Default, MouseGetPos(1) - $iOffset)

                ;Reposition of Labels
                _ArraySort($aLabel, 0, 1, 0, 1)
                For $i = 1 To $aLabel[0][0]
                    If $aLabel[$i][0] = $ActiveCtrl Then
                        $aLabel[$i][1] = MouseGetPos(1) - $iOffset
                        ContinueLoop
                    EndIf
                    $aLabel[$i][1] = ($iStep * ($i - 1))
                    GUICtrlSetPos($aLabel[$i][0], 0, $aLabel[$i][1])
                Next
            EndIf
            Sleep(10)
        WEnd

        If $bDragging = True Then
            GUISetCursor($iCursorId, 1, $hGUI)
            GUICtrlSetBkColor($ActiveCtrl, 0xFF0000)

            For $i = 1 To $aLabel[0][0]
                $aLabel[$i][1] = ($iStep * ($i - 1))
                ;GUICtrlSetPos($aLabel[$i][0], 0, $aLabel[$i][1]) ; use ControlMove to avoid repaint issues
                ControlMove($hGUI, '', $aLabel[$i][0], Default, $aLabel[$i][1])
                ConsoleWrite(" -> " & GUICtrlRead($aLabel[$i][0]) & " at PosY:" & $aLabel[$i][1] & @CRLF)
            Next

            $iEndPos = MouseGetPos(1)
            ConsoleWrite("-   End Dragging, " & GUICtrlRead($ActiveCtrl))
            ConsoleWrite(", at PosY:" & $iEndPos & @CRLF)
            ConsoleWrite("" & @CRLF)

            $bDragging = False
            _WinAPI_RedrawWindow($hGUI)
        EndIf

    EndIf

EndFunc   ;==>_IsDragging
;--------------------------------------------------------------------------------------------------------------------------------

 

Edited by ioa747
UpDate

I know that I know nothing

Link to comment
Share on other sites

Just Update

If _IsPressed('01') And WinActive($hGUI) Then  -  because he caught the window, even when he was in the background

instead GUICtrlSetPos($aLabel[$i][0], 0, $aLabel[$i][1])  -  use ControlMove to avoid repaint issues

I know that I know nothing

Link to comment
Share on other sites

Posted (edited)

Here is the  better and smaller  version

; https://www.autoitscript.com/forum/topic/211959-drag-and-drop-items-labels-vertically-among-themselves/?do=findComment&comment=1534576
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

#include <StaticConstants.au3>
#include <WinAPIGdi.au3>
#include <Array.au3>

Global $iStart = 70, $iSpace = 5, $iLeft = 20, $iLabelHeight = 50
Global $hGUI = GUICreate('Dragging items vertically (this is a draft)', 500, ($iLabelHeight + $iSpace) * 12)
GUISetBkColor(0x00FF00) ; background color is green
Global $aLabel[10][2]
$aLabel[0][0] = 9 ;NumOfLabels

For $i = 1 To $aLabel[0][0] ;Creating test items (labels)
    $aLabel[$i][1] = (($iLabelHeight + $iSpace) * ($i - 1)) + $iStart
    $aLabel[$i][0] = GUICtrlCreateLabel("Label " & $i, $iLeft, $aLabel[$i][1], 460, $iLabelHeight, BitOR($SS_SUNKEN, $SS_CENTER, $SS_CENTERIMAGE))
    GUICtrlSetBkColor(-1, 0xFF0000)
    GUICtrlSetColor(-1, 0xFFFFFF)
    GUICtrlSetFont(-1, 14, 700, 'Tahoma')
Next
GUISetState(@SW_SHOW, $hGUI)

;**********************************
While 1
    Switch GUIGetMsg()
        Case -3 ;$GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
    _IsDragging()
    Sleep(10)
WEnd
;**********************************
Exit

;--------------------------------------------------------------------------------------------------------------------------------
Func _IsDragging()
    Local Static $iOffset = Int($iLabelHeight / 2)

    If Not WinActive($hGUI) Then Return SetError(1, 0, False)
    Local $aCtrl = GUIGetCursorInfo($hGUI)
    If Not $aCtrl[2] Then Return SetError(2, 0, False)

    Local $ActiveCtrl = Null
    For $i = 1 To $aLabel[0][0]
        If $aLabel[$i][0] = $aCtrl[4] Then
            $ActiveCtrl = $aCtrl[4]
        EndIf
    Next

    If $ActiveCtrl = Null Then Return SetError(3, 0, False)

    Opt("MouseCoordMode", 2) ;1=absolute, 0=relative, 2=client
    Local $iCursorId = MouseGetCursor()
    GUISetCursor(11, 1, $hGUI)
    GUICtrlSetBkColor($ActiveCtrl, 0xCC0000) ;0xFF0000

    Do
        $aCtrl = GUIGetCursorInfo($hGUI)
        ControlMove($hGUI, '', $ActiveCtrl, Default, MouseGetPos(1) - $iOffset)
        ;Reposition of Labels
        _ArraySort($aLabel, 0, 1, 0, 1)
        For $i = 1 To $aLabel[0][0]
            If $aLabel[$i][0] = $ActiveCtrl Then
                $aLabel[$i][1] = MouseGetPos(1) - $iOffset
                ContinueLoop
            EndIf
            $aLabel[$i][1] = (($iLabelHeight + $iSpace) * ($i - 1)) + $iStart
            GUICtrlSetPos($aLabel[$i][0], $iLeft, $aLabel[$i][1])
        Next
        Sleep(10)
    Until Not $aCtrl[2]

    Opt("MouseCoordMode", 1) ;1=absolute, 0=relative, 2=client
    GUISetCursor($iCursorId, 1, $hGUI)
    GUICtrlSetBkColor($ActiveCtrl, 0xFF0000)
    For $i = 1 To $aLabel[0][0]
        $aLabel[$i][1] = (($iLabelHeight + $iSpace) * ($i - 1)) + $iStart
        GUICtrlSetPos($aLabel[$i][0], $iLeft, $aLabel[$i][1])
    Next
    _WinAPI_RedrawWindow($hGUI)
EndFunc   ;==>_IsDragging
;--------------------------------------------------------------------------------------------------------------------------------

 

Edited by ioa747
corection

I know that I know nothing

Link to comment
Share on other sites

5 minutes ago, ioa747 said:

Here is the  better and smaller  version

; https://www.autoitscript.com/forum/topic/211959-drag-and-drop-items-labels-vertically-among-themselves/?do=findComment&comment=1534550
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

#include <StaticConstants.au3>
#include <WinAPIGdi.au3>
#include <Array.au3>

Global $iStart = 70, $iSpace = 5, $iLeft = 20, $iLabelHeight = 50
Global $hGUI = GUICreate('Dragging items vertically (this is a draft)', 500, ($iLabelHeight + $iSpace) * 12)
GUISetBkColor(0x00FF00) ; background color is green
Global $aLabel[10][2]
$aLabel[0][0] = 9 ;NumOfLabels

For $i = 1 To $aLabel[0][0] ;Creating test items (labels)
    $aLabel[$i][1] = (($iLabelHeight + $iSpace) * ($i - 1)) + $iStart
    $aLabel[$i][0] = GUICtrlCreateLabel("Label " & $i, $iLeft, $aLabel[$i][1], 460, $iLabelHeight, BitOR($SS_SUNKEN, $SS_CENTER, $SS_CENTERIMAGE))
    GUICtrlSetBkColor(-1, 0xFF0000)
    GUICtrlSetColor(-1, 0xFFFFFF)
    GUICtrlSetFont(-1, 14, 700, 'Tahoma')
Next
GUISetState(@SW_SHOW, $hGUI)

;**********************************
While 1
    Switch GUIGetMsg()
        Case -3 ;$GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
    _IsDragging()
    Sleep(10)
WEnd
;**********************************
Exit

;--------------------------------------------------------------------------------------------------------------------------------
Func _IsDragging()
    Local Static $iOffset = Int($iLabelHeight / 2)

    If Not WinActive($hGUI) Then Return SetError(1, 0, False)
    Local $aCtrl = GUIGetCursorInfo($hGUI)
    If Not $aCtrl[2] Then Return SetError(2, 0, False)

    Local $ActiveCtrl = Null
    For $i = 1 To $aLabel[0][0]
        If $aLabel[$i][0] = $aCtrl[4] Then
            $ActiveCtrl = $aCtrl[4]
        EndIf
    Next

    If $ActiveCtrl = Null Then Return SetError(3, 0, False)

    Opt("MouseCoordMode", 2) ;1=absolute, 0=relative, 2=client
    Local $iCursorId = MouseGetCursor()
    GUISetCursor(11, 1, $hGUI)
    GUICtrlSetBkColor($ActiveCtrl, 0xCC0000) ;0xFF0000

    Do
        $aCtrl = GUIGetCursorInfo($hGUI)
        ControlMove($hGUI, '', $ActiveCtrl, Default, MouseGetPos(1) - $iOffset)
        ;Reposition of Labels
        _ArraySort($aLabel, 0, 1, 0, 1)
        For $i = 1 To $aLabel[0][0]
            If $aLabel[$i][0] = $ActiveCtrl Then
                $aLabel[$i][1] = MouseGetPos(1) - $iOffset
                ContinueLoop
            EndIf
            $aLabel[$i][1] = (($iLabelHeight + $iSpace) * ($i - 1)) + $iStart
            GUICtrlSetPos($aLabel[$i][0], $iLeft, $aLabel[$i][1])
        Next
        Sleep(10)
    Until Not $aCtrl[2]

    Opt("MouseCoordMode", 1) ;1=absolute, 0=relative, 2=client
    GUISetCursor($iCursorId, 1, $hGUI)
    GUICtrlSetBkColor($ActiveCtrl, 0xFF0000)
    For $i = 1 To $aLabel[0][0]
        $aLabel[$i][1] = (($iLabelHeight + $iSpace) * ($i - 1)) + $iStart
        ControlMove($hGUI, '', $aLabel[$i][0], Default, $aLabel[$i][1])
    Next
    _WinAPI_RedrawWindow($hGUI)
EndFunc   ;==>_IsDragging
;--------------------------------------------------------------------------------------------------------------------------------

 

Thank you for your help, great code! Sadly, I'm not as skilled in coding like a pro. I'll show my version later on. Just one of the important requirements is smooth item replacement. When one item is dragged, another is smoothly positioned at the same speed in place of the dragged item.

Link to comment
Share on other sites

  • Solution
Posted (edited)
On 6/9/2024 at 2:56 PM, SEKOMD said:

I'm not as skilled in coding like a pro.

neither am I, I'm a carpenter. I just love these challenges

 

On 6/9/2024 at 2:56 PM, SEKOMD said:

smooth item replacement

Check again  how Chrome move open tabs .  Once you're halfway through, it instantly goes to the other side

 

My attempt to make it "smoothly positioned" probably had the opposite result.
Here are the results

; https://www.autoitscript.com/forum/topic/211959-drag-and-drop-items-labels-vertically-among-themselves/?do=findComment&comment=1534586
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

#include <StaticConstants.au3>
#include <WinAPIGdi.au3>
#include <Array.au3>

Global $iStart = 70, $iSpace = 5, $iLeft = 20, $iLabelHeight = 50
Global $hGUI = GUICreate('Dragging items vertically (this is a draft)', 500, ($iLabelHeight + $iSpace) * 12)
GUISetBkColor(0x00FF00) ; background color is green
Global $aLabel[10][2]
$aLabel[0][0] = 9 ;NumOfLabels

For $i = 1 To $aLabel[0][0] ;Creating test items (labels)
    $aLabel[$i][1] = (($iLabelHeight + $iSpace) * ($i - 1)) + $iStart
    $aLabel[$i][0] = GUICtrlCreateLabel("Label " & $i, $iLeft, $aLabel[$i][1], 460, $iLabelHeight, BitOR($SS_SUNKEN, $SS_CENTER, $SS_CENTERIMAGE))
    GUICtrlSetBkColor(-1, 0xFF0000)
    GUICtrlSetColor(-1, 0xFFFFFF)
    GUICtrlSetFont(-1, 14, 700, 'Tahoma')
Next
GUISetState(@SW_SHOW, $hGUI)

;**********************************
While 1
    Switch GUIGetMsg()
        Case -3 ;$GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
    _IsDragging()
    Sleep(10)
WEnd
;**********************************
Exit

;--------------------------------------------------------------------------------------------------------------------------------
Func _IsDragging()
    Local Static $iOffset = Int($iLabelHeight / 2)

    If Not WinActive($hGUI) Then Return SetError(1, 0, False)
    Local $aCtrl = GUIGetCursorInfo($hGUI)
    If Not $aCtrl[2] Then Return SetError(2, 0, False)

    Local $ActiveCtrl = Null
    For $i = 1 To $aLabel[0][0]
        If $aLabel[$i][0] = $aCtrl[4] Then
            $ActiveCtrl = $aCtrl[4]
        EndIf
    Next

    If $ActiveCtrl = Null Then Return SetError(3, 0, False)

    Opt("MouseCoordMode", 2) ;1=absolute, 0=relative, 2=client
    Local $iCursorId = MouseGetCursor()
    GUISetCursor(11, 1, $hGUI)
    GUICtrlSetBkColor($ActiveCtrl, 0xCC0000) ;0xFF0000

    Local $iOldPos, $iStp

    Do
        $aCtrl = GUIGetCursorInfo($hGUI)
        ControlMove($hGUI, '', $ActiveCtrl, Default, MouseGetPos(1) - $iOffset)
        ;Reposition of Labels
        _ArraySort($aLabel, 0, 1, 0, 1)
        For $i = 1 To $aLabel[0][0]
            If $aLabel[$i][0] = $ActiveCtrl Then
                $aLabel[$i][1] = MouseGetPos(1) - $iOffset
                ContinueLoop
            EndIf
            $aLabel[$i][1] = (($iLabelHeight + $iSpace) * ($i - 1)) + $iStart
            $iOldPos = ControlGetPos($hGUI, '', $aLabel[$i][0])[1]
            $iStp = ($iOldPos > $aLabel[$i][1] ? -5 : 5)
            For $Y = $iOldPos To $aLabel[$i][1] Step $iStp
                GUICtrlSetPos($aLabel[$i][0], $iLeft, $Y)
                Sleep(10)
            Next

        Next
;~      Sleep(10)
    Until Not $aCtrl[2]

    Opt("MouseCoordMode", 1) ;1=absolute, 0=relative, 2=client
    GUISetCursor($iCursorId, 1, $hGUI)
    GUICtrlSetBkColor($ActiveCtrl, 0xFF0000)
    For $i = 1 To $aLabel[0][0]
        $aLabel[$i][1] = (($iLabelHeight + $iSpace) * ($i - 1)) + $iStart
        ;ConsoleWrite(GUICtrlRead($aLabel[$i][0]) & " " & $aLabel[$i][1] & @CRLF)
        GUICtrlSetPos($aLabel[$i][0], $iLeft, $aLabel[$i][1])
    Next
    ConsoleWrite("" & @CRLF)

    _WinAPI_RedrawWindow($hGUI)
EndFunc   ;==>_IsDragging
;--------------------------------------------------------------------------------------------------------------------------------

 

 

Edited by ioa747
corection

I know that I know nothing

Link to comment
Share on other sites

Do you guys get the same issue that I am getting with @ioa747 code.

1- Move one label to another location

2- Minimize the GUI

3- Restore the GUI

The one label that was moved now has disappeared !  Even if the GUI was redrawn...

 

Edit : found the problem, replace last :

ControlMove($hGUI, '', $aLabel[$i][0], Default, $aLabel[$i][1])

with

GUICtrlSetPos($aLabel[$i][0], $iLeft, $aLabel[$i][1])

Seems that ControlMove does not inform the GUI of the new position of the controls

Edited by Nine
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...