Treeview

TreeView control work-alike
code format="vbnet" 'tree view work-alike by tsh73 'august 2010

descr$="This is a tree view work-alike for Just BASIC." _   +chr$(13)+"It handles clicks and double clicks on items," _ +chr$(13)+"clicking on '-' or '+' will fold/unfold" _ +chr$(13)+"items, as expected." _   +chr$(13)+"" _ +chr$(13)+"Enjoy! (and feel free to use it)"

'get tree full size nTree = 30'9 'print nTree

'Dim arrays, generate tree data dim treeLevel(nTree), treeItems$(nTree), treeState(nTree), treeLine2Item(nTree) gosub [getTreeData]

'GUI nomainwin

WindowWidth = 600 WindowHeight = 525

UpperLeftX=int((DisplayWidth-WindowWidth)/2) UpperLeftY=int((DisplayHeight-WindowHeight)/2)

treeBoxHeight=300 treeBoxWidth=300 graphicbox #main.gr, 1, 25, treeBoxWidth, treeBoxHeight statictext #main.statictext2, "Tree View", 1, 1, 144, 20 texteditor #main.log, 305, 25, 280, 440 statictext #main.statictext4, "Log pane", 305, 1, 144, 20 statictext #main.statictext5, descr$, 6, 330, 288, 140

menu #main, "File", "Exit", [onFileExit] menu #main, "Edit"   '<--- Text-editor Menu can be moved but not removed.

open "TreeView demo" for window_nf as #main print #main.gr,"down; fill white; flush" print #main, "trapclose [quit.main]"

print #main, "font ms_sans_serif 10" print #main.gr, "font Courier_New 10" charWidth=8 charHeight=16 'let's make space enough to show unfolded tree if charHeight*nTree+charHeight/2-treeBoxHeight >0 then #main.gr "vertscrollbar on 0 ";charHeight*nTree+charHeight/2-treeBoxHeight end if   'initialise graphicbox (?needed? - for bigger number may be) print #main.gr, "place 0 0 " print #main.gr, "boxfilled "; treeBoxWidth;" ";treeBoxHeight

gosub [showFullTree] gosub [printFoldedTree] print #main.gr, "when leftButtonUp [click]" print #main.gr, "when leftButtonDouble [doubleClick]"

wait

[quit.main] Close #main END

[click] timer 120, [clickTimer] wait

[doubleClick] timer 0 gosub [getClickedItem] if clickedItem=0 then wait #main.log "Double clicked item "; treeItems$(clickedItem) wait

[clickTimer] timer 0 goto [ProcessClick] wait

[ProcessClick] gosub [getClickedItem] if clickedItem=0 then wait #main.log "Clicked item "; treeItems$(clickedItem) 'now, does it have children? if clickedItem = nTree then  'last one hasChildren = 0 else hasChildren = (treeLevel(clickedItem)<treeLevel(clickedItem+1)) end if   if hasChildren then 'let's sure we fold/ unfold only if we got to '+' or '-' 'space$(treeLevel(clickedItem)*2);pad$ if charPos = treeLevel(clickedItem)*2+2 then treeState(clickedItem)=1-treeState(clickedItem) #main.log "item "; treeItems$(clickedItem); " "; word$("unfolded folded", treeState(clickedItem)+1) gosub [printFoldedTree] end if   end if wait

[onFileExit] goto [quit.main] wait

[getClickedItem] clickedLine = int(MouseY/charHeight)+1 clickedItem = treeLine2Item(clickedLine) 'chick if we on text 'space$(treeLevel(clickedItem)*2);pad$ charPos = int((MouseX)/charWidth)+1 if charPos <= treeLevel(clickedItem)*2 + 1 _ or charPos > treeLevel(clickedItem)*2+3+len(treeItems$(clickedItem)) then clickedItem=0 return

[showFullTree] 'print tree with indents print "Full tree" print "" for i = 1 to nTree print i, space$(treeLevel(i)*2);treeItems$(i) next print "//--" return

[getTreeData] curLevel=1 for i = 1 to nTree treeLevel(i)=curLevel treeItems$(i)="item";i if rnd(1)<.5 then  'level change if rnd(1)<.5 then curLevel=curLevel+1 else if curLevel>1 then curLevel=curLevel-1 end if       end if    next 'now, let's fill treeState array 'lets say 0 means unfolded, 1 means folded 'so empty array means full tree opened 'random folding for i = 1 to nTree treeState(i) = rnd(1)>.7 'print i;" ";treeState(i), space$(treeLevel(i)*2);treeItems$(i) next

return

[printFoldedTree] print "Folded tree" print "//--" 'print with folding. 'If item is folded, it should have + (if it has children) 'and all childs should not be printed 'If unfolded, should have - (if it has children) 'has children == not last AND next level is one less #main.gr, "cls; place 0 0" #main.gr, "\" wait4sibling = 0 linesPrinted = 0 for i = 1 to nTree treeLine2Item(i)=0 '? has children ? if i = nTree then  'last one hasChildren = 0 else hasChildren = (treeLevel(i)<treeLevel(i+1)) end if       '? pad symbol - (+), (-) or space ? pad$="  " if hasChildren then if treeState(i) then pad$=" + " else pad$=" - " end if       shouldPrint = 1 if wait4sibling then   'do not print until sibling found (next item with wait4sibling level) shouldPrint = 0 if treeLevel(i)<= wait4sibling then wait4sibling = 0 shouldPrint = 1 end if       end if        if shouldPrint then print i, space$(treeLevel(i)*2);pad$;treeItems$(i) #main.gr, "\";space$(treeLevel(i)*2);pad$;treeItems$(i) linesPrinted = linesPrinted + 1 treeLine2Item(linesPrinted)=i 'folded if treeState(i) then wait4sibling = treeLevel(i) end if   next print #main.gr, "flush" return code