Page 1 of 2

[Solved] TreeGadget population help

Posted: Sat Jun 17, 2023 10:04 am
by BarryG
[Edit] Solved! See here -> viewtopic.php?p=602949#p602949

I'm having a major mental block at the moment and can't figure this basic thing out. All I want to do, is populate a TreeGadget with a recursive folder listing, as shown below. Left is the folder structure, and right is what I want to achieve. It should work with multiple sub-folders, too. I don't know what the heck I'm doing wrong but I can't do it. And yes, it has to be a TreeGadget only (not any other gadget type). Can someone please post some bleeding obvious code for me? Thanks.

Note: I've already got the recursed file list saved in an array; I just can't seem to make each new parent folder (and its sub-folders) be a new "node" with indented kids, especially with folder 3 and it's sub-folders.

Image

Code: Select all

Dim f$(9)
f$(1)="Folder 1\File 11"
f$(2)="Folder 1\File 12"
f$(3)="Folder 1\File 13"
f$(4)="Folder 2\File 21"
f$(5)="Folder 2\File 22"
f$(6)="Folder 2\File 23"
f$(7)="Folder 3\Sub-folder 3\File 331"
f$(8)="Folder 3\Sub-folder 3\File 332"
f$(9)="Folder 3\Sub-folder 3\File 333"

If OpenWindow(0, 0, 0, 355, 200, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TreeGadget(0, 10, 10, 340, 180)   ; TreeGadget standard
  For i=1 To 9
    f$=f$(i)
    s=FindString(f$,"\")
    dir$=Left(f$,s-1)
    If dir$<>""
      f$=Mid(f$,Len(dir$)+2)
      If dir$<>old$
        old$=dir$
        AddGadgetItem(0,-1,dir$,0,0)
        AddGadgetItem(0,-1,f$,0,1)
      Else
        AddGadgetItem(0,-1,f$,0,1)
      EndIf
    EndIf
  Next
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Re: TreeGadget population help

Posted: Sat Jun 17, 2023 10:36 am
by spikey
When you call AddGadgetItem you need to specify a sub-level indentation as the 'Flag' parameter. 0 is top level, 1 is the first sub-level, 2 the next and so on. This may mean supplying zero or null as an image id if you aren't using images.

Code: Select all

If OpenWindow(0, 0, 0, 355, 200, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TreeGadget(0, 10, 10, 340, 180)   ; TreeGadget standard
  AddGadgetItem (0, 0, "Folder 1", 0, 0) ; last zero denotes no offset.
  AddGadgetItem (0, 1, "File 1", 0, 1) ; last 1 denotes first sub-level       
  AddGadgetItem (0, 2, "File 2", 0, 1)        
  AddGadgetItem (0, 3, "File 3", 0, 1)        
  AddGadgetItem(0, 4, "Folder 2", 0, 0)  ; last zero denotes back to no offset.
  AddGadgetItem (0, 5, "File 1", 0, 1)        
  AddGadgetItem (0, 6, "File 2", 0, 1)        
  AddGadgetItem (0, 7, "File 3", 0, 1)        
  AddGadgetItem (0, 8, "Folder 3", 0, 0) ; sublevel 0 again
  AddGadgetItem (0, 9, "Folder 4", 0, 1) ; sublevel 1 again - child folder in a root folder
  AddGadgetItem (0, 10, "File 1", 0, 2) ; sublevel 2 - files in Folder 4        
  AddGadgetItem (0, 11, "File 2", 0, 2)        
  AddGadgetItem (0, 12, "File 3", 0, 2)        
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Re: TreeGadget population help

Posted: Sat Jun 17, 2023 10:49 am
by BarryG
Thanks... first post edited to show my next problem... sub-folder 3 doesn't get a new node?

Re: TreeGadget population help

Posted: Sat Jun 17, 2023 11:28 am
by Olli

Code: Select all

Dim f$(9)
f$(1)="Folder 1\File 11"
f$(2)="Folder 1\File 12"
f$(3)="Folder 1\File 13"
f$(4)="Folder 2\File 21"
f$(5)="Folder 2\File 22"
f$(6)="Folder 2\File 23"
f$(7)="Folder 3\Sub-folder 3\File 331"
f$(8)="Folder 3\Sub-folder 3\File 332"
f$(9)="Folder 3\Sub-folder 3\File 333"

If OpenWindow(0, 0, 0, 355, 200, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TreeGadget(0, 10, 10, 340, 180)   ; TreeGadget standard
  For i=1 To 9
    f$=f$(i)
    f$ = reversestring(f$) ; <<<<<<<<< inserted 1/7
    s=len(f$)‐FindString(f$,"\")+1 ; <<<<<<< modified 2/7
    f$ = reversestring(f$) ; <<<<<<<<< inserted 3/7
    depth = countstring(f$,"\")-1 ;<<<<<<<<< inserted 4/7
    dir$=Left(f$,s-1)
    If dir$<>""
      f$=Mid(f$,Len(dir$)+2)
      If dir$<>old$
        old$=dir$
        AddGadgetItem(0,-1,dir$,0,depth) ; modified 5/7
        AddGadgetItem(0,-1,f$,0,depth+1) ; modified 6/7
      Else
        AddGadgetItem(0,-1,f$,0,depth+1) ; modified 7/7
      EndIf
    EndIf
  Next
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Re: TreeGadget population help

Posted: Sat Jun 17, 2023 11:31 am
by BarryG
Thanks for jumping in, Olli, but Folder 3 isn't a sub-folder of folder 2. It's a root folder.

Re: TreeGadget population help

Posted: Sat Jun 17, 2023 11:34 am
by Olli
fixed...

Re: TreeGadget population help

Posted: Sat Jun 17, 2023 11:37 am
by BarryG
Sorry... but not fixed. It's not easy to do. Bear in mind there could be many sub-folders under each root one.

Image

Re: TreeGadget population help

Posted: Sat Jun 17, 2023 11:39 am
by Olli
uh... you force me to switch a computer on... Some spiders to remove... please wait...

Re: TreeGadget population help

Posted: Sat Jun 17, 2023 11:49 am
by Olli
the computer doesn't start... I add this try...

Code: Select all

Dim f$(9)
f$(1)="Folder 1\File 11"
f$(2)="Folder 1\File 12"
f$(3)="Folder 1\File 13"
f$(4)="Folder 2\File 21"
f$(5)="Folder 2\File 22"
f$(6)="Folder 2\File 23"
f$(7)="Folder 3\Sub-folder 3\File 331"
f$(8)="Folder 3\Sub-folder 3\File 332"
f$(9)="Folder 3\Sub-folder 3\File 333"

If OpenWindow(0, 0, 0, 355, 200, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TreeGadget(0, 10, 10, 340, 180)   ; TreeGadget standard
  For i=1 To 9
    f$=f$(i)
    f$ = reversestring(f$) ; <<<<<<<<< inserted 1/7
    s=len(f$)‐FindString(f$,"\")+1 ; <<<<<<< modified 2/7
    f$ = reversestring(f$) ; <<<<<<<<< inserted 3/7
    depth = countstring(f$,"\")-1 ;<<<<<<<<< inserted 4/7
    dir$=Left(f$,s-1)
    sf$=right(f$,len(dir$)-s) ; <<<<<<<< inserted 8/8
    If dir$<>""
      f$=Mid(f$,Len(dir$)+2)
      If dir$<>old$
        old$=dir$
        AddGadgetItem(0,-1,dir$,0,depth) ; modified 5/7
        ;;;;AddGadgetItem(0,-1,sf$,0,depth+1) ; modified 6/8
        endif ; added x/11
      ;;;Else ; removed x/11
        AddGadgetItem(0,-1,sf$,0,depth+1) ; modified 7/8
      ;;;;EndIf ; removed x/11
    EndIf
  Next
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Re: TreeGadget population help

Posted: Sat Jun 17, 2023 11:54 am
by BarryG
Nope. Appreciate the attempts, though. You can see why I asked for help, lol.

Image

Re: TreeGadget population help

Posted: Sat Jun 17, 2023 11:54 am
by Olli
Last chance. Then we tear down your code. He suffers too much...

Re: TreeGadget population help

Posted: Sat Jun 17, 2023 12:07 pm
by Olli
I will post a code after several hours of job. I already did this type of algo successfully.

Re: TreeGadget population help

Posted: Sat Jun 17, 2023 12:07 pm
by BarryG
Thanks. Maybe someone else will beat you to it.

Re: TreeGadget population help

Posted: Sat Jun 17, 2023 12:08 pm
by Axolotl
please, try this....

Code: Select all

Global Dim f$(9)
f$(1)="Folder 1\File 11"
f$(2)="Folder 1\File 12"
f$(3)="Folder 1\File 13"
f$(4)="Folder 2\File 21"
f$(5)="Folder 2\File 22"
f$(6)="Folder 2\File 23"
f$(7)="Folder 3\Sub-folder 3\File 331"
f$(8)="Folder 3\Sub-folder 3\File 332"
f$(9)="Folder 3\Sub-folder 3\File 333"

Procedure main() 
  Protected fn.s, currdir.s, idx, cnt, level  
  Dim lastdir.s(10)  

  If OpenWindow(0, 0, 0, 355, 200, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    TreeGadget(0, 10, 10, 340, 180)   ; TreeGadget standard
    For idx = 1 To 9  ; arraysize 
      fn = f$(idx) 

      cnt = CountString(fn, #PS$) 
      For level = 0 To cnt - 1
        currdir = StringField(fn, level+1, #PS$) 
        If lastdir(level) <> currdir 
          lastdir(level) = currdir 
          AddGadgetItem(0, -1, currdir, 0, level) 
        EndIf 
      Next level 

      fn = StringField(fn, level+1, #PS$) 
      AddGadgetItem(0, -1, fn, 0, level)
    Next
    Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
  EndIf
  ProcedureReturn 0 
EndProcedure 

End main() 

Re: TreeGadget population help

Posted: Sat Jun 17, 2023 12:32 pm
by mk-soft
Was a Think Task

Update with item data for selection

Code: Select all

Dim f$(10)
f$(0)="File 01"
f$(1)="Folder 1\File 11"
f$(2)="Folder 1\File 12"
f$(3)="Folder 1\File 13"
f$(4)="Folder 2\File 21"
f$(5)="Folder 2\File 22"
f$(6)="Folder 2\File 23"
f$(7)="Folder 3\Sub-folder 3\File 331"
f$(8)="Folder 3\Sub-folder 3\File 332"
f$(9)="Folder 3\Sub-folder 3\File 333"
f$(10)="Folder 4\File 41"

Structure udtTreeFiles
  Path.s
  File.s
  Index.i
EndStructure

Procedure FillTreeFiles(Gadget, Array Files.s(1))
  Protected size, path.s, oldpath.s, count, level, temp.s, pos
  
  size = ArraySize(Files())
  Dim FileData.udtTreeFiles(size)
  For i = 0 To size
    FileData(i)\Path = GetPathPart(Files(i))
    FileData(i)\File = GetFilePart(Files(i))
    FileData(i)\Index = i
  Next
  ;SortStructuredArray(FileData(), #PB_Sort_Ascending | #PB_Sort_NoCase, OffsetOf(udtTreeFiles\Path), #PB_String)
  
  For i = 0 To ArraySize(FileData())
    path = FileData(i)\Path
    If path <> oldpath
      oldpath = path
      level = 0
      count = CountString(path, #PS$)
      For level = 1 To count
        temp = StringField(path, level, #PS$)
        AddGadgetItem(Gadget, pos, temp, 0, level - 1)
        SetGadgetItemData(Gadget, pos, -1)
        pos + 1
      Next
      level - 1
    EndIf
    temp = FileData(i)\File
    If temp
      AddGadgetItem(Gadget, pos, temp, 0, level)
      SetGadgetItemData(Gadget, pos, FileData(i)\Index)
      pos + 1
    EndIf
  Next
EndProcedure
      
If OpenWindow(0, 0, 0, 355, 200, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TreeGadget(0, 10, 10, 340, 180)   ; TreeGadget standard
  
  ; Fit OS
  For i = 0 To ArraySize(f$())
    ReplaceString(f$(i), #NPS$, #PS$, #PB_String_InPlace)
  Next
  FillTreeFiles(0, f$())
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Break
        
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 0
            Select EventType()
              Case #PB_EventType_Change
                node = GetGadgetState(0)
                If node >= 0
                  index = GetGadgetItemData(0, node)
                  If index >= 0
                    Debug f$(index)
                  EndIf
                EndIf
            EndSelect
        EndSelect
        
    EndSelect
  ForEver
EndIf