Einzelnen Beitrag anzeigen

Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: GLScene.Objects in TTreeview

  Alt 27. Dez 2005, 21:29
Hi,
Was genau möchtest du denn anzeigen lassen? Den Namen der jeweiligen Komponente?

Also jetzt etwas abstrakt gibt es zwei Möglichkeiten. Der unschönere aber leichter zu programmierende wäre es das ganze einfach rekursiv zu machen. Du übergibst immer den aktuellen Vaterknoten in deiner Listview und das aktuelle GLObject. Dann trägst du dort das Kind ein und der dort entstandene Knoten durchläuft rekursiv die gleiche Methode.
Sehr grob modelliert (muss hier nicht richtig sein!)
Delphi-Quellcode:
var Tree : TTreeView;

procedure toTree(ParentNode : TTreeNode; Obj : TGLBaseSceneObject);
var buffer : TTreeNode;
    i : Integer;
begin
  if assigned(Obj) then
    begin
      buffer := Tree.AddChild(ParentNode, Obj.Name);
      if Obj.Count > 0 then
        begin
          for i := 0 to Obj.Count - 1 do
            begin
              toTree(buffer, Obj.Children[i]);
            end; // for i := 0 to Obj.Count - 1
        end; // if Obj.Count > 0
    end; // if assigned(Obj)
end;

// Aufruf:
procedure SceneToTree;
var i : Integer;
begin
  if GLScene.Objects.Count > 0 then
    begin
      for i := 0 to GLScene.Objects.Count - 1 do
        begin
          toTree(nil, GLScene.Objects.Children[i]);
        end; // for i := 0 to GLScene.Objects.Count - 1
    end; // if GLScene.Objects.Count > 0
end;
Ja, wie gesagt nicht gerade ein schöner Weg, dein Stack wird sich wenig dankbar zeigen.
Versuch es lieber iterativ. Mir würde hier natürlich sofort Breitensuche einfallen. Du verwaltest einfach eine Liste, mit Elementen die du noch betrachten willst (kannst du natürlich auch mittels Tiefensuche realisieren).
Also du hast eine Liste und packst dort immer alle Elemente der ersten Ebene rein. Diese betrachtest du nacheinander. Findest du in einem dieser Elemente Kinder, hängst du die einfach hintern ran (und merkst dir den Vater). Dann arbeitest du so einfach nur die Liste ab.

Delphi-Quellcode:
type
  TElement = class(TObject)
    Node : TTreeNode;
    Obj : TGLBaseSceneObject;
    constructor create(Node : TTreeNode; Obj : TGLBaseSceneObject);
  end;

constructor TElement.create(Node : TTreeNode; Obj : TGLBaseSceneObject);
begin
  self.Node := Node;
  self.Obj := Obj;
end;

procedure TForm1.toTree;
var i : Integer;
    List : TObjectList;
    element : TElement;
    buffer : TTreeNode;
begin
  List := TObjectList.Create;
  if GLScene.Objects.Count > 0 then
    begin
      for i := 0 to GLScene.Objects.Count - 1 do
        begin
          List.Add(TElement.Create(nil, GLScene.Objects.Children[i]));
        end; // for i := 0 to GLScene.Objects.Count - 1
    end; // if GLScene.Objects.Count > 0

  while List.Count > 0 do
    begin
      element := TElement(List.Extract(List.First));
      buffer := TreeView.Items.AddChild(element.Node, element.Obj.Name);
      if element.Obj.Count > 0 then
        begin
          for i := 0 to element.Obj.Count - 1 do
            begin
              List.Add(TElement.Create(buffer, element.Obj.Children[i]));
            end; // for i := 0 to element.Obj.Count - 1
        end; // if element.Obj.Count > 0
      element.Free;
    end; // while List.Count > 0
end;
Sorry, ist sicher kein sauberer Code (gerade Kommentare fehlen) und es gibt sicher auch schönere Lösungen, aber vielleicht dient es dir ja schon als Basis.

Gruß Der Unwissende
  Mit Zitat antworten Zitat