unit AdvNodesEditor;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Spin, StdCtrls, ComCtrls, AdvTreeNodes, ExtCtrls, ImgList;

type
  TAdvNodesEditor = class(TForm)
    GroupBox1: TGroupBox;
    Treeview1: TTreeView;
    Btn_NewItem: TButton;
    Btn_NewSubItem: TButton;
    Btn_Delete: TButton;
    GroupBox2: TGroupBox;
    Label1: TLabel;
    Ed_Text: TEdit;
    Btn_Ok: TButton;
    Btn_Cancel: TButton;
    Ed_URL: TEdit;
    Label3: TLabel;
    Ed_ImageURL: TEdit;
    Label4: TLabel;
    Sp_Tag: TSpinEdit;
    Label5: TLabel;
    Cb_NodeType: TComboBox;
    Ckb_Checked: TCheckBox;
    Label6: TLabel;
    Ckb_Expanded: TCheckBox;
    Label7: TLabel;
    Ed_Hint: TEdit;
    Label2: TLabel;
    Ed_ImageCollapsedURL: TEdit;
    procedure Btn_OkClick(Sender: TObject);
    procedure Btn_NewItemClick(Sender: TObject);
    procedure Ed_TextChange(Sender: TObject);
    procedure Sp_ImageIndexChange(Sender: TObject);
    procedure Btn_NewSubItemClick(Sender: TObject);
    procedure Btn_DeleteClick(Sender: TObject);
    procedure Treeview1Change(Sender: TObject; Node: TTreeNode);
    procedure FormCreate(Sender: TObject);
    procedure Ed_URLChange(Sender: TObject);
    procedure Ed_ImageURLChange(Sender: TObject);
    procedure Cb_NodeTypeChange(Sender: TObject);
    procedure Ckb_CheckedClick(Sender: TObject);
    procedure Sp_TagChange(Sender: TObject);
    procedure Ckb_ExpandedClick(Sender: TObject);
    procedure Ed_ImageCollapsedURLChange(Sender: TObject);
    procedure Ed_HintChange(Sender: TObject);
  private
    FAdvTreeNodes: TAdvTreeNodes;
    FInternalChange: Boolean;
    FImages: TCustomImageList;
    procedure SetAdvTreeNodes(Value: TAdvTreeNodes);
    procedure UpdateImage;
    procedure SetImages(const Value: TCustomImageList);
    { Private declarations }
  protected
    //Add AdvNode to TreeviewNode
    procedure AddNodeChildren(var AdvNode: TAdvTreeNode; var Node: TTreeNode);
    procedure CopyItemsFromTvToAdvNodes;
    procedure AddAdvNodeChildren(var Node: TTreeNode; var AdvNode: TAdvTreeNode);
    procedure UpdateButtons;
    procedure InitializeNodeInfo(NodeInfo: PNodeInfo);
  public
    { Public declarations }
    property AdvTreeNodes: TAdvTreeNodes read FAdvTreeNodes write SetAdvTreeNodes;
    property Images: TCustomImageList read FImages write SetImages;
  end;

var
  NodesEditor: TAdvNodesEditor;

implementation

{$R *.dfm}

{ TNodesEditor }

//------------------------------------------------------------------------------
// Add AdvNode to TreeviewNode

procedure TAdvNodesEditor.AddNodeChildren(var AdvNode: TAdvTreeNode; var Node: TTreeNode);
var
  ExN: TAdvTreeNode;
  N: TTreeNode;
  NodeInfo: PNodeInfo;
begin
  if not Assigned(AdvNode) or not Assigned(Node) then
    Exit;

  ExN := AdvNode.getFirstChild;
  if Assigned(ExN) then
  begin
    while (ExN <> nil) do
    begin
      New(NodeInfo);
      InitializeNodeInfo(NodeInfo);
      N := Treeview1.Items.AddChildObject(Node, ExN.Text, NodeInfo);
//      N.ImageIndex := ExN.ImageIndex;
      NodeInfo^.NodeType := ExN.NodeType;
      NodeInfo^.Checked := ExN.Checked;
      NodeInfo^.URL := ShortString(ExN.URL);
      NodeInfo^.ImageURL := ShortString(ExN.ImageURL);
      NodeInfo^.ImageCollapsedURL := ShortString(ExN.ImageCollapsedURL);
      NodeInfo^.Hint := ShortString(ExN.Hint);
      NodeInfo^.IsExpanded := ExN.IsExpanded;
      NodeInfo^.Tag := ExN.Tag;
      N.Data := NodeInfo;

      AddNodeChildren(ExN, N);
      ExN := ExN.getNextSibling;
    end;
  end;
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.SetAdvTreeNodes(Value: TAdvTreeNodes);
var
   AdvNode: TAdvTreeNode;
   Node: TTreeNode;
   NodeInfo: PNodeInfo;
begin
  FAdvTreeNodes := Value;
  if Assigned(AdvTreeNodes) then
  begin
    Treeview1.Items.Clear;
    AdvNode := AdvTreeNodes.GetFirstNode;
    if Assigned(AdvNode) then
    begin
      while (AdvNode <> nil) do
      begin
        Node := Treeview1.Items.AddChildObject(nil, AdvNode.Text, AdvNode);
//        Node.ImageIndex := AdvNode.ImageIndex;
        New(NodeInfo);
        InitializeNodeInfo(NodeInfo);
        NodeInfo^.NodeType := AdvNode.NodeType;
        NodeInfo^.Checked := AdvNode.Checked;
        NodeInfo^.URL := ShortString(AdvNode.URL);
        NodeInfo^.ImageURL := ShortString(AdvNode.ImageURL);
        NodeInfo^.ImageCollapsedURL := ShortString(AdvNode.ImageCollapsedURL);
        NodeInfo^.Hint := ShortString(AdvNode.Hint);
        NodeInfo^.IsExpanded := AdvNode.IsExpanded;
        NodeInfo^.Tag := AdvNode.Tag;
        Node.Data := NodeInfo;

        AddNodeChildren(AdvNode, Node);
        AdvNode := AdvNode.getNextSibling;
      end;
    end;
  end;
  Treeview1.Selected := Treeview1.Items.GetFirstNode;
  UpdateButtons;
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.SetImages(const Value: TCustomImageList);
begin
  FImages := Value;
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.Btn_OkClick(Sender: TObject);
begin
// OK button
  CopyItemsFromTvToAdvNodes;
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.Cb_NodeTypeChange(Sender: TObject);
begin
  if Assigned(Treeview1.Selected) then
  begin
    PNodeInfo(Treeview1.Selected.Data)^.NodeType := TNodeType(Cb_NodeType.ItemIndex);
  end;
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.Ckb_CheckedClick(Sender: TObject);
begin
  if Assigned(Treeview1.Selected) then
  begin
    PNodeInfo(Treeview1.Selected.Data)^.Checked := Ckb_Checked.Checked;
  end;
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.Ckb_ExpandedClick(Sender: TObject);
begin
  if Assigned(Treeview1.Selected) then
  begin
    PNodeInfo(Treeview1.Selected.Data)^.IsExpanded := Ckb_Expanded.Checked;
  end;
end;

procedure TAdvNodesEditor.InitializeNodeInfo(NodeInfo: PNodeInfo);
begin
  NodeInfo^.SelectedIndex := -1;
  NodeInfo^.StateIndex := -1;
  NodeInfo^.SelectedIndex := -1;
  NodeInfo^.Data := nil;
  NodeInfo^.Count := 0;
  NodeInfo^.Text := '';
  NodeInfo^.NodeType := ntText;
  NodeInfo^.Checked := False;
  NodeInfo^.ImageURL := '';
  NodeInfo^.ImageCollapsedURL := '';
  NodeInfo^.URL := '';
  NodeInfo^.Tag := 0;
  NodeInfo^.Hint := '';
  NodeInfo^.IsExpanded := True;
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.CopyItemsFromTvToAdvNodes;
var
   AdvNode: TAdvTreeNode;
   Node: TTreeNode;
   NodeInfo: PNodeInfo;
begin
  if Assigned(AdvTreeNodes) then
  begin
    AdvTreeNodes.Clear;
    Node := Treeview1.Items.GetFirstNode;
    while (Node <> nil) do
    begin
      AdvNode := AdvTreeNodes.Add(Node.Text);
//      AdvNode.ImageIndex := Node.ImageIndex;
      NodeInfo := PNodeInfo(Node.Data);
      AdvNode.NodeType := NodeInfo^.NodeType;
      AdvNode.Checked := NodeInfo^.Checked;
      AdvNode.URL := String(NodeInfo^.URL);
      AdvNode.ImageURL := String(NodeInfo^.ImageURL);
      AdvNode.ImageCollapsedURL := String(NodeInfo^.ImageCollapsedURL);
      AdvNode.Hint := String(NodeInfo^.Hint);
      AdvNode.IsExpanded := NodeInfo^.IsExpanded;
      AdvNode.Tag := NodeInfo^.Tag;

      AddAdvNodeChildren(Node, AdvNode);
      Node := Node.getNextSibling;
    end;
  end;
end;

//------------------------------------------------------------------------------

// Add TreeviewNode to AdvTreeNode
procedure TAdvNodesEditor.AddAdvNodeChildren(var Node: TTreeNode; var AdvNode: TAdvTreeNode);
var
  AdvN: TAdvTreeNode;
  N: TTreeNode;
  NodeInfo: PNodeInfo;
begin
  if not Assigned(AdvNode) or not Assigned(Node) then
    Exit;

  N := Node.getFirstChild;
  if Assigned(N) then
  begin
    while (N <> nil) do
    begin
      AdvN := AdvNode.AddChild(N.Text);
//      AdvN.ImageIndex := N.ImageIndex;
      NodeInfo := PNodeInfo(N.Data);
      AdvN.NodeType := NodeInfo^.NodeType;
      AdvN.Checked := NodeInfo^.Checked;
      AdvN.URL := String(NodeInfo^.URL);
      AdvN.ImageURL := String(NodeInfo^.ImageURL);
      AdvN.ImageCollapsedURL := String(NodeInfo^.ImageCollapsedURL);
      AdvN.Hint := String(NodeInfo^.Hint);
      AdvN.IsExpanded := NodeInfo^.IsExpanded;
      AdvN.Tag := NodeInfo^.Tag;

      AddAdvNodeChildren(N, AdvN);
      N := N.getNextSibling;
    end;
  end;
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.Btn_NewItemClick(Sender: TObject);
var
  NodeInfo: PNodeInfo;
begin
  New(NodeInfo);
  InitializeNodeInfo(NodeInfo);
  if Assigned(Treeview1.Selected) then
    Treeview1.Selected := Treeview1.Items.AddChildObject(Treeview1.Selected.Parent, '', NodeInfo)
  else
    Treeview1.Selected := Treeview1.Items.AddChildObjectFirst(nil, '', NodeInfo);
  Treeview1.Selected.ImageIndex := -1;
//  Sp_ImageIndex.Value := Treeview1.Selected.ImageIndex;
//  UpdateImage;
  Ed_Text.SetFocus;
  UpdateButtons;
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.Ed_HintChange(Sender: TObject);
begin
  if Assigned(Treeview1.Selected) then
  begin
    PNodeInfo(Treeview1.Selected.Data)^.Hint := ShortString(Ed_Hint.Text);
  end;
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.Ed_ImageCollapsedURLChange(Sender: TObject);
begin
  if Assigned(Treeview1.Selected) then
  begin
    PNodeInfo(Treeview1.Selected.Data)^.ImageCollapsedURL :=
      ShortString(Ed_ImageCollapsedURL.Text);
  end;
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.Ed_ImageURLChange(Sender: TObject);
begin
  if Assigned(Treeview1.Selected) then
  begin
    PNodeInfo(Treeview1.Selected.Data)^.ImageURL := ShortString(Ed_ImageURL.Text);
  end;
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.Ed_TextChange(Sender: TObject);
begin
  if Assigned(Treeview1.Selected) then
    Treeview1.Selected.Text := Ed_Text.Text;
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.Ed_URLChange(Sender: TObject);
begin
  if Assigned(Treeview1.Selected) then
  begin
    PNodeInfo(Treeview1.Selected.Data)^.URL := ShortString(Ed_URL.Text);
  end;
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.FormCreate(Sender: TObject);
begin

end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.UpdateImage;
begin
  {
  if Assigned(Treeview1.Selected) and not FInternalChange then
  begin
    Image1.Picture.Bitmap.Canvas.Brush.Color := Self.Color;
    Image1.Picture.Bitmap.Canvas.Pen.Color := Self.Color;
    Image1.Picture.Bitmap.Canvas.FillRect(Image1.ClientRect);
    if Assigned(AdvTreeNodes) and Assigned(Images) and (Treeview1.Selected.ImageIndex >= 0) then
    begin
      Images.GetBitmap(Treeview1.Selected.ImageIndex, Image1.Picture.Bitmap);
      Image1.Picture.Bitmap.Transparent := True;
      Image1.Invalidate;
    end;
  end;
  }
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.Sp_ImageIndexChange(Sender: TObject);
begin
{
  if Assigned(Treeview1.Selected) and not FInternalChange then
  begin
    Treeview1.Selected.ImageIndex := Sp_ImageIndex.Value;
    UpdateImage;
  end;
  }
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.Sp_TagChange(Sender: TObject);
begin
  if Assigned(Treeview1.Selected) then
  begin
    PNodeInfo(Treeview1.Selected.Data)^.Tag := Sp_Tag.Value;
  end;
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.Btn_NewSubItemClick(Sender: TObject);
var
  NodeInfo: PNodeInfo;
begin
  New(NodeInfo);
  InitializeNodeInfo(NodeInfo);
  if Assigned(Treeview1.Selected) then
    Treeview1.Selected := Treeview1.Items.AddChildObject(Treeview1.Selected, '', NodeInfo);
  Ed_Text.SetFocus;  
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.Btn_DeleteClick(Sender: TObject);
begin
  if Assigned(Treeview1.Selected) then
    Treeview1.Items.Delete(Treeview1.Selected);
  UpdateButtons;
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.UpdateButtons;
begin
  Btn_NewSubItem.Enabled := Assigned(Treeview1) and Assigned(Treeview1.Selected);
  Btn_Delete.Enabled := Assigned(Treeview1) and Assigned(Treeview1.Selected);
end;

//------------------------------------------------------------------------------

procedure TAdvNodesEditor.Treeview1Change(Sender: TObject;
  Node: ComCtrls.TTreeNode);
var
  NodeInfo: PNodeInfo;
begin
  if Assigned(Node) then
  begin
    FInternalChange := True;
    Ed_Text.Text := Node.Text;
//    Sp_ImageIndex.Value := Node.ImageIndex;
    NodeInfo := PNodeInfo(Node.Data);
    Cb_NodeType.ItemIndex := Integer(NodeInfo^.NodeType);
    Ckb_Checked.Checked := NodeInfo^.Checked;
    Ckb_Expanded.Checked := NodeInfo^.IsExpanded;
    Ed_URL.Text := String(NodeInfo^.URL);
    Ed_ImageURL.Text := String(NodeInfo^.ImageURL);
    Ed_ImageCollapsedURL.Text := String(NodeInfo^.ImageCollapsedURL);
    Ed_Hint.Text := String(NodeInfo^.Hint);
    Sp_Tag.Value := NodeInfo^.Tag;

    FInternalChange := False;
    UpdateImage;
  end;  
end;

//------------------------------------------------------------------------------


end.
