Jump to content

Draw Path Points -- helps create GDI line paths


Bilgus
 Share

Recommended Posts

Draw Path Points allows you to make line paths for drawing with gdi

You can even load an image and trace the outline

Save and load functionality undo and redo zoom and scale; Don't Forget Rotate!

;Draw Path Points BILGUS 2018

;Includes
#include <File.au3>
#include <GDIPlus.au3>
#include <GUIConstants.au3>
#include <GuiEdit.au3>
#include <GuiListView.au3>
#include <GuiTab.au3>
#include <Misc.au3>

If OnAutoItExitRegister("_Exit") <> 0 Then
    _GDIPlus_Startup() ;initialize GDI+
    ConsoleWrite("GDI+ Started" & @CRLF)
EndIf

Opt("MouseCoordMode", 2) ;Relative coords to the client area of the active window
Opt("PixelCoordMode", 2) ;Relative coords to the client area of the active window

Global $g_iXScale = 8
Global $g_iYScale = $g_iXScale

Global $g_sFileSave = @ScriptDir & "\DrawPath.txt" ;Default

Global $g_bClosePath = False
Global $g_bShowImage = False
Global $g_sImagefile = ""

Global $g_iUndo_Max = 50
Global $g_asUndo_Files[1] = [""]
Global $g_asRedo_Files[1] = [""]

Global $g_aPath_Points[1][2] = [[0, 0]]
Global $g_aPath_Rot_Points

Global $g_hForm1 = GUICreate("Draw Path Points", 615, 437, 192, 124)

Global $g_hSelSquare = GUICtrlCreateLabel("", 0, 0, 0, 0, $SS_BLACKFRAME, $WS_EX_TOPMOST)
GUICtrlSetState(-1, $GUI_HIDE)
;-------------------------------------------------------------------------------
Global Enum $eC1_delete, $eC1_del_all, $eC1_update, $eC1_shift_dn, $eC1_shift_up, _
        $eC1_closepath, $eC1_showimg, $eC1_lock, $eC1_undo, $eC1_redo, $aCtl1_LAST
Global $g_ahCtl1[$aCtl1_LAST]
Control_Create_Group1()
;-------------------------------------------------------------------------------
Global Enum $eC2_zin, $eC2_zout, $eC2_dgroup, $eC2_decx, $eC2_incx, $eC2_decy, _
        $eC2_incy, $eC2_edit_rot, $eC2_rot, $eC2_ud_rot, $eC2_rev, $eC2_toall, $aCtl2_LAST
Global $g_ahCtl2[$aCtl2_LAST]
Control_Create_Group2()
;-------------------------------------------------------------------------------

Global $g_hBtn_load = GUICtrlCreateButton("Load", 5, 1, 35, 20)
Global $g_hBtn_save = GUICtrlCreateButton("Save", 40, 1, 35, 20)
Global $g_hBtn_arr_disp = GUICtrlCreateButton("Array", 75, 1, 35, 20)

Global $g_hEdit_encoded = GUICtrlCreateEdit("", 115, 2, 50, 18, $ES_READONLY + $ES_AUTOHSCROLL, $WS_EX_STATICEDGE + $WS_EX_TRANSPARENT)

Global $g_hList1 = GUICtrlCreateListView("#|x|y", 5, 24, 161, 201, $LVS_SHOWSELALWAYS Or $LVS_SINGLESEL)
Global $g_hList1_LVN = GUICtrlCreateDummy() ;listview notifications

Global $g_hImage1 = GUICtrlCreatePic("", 200, 16, 400, 400, -1, $WS_EX_LAYERED)

Global $g_hTab1 = GUICtrlCreateTab(1, 225, 20, 500, $TCS_VERTICAL)
GUICtrlCreateTabItem(" ")
GUICtrlSetState(-1, $GUI_SHOW) ; will be display first
GUICtrlCreateTabItem(" ")
GUICtrlCreateTabItem("") ; end tabitem definition

For $i = 0 To UBound($g_ahCtl2) - 1
    GUICtrlSetState($g_ahCtl2[$i], $GUI_HIDE)
Next

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

List_Update()
List_Index()
GUISetState(@SW_SHOW)
State_Save($g_aPath_Points)
Points_Update($g_aPath_Points)

Global $g_nMsg = 0
While 1
    $g_nMsg = GUIGetMsg()

    If $g_nMsg > 0 And $g_nMsg <> $g_ahCtl2[$eC2_ud_rot] And $g_nMsg <> $g_ahCtl2[$eC2_edit_rot] And GUICtrlRead($g_ahCtl2[$eC2_edit_rot]) <> 0 Then
        ;ConsoleWrite("Cancel_Rotate? " & $g_nMsg & @CRLF)
        If MsgBox($MB_ICONQUESTION + $MB_OKCANCEL + $MB_DEFBUTTON2, "Save?", "Save Rotated Points?", 10) == $IDOK Then
            _GUICtrlEdit_SetText($g_ahCtl2[$eC2_edit_rot], "0")
            $g_aPath_Points = $g_aPath_Rot_Points
            State_Save($g_aPath_Points)
            List_Update(List_Index())
        Else
            _GUICtrlEdit_SetText($g_ahCtl2[$eC2_edit_rot], "0")
            Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage, List_Index()) ;, True)
        EndIf
    EndIf

    Switch $g_nMsg
        Case $GUI_EVENT_CLOSE
            Exit

        Case $g_hTab1
            Tab1_Select()

        Case $g_hSelSquare
            ;ConsoleWrite("SelSquare" & @CRLF)
            SelSquare_Drag()

        Case $g_hList1
            ;ConsoleWrite("List1 " & $g_nMsg & @CRLF)
            Local $iIndex = List_Index()
            If $iIndex <> -1 Then
                Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage, $iIndex)
                _GUICtrlListView_SetItemSelected($g_hList1, $iIndex, True, True)
            EndIf
        Case $g_hList1_LVN
            Point_Selected($g_aPath_Points, $g_hImage1, List_Index())
        Case $g_hList1_LVN

        Case $g_hImage1
            Image1_Clicked()

        Case $g_hBtn_save
            Btn_save_Clicked()

        Case $g_hBtn_load
            Btn_load_Clicked()

        Case $g_hBtn_arr_disp
            _ArrayDisplay($g_aPath_Points)
            ;-------------------------------------------------------------------
        Case $g_ahCtl1[$eC1_shift_up]
            $iIndex = List_Index()
            Point_Swap($iIndex, -1)
            Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage)

        Case $g_ahCtl1[$eC1_shift_dn]
            $iIndex = List_Index()
            Point_Swap($iIndex, 1)
            Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage)

        Case $g_ahCtl1[$eC1_del_all]
            $g_aPath_Points = 0
            Global $g_aPath_Points[1][2] = [[0, 0]]
            List_Update()
            Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage)

        Case $g_ahCtl1[$eC1_delete]
            $iIndex = List_Index()
            Point_Delete($iIndex)
            _GUICtrlListView_ClickItem($g_hList1, $iIndex)
            Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage)

        Case $g_ahCtl1[$eC1_redo]
            $g_aPath_Points = State_Restore($g_aPath_Points, False)
            List_Update()
            Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage)

        Case $g_ahCtl1[$eC1_undo]
            $g_aPath_Points = State_Restore($g_aPath_Points, True)
            List_Update()
            Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage)

        Case $g_ahCtl1[$eC1_update]
            List_Update(List_Index())
            Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage)
            Ascii_Points($g_aPath_Points)
            _GUICtrlEdit_SetSel($g_hEdit_encoded, 0, -1)

        Case $g_ahCtl1[$eC1_closepath]
            $g_bClosePath = Control_IsChecked($g_ahCtl1[$eC1_closepath])
            List_Update(List_Index())
            Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage)
            If $g_bClosePath Then
                GUICtrlSetState($g_ahCtl2[$eC2_rev], $GUI_DISABLE)
            Else
                GUICtrlSetState($g_ahCtl2[$eC2_rev], $GUI_ENABLE)
            EndIf

        Case $g_ahCtl1[$eC1_showimg]
            If Not $g_bShowImage Then
                $g_sImagefile = FileOpenDialog("Select an image", SplitDir($g_sImagefile), "All Files(*.*)", 0, SplitFileName($g_sImagefile), $g_hForm1)
            EndIf
            $g_bShowImage = Control_IsChecked($g_ahCtl1[$eC1_showimg])
            List_Update(List_Index())
            Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage)
            ;-------------------------------------------------------------------
        Case $g_ahCtl2[$eC2_zin]
            If Control_IsChecked($g_ahCtl2[$eC2_toall]) Then
                Points_Scale(1, 1)
            Else
                $g_iXScale += 1
                $g_iYScale += 1
                Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage)
            EndIf
            _GUICtrlListView_ClickItem($g_hList1, List_Index())

        Case $g_ahCtl2[$eC2_zout]
            If Control_IsChecked($g_ahCtl2[$eC2_toall]) Then
                Points_Scale(-1, -1)
            Else
                $g_iXScale -= 1
                $g_iYScale -= 1
                Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage)
            EndIf
            _GUICtrlListView_ClickItem($g_hList1, List_Index())

        Case $g_ahCtl2[$eC2_rev]
            $iIndex = List_Index()
            $g_aPath_Points = Points_Reverse($g_aPath_Points)
            Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage, $iIndex) ;, True)
            List_Update($iIndex)

        Case $g_ahCtl2[$eC2_edit_rot]
            ;ConsoleWrite("Rotate" & @CRLF)
            $iIndex = List_Index()
            Local $iDegrees = GUICtrlRead($g_ahCtl2[$eC2_edit_rot])
            $g_aPath_Rot_Points = Points_Rotate($g_aPath_Points, $iDegrees)
            Points_Update($g_aPath_Rot_Points, $g_bClosePath, $g_bShowImage, $iIndex) ;, True)

        Case $g_ahCtl2[$eC2_incx]
            Point_Adjust(1, 0, Control_IsChecked($g_ahCtl2[$eC2_toall]))
        Case $g_ahCtl2[$eC2_decx]
            Point_Adjust(-1, 0, Control_IsChecked($g_ahCtl2[$eC2_toall]))
        Case $g_ahCtl2[$eC2_incy]
            Point_Adjust(0, 1, Control_IsChecked($g_ahCtl2[$eC2_toall]))
        Case $g_ahCtl2[$eC2_decy]
            Point_Adjust(0, -1, Control_IsChecked($g_ahCtl2[$eC2_toall]))

    EndSwitch
WEnd
;----------------------------------------------------------------------------------------------------
Func _Exit()
    _GDIPlus_Shutdown()
    ConsoleWrite("GDI+ Stopped" & @CRLF)
    State_Destroy()
EndFunc   ;==>_Exit

Func Ascii_Points($aPts)
    ;encodes points into an ascii string
    Local Const $iChrOffset = 33
    Local Const $iMaxOffset = 126 - $iChrOffset
    If Not IsArray($aPts) Then Return
    Local $sAscEnc = StringFormat("%03i%05i", $iChrOffset, UBound($aPts) * 2 + 8)
    If _ArrayMin($aPts) >= 0 And (_ArrayMax($aPts) - _ArrayMin($aPts)) <= $iMaxOffset Then

        For $i = 0 To UBound($aPts) - 1
            $sAscEnc = $sAscEnc & Chr($aPts[$i][0] + $iChrOffset) & Chr($aPts[$i][1] + $iChrOffset)
        Next
    EndIf
    _GUICtrlEdit_SetText($g_hEdit_encoded, $sAscEnc)
EndFunc   ;==>Ascii_Points

Func Btn_load_Clicked()
    ConsoleWrite("Load: " & SplitDir($g_sFileSave) & @CRLF)
    $g_sFileSave = FileOpenDialog("Select a save file", SplitDir($g_sFileSave), "All Files(*.*)", 0, SplitFileName($g_sFileSave), $g_hForm1)
    _FileReadToArray($g_sFileSave, $g_aPath_Points, 0, ",")
    If @error Then
        Dim $g_aPath_Points[1][2] = [[0, 0]]
    Else
        State_Destroy()
        State_Save($g_aPath_Points)
    EndIf

    List_Update()
    Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage)
EndFunc   ;==>Btn_load_Clicked

Func Btn_save_Clicked()
    List_Update(List_Index())
    $g_sFileSave = FileOpenDialog("Select a save file", SplitDir($g_sFileSave), "All Files(*.*)", 0, SplitFileName($g_sFileSave), $g_hForm1)
    _FileWriteFromArray($g_sFileSave, $g_aPath_Points, 0, Default, ",")
EndFunc   ;==>Btn_save_Clicked

Func Control_Create_Group1()
    Local $iX = 30
    Local $iY = 225
    $g_ahCtl1[$eC1_delete] = GUICtrlCreateButton("Delete", $iX + 0, $iY + 0, 50, 20)
    $g_ahCtl1[$eC1_shift_dn] = GUICtrlCreateButton("+", $iX + 70, $iY + 0, 20, 20)
    $g_ahCtl1[$eC1_shift_up] = GUICtrlCreateButton("-", $iX + 95, $iY + 0, 20, 20)
    $g_ahCtl1[$eC1_del_all] = GUICtrlCreateButton("Delete All", $iX + 0, $iY + 25, 50, 20)
    $g_ahCtl1[$eC1_update] = GUICtrlCreateButton("Update", $iX + 70, $iY + 25, 50, 20)
    $g_ahCtl1[$eC1_undo] = GUICtrlCreateButton("Undo", $iX + 0, $iY + 50, 50, 20)
    $g_ahCtl1[$eC1_redo] = GUICtrlCreateButton("Redo", $iX + 70, $iY + 50, 50, 20)
    GUICtrlSetState($g_ahCtl1[$eC1_undo], $GUI_DISABLE)
    GUICtrlSetState($g_ahCtl1[$eC1_redo], $GUI_DISABLE)

    $g_ahCtl1[$eC1_closepath] = GUICtrlCreateCheckbox("Complete", $iX + 0, $iY + 70, 65, 25)
    $g_ahCtl1[$eC1_showimg] = GUICtrlCreateCheckbox("Image", $iX + 0, $iY + 90, 65, 25)
    $g_ahCtl1[$eC1_lock] = GUICtrlCreateCheckbox("Locked", $iX + 0, $iY + 110, 65, 25)
EndFunc   ;==>Control_Create_Group1

Func Control_Create_Group2()
    Local $iX = 30
    Local $iY = 225
    $g_ahCtl2[$eC2_rev] = GUICtrlCreateButton("Reverse", $iX + 0, $iY + 0, 50, 20)
    $g_ahCtl2[$eC2_edit_rot] = GUICtrlCreateInput("0", $iX + 0, $iY + 25, 40, 20)
    $g_ahCtl2[$eC2_ud_rot] = GUICtrlCreateUpdown(-1)
    GUICtrlSetLimit($eC2_ud_rot, 360, -360)
    $g_ahCtl2[$eC2_rot] = GUICtrlCreateButton("", $iX + 40, $iY + 25, 10, 20)

    $g_ahCtl2[$eC2_dgroup] = GUICtrlCreateGroup("Coords", 5 + $iX + 70, $iY + 0, 55, 70)
    $g_ahCtl2[$eC2_decy] = GUICtrlCreateButton("-", 24 + $iX + 70, 16 + $iY + 0, 17, 17)
    $g_ahCtl2[$eC2_incy] = GUICtrlCreateButton("+", 24 + $iX + 70, 48 + $iY + 0, 17, 17)
    $g_ahCtl2[$eC2_decx] = GUICtrlCreateButton("-", 8 + $iX + 70, 32 + $iY + 0, 17, 17)
    $g_ahCtl2[$eC2_incx] = GUICtrlCreateButton("+", 40 + $iX + 70, 32 + $iY + 0, 17, 17)
    GUICtrlCreateGroup("", -99, -99, 1, 1)

    $g_ahCtl2[$eC2_zout] = GUICtrlCreateButton("Zoom -", $iX + 0, $iY + 75, 50, 20)
    $g_ahCtl2[$eC2_zin] = GUICtrlCreateButton("Zoom +", $iX + 75, $iY + 75, 50, 20)
    $g_ahCtl2[$eC2_toall] = GUICtrlCreateCheckbox("Apply to all", $iX + 0, $iY + 100, 80, 25)
EndFunc   ;==>Control_Create_Group2

Func Control_IsChecked($IdCtrl)
    Return (BitAND(GUICtrlRead($IdCtrl), $GUI_CHECKED) = $GUI_CHECKED)
EndFunc   ;==>Control_IsChecked

Func GDI_Draw_ArrayPoints(ByRef $aPts, $hImage, $g_bClosePath, $iX, $iY, $sFileName, $iSelected = -1)
    Local $hWnd = GUICtrlGetHandle($hImage)
    If UBound($aPts) > 1 Then
        Local $aPoints = GDI_Points($aPts, $iX, $iY)
    Else
        Local $aPoints[1][2] = [[0, 0]]
    EndIf

    Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd) ;create a graphics object from a window handle
    _GDIPlus_GraphicsClear($hGraphics, 0xFFFFFFFF)
    If FileExists($sFileName) Then
        Local $hBitmap = _GDIPlus_BitmapCreateFromFile($sFileName)
        Local Const $iWidth = ScaleX(_GDIPlus_ImageGetWidth($hBitmap))
        Local Const $iHeight = ScaleY(_GDIPlus_ImageGetHeight($hBitmap))
        Local $hBitmap_Scaled = _GDIPlus_ImageResize($hBitmap, $iWidth, $iHeight) ;resize image
        _GDIPlus_BitmapDispose($hBitmap) ;Done with initial bitmap
        _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap_Scaled, 0, 0)
        _GDIPlus_BitmapDispose($hBitmap_Scaled)
    EndIf

    Local $hPen = _GDIPlus_PenCreate(0xFFFF0000, ScaleX(1))

    Local $hEndCap = _GDIPlus_ArrowCapCreate(1, 1)
    _GDIPlus_PenSetCustomEndCap($hPen, $hEndCap)

    If $g_bClosePath Then _GDIPlus_GraphicsDrawPolygon($hGraphics, $aPoints, $hPen)
    Local $iX0, $iY0, $iX1, $iY1
    For $i = 1 To $aPoints[0][0]
        If Not $g_bClosePath And $i < $aPoints[0][0] Then
            $iX0 = $aPoints[$i][0]
            $iY0 = $aPoints[$i][1]
            $iX1 = $aPoints[$i + 1][0]
            $iY1 = $aPoints[$i + 1][1]

            _GDIPlus_GraphicsDrawLine($hGraphics, $iX0, $iY0, $iX1, $iY1, $hPen)
        EndIf
    Next

    _GDIPlus_ArrowCapDispose($hEndCap)
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hGraphics)
    Point_Selected($aPts, $hImage, $iSelected)
EndFunc   ;==>GDI_Draw_ArrayPoints

Func GDI_Line_hPath_From_Points($aPts, $iXorig, $iYorig)
    ;Returns hpath object be sure to delete it when finished
    Local $hPath = _GDIPlus_PathCreate() ;Create new path object
    Local $aPoints = GDI_Points($aPts, $iXorig, $iYorig)
    Local $iX0, $iY0, $iX1, $iY1
    If IsArray($aPoints) Then
        For $i = 1 To $aPoints[0][0] - 1
            $iX0 = $aPoints[$i][0]
            $iY0 = $aPoints[$i][1]
            $iX1 = $aPoints[$i + 1][0]
            $iY1 = $aPoints[$i + 1][1]
            _GDIPlus_PathAddLine($hPath, $iX0, $iY0, $iX1, $iY1)
        Next
    EndIf
    Return $hPath
    ;_GDIPlus_PathDispose($hPath)
EndFunc   ;==>GDI_Line_hPath_From_Points

Func GDI_Points($aPts, $iXo, $iYO)
    Local $aGDIPts
    If IsArray($aPts) And UBound($aPts) > 1 Then

        Local $aGDIPts[UBound($aPts) + 1][2]
        $aGDIPts[0][0] = UBound($aPts)

        For $i = 1 To $aGDIPts[0][0] ;Build points list
            $aGDIPts[$i][0] = ScaleX($aPts[$i - 1][0]) + $iXo
            $aGDIPts[$i][1] = ScaleY($aPts[$i - 1][1]) + $iYO
        Next

    Else
        Local $aGDIPts[1][2] = [[0, 0]]
    EndIf
    Return $aGDIPts
EndFunc   ;==>GDI_Points

Func Image1_Clicked()
    If Not Control_IsChecked($g_ahCtl1[$eC1_lock]) Then
        Local $aCPos = ControlGetPos(GUICtrlGetHandle($g_hImage1), "", 0)
        Local $aPos = MouseGetPos()

        If IsArray($aPos) And IsArray($aCPos) Then
            Local $iXn = Int(($aPos[0] - $aCPos[0] + ScaleX(1) / 2) / ScaleX(1))
            Local $iYn = Int(($aPos[1] - $aCPos[1] + ScaleY(1) / 2) / ScaleY(1))
            Point_Add(List_Index(), $iXn, $iYn)
        EndIf
        Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage)
    Else
        ToolTip("Locked")
        Sleep(500)
        ToolTip("")
    EndIf
EndFunc   ;==>Image1_Clicked

Func List_Index()
    Static Local $hWndList1 = GUICtrlGetHandle($g_hList1)
    Local $iIndex = _GUICtrlListView_GetSelectionMark($hWndList1)
    If _GUICtrlListView_GetItemSelected($g_hList1, $iIndex) Then Return $iIndex
    Return -1
EndFunc   ;==>List_Index

Func List_Update($iIndex = -1)
    Static $hWnd_List1 = GUICtrlGetHandle($g_hList1)
    _GUICtrlListView_BeginUpdate($g_hList1)
    _GUICtrlListView_DeleteAllItems($hWnd_List1)
    For $i = 0 To UBound($g_aPath_Points) - 1
        GUICtrlCreateListViewItem($i & "|" & $g_aPath_Points[$i][0] & "|" & $g_aPath_Points[$i][1], $g_hList1)
    Next
    If $iIndex > -1 Then
        _GUICtrlListView_ClickItem($g_hList1, $iIndex)
        _GUICtrlListView_EnsureVisible($g_hList1, $iIndex)
    EndIf
    _GUICtrlListView_EndUpdate($g_hList1)
EndFunc   ;==>List_Update

Func Point_Add($iIndex, $iX, $iY)
    If $iIndex <> -1 Then
        _ArrayInsert($g_aPath_Points, $iIndex, $iX & "|" & $iY, 0)
        _GUICtrlListView_InsertItem($g_hList1, $iIndex, $iIndex)
        _GUICtrlListView_SetItemText($g_hList1, $iIndex, $iX, 1)
        _GUICtrlListView_SetItemText($g_hList1, $iIndex, $iY, 2)
        _GUICtrlListView_EnsureVisible($g_hList1, $iIndex)
    Else
        _ArrayAdd($g_aPath_Points, $iX & "|" & $iY, 0)
        GUICtrlCreateListViewItem(UBound($g_aPath_Points) - 1 & "|" & $iX & "|" & $iY, $g_hList1)
        _GUICtrlListView_EnsureVisible($g_hList1, UBound($g_aPath_Points) - 1)
    EndIf
    State_Save($g_aPath_Points)
EndFunc   ;==>Point_Add

Func Point_Adjust($iX, $iY, $bToAll)
    If Not $bToAll Then
        Local $iIndex = List_Index()
        If $iIndex == -1 And IsArray($g_aPath_Points) Then $iIndex = UBound($g_aPath_Points) - 1
        If $iIndex == -1 Then Return
        $g_aPath_Points[$iIndex][0] += $iX
        $g_aPath_Points[$iIndex][1] += $iY
        _GUICtrlListView_SetItemText($g_hList1, $iIndex, $g_aPath_Points[$iIndex][0], 1)
        _GUICtrlListView_SetItemText($g_hList1, $iIndex, $g_aPath_Points[$iIndex][1], 2)
        If $iIndex <> UBound($g_aPath_Points) - 1 Then _GUICtrlListView_ClickItem($g_hList1, $iIndex)
    Else
        For $i = 0 To UBound($g_aPath_Points) - 1
            $g_aPath_Points[$i][0] += $iX
            $g_aPath_Points[$i][1] += $iY
        Next
        List_Update(List_Index())
    EndIf
    State_Save($g_aPath_Points)
    Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage)
EndFunc   ;==>Point_Adjust

Func Point_Delete($iIndex)
    If $iIndex <> -1 Then
        _ArrayDelete($g_aPath_Points, $iIndex)
        _GUICtrlListView_DeleteItem($g_hList1, $iIndex)
        State_Save($g_aPath_Points)
        ;List_Update($iIndex)
    EndIf
EndFunc   ;==>Point_Delete

Func Point_Modify($iIndex, $iX, $iY)
    If $iIndex <> -1 Then
        $g_aPath_Points[$iIndex][0] = $iX
        $g_aPath_Points[$iIndex][1] = $iY
        _GUICtrlListView_SetItemText($g_hList1, $iIndex, $iX, 1)
        _GUICtrlListView_SetItemText($g_hList1, $iIndex, $iY, 2)
        _GUICtrlListView_EnsureVisible($g_hList1, $iIndex)
        State_Save($g_aPath_Points)
    EndIf
EndFunc   ;==>Point_Modify

Func Point_Selected($aPts, $hImage, $iIndex)
    If $iIndex > -1 Then
        GUICtrlSetState($g_hSelSquare, $GUI_HIDE)
        Local $hWnd = GUICtrlGetHandle($hImage)
        Local $aPos = ControlGetPos($hWnd, "", 0)
        If IsArray($aPos) And IsArray($aPts) Then
            _WinAPI_RedrawWindow($hWnd, Default, Default, $RDW_ERASENOW)
            Local $iXs = ScaleX($aPts[$iIndex][0]) + $aPos[0] - ScaleX(1) / 2
            Local $iYs = ScaleY($aPts[$iIndex][1]) + $aPos[1] - ScaleY(1) / 2
            WinMove(GUICtrlGetHandle($g_hSelSquare), "", $iXs, $iYs, ScaleX(1), ScaleY(1))
            GUICtrlSetState($g_hSelSquare, $GUI_SHOW)
            ;ConsoleWrite("Point_Selected" & @CRLF)
        Else
            ConsoleWriteError("Error: Point_Selected" & @CRLF)
        EndIf
    EndIf
EndFunc   ;==>Point_Selected

Func Point_Swap($iIndex1, $iNext)
    _GUICtrlListView_BeginUpdate($g_hList1)
    Local $iIndex2 = 0
    Local $aTmp = 0
    If $iIndex1 <> -1 Then
        $iIndex2 = $iIndex1 + $iNext
        If $iIndex2 > UBound($g_aPath_Points) - 1 Then
            $iIndex2 = 0
        ElseIf $iIndex2 < 0 Then
            $iIndex2 = UBound($g_aPath_Points) - 1
        EndIf
        _ArraySwap($g_aPath_Points, $iIndex1, $iIndex2)
        Local $iX1 = _GUICtrlListView_GetItemText($g_hList1, $iIndex1, 2)
        Local $iY1 = _GUICtrlListView_GetItemText($g_hList1, $iIndex1, 2)
        Local $iX2 = _GUICtrlListView_GetItemText($g_hList1, $iIndex2, 2)
        Local $iY2 = _GUICtrlListView_GetItemText($g_hList1, $iIndex2, 2)
        _GUICtrlListView_SetItemText($g_hList1, $iIndex1, $iX2, 1)
        _GUICtrlListView_SetItemText($g_hList1, $iIndex1, $iY2, 2)
        _GUICtrlListView_SetItemText($g_hList1, $iIndex2, $iX1, 1)
        _GUICtrlListView_SetItemText($g_hList1, $iIndex2, $iY1, 2)
        _GUICtrlListView_ClickItem($g_hList1, $iIndex2)
        _GUICtrlListView_EnsureVisible($g_hList1, $iIndex2)
    Else
        ;ConsoleWrite("Array Shift" & @CRLF)
        If $iNext > 0 Then ;ARRAY SHIFT -- Melba23
            Local $iUBound = UBound($g_aPath_Points) ; Get size of array
            $aTmp = _ArrayExtract($g_aPath_Points, 0, $iUBound - 2) ; Extract all but last
            _ArrayInsert($aTmp, 0, _ArrayExtract($g_aPath_Points, $iUBound - 1, Default)) ; Insert last at top
            $g_aPath_Points = $aTmp
        Else
            $aTmp = _ArrayExtract($g_aPath_Points, 1, Default) ; Extract all but top row
            _ArrayAdd($aTmp, _ArrayExtract($g_aPath_Points, 0, 0)) ; Add top row at bottom
            $g_aPath_Points = $aTmp
        EndIf

        List_Update(List_Index())
        Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage)
    EndIf
    State_Save($g_aPath_Points)
    _GUICtrlListView_EndUpdate($g_hList1)
EndFunc   ;==>Point_Swap

Func Points_Reverse($aPts)
    Local $hPath = GDI_Line_hPath_From_Points($aPts, 0, 0)
    ;_GDIPlus_PathFlatten($hPath)
    _GDIPlus_PathReverse($hPath)
    Local $aPoints = _GDIPlus_PathGetPoints($hPath)
    _GDIPlus_PathDispose($hPath)
    If IsArray($aPoints) Then
        ;ConsoleWrite("Flipped_Points" & @CRLF)
        Global $aPts_Rev[$aPoints[0][0]][2]
        For $i = 1 To $aPoints[0][0]
            $aPts_Rev[$i - 1][0] = Int($aPoints[$i][0] / ScaleX(1))
            $aPts_Rev[$i - 1][1] = Int($aPoints[$i][1] / ScaleY(1))
        Next
        Return $aPts_Rev
    Else
        Return $aPts
    EndIf
EndFunc   ;==>Points_Reverse

Func Points_Rotate($aPts, $iDegrees)

    Local $hPath = GDI_Line_hPath_From_Points($aPts, 0, 0)
    ;_GDIPlus_PathFlatten($hPath)
    Local $hPen = _GDIPlus_PenCreate(0x0, ScaleX(1))
    Local $aBounds = _GDIPlus_PathGetWorldBounds($hPath, 0, $hPen)
    _GDIPlus_PenDispose($hPen)

    If IsArray($aBounds) Then
        Local $hMatrix = _GDIPlus_MatrixCreate()
        _GDIPlus_MatrixTranslate($hMatrix, $aBounds[0] + $aBounds[2] / 2, $aBounds[1] + $aBounds[3] / 2)
        _GDIPlus_MatrixRotate($hMatrix, $iDegrees)
        _GDIPlus_MatrixTranslate($hMatrix, -($aBounds[0] + $aBounds[2] / 2), -($aBounds[1] + $aBounds[3] / 2))
        _GDIPlus_PathTransform($hPath, $hMatrix)
        _GDIPlus_MatrixDispose($hMatrix)
    EndIf

    Local $aPoints = _GDIPlus_PathGetPoints($hPath)
    _GDIPlus_PathDispose($hPath)
    If IsArray($aPoints) Then
        ;ConsoleWrite("Rotate_Points" & @CRLF)
        Dim $aPts_Rev[$aPoints[0][0]][2]
        For $i = 1 To $aPoints[0][0]
            $aPts_Rev[$i - 1][0] = Int($aPoints[$i][0] / ScaleX(1))
            $aPts_Rev[$i - 1][1] = Int($aPoints[$i][1] / ScaleY(1))
        Next
        Return $aPts_Rev
    Else
        Return $aPts
    EndIf
EndFunc   ;==>Points_Rotate

Func Points_Scale($iScaleX, $iScaleY)

    For $i = 0 To UBound($g_aPath_Points) - 1
        If $iScaleX > 0 Then
            $g_aPath_Points[$i][0] *= 2
        Else
            $g_aPath_Points[$i][0] /= 2
        EndIf
        If $iScaleY > 0 Then
            $g_aPath_Points[$i][1] *= 2
        Else
            $g_aPath_Points[$i][1] /= 2
        EndIf
    Next
    State_Save($g_aPath_Points)
    List_Update(List_Index())
    Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage)
EndFunc   ;==>Points_Scale

Func Points_Update($aPts, $g_bClosePath = False, $b_Show_Image = True, $iSelected = -1)
    Local $_Image_File = $g_sImagefile
    If Not $b_Show_Image Then $_Image_File = ""
    GDI_Draw_ArrayPoints($aPts, $g_hImage1, $g_bClosePath, 0, 0, $_Image_File, $iSelected)
EndFunc   ;==>Points_Update

Func ScaleX($iX)
    Local $iXs = $g_iXScale
    If $iXs == 0 Then $iXs = -1

    If $iXs > 0 Then
        $iX = $iX * $iXs
    Else
        $iX = $iX / Abs($iXs)
    EndIf
    Return $iX
EndFunc   ;==>ScaleX

Func ScaleY($iY)
    Local $iYs = $g_iYScale
    If $iYs == 0 Then $iYs = -1

    If $iYs > 0 Then
        $iY = $iY * $iYs
    Else
        $iY = $iY / Abs($iYs)
    EndIf
    Return $iY
EndFunc   ;==>ScaleY

Func SelSquare_Drag()
    Local $iIndex = List_Index()
    If $iIndex <> -1 Then
        Local $cInfo = GUIGetCursorInfo($g_hForm1)
        Local $aPosSelOrig = ControlGetPos($g_hForm1, "", $g_hSelSquare)
        If IsArray($aPosSelOrig) Then
            Local $iSubtractX = $cInfo[0] - $aPosSelOrig[0]
            Local $iSubtractY = $cInfo[1] - $aPosSelOrig[1]
        EndIf

        If IsArray($cInfo) Then
            Do
                $cInfo = GUIGetCursorInfo($g_hForm1)
                ControlMove($g_hForm1, "", $g_hSelSquare, $cInfo[0] - $iSubtractX, $cInfo[1] - $iSubtractY)
            Until Not $cInfo[2]
        EndIf
        Local $aPosSelNew = ControlGetPos($g_hForm1, "", $g_hSelSquare)
        If IsArray($aPosSelNew) And IsArray($aPosSelOrig) Then
            Local $iXm = $g_aPath_Points[$iIndex][0] + Int(($aPosSelNew[0] - $aPosSelOrig[0]) / ScaleX(1))
            Local $iYm = $g_aPath_Points[$iIndex][1] + Int(($aPosSelNew[1] - $aPosSelOrig[1]) / ScaleY(1))
            Point_Modify($iIndex, $iXm, $iYm)
            Points_Update($g_aPath_Points, $g_bClosePath, $g_bShowImage, $iIndex)
        EndIf
    EndIf
EndFunc   ;==>SelSquare_Drag

Func SplitDir($FullPath)
    Local $sDrive, $sDir, $sDummy
    _PathSplit($FullPath, $sDrive, $sDir, $sDummy, $sDummy)
    Return $sDrive & $sDir
EndFunc   ;==>SplitDir

Func SplitFileName($FullPath)
    Local $sDummy, $sFileName, $sExt
    _PathSplit($FullPath, $sDummy, $sDummy, $sFileName, $sExt)
    Return $sFileName & "" & $sExt
EndFunc   ;==>SplitFileName

Func State_Cleanup(ByRef $a1)
    If (UBound($a1) > $g_iUndo_Max + 2) Then
        Local $a1Rem = _ArrayExtract($a1, 1, Default)
        $a1Rem[0] = $a1[0]
        Local $sTmp = $a1[1]

        If $sTmp <> "" And FileExists($sTmp) Then
            FileDelete($sTmp)
            ;ConsoleWrite("Cleanup Delete (UnD) " & $sTmp & @CRLF)
        EndIf
        $a1 = $a1Rem
    EndIf
EndFunc   ;==>State_Cleanup

Func State_Destroy($bRedo_Only = False)
    Local $sTmp

    While (UBound($g_asRedo_Files) > 1)
        $sTmp = _ArrayPop($g_asRedo_Files)
        If $sTmp <> "" And FileExists($sTmp) Then
            FileDelete($sTmp)
            ;ConsoleWrite(", Delete (ReD) " & $sTmp)
            If @error Then ConsoleWriteError("Failed to Delete " & $sTmp)
        EndIf
    WEnd

    GUICtrlSetState($g_ahCtl1[$eC1_redo], $GUI_DISABLE)
    If $bRedo_Only Then Return

    While (UBound($g_asUndo_Files) > 1)
        $sTmp = _ArrayPop($g_asUndo_Files)
        If $sTmp <> "" And FileExists($sTmp) Then
            FileDelete($sTmp)
            ;ConsoleWrite(", Delete (UnD)" & $sTmp)
            If @error Then ConsoleWriteError("Failed to Delete " & $sTmp)
        EndIf
    WEnd
    GUICtrlSetState($g_ahCtl1[$eC1_undo], $GUI_DISABLE)

EndFunc   ;==>State_Destroy

Func State_Is_Diff(ByRef $a1, ByRef $a2)
    Local $bIsDiff = True

    If UBound($a1) = UBound($a2) Then
        $bIsDiff = False

        For $i = UBound($a1) - 1 To 0 Step -1
            If $a1[$i][0] == $a2[$i][0] And $a1[$i][1] == $a2[$i][1] Then
                ContinueLoop
            Else
                ;ConsoleWrite("Diff " & $i & @CRLF)
                $bIsDiff = True
                ExitLoop
            EndIf
        Next
    Else
        ;ConsoleWrite("Diff " & @CRLF)
    EndIf

    Return $bIsDiff
EndFunc   ;==>State_Is_Diff

Func State_Restore(ByRef $aPts, $bUndo)
    Local $sTmp = ""
    Local $aRes

    If $bUndo Then
        $sTmp = _ArrayPop($g_asUndo_Files)
        ;ConsoleWrite(", Restore (UnD)" & $sTmp)

        If $sTmp <> "" And FileExists($sTmp) Then
            _ArrayAdd($g_asRedo_Files, $sTmp)
            _FileReadToArray($sTmp, $aRes, 0, ",")

            If UBound($g_asUndo_Files) < 2 Then GUICtrlSetState($g_ahCtl1[$eC1_undo], $GUI_DISABLE)
            If UBound($g_asRedo_Files) > 2 Then GUICtrlSetState($g_ahCtl1[$eC1_redo], $GUI_ENABLE)

            If UBound($g_asUndo_Files) > 1 And Not State_Is_Diff($aPts, $aRes) Then Return State_Restore($aPts, $bUndo)

            If Not @error Then Return $aRes
        Else
            ConsoleWriteError("Failed to Restore " & $sTmp)
        EndIf
    Else
        $sTmp = _ArrayPop($g_asRedo_Files)
        ;ConsoleWrite(", Restore (ReD) " & $sTmp)
        If $sTmp <> "" And FileExists($sTmp) Then
            _ArrayAdd($g_asUndo_Files, $sTmp)
            _FileReadToArray($sTmp, $aRes, 0, ",")

            If UBound($g_asRedo_Files) < 2 Then GUICtrlSetState($g_ahCtl1[$eC1_redo], $GUI_DISABLE)
            If UBound($g_asUndo_Files) > 2 Then GUICtrlSetState($g_ahCtl1[$eC1_undo], $GUI_ENABLE)

            If UBound($g_asRedo_Files) > 1 And Not State_Is_Diff($aPts, $aRes) Then Return State_Restore($aPts, $bUndo)

            If Not @error Then Return $aRes
        Else
            ConsoleWriteError("Failed to Restore " & $sTmp)
        EndIf
    EndIf
    Return $aPts
EndFunc   ;==>State_Restore

Func State_Save($aPts)
    If $g_iUndo_Max < 1 Then Return
    Local $sTmp = _TempFile(@TempDir, "DPP_")

    If UBound($g_asRedo_Files) > 2 Then _ArrayAdd($g_asUndo_Files, _ArrayPop($g_asRedo_Files))

    _ArrayAdd($g_asUndo_Files, $sTmp)
    _FileWriteFromArray($sTmp, $aPts, 0, Default, ",")

    If UBound($g_asRedo_Files) > 2 Then State_Destroy(True)
    State_Cleanup($g_asUndo_Files)

    ;ConsoleWrite("Save State " & UBound($g_asUndo_Files) & " " & $sTmp & @CRLF)
    If UBound($g_asUndo_Files) > 2 Then GUICtrlSetState($g_ahCtl1[$eC1_undo], $GUI_ENABLE)

    If @error Then
        MsgBox(0, @ScriptName & " Error", "Unable to create undo file " & $sTmp)
        GUICtrlSetState($g_ahCtl1[$eC1_undo], $GUI_DISABLE)
        GUICtrlSetState($g_ahCtl1[$eC1_redo], $GUI_DISABLE)
        $g_iUndo_Max = 0
    EndIf
EndFunc   ;==>State_Save

Func Tab1_Select()
    Local $iStateCtl1, $iStateCtl2
    Local $tabindex = GUICtrlRead($g_hTab1)
    ;ConsoleWrite("tab" & $tabindex + 1 & "_selected" & @CRLF)
    Select
        Case $tabindex = 0
            $iStateCtl1 = $GUI_SHOW
            $iStateCtl2 = $GUI_HIDE
        Case $tabindex = 1
            $iStateCtl1 = $GUI_HIDE
            $iStateCtl2 = $GUI_SHOW
        Case Else
            _GUICtrlTab_ActivateTab($g_hTab1, 0)
            Return
    EndSelect

    For $i = 0 To UBound($g_ahCtl1) - 1
        GUICtrlSetState($g_ahCtl1[$i], $iStateCtl1)
    Next

    For $i = 0 To UBound($g_ahCtl2) - 1
        GUICtrlSetState($g_ahCtl2[$i], $iStateCtl2)
    Next
EndFunc   ;==>Tab1_Select

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    Static Local $hWndList1 = GUICtrlGetHandle($g_hList1)
    If Not IsHWnd($hWndList1) Then $hWndList1 = GUICtrlGetHandle($g_hList1)
    If @error Then Return $GUI_RUNDEFMSG
    If $wParam = $g_hList1 Then
        Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)

        Switch DllStructGetData($tNMHDR, "Code")

            Case $LVN_KEYDOWN, $NM_CLICK
                GUICtrlSendToDummy($g_hList1_LVN, $lParam)
        EndSwitch
    EndIf

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

 

DPP1.png

DPP2.png

DrawPathPoints.au3

Edited by Bilgus
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

×
×
  • Create New...