Page 1 of 1

How to me to save Tree1 forms?

Posted: Sun Nov 22, 2009 6:45 am
by 10552878
Hello!

1) As to me to save Tree1 if I have created an own class?

TCompas = class(TTreeNodeShape)
private
FIndicator: Boolean;
Timer: TTimer;
FAngleFirst: Extended;
FAngleLast: Extended;
FAngleValue: Extended;
FBrushPie: TChartBrush;
FBrushCircle: TChartBrush;
FBrushRect: TChartBrush;
FBrushArrow: TChartBrush;
FPenPie: TChartPen;
FPenCircle: TChartPen;
FPenRect: TChartPen;
FPenArrow: TChartPen;
FLabelFont: TTeeFont;
FDanger: Boolean;
FBrushDanger: TChartBrush;
FISDanger: Boolean;
FLabelIncriment: Integer;
procedure SetAngleFirst(const Value: Extended);
procedure SetAngleLast(const Value: Extended);
procedure SetAngleValue(const Value: Extended);
procedure SetBrushPie(const Value: TChartBrush);
procedure SetBrushArrow(const Value: TChartBrush);
procedure SetBrushCircle(const Value: TChartBrush);
procedure SetBrushRect(const Value: TChartBrush);
procedure SetLabelFont(const Value: TTeeFont);
procedure SetPenArrow(const Value: TChartPen);
procedure SetPenCircle(const Value: TChartPen);
procedure SetPenPie(const Value: TChartPen);
procedure SetPenRect(const Value: TChartPen);
procedure SetDanger(const Value: Boolean);
procedure SetBrushDanger(const Value: TChartBrush);
procedure SetISDanger(const Value: Boolean);
procedure SetLabelIncriment(const Value: Integer);
public
procedure Timer1Timer(Sender: TObject);
Constructor Create(AOwner:TComponent); override;
Destructor Destroy; override;
procedure Draw; override; // to draw the background...
Published
Property ISDanger: Boolean read FISDanger write SetISDanger;
Property Danger: Boolean read FDanger write SetDanger;
Property BrushDanger: TChartBrush read FBrushDanger write SetBrushDanger;
Property BrushRect: TChartBrush read FBrushRect write SetBrushRect;
Property BrushCircle: TChartBrush read FBrushCircle write SetBrushCircle;
Property BrushPie:TChartBrush read FBrushPie write SetBrushPie;
Property BrushArrow: TChartBrush read FBrushArrow write SetBrushArrow;

Property PenRect: TChartPen read FPenRect write SetPenRect;
Property PenCircle: TChartPen read FPenCircle write SetPenCircle;
Property PenPie:TChartPen read FPenPie write SetPenPie;
Property PenArrow: TChartPen read FPenArrow write SetPenArrow;

Property AngleFirst: Extended read FAngleFirst write SetAngleFirst;
Property AngleLast: Extended read FAngleLast write SetAngleLast;
Property AngleValue: Extended read FAngleValue write SetAngleValue;
Property LabelFont: TTeeFont read FLabelFont write SetLabelFont;
Property LabelIncriment: Integer read FLabelIncriment write SetLabelIncriment;
end;

Re: How to me to save Tree1 forms?

Posted: Wed Nov 25, 2009 12:53 pm
by yeray
Hi BoikovSoft,

I'm not sure to understand the main question. You've created TCompas class that inherits from TTreeNodeShape.
What are you exactly trying to save?
Are you trying to save it in a file or in memory?

Re: How to me to save Tree1 forms?

Posted: Thu Nov 26, 2009 4:29 am
by 10552878
I have made the small editor on the basis of Tree. And additional components of type TCompas were necessary for me.
The user should create the form, and then keep her. If necessary to read.
I have already solved this problem.

Here my realization:

Code: Select all

procedure SaveToFile(aFileNAme: TFileNAme; aForm: TFormEdit);
VAr
  kB:Boolean;
  sf: TMemoryStream;
  b: Byte;
  i: Integer;
  aFile, aPath: String;
begin
  With aForm Do
  Begin
    sf := TMemoryStream.Create;
    try
      sf.Position := 0;
      sf.Write(Tree1.Roots.count, SizeOf(Tree1.Roots.Count));
      For i:=0 to tree1.Shapes.Count-1 do
      Begin
        if tree1.Shape[i].ClassType = TCompas then
        Begin
          B := ord(mCompas);
          sf.Write(b, SizeOf(b));
        end;
        if tree1.Shape[i].ClassType = TImageShape then
        Begin
          B := ord(mImage);
          sf.Write(b, SizeOf(b));
        end;
        if tree1.Shape[i].ClassType = TTextShape then
        Begin
          B := ord(mLabel);
          sf.Write(b, SizeOf(b));
        end;
      End;
      Kb := tree1.Designing;
      tree1.Designing := false;
      Tree1.Grid.Visible := false;
      sf.WriteComponentRes(tree1.Name, tree1);
      tree1.Designing := kb;
      Tree1.Grid.Visible := kb;
      For i:=0 to tree1.Shapes.Count-1 do
      Begin
        if tree1.Shape[i].ClassType = TCompas then
          sf.WriteComponentRes(tree1.Shape[i].Name, TCompas(tree1.Shape[i]));
        if tree1.Shape[i].ClassType = TImageShape then
          sf.WriteComponentRes(tree1.Shape[i].Name, TImageShape(tree1.Shape[i]));
        if tree1.Shape[i].ClassType = TTextShape then
          sf.WriteComponentRes(tree1.Shape[i].Name, TTextShape(tree1.Shape[i]));
      end;
      
      aPath := ExtractFilePath(aFileNAme);
      aFile := ExtractFileName(aFileNAme);
      i := pos('.', aFile);
      if i>1 then
        afile :=Copy(afile, 1, i - 1);
      Sf.SaveToFile(aPath + aFile + '.UDG');
    finally
      sf.Free;
    end;
  End; // With
end;

procedure LoadToFile(aFileNAme: TFileNAme);
var
  A, I: Integer;
  B: Array of Byte;
  sf: TMemoryStream;
Procedure AddmyShape(value: Byte);
Var
  V: TTreeNodeShape;
Begin
   With FormEdit do
   Case value of
   ORd(mLabel) :
    Begin
        Tree1.GlobalFormat.NodeClass := TTextShape;
        V := Tree1.AddShapeClass(0, 0, 'Text', nil, TTextShape);
        v.Name := GetUniqueName('Label');
        v.Border.Visible := true;
    End;
   Ord(mImage) :
    Begin
        Tree1.GlobalFormat.NodeClass := TImageShape;
        V := Tree1.AddShapeClass(0, 0, '', nil, TImageShape);
        v.SimpleText := '';
        v.Transparent := false;
        v.Border.Visible := true;
        v.Name := GetUniqueName('Image');
    end;
   ORD(mCompas):
    Begin
        Tree1.GlobalFormat.NodeClass := TCompas;
        V := Tree1.AddShapeClass(0, 0, '', nil, TCompas);
        v.SimpleText := '';
        V.Transparent := true;
        v.Border.Visible := true;
        v.Name := GetUniqueName('Compas');
    End;
   End; // Case
   v.Image.Bitmap.FreeImage;
   sf.ReadComponentRes(V);
   FormEdit.tree1.GlobalFormat.NodeClass := nil;
End;
begin
  FormEdit := TFormEdit.Create(MainForm);
  FormEdit.Name := MainForm.GetUniName('form');
  FormEdit.Caption := FormEdit.Name;
  sf := TMemoryStream.Create;
  Try
    sf.LoadFromFile(aFileNAme);
    Sf.Read(a, SizeOf(A));
    SetLength(B, A);
    Sf.Read(b[0], a);
    sf.ReadComponentRes(FormEdit.Tree1);
    For I := 0 to A-1 do
      AddmyShape(b[i]);
  Finally
    SF.Free;
  End;
  FormEdit.Caption := ExtractFileName(aFileNAme);
end;

....
initialization

  RegisterClasses([TCompas]);

Re: How to me to save Tree1 forms?

Posted: Thu Nov 26, 2009 4:56 am
by 10552878
Has found also a defect in Tree

Problem:
It is necessary to deduce values of properties of object TTreeNodeShape dynamically:

Left
Top
width
Height

In events OnMovingShape and OnResizingShape at change of the sizes are accessible DeltaX, DeltaY.
To define the sizes of a figure it is necessary to perform following operations:

Code: Select all

procedure TFormEdit.Tree1MovingShape(Sender: TTreeNodeShape; var DeltaX,
  DeltaY: Integer);
Var
   R: TRect;
begin
    r := Sender.Bounds;
    R.Left := r.Left + DeltaX;
    r.Top  := r.Top  + DeltaY;
    R.Right  := r.Right  + DeltaX;
    r.Bottom := r.Bottom + DeltaY;

   with TeeInspector1.Items do
   Begin
     Add(iiInteger,  'Left',      r.Left,                ChangeLeft);
     Add(iiInteger,  'Top',      r.Top,                 ChangeTop);
     Add(iiInteger,  'Height',    r.Bottom - r.Top,      ChangeHeight);
     Add(iiInteger,  'Width',    r.Right  - r.Left,     ChangeWidth);
   end;
end;


procedure TFormEdit.Tree1ResizingShape(Sender: TTreeNodeShape;
  ACorner: TTreeShapeHandle; var DeltaX, DeltaY: Integer);
Var
   R: TRect;
begin
   r := Sender.Bounds;
  case ACorner of
    rcLeftTop     :
      BEgin
        R.Left := r.Left + DeltaX;
        r.Top  := r.Top  + DeltaY
      End;
    rcRightBottom	:
      BEgin
        R.Right := r.Right +DeltaX;
        r.Bottom  := r.Bottom  + DeltaY;
      End;
    rcLeftBottom  :
      BEgin
        R.Left := r.Left + DeltaX;
        r.Bottom  := r.Bottom  + DeltaY;
      End;
    rcRightTop    :
      BEgin
        R.Right := r.Right + DeltaX;
        r.Top  := r.Top  +DeltaY;
      End;
    rcLeft        : R.Left := r.Left + DeltaX;
    rcTop         : R.Top := r.Top + DeltaY;
    rcRight       : R.Right := r.Right + DeltaX;
    rcBottom      : R.Bottom := r.Bottom + DeltaY;
    
    End;
   with TeeInspector1.Items do
   Begin
     Add(iiInteger,  'Left',      r.Left,                ChangeLeft);
     Add(iiInteger,  'Top',      r.Top,                 ChangeTop);
     Add(iiInteger,  'Height',    r.Bottom - r.Top,      ChangeHeight);
     Add(iiInteger,  'Width',    r.Right  - r.Left,     ChangeWidth);
   end;
End;
Whether it is impossible to add event OnAfterResizingOrMoving (Sender: TTreeNodeShape),
Where Sender already has the new sizes?
OnAfterResizingOrMoving occurs after change of the sizes Shape or after object moving.

Re: How to me to save Tree1 forms?

Posted: Mon Nov 30, 2009 11:07 am
by yeray
Hi BoikovSoft,

Is it possible that the Tree needs a repaint to have internal values updated? Try with this:

Code: Select all

Tree1.Draw;
If this doesn't solve the problem for you, please, try to arrange a simple example project we can run as-is to reproduce the problem here. Thanks in advance.

Re: How to me to save Tree1 forms?

Posted: Mon Nov 30, 2009 11:16 am
by 10552878
Consider wrong to cause method Draw. It will lead double copying.

Thanks, I already have no time to alter.
I have left as is. Terms draw in.