Tutorial 18: Der Treeview-Gadget - Teil 1
The MaxGUI Beginner Tutorial Series - Tutorial 18: Der Treeview-Gadget - Teil 1
(c) Assari Feb 21 2006
Ins Deutsche übersetzt von simi
Der Treeview-Gadget wird oft in allen Arten von Applikationen benutzt. In der MaxIDE wird er zum Beispiel für das Anzeigen der Funktionen und Debug-Informationen verwendet.
Ein Treeview braucht immer ein root (Wurzel) zum starten. Dann kannst du nodes (Äste) zu diesem root hinzufügen. Die nodes können mit weiteren nodes verbunden sein. So wie im Windows Explorer!
Zum dich in die Wunder des Treeview-Gadget einzuführen, werde ich den Dateiexplorer als roten Faden nehmen.
Function CreateTreeView:TGadget(x,y,w,h,group:TGadget,style=0) |
Ein sehr simpler Start mit diesem Gadget erfolgt so:
SuperStrict
|
Anders als andere CreateGadget-Funktionen, macht diese nicht gerade viel
|
Wir lesen jetzt die Dateien und Ordner aus dem BlitzMax Installationsverzeichnis aus, und fügen diese zu unserem TreeView via AddTreeViewNode hinzu.
SuperStrict
|
Der TreeView ist jetzt mit eineigen Items gefüllt. Noch nicht vergleichbar mit dem Explorer, aber wir können schon ein paar Ähnlichkeiten feststellen.
|
Lass uns ein bisschen erklären, wie das Einlesen der Dateien/Ordner funktioniert. Zuerst müssen wir ein Ordner mit ReadDir öffnen, um dessen Inhalt auszulesen. In diesem Fall ist das das Installationsverzeichnis von BlitzMax.
Local Folder:int=ReadDir(BlitzMaxPath()) |
NextFile erlaubt uns durch alle Dateien und Ordner zu gehen, bis wir eine null bekommen, was uns sagt, dass es keine weiteren Dateien mehr hat. Deshalb können wir stoppen.
Repeat File=NextFile(Folder) AddTreeViewNode(file,MyTreeView) Until File=Null |
Du wirst wahrscheinlich festgestellt haben, dass unser TreeView Items enthält, die wir nie im richtigen Explorer gesehen haben. Also müssen wir sie wie folgt ausfiltern:
Repeat File=NextFile(Folder) If File=".." Or File="." Or File=Null Then 'Do Nothing Else AddTreeViewNode(file,MyTreeView) EndIf Until File=Null |
Jetzt sieht's schon viel aufgeräumter aus.
|
Wenn wir uns die Syntax von AddTreeViewNode anschauen, sehen wir dass die Funktion einen icon-Parameter hat.
Function AddTreeViewNode:TGadget( text$,node:TGadget,icon=-1 ) |
Bei früheren Anwendungen mit Icons haben wir gelernt, dass wir zuerst einen Iconstrip laden, und ihn dann dem relevanten Gadget hinzufügen müssen.
** Lade diese PNG-Datei herunter, und speichere es im gleichen Verzeichniss wie das Programm unten.
|
SuperStrict Import MaxGui.Driver Local MyWindow:TGadget=CreateWindow("TreeView-Beispiel", 40,40,400,400) Global MyTreeView:TGadget=CreateTreeView(5,0,200,360,MyWindow) Local Folder:int=ReadDir(BlitzMaxPath()) Local File:String Local IconStrip:TIconStrip=LoadIconStrip("toolbar.png") SetGadgetIconStrip(MyTreeView, IconStrip) Repeat File=NextFile(Folder) If File=".." Or File="." Or File=Null Then 'Do Nothing Else AddTreeViewNode(file,MyTreeView) EndIf Until File=Null Repeat WaitEvent() Select EventID() Case EVENT_WINDOWCLOSE End End Select Forever End |
Beachte dass das erste Icon von unserer Grafikdatei nun das Standardicon ist, weil wir den Iconstrip unserem Gadget hinzugefügt haben.
|
Wir können jetzt versuchen den Explorer mehr zu kopieren, indem wir dies wie folgt machen:
SuperStrict Import MaxGui.Driver Local MyWindow:TGadget=CreateWindow("TreeView-Beispiel", 40,40,400,400) Global MyTreeView:TGadget=CreateTreeView(5,0,200,360,MyWindow) Local Folder:int=ReadDir(BlitzMaxPath()) Local File:String Local FullPath:String Local IconStrip:TIconStrip=LoadIconStrip("toolbar.png") SetGadgetIconStrip(MyTreeView, IconStrip) Repeat File=NextFile(Folder) If File=".." Or File="." Or File=Null Then 'Do Nothing Else fullPath = RealPath(BlitzMaxPath()+"/"+file) If FileType(FullPath)=FILETYPE_DIR Then AddTreeViewNode(file,MyTreeView,1) Else AddTreeViewNode(file,MyTreeView,0) EndIf EndIf Until File=Null Repeat WaitEvent() Select EventID() Case EVENT_WINDOWCLOSE End End Select Forever End |
Mit der FileType-Funktion können wir checken, ob die Datei ein Verzeichniss oder eine Datei ist. Wir setzten dann noch das richtige Icon neben dem Node, und et voilà, schon schauts ein bisschen mehr nach dem Explorer aus
|
Wir können unser obiges Programm ein bisschen abändern, indem wir einige Codestellen in eine Funktion packen. So sind wir bereit für den nächsten Schritt.
SuperStrict Import MaxGui.Driver Local MyWindow:TGadget=CreateWindow("TreeView-Beispiel", 40,40,400,400) Global MyTreeView:TGadget=CreateTreeView(5,0,200,360,MyWindow) Local IconStrip:TIconStrip=LoadIconStrip("toolbar.png") SetGadgetIconStrip(MyTreeView, IconStrip) EnumFiles(BlitzMaxPath(),MyTreeView) Repeat WaitEvent() Select EventID() Case EVENT_WINDOWCLOSE End End Select Forever End Function EnumFiles:Int(Dir:String, Parent:TGadget) Local Folder:int=ReadDir(Dir) Local File:String Local FullPath:String Repeat File=NextFile(Folder) If File=".." Or File="." Or File=Null Then 'Do Nothing Else fullPath = RealPath(BlitzMaxPath()+"/"+file) If FileType(FullPath)=FILETYPE_DIR Then AddTreeViewNode(file,MyTreeView,1) Else AddTreeViewNode(file,MyTreeView,0) EndIf EndIf Until File=Null End Function |
Wenn man das ausführt, gibt es genau das gleiche.
|
Lass uns jetzt ein bisschen Code hinzufügen (fetter text). Mit dieser Erweiterungen kann man, wenn man auf einen Ordner klickt, dessen Inhalt anschauen, so wie im Explorer.
SuperStrict Import MaxGui.Driver Local MyWindow:TGadget=CreateWindow("TreeView-Beispiel", 40,40,400,400) Global MyTreeView:TGadget=CreateTreeView(5,0,200,330,MyWindow) Local IconStrip:TIconStrip=LoadIconStrip("toolbar.png") SetGadgetIconStrip(MyTreeView, IconStrip) EnumFiles(BlitzMaxPath(),MyTreeView) Repeat WaitEvent() Select EventID() Case EVENT_WINDOWCLOSE End Case EVENT_GADGETACTION Local Node:TGadget = SelectedTreeViewNode(MyTreeView) Local s:String=String(Node.Context) If s>"" EnumFiles(s,node) node.context="" EndIf ExpandTreeViewNode(node) End Select Forever End Function EnumFiles:Int(Dir:String, Parent:TGadget) Local Folder:int=ReadDir(Dir) Local File:String Local FullPath:String Repeat File=NextFile(Folder) If File=".." Or File="." Or File=Null Then 'Do Nothing Else fullPath = RealPath(Dir+"/"+file) If FileType(FullPath)=FILETYPE_DIR Then Local handle:TGadget=AddTreeViewNode(file,Parent,1) handle.context=FullPath Else AddTreeViewNode(file,Parent,0) EndIf EndIf Until File=Null End Function |
Mit dem obigen Code können wir unseren BlitzMax-Ordner bis auf das Herzstück erforschen. Beachte dass die Srcollbar automatisch erscheint, wenn der Inhalt grösser als die Höhe oder Breite des Gadgets werden.
|
Nun lass uns sehen, wie wir es machen, dass wir dies erreichen.
Function EnumFiles:Int(Dir:String, Parent:TGadget) Local Folder:int=ReadDir(Dir) Local File:String Local FullPath:String Repeat File=NextFile(Folder) If File=".." Or File="." Or File=Null Then 'Do Nothing Else fullPath = RealPath(Dir+"/"+file) If FileType(FullPath)=FILETYPE_DIR Then Local handle:TGadget=AddTreeViewNode(file,Parent,1) handle.context=FullPath Else AddTreeViewNode(file,Parent,0) EndIf EndIf Until File=Null End Function |
AddTreeViewNode gibt ein TGadget-Type zurück, den wir handle nennen. TGadget hat ein Field, das context heisst. Es kann benutzt werden, um den vollständigen Pfad von unserem Verzeichnis für später "aufzubewahren".
Case EVENT_GADGETACTION Local Node:TGadget = SelectedTreeViewNode(MyTreeView) Local s:String=String(Node.Context) If s>"" EnumFiles(s,node) node.context="" EndIf ExpandTreeViewNode(node) |
Wenn wir auf einen Item doppelklicken, wir ein EVENT_GADGETACTION ausgelöst. Wir können den ausgewählten Node mittels SelectedTreeViewNode herausfinden und dann das context-Field überprüfen. Beachte dass dieses den Type Object hat. Wir müssen den Inhalt also zuerst zu einem String casten, bevor wir es als eine String-Variable benutzen können.
Da wir uns den Pfad gespeichert haben, können wir jetzt die nächste Stufe mittels EnumFiles "erforschen". Wir setzten dann das context-Field auf null um zu zeigen, dass wir diesen Node bereits erforscht haben.
Die ExpandTreeViewNode-Funktion wird dann benutzt, um die entsprechende Node auszuklappen.
Zum Schluss...
Es gibt noch mehr TreeView-Funktionen, die wir im nächsten Tutorial behandeln werden. In diesem Tutorial lernten wir, wie wir
- mit der CreateTreeView-Funktion ein TreeView erstellen können
- Items (Nodes) mit AddTreeViewNode hinzufügen können
- unser TreeView mit Icons verschönern können, indem wir den icon-Parameter von AddTreeViewNode benutzen
- eine Node mittels ExpandTreeVewNode ausklappen können (die entgegengesetzte Version ist CollapseTreeViewNode)
- EVENT_GADGETACTION nutzen können, um Mausklicks auf eine Item festzustellen. SelectedTreeViewNode gibt uns dann die Node zurück, auf die der Benutzer geklickt hat.
Wie du an den obigen Beispielen sehen kannst, erlaubt uns dies bereits einen rudimentären Explorer zu erstellen.