Tutorial: Family Tree (page 2)






From the Tool Palette, add a MainMenu, ActionList and an ImageList.

Set the Images property of both the MainMenu and the ActionList to point to the ImageList using the Object Inspector.

We will show our relatives in a TreeView. Add one to the MainForm and set the Align property to alLeft.

Add a Splitter to enable the user to set the width of the TreeView. It should align itself to the right of the TreeView. Drag it here if it has gone to the left.

Set the TreeView Images property to the ImageList.


The grunt of the application

It is a very good idea to separate the logic of your application from the user interface.

The main form will contain a lot of code just controlling the way the user interacts with the application. If we have many lines of implementation code “under the button” then the unit will become large and unmanageable. It is better to have the implementation in a separate unit so you can have just one or two lines of code in response to clicks and other user-interaction Events.

If you change the target platform of your application (to smart 'phone from PC for example) or from Lazarus to Delphi or vice-versa, it is a whole lot easier if the visual form Units are kept simple.


In Lazarus, create a File | New Unit (Delphi: File | New | Unit) from the menu and save it as “FamilyComponents” in the project folder.


We need to pause and think about how the application will work and about the Objects that we will use.


A Relative is an Object (well - mine are anyway!). The definition in code of an Object type is called a “Class”. Using the class function “Create” you can create as many objects as you need of that class type. Class names start with a “T” by convention so we will define a class called “TRelative”. Class definitions go in the “interface” part of the unit under a heading of “type”.


TRelative = class(TComponent);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property DateOfBirth: TDateTime;
property DateOfDeath: TDateTime;
property FullName: string;

property Gender: TGender read FGender write FGender;
property Notes: TStrings;
property Photos: TStrings;
property TreeNode: TTreeNode;
end;


The observant reader will have noticed that this code is incomplete: For example where is the read/write implementation for the FullName property? Where is FGender declared?

Just type [Shift] + [Ctrl] + [C]. Lazarus/Delphi knows what is missing and will fill it in for you along with the empty method stubs in the implementation section of the unit. Cool huh?


All classes descend from “TObject”. You need to select a suitable base class for the new class, depending on what functionality you want already built in. I have chosen “TComponent” as this would allow it to be added to the Lazarus “Component Palette” should you wish to do so. In addition it has


an “Owner” which will be responsible for destroying objects when the application closes which saves us writing “clean up” code.

Pascal does not offer “garbage collection” so you need to ensure that all objects created are also destroyed before the application closes.


In the “public” part of the definition there are methods to create and destroy objects of this class type and the properties of a relative.

We need to declare an enumeration for the Gender property.

type
TGender = (gMale, gFemale);


Line relatives

My brothers and sisters are Relatives but my Mum and Dad are special Relatives because they are my blood Line Relatives. They descend from my grandparents and their grandparents before them.


(Adding cousins is not implemented and left as a reader exercise.)


TLineRelative = class(TRelative)
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Father: TLineRelative;
property Mother: TLineRelative;
property Siblings: TList read FSiblings;
end;


TLineRelative gets all the functionality of TRelative. Use the constructor to create the TList and the destructor to destroy it.


To build the tree we will allow LineRelatives to add TLineRelative parents and also to add ordinary TRelative siblings (brothers and

sisters). We maintain a List of these.


Adding controls to the Form


We will need to create the folder to store the data files. We do this in the MainForm OnShow event.

Select FormMain in the Object Inspector (Structure window in Delphi) then double-click in the blank space to the right of “OnShow” in the Events tab to create the empty method code stub.



create the Form1.OnShow event method stub


In the FormShow method stub put

ForceDirectories(DataPath+'images');

This creates all the folders for us including somewhere to put the images for our html files. If the folders already exist it does nothing.