Tri manuel par Drag'n Drop pour TreeGadget

Programmation d'applications complexes
Avatar de l’utilisateur
ZapMan
Messages : 460
Inscription : ven. 13/févr./2004 23:14
Localisation : France
Contact :

Tri manuel par Drag'n Drop pour TreeGadget

Message par ZapMan »

Encore un petit code pour gérer le Drag'n drop. Cette fois, il s'agit de permettre à l'utilisateur d'organiser et de trier manuellement les éléments d'un TreeGadget par glisser/déposer.

Ca peut être utile si l'un de vos programmes nécessite une gestion de liste hiérarchique par l'utilisateur. Personnellement, je vais m'en servir pour permettre aux utilisateur de DropUpLoad d'organiser et de gérer la liste des serveurs FTP. Ca pourrait servir à gérer une liste de raccourcis, une liste de fichiers, etc.

Si vous le testez, merci de me tenir au courant des résultats :)

Code : Tout sélectionner

; Drag'nDrop manual sort for TreeGadget
; By Zapman
;
; This demo code shows how to implemente a drag'n drop ability for TreeGadget
; in order to allow the user to sort manually the gadget content by draging
; it elements.
;
Procedure GetFolderIconHandle()
  *sfi.SHFILEINFO = AllocateMemory(SizeOf(SHFILEINFO))
  If SHGetFileInfo_("aa.txt",#FILE_ATTRIBUTE_DIRECTORY,*sfi, SizeOf(SHFILEINFO), #SHGFI_ICON| #SHGFI_SMALLICON | #SHGFI_USEFILEATTRIBUTES)
    hFolderIcon = *sfi\hIcon
  EndIf
  FreeMemory(*sfi)
  ProcedureReturn hFolderIcon
EndProcedure

Procedure GetTreeItemIndexFromHandle(IHandle,TreeGadgetID)
;   By Timo 'fr34k' Harter and Zapman
  dItem = 0
  hItem = SendMessage_(TreeGadgetID, #TVM_GETNEXTITEM, #TVGN_ROOT, 0)
  While IHandle And hItem And hItem <> IHandle
    hItem2 = SendMessage_(TreeGadgetID, #TVM_GETNEXTITEM, #TVGN_CHILD, hItem)
    Repeat
      If hItem2 = #Null: hItem2 = SendMessage_(TreeGadgetID, #TVM_GETNEXTITEM, #TVGN_NEXT, hItem): EndIf
      If hItem2 = #Null: hItem = SendMessage_(TreeGadgetID, #TVM_GETNEXTITEM, #TVGN_PARENT, hItem): EndIf
    Until hItem2 <> #Null
    hItem = hItem2
    dItem + 1
  Wend
  ProcedureReturn dItem
EndProcedure
;
Procedure HighLightTreeItem(TreeGadgetID,hItem,HighLight)
;   By Timo 'fr34k' Harter and Zapman
  If HighLight : HighLight = #TVIS_DROPHILITED : EndIf ; to be sure that te right value is used
  ; We'll send a #TVM_SETITEM message. We only need to change the
  ; item state, so #TVIF_STATE is enough for the mask.          
  pitem.TV_ITEM
  pitem\mask = #TVIF_STATE
  pitem\hItem = hItem
  
  ; 'stateMask' determines, what will be changed, and 'state' sets the actual value,
  ; so here, we set the TVIS_DROPHILITED state flag to HighLight.
  pitem\state = HighLight
  pitem\stateMask = #TVIS_DROPHILITED
  Result = SendMessage_(TreeGadgetID, #TVM_SETITEM, 0, @pitem)
  
  ; a redraw is neccesary here to avoid problems.
  RedrawWindow_(TreeGadgetID, 0, 0, #RDW_UPDATENOW)
  ProcedureReturn Result
EndProcedure
;
Procedure GetTreeItemIconIndex(TreeGadget,hitem)
  ; by Zapman
  tvitem.TV_ITEM\mask=#TVIF_IMAGE
  tvitem\hitem=hitem
  If SendMessage_(GadgetID(TreeGadget), #TVM_GETITEM,0,@tvitem) ; get the icon index from the item
    ProcedureReturn tvitem\iImage
  Else
    ProcedureReturn -1
  EndIf
EndProcedure
;
Procedure SetTreeItemIconIndex(TreeGadget,hitem,iconeIndex)
  ; by Zapman
  tvitem.TV_ITEM\mask=#TVIF_IMAGE|#TVIF_SELECTEDIMAGE 
  tvitem\hitem=hitem
  tvitem\iImage= iconeIndex
  tvitem\iSelectedImage = iconeIndex
  result = SendMessage_(GadgetID(TreeGadget), #TVM_SETITEM,0,@tvitem) ; set the icon index from the item
  ProcedureReturn result
EndProcedure
;
Procedure InvertTreeGadgetItems(TreeGadget,p1,p2)
  t1$=GetGadgetItemText(TreeGadget,p1)
  t2$=GetGadgetItemText(TreeGadget,p2)
  SetGadgetItemText(TreeGadget,p1,t2$)
  SetGadgetItemText(TreeGadget,p2,t1$)
  iconindex1 = GetTreeItemIconIndex(TreeGadget,GadgetItemID(TreeGadget,p1)); get the icon from the first item
  iconindex2 = GetTreeItemIconIndex(TreeGadget,GadgetItemID(TreeGadget,p2)); get the icon from the second item
  SetTreeItemIconIndex(TreeGadget,GadgetItemID(TreeGadget,p1),iconindex2); set the icon for the first item
  SetTreeItemIconIndex(TreeGadget,GadgetItemID(TreeGadget,p2),iconindex1); set the icon for the second item
EndProcedure
;
;
Global DD_TreeGadget
Procedure DD_TreeCallback(Window, Message, wParam, lParam)
;   By Timo 'fr34k' Harter for ListView Gadget
;   Adapted to TreeView by Zapman
  Shared OldTreeItem,TreeIsDraging,DraggedItemsList$,DragImageList
  result = #PB_ProcessPureBasicEvents

  ; The first message we need is #TVN_BEGINDRAG. This is a so called
  ; Notification message. This means, that you don't get a message called
  ; #TVN_BEGINDRAG, but you get a #WM_NOTIFY message, with further information, 
  ; that tells you, that it is #TVN_BEGINDRAG
  
  If Message = #WM_NOTIFY
    ; The lparam paramenter contains a pointer to a NMHDR structure. There is
    ; the information about the Message    
    *nmhdr.NMHDR = lParam

    ; The 'hwndfrom' member tells you, which Gadget actually sent the message
    ; This must be always checked to be sure, it is the right gadget.
    ; We allow only our own Gadgets:
    If *nmhdr\hwndfrom = GadgetID(DD_TreeGadget)
        
      ; The 'code' member contains the real message, in our case #TVN_BEGINDRAG
      If *nmhdr\code = #TVN_BEGINDRAG
        ; Ok, for the #TVN_BEGINDRAG notification message, lParam is a pointer to a
        ; NMTREEVIEW Structure. You might think that this can't be, as lParam allready
        ; pointed to a NMHDR structure, but this is correct, as NMTREEVIEW has a
        ; NMHDR structure inside, it only adds more members to it.
    
        *nmv.NMTREEVIEW = lParam
        
        ; The 'hItem' member contains the index of the source item, which we will need
        ; later.        
        TreeItemSource = *nmv\itemNew\hItem
        OldTreeItem = TreeItemSource ; will be used to unhilite the item which was hilited
        
        ; By sending a #TVM_CREATEDRAGIMAGE message to the gadget, we create an ImageList
        ; that contains just one image, the drag&drop image. We will need the Imagelist WinAPI
        ; commands to work with that one later.            
        HighLightTreeItem(GadgetID(DD_TreeGadget),TreeItemSource,0)
        HighLightTreeItem(GadgetID(DD_TreeGadget),GadgetItemID(DD_TreeGadget,GetGadgetState(DD_TreeGadget)),0)
        DragImageList = SendMessage_(GadgetID(DD_TreeGadget), #TVM_CREATEDRAGIMAGE, 0,TreeItemSource)
        ;
        ; If the user is draging a node,
        ; we'll modify the image by adding all the items contained by the node
        LImage = 400
        HImage = 600
        Pb_Image = CreateImage(#PB_Any,LImage,HImage)
        Font1 = LoadFont(#PB_Any, "Tahoma"  ,  8) 
        StartDrawing(ImageOutput(Pb_Image))
        DrawingFont(FontID(Font1))
        Box(0, 0, LImage, HImage ,RGB(255,255,255))
        ItemIndex = GetTreeItemIndexFromHandle(TreeItemSource,GadgetID(DD_TreeGadget))
        ItemText$ = GetGadgetItemText(DD_TreeGadget,ItemIndex,0)
        DraggedItemsList$ = Str(ItemIndex)+Chr(13)+ReplaceString(ItemText$,Chr(13),"")+Chr(13)+"0"+Chr(13)
        DrawText(0,0,ItemText$,0,RGB(255,255,255))
        dep = TextWidth(ItemText$)
        posvert=0
        hcar = 14
        hItem = SendMessage_(GadgetID(DD_TreeGadget), #TVM_GETNEXTITEM, #TVGN_CHILD, TreeItemSource)
        If hItem
          level = 1
          Repeat
            posvert + hcar
            ItemIndex = GetTreeItemIndexFromHandle(hItem,GadgetID(DD_TreeGadget))
            ItemText$ = GetGadgetItemText(DD_TreeGadget,ItemIndex,0)
            DraggedItemsList$ + Str(ItemIndex)+Chr(13)+ReplaceString(ItemText$,Chr(13),"")+Chr(13)+Str(level)+Chr(13)
            DrawText(level*20,posvert,ItemText$,0,RGB(255,255,255))
            nWidth = TextWidth(ItemText$)+(level*20)
            If nWidth>dep ; calculate max text width for our draging image
              dep = nWidth
            EndIf
            hItem2 = SendMessage_(GadgetID(DD_TreeGadget), #TVM_GETNEXTITEM, #TVGN_CHILD, hItem) ; is the next item a child ?
            If hItem2
              level + 1
              hItem = hItem2
            Else
              hItem2 = SendMessage_(GadgetID(DD_TreeGadget), #TVM_GETNEXTITEM, #TVGN_NEXT, hItem) ; is it a same level item ?
              If hItem2
                hItem = hItem2
              Else
                hItem = SendMessage_(GadgetID(DD_TreeGadget), #TVM_GETNEXTITEM,#TVGN_PARENT, hItem) ; get the parent of our item
                hItem = SendMessage_(GadgetID(DD_TreeGadget), #TVM_GETNEXTITEM, #TVGN_NEXT, hItem) ; and go to the next
                level - 1
              EndIf             
            EndIf
          Until level = 0 Or hItem = 0
        EndIf
        DraggedItemsList$ + "Store_end" + Chr(13)
        
        StopDrawing()
        FreeFont(Font1)
        
        ImageList_SetIconSize_(DragImageList,dep+5,posvert+hcar)
        ImageList_AddMasked_(DragImageList,ImageID(Pb_Image),RGB(255,255,255))
        FreeImage(Pb_Image)

        If DragImageList 
          ; This begins the drag&drop operation by displaying the image
          If ImageList_BeginDrag_(DragImageList , 0, 0, 0)

            ; this command shows or hides the drag&drop image. Or course,
            ; we want to see it now :)
            ImageList_DragShowNolock_(#True)
            
            ; this causes windows to send all mouse messages to our window,
            ; even if the mouse is outside of our window. This is neccesary,
            ; because we need to detect the mouseup event to abort the
            ; operation, even if the mouse is outside our window.
            SetCapture_(GetParent_(GadgetID(DD_TreeGadget)))
            
            ; hide the standard cursor
            ShowCursor_(#False)
            
            ; When processing the other events, we need to know whether something
            ; is being draged or not.
            TreeIsDraging = #True
   
          EndIf ; check for ImageList_BeginDrag_()       
        
        EndIf ; check for DragImageList
        
      EndIf ; check for #TVN_BEGINDRAG
          
    EndIf ; check for right gadget
    
  
  ; The next message we need is #WM_MOUSEMOVE, to update the mouse.
  ; But only if TreeIsDraging is #TRUE.  
  ElseIf Message = #WM_MOUSEMOVE And TreeIsDraging
    
    
    ; now we hide the image to avoid redrawn problems.
    ImageList_DragShowNolock_(#False)
    
    ; the next thing we do is hilighting the target item in the target gadget.
    GetWindowRect_(GadgetID(DD_TreeGadget),re.RECT) 
    GetCursorPos_(pt.POINT)  
    If PtInRect_(@re, pt\x | (pt\y<<32))

      ; What we need next is the Item, that is currently under the mouse cursor.
      ; the #TVM_HITTEST message does that test for us.
    
      ; here, we need coordinates relative to the top/left corner of our target
      ; Gadget, so we substract the Gadget position from our window coordinates
      ;  When #EM_MOUSEMOVE is sent, the lParam parameter contains
      ; the x coordinate in the low-word and the y coordinate in the high-word, so we
      ; just use them here:
      MouseX = lParam & $FFFF
      MouseY = lParam >> 16
      hittestinfo.TV_HITTESTINFO
      hittestinfo\pt\x = MouseX - GadgetX(DD_TreeGadget)
      hittestinfo\pt\y = MouseY - GadgetY(DD_TreeGadget)
      
      ; find the item, if none is under the cursor, we get -1, and the next
      ; SendMessage won't work, and nothing is hilighted.
      TargetItem = SendMessage_(GadgetID(DD_TreeGadget), #TVM_HITTEST, 0, @hittestinfo)
      If TargetItem<>-1 And TargetItem<>OldTreeItem
        If OldTreeItem
          HighLightTreeItem(GadgetID(DD_TreeGadget),OldTreeItem,0) ; Unhilighte the precedent hilighted item
        EndIf
        OldTreeItem = TargetItem
        HighLightTreeItem(GadgetID(DD_TreeGadget),OldTreeItem,1)
      EndIf
    Else ; scroll treegadget if mouse is upper or lower than it
      GetWindowRect_(GadgetID(DD_TreeGadget),re.RECT) 
      GetCursorPos_(@MP.POINT) 
      If MP\y < re\top
        SendMessage_(GadgetID(DD_TreeGadget), #WM_VSCROLL, #SB_LINEUP, 0);
      EndIf
      If MP\y > re\bottom
        SendMessage_(GadgetID(DD_TreeGadget), #WM_VSCROLL, #SB_LINEDOWN, 0);
      EndIf
    EndIf
    
    ; now we can show the drag image again:        
    ImageList_DragShowNolock_(#True)

        ; this moves the drag Image.
    GetCursorPos_(@MP.Point)
    ImageList_DragMove_(MP\x, MP\y-7)
    
    ; that's all to do while moving the mouse. Of course, there can be more checks added,
    ; and for example, a different cursor displayed, if you don't want the source to
    ; be draged to the current target and so on, but i think this is enough for a basic
    ; example.
  
  
  ; next is the end of the drag&drop operation... when the user releases the mouse.           
  ElseIf Message = #WM_LBUTTONUP And TreeIsDraging
    ; first, we release all we did, to unlock the mouse. 
    
    ; mouse messages will be sent to other windows again    
    ReleaseCapture_()
    
    ; and drag&drop (remove the image)
    ImageList_EndDrag_()
    
    ; free the image list
    ImageList_Destroy_(DragImageList)
    
    ; show cursor again
    ShowCursor_(#True)
    
    ; no draging in progress now.
    TreeIsDraging = #False
    
    
    ; next, we unhilight the last target item        
    If OldTreeItem
      HighLightTreeItem(GadgetID(DD_TreeGadget),OldTreeItem,0)
    EndIf
    
    GetWindowRect_(GadgetID(DD_TreeGadget),re.RECT) 
    GetCursorPos_(pt.POINT)  
    If PtInRect_(@re, pt\x | (pt\y<<32))
      ; now, move the items as demanded by the user:
      ;
      ; examine items at old positions
      ;
      nbitems = 0
      FIndex = -1
      ct = 0
      Repeat
        ct + 1
        LValue$ = StringField(DraggedItemsList$,ct,Chr(13))
        If LValue$ <> "Store_end"
          ItemIndex = Val(LValue$)
          If FIndex = -1 : FIndex = ItemIndex: EndIf
          ct + 2
          nbitems + 1
        EndIf
      Until LValue$ = "Store_end"
      ;
      ; add items at new position
      ;
      nPosition = GetTreeItemIndexFromHandle(OldTreeItem,GadgetID(DD_TreeGadget))+1
      If nPosition>FIndex And nPosition<(FIndex+nbitems+1)
        Debug "Trying to put a node inside its own content !!!!"
      Else
        mnPosition = nPosition
        nLevel = GetGadgetItemAttribute(DD_TreeGadget,nPosition-1,#PB_Tree_SubLevel)
        iconindex = GetTreeItemIconIndex(DD_TreeGadget,GadgetItemID(DD_TreeGadget,nPosition-1))
        If iconindex And iconindex<>-1 ; get the icon from the target item
          Debug "target is a folder"   ; if there is one, we suppose that the item is a folder (a potential node)
          nLevel + 1
        EndIf
        ct = 0
        Repeat
          ct + 1
          LValue$ = StringField(DraggedItemsList$,ct,Chr(13))
          If LValue$ <> "Store_end"
            ItemIndex = Val(LValue$)
            ct + 1
            ItemText$ = StringField(DraggedItemsList$,ct,Chr(13))
            ct + 1
            level = Val(StringField(DraggedItemsList$,ct,Chr(13)))
            If FIndex>= mnPosition
              ItemIndex + nPosition - mnPosition
            EndIf
            iconindex = GetTreeItemIconIndex(DD_TreeGadget,GadgetItemID(DD_TreeGadget,ItemIndex)); get the icon from the old item
            AddGadgetItem(DD_TreeGadget, nPosition, ItemText$,0,level+nLevel)
            SetTreeItemIconIndex(DD_TreeGadget,GadgetItemID(DD_TreeGadget,nPosition),iconindex); set the icon for the new item
            nPosition + 1
          EndIf
        Until LValue$ = "Store_end"
        
        If FIndex>= mnPosition ; position has to be adjusted if items to delete are after added items
          FIndex + nbitems
          nPosition = mnPosition
        Else
          nPosition = mnPosition-nbitems
        EndIf
        RemoveGadgetItem(DD_TreeGadget,FIndex)
  
        SetGadgetState(DD_TreeGadget,nPosition)
        SetActiveGadget(DD_TreeGadget)
      EndIf ; IsMouseOver(GadgetID(DD_TreeGadget))
    EndIf ; If Message = #WM_LBUTTONUP And TreeIsDraging
    
  EndIf ; check Message

  ProcedureReturn Result
EndProcedure
;
Global hFolderIcon
Procedure Enable_DragnDrop_On_TreeGadget(Window,TreeGadget)
  DD_TreeGadget = TreeGadget
  hWndTV = GadgetID(TreeGadget)
  Style = GetWindowLong_(hWndTV, #GWL_STYLE)
  Style = Style & (~#TVS_DISABLEDRAGDROP) 
  SetWindowLong_(hWndTV, #GWL_STYLE, Style) ; enable drag'n drop for the gadget
  ;
  hFolderIcon = GetFolderIconHandle() ; get a folder icon to use later in our list
  ;
  SendMessage_(hWndTV, #TVM_GETIMAGELIST,#TVSIL_NORMAL,imageList)
  If imageList = 0 ; The TreeGadget has no image list!! We need one, so we'll create one.
    AddGadgetItem(TreeGadget, -1, "ToDelete", hFolderIcon,0) ; PB will automatically create an image list if we add an item with an icon
    RemoveGadgetItem(TreeGadget, CountGadgetItems(TreeGadget)-1) ; OK, we can now delete this item
  EndIf
  ;
  SetWindowCallback(@DD_TreeCallback(),Window)
EndProcedure

; Window und Gadget...
winMain = OpenWindow(#PB_Any, 0, 0, 350, 260, "Drag'n Drop sorting with a TreeView", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

TreeGadget = TreeGadget(#PB_Any, 5, 5, 200, 250,#PB_Tree_AlwaysShowSelection)
Enable_DragnDrop_On_TreeGadget(winMain,TreeGadget)

ItemString = StringGadget(#PB_Any,220,5,120,20,"")

TextGadget = TextGadget(#PB_Any, 220, 50, 120, 250,"You can sort this treeview manually by draging items from one position to another one.")

PosVert = 160
BNewFolder = ButtonGadget(#PB_Any,220,PosVert,120,20,"New Folder")
PosVert + 25
BNewItem = ButtonGadget(#PB_Any,220,PosVert,120,20,"New Item")
PosVert + 25
BDelete = ButtonGadget(#PB_Any,220,PosVert,120,20,"Delete")
PosVert + 25
BSort = ButtonGadget(#PB_Any,220,PosVert,120,20,"Alphabetical Sort")

AddGadgetItem(TreeGadget, -1, "Item1"+Chr(13), 0,0)
AddGadgetItem(TreeGadget, -1, "Folder#1", hFolderIcon,0)
  AddGadgetItem(TreeGadget, -1, "Item11",0,1)
  AddGadgetItem(TreeGadget, -1, "Item12",0,1)
  AddGadgetItem(TreeGadget, -1, "Folder#12",hFolderIcon,1)
    AddGadgetItem(TreeGadget, -1, "Item121",0,2)
    AddGadgetItem(TreeGadget, -1, "Item122",0,2)
AddGadgetItem(TreeGadget, -1, "Folder#2", hFolderIcon,0)
  AddGadgetItem(TreeGadget, -1, "Itemz11",0,1)
  AddGadgetItem(TreeGadget, -1, "zItem1a",0,1)

For ct = 1 To 20
  AddGadgetItem(TreeGadget, -1, "Item"+Str(ct+1),0,0)
Next
SetGadgetState(TreeGadget,0)
SetGadgetText(ItemString,GetGadgetText(TreeGadget))
SendMessage_(GadgetID(ItemString), #EM_SETSEL, 0, Len(GetGadgetText(TreeGadget)))
SetActiveGadget(ItemString)


Repeat
  Event = WaitWindowEvent()
  If Event = #PB_Event_Gadget
    If EventGadget() = TreeGadget
      ItemText$ = GetGadgetItemText(TreeGadget,GetGadgetState(TreeGadget))
      SetGadgetText(ItemString,ItemText$)
      SendMessage_(GadgetID(ItemString), #EM_SETSEL, 0, Len(ItemText$))
    EndIf
    If EventGadget() = ItemString And EventType() = #PB_EventType_Change
      SetGadgetItemText(TreeGadget,GetGadgetState(TreeGadget),GetGadgetText(ItemString))
    ElseIf EventGadget() = BNewFolder Or EventGadget() = BNewItem
      IIndex = GetGadgetState(TreeGadget)+1
      If EventGadget() = BNewFolder 
        AddGadgetItem(TreeGadget,IIndex,"New folder",hFolderIcon)
      Else
        AddGadgetItem(TreeGadget,IIndex,"New item")
      EndIf
      SetGadgetState(TreeGadget,IIndex)
      ItemText$ = GetGadgetItemText(TreeGadget,IIndex)
      SetGadgetText(ItemString,ItemText$)
      SendMessage_(GadgetID(ItemString), #EM_SETSEL, 0, Len(ItemText$))
      SetActiveGadget(ItemString)
    ElseIf EventGadget() = BDelete
      IIndex = GetGadgetState(TreeGadget)
      RemoveGadgetItem(TreeGadget, IIndex)
      SetGadgetState(TreeGadget,IIndex)
      SetGadgetText(ItemString,ItemText$)
      SendMessage_(GadgetID(ItemString), #EM_SETSEL, 0, Len(ItemText$))
      SetActiveGadget(TreeGadget)
    ElseIf EventGadget() = BSort
      ; Windows API has a sort function for treeview (#TVM_SORTCHILDREN message)
      ; but we can't use it because the PureBasic element index is not sorted with the elements.
      ; So, we recreate a complete sort function for PB treegadget.
      lastitem = CountGadgetItems(TreeGadget)-1
      maxlevel = 0
      For clevel = 0 To maxlevel
        For i=0 To lastitem-1
          nlevel = GetGadgetItemAttribute(TreeGadget,i,#PB_Tree_SubLevel)
          If nlevel>maxlevel : maxlevel = nlevel : EndIf
          If nlevel = clevel
            min=i
            For j=i+1 To lastitem 
              If GetGadgetItemText(TreeGadget,j)<GetGadgetItemText(TreeGadget,min) And GetGadgetItemAttribute(TreeGadget,j,#PB_Tree_SubLevel)=clevel
                min=j 
              EndIf
              If GetGadgetItemAttribute(TreeGadget,j,#PB_Tree_SubLevel)<nlevel
                j = lastitem
              EndIf
            Next
            If min<>i
              For b = 1 To 2
                storeitems$ = ""
                If b = 1
                  posd = i
                Else
                  posd = min
                EndIf
                ; Store the node content
                ct = 1
                While GetGadgetItemAttribute(TreeGadget,posd+ct,#PB_Tree_SubLevel)>clevel
                  storeitems$ + GetGadgetItemText(TreeGadget,posd+ct)+Chr(13)+Str(GetGadgetItemAttribute(TreeGadget,posd+ct,#PB_Tree_SubLevel))+Chr(13)+Str(GetTreeItemIconIndex(TreeGadget,GadgetItemID(TreeGadget,posd+ct)))+Chr(13)
                  ct + 1
                  If b = 1 And min>i
                    min - 1
                  EndIf
                  If b = 2 And i>min
                    i - 1
                  EndIf
                Wend
                If b = 1
                  storeitems_i$ = storeitems$
                Else
                  storeitems_min$ = storeitems$
                EndIf
                ; Delete the node content
                While GetGadgetItemAttribute(TreeGadget,posd+1,#PB_Tree_SubLevel)>clevel
                  RemoveGadgetItem(TreeGadget,posd+1)
                Wend
              Next
              ; recreate the node content at the right place
              For b = 1 To 2
                If b = 1
                  posi = min
                  storeitems$ = storeitems_i$
                Else
                  posi = i
                  storeitems$ = storeitems_min$
                EndIf
                ct = 0
                Repeat
                  ct + 1
                  itemtext$ = StringField(storeitems$,ct,Chr(13))
                  If itemtext$
                    ct + 1
                    level = Val(StringField(storeitems$,ct,Chr(13)))
                    ct + 1
                    iconindex = Val(StringField(storeitems$,ct,Chr(13)))
                    posi + 1
                    AddGadgetItem(TreeGadget,posi,itemtext$,0,level)
                    SetTreeItemIconIndex(TreeGadget,GadgetItemID(TreeGadget,posi),iconindex)
                    If b = 1 And i>min
                      i + 1
                    EndIf
                    If b = 2 And min>i
                      min + 1
                    EndIf
                  EndIf
                Until itemtext$ = ""
              Next
              InvertTreeGadgetItems(TreeGadget,i,min)
            EndIf         
          EndIf
        Next 
      Next
      SetGadgetState(TreeGadget,0)
      SetGadgetText(ItemString,GetGadgetText(TreeGadget))
      SendMessage_(GadgetID(ItemString), #EM_SETSEL, 0, Len(GetGadgetText(TreeGadget)))
      SetActiveGadget(ItemString)
    EndIf
  EndIf
Until Event = #PB_Event_CloseWindow
End

; -------------------------------------------------------------------------
Tout obstacle est un point d'appui potentiel.

Bibliothèques PureBasic et autres codes à télécharger :https://www.editions-humanis.com/downlo ... ads_FR.htm
Avatar de l’utilisateur
ZapMan
Messages : 460
Inscription : ven. 13/févr./2004 23:14
Localisation : France
Contact :

Re: Tri manuel par Drag'n Drop pour TreeGadget

Message par ZapMan »

A noter que Freak propose une version crossplatform sur le forum anglais :
http://www.purebasic.fr/english/viewtop ... 14#p206014

Elle est un peu incomplète au niveau des fonctionnalités, mais reste très intéressante pour ceux qui programment sur Mac ou qui veulent rester sur un code ultra-simple.
Tout obstacle est un point d'appui potentiel.

Bibliothèques PureBasic et autres codes à télécharger :https://www.editions-humanis.com/downlo ... ads_FR.htm
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: Tri manuel par Drag'n Drop pour TreeGadget

Message par comtois »

Ton code fonctionne bien, je l'ai collé sur dvp
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Répondre