TeeTree 2 issues with scrolling, layout & behaviour chan

TeeTree VCL for Borland Delphi and C++ Builder.
Post Reply
Posts: 15
Joined: Wed Oct 31, 2007 12:00 am

TeeTree 2 issues with scrolling, layout & behaviour chan

Post by Collinor » Fri Nov 09, 2007 6:05 pm

We are migrating our application from Delphi 6 and TeeTree v1 to Delphi 2007 for Win32 and TeeTree 2 of the TeeChart v8.01 package. We encountered the following issues with the TeeTree 2 components:

1. The bevel frame is overwritten when a TTree is scrolled. This occurs in every scroll direction.

2. A selected node is not (completely) within the TTree's visible area, e.g. the vertical scroll bar is not located at the top if the root node is selected.

3. In contrast to TeeTree v1, connections are not drawn with small dots, but solid. The reason for this was the following code fragment in the initialization routine of TeeTree.pas:
Unfortunately D10 is also defined for Delphi 2007 (D11). Removing the IFNDEF, connections were drawn with small dots again.

4. In contrast to TeeTree 1, TCustomTree's AssignParent property defaults to false at runtime. It is now required to explicitly assign True to the child node's AssignParent property.

5. Unfortunately, a TTreeList is not derived from TList anymore. Methods like TList.Sort(Compare) have to be reimplemented.

6. In contrast to TeeTree v1, horizontal arrows of a connection are always drawn with a line 5px (see CrossMargin property in TTreeExplorerAlignChild.XPosition). This makes it impossible to just draw the arrow in the horizontal portion of the connection to save space.

We have solved issues 3-6 by patching the source of TeeTree.pas. For issues 1 and 2 your help would be appreciated.

Posts: 211
Joined: Mon Dec 01, 2003 5:00 am

Post by tom » Tue Jan 15, 2008 12:50 am


First, excuse us for the very late answer.

1. Yes, you are correct, this issue will be fixes.

2. Please check if the property Selected.ScrollToView is enabled. If this property is set to true, then clicking on a node which is partly shown will result in a change in the current view so that the node is completely visible

3. Thanks for making us aware of this

4. The following is a list of important changes and new features from teeTree v1 to v2:
Important Changes

1) Node Parent and Parents properties.

In version 1, the node Parent property was the first element in the Parents[] array property.
Now in version 2, the Parent property is independent from the Parents[] array.

That means, one node can be a child of another node (the Parent), without the necessity of having any connection object between them.
On the other hand, one node can be connected to another node without the necessity of having a Parent->Child relationship.

When a node (A) is the child of another node (B), then B is the Parent of A ( A.Parent=B ).
A node can have only one Parent.

The node Parents[] array property holds the nodes that have connections to it.


2) Tree NoOwnerShapes and AssignParent properties.

In this new version these properties have different values depending if we're adding nodes at design time under Delphi or we are adding nodes programatically at runtime using code.
At design-time NoOwnerShapes is False (so all new nodes created at design-time will be assigned the Form as the Owner to ensure the nodes will be streamed out to the form's DFM file). The AssignParent property at design-time is True.

At run-time, NoOwnerShapes is True (so new created nodes at runtime will have no Owner, this increases speed a lot).
AssignParent property at runtime is False (to increase speed when creating new nodes at runtime).


3) Connection styles.

In previous version there were 3 "styles" for connection objects:


Now in version 2.0 there is a new style: csAuto.
By default connections are set to csAuto style. This means the connection style is determined by the new Tree.GlobalFormat.ChildManager class.
As soon a connection is dragged using the Tree editor, the style is changed from csAuto to csLine.

More explanation about connection styles can be found below.


4) Tag property of nodes

The Tag property was previously used to store custom user data at every node, for example when using the AddChildObject method.
Now in version 2.0, each node has a Data property (of type "Pointer"), which replaces Tag.
The node Tag property is not used anymore, so you are free to use it if you want in your projects.


5) TCustomTreeShape class

In version 1, this class was an ancestor class of TTreeNodeShape. In version 2, it is exactly the opposite, TCustomTreeShape class derives from TTreeNodeShape. The main reason is performance when creating many nodes, by reducing the number of constructors to inherit when creating nodes.


6) Drag and drop

In version 1 the method to drag and drop nodes was the standard VCL mechanism and TDragObject class.
In version 2 the Tree has a new subproperty "DragAndDrop" that replaces (overrides) the default VCL code.


7) Change in default *.TEE extension

The default extension for saved native TeeTree files is no longer *.TEE
It has been changed to *.TTR to avoid conflict with TeeChart native files created with TeeChartOffice.

New Features


Many new speed optimizations have been carefully applied to TeeTree code, specially to code related to manage creation and destruction of nodes (see table below), and to painting procedures.

Now most of the sub-properties of every node (such as Border, Brush, Gradient, etc) are now created "just-in-time" the first time they are accessed, instead of creating them when the node is created. This "on demand" mechanism reduces a lot the time it takes to create new nodes, and reduces also the memory used at startup.

Other optimizations include reusing node properties thanks to a new Tree property (GlobalFormat) which contains properties shared among all tree nodes.
Another optimization is the use of an internal TTreeList class, very similar to Borland's VCL TList class but with less overhead (and more speed).
Several properties are now stored in private variables instead of recalculating them every time (for example the node BrotherIndex property).

The source code contains comments describing and indicating the optimizations.


Speed comparison:

The table below shows the results of comparing the speed of TeeTree versus Borland's TreeView component.
Tested using Delphi 5 under Windows 2000 Server, on a Pentium III 650 Mhz with 256MB of ram, using BeginUpdate / EndUpdate.
Results show the average time running the test consecutively 5 times. "Your mileage may vary".

Download comparative application (259Kb).

Operation TeeTree Borland's TreeView % Better
Add 5000 nodes 90 msec 1142 msec 1269%
Add 10000 nodes 161 msec 4997 msec 2776%
Add 50000 nodes 1022 msec 167681 msec 16407%
Clear Tree with 10000 nodes 80 msec 4066 msec 5082%



Less memory is consumed due to the new speed optimizations.
Other memory optimizations are using a single internal String variable instead of a TStringList when a node has only one line of text.
However, bear in mind TeeTree is relatively memory-hungry, because every node is a full standalone component with lots of properties, methods and events.



The Tree HotTrack subcomponent controls how nodes will be displayed when the mouse is over each node boundaries.
You can use HotTrack in several ways:

To underline the node's text (simulating hyperlink): Tree1.HotTrack.Active:=True

To change the node's border: Tree1.HotTrack.UseBorder:=True

To change the node's font: Tree1.HotTrack.UseFont:=True



The new TeeTree GlobalFormat sub-component contains properties that are globally used by all Tree nodes, unless each individual node specifies (overrides) the global setting.


Tree1.GlobalFormat.Border.Visible:=False (all nodes will hide the border)


The NodeClass property of TeeTree GlobalFormat property specifies the default node class that will be used when adding new nodes using the Add methods, or when adding new nodes using the editor dialog.


Overloaded Add methods

Several new ways to add nodes, using the overloaded Add method with different parameters.


DeleteShape method

To remove a node (and all its children nodes and connections) from a Tree, you can simply do this:


or alternatively:

Tree1.DeleteShape( MyNode );


Default Items property

The Tree component has now a default array property to make easier (and write less code) when accessing nodes.
Thus, the following is equivalent:

TreeNodeShape123.Color := clRed ; // <-- using node component

Tree1.Shapes[123].Color := clRed ; // <-- using Shapes array

Tree1[123].Color := clRed ; // <-- using default array property


Default List Capacity constants

Two new TeeTree public variables can be used to control the initial "capacity" of all Tree lists.
Setting these variables can increment speed when adding lots of nodes that are children of other nodes:

TreeListCapacity : Integer = 100;
TreeShapeListCapacity : Integer = 0;

Note: When adding few children nodes, setting the capacity values might require more memory than necessary.


Connection Points

The TreeConnection component has a new Points property which contains the points that determine the connection.
These point coordinates are stored at Form's DFM.

Each point X and Y coordinates can be specified in several ways.
X and Y style are independent and can be different.
The following styles cover most of the functionality required to construct complex multi-segment connection lines.

Style Description
Automatic "From" The coordinate is automatically calculated to a "best" near point in the "From" connection node.
Automatic "To" The coordinate is automatically calculated to a "best" near point in the "From" connection node.
Fixed The coordinate is in screen pixels, relative to TeeTree Left,Top origin.
Relative to "From" The coordinate is in pixels, relative to the Left,Top position of the "From" connection node.
Relative to "To" The coordinate is in pixels, relative to the Left,Top position of the "To" connection node.
Percent "From" The coordinate is at a percent ( from 0 to 100 ) of the "From" node size (width or height)
Percent "To" The coordinate is at a percent ( from 0 to 100 ) of the "To" node size (width or height)
Previous The coordinate is relative to the previous point coordinate.
Next The coordinate is relative to the next point coordinate.

Note: Not all style combinations are valid. (For example, this is invalid : Point[0].Style = Next and Point[1].Style = Previous).


Curved connections

Connection lines now display curves using the standard Windows GDI Bezier algorithm.
The minimum number of points a connection must have to enable curved display is 4.

Note: The maximum number of points in this beta release allowed per curve is 100.


Level property

This property returns the number of parents a Node has.
For root nodes, it returns zero.


ClipText property

By default the node ClipText property is false. That means the node text will be fully displayed, even if the node dimensions are smaller than the text size. When ClipText is True, the node text will be clipped (obscured) outside the node boundaries.



Every node can be displayed with a percent degree of Transparency (semi-glass effect).
The node's index in the Tree Shapes array determines the order of displaying nodes, which is a very important factor to consider when displaying semi-transparent nodes over other nodes.


OnMouseEnter, OnMouseLeave events

When the mouse passes over node boundaries, the OnMouseEnter and OnMouseLeave events are called.
You can use these events to, for example, change the node background color to simulate "hottracking".


Selecting and dragging connections

The Tree Connections array property has a new property "Selected" to indicate the connection object that will be focused at design-time. Using the mouse it is possible to drag each connection point and to add new points to the connection to form a multi-segment connection.


Editor improvements

Several new features at the Tree editor, like design / preview modes, more toolbars, improved popup-menus, drag and drop in the "node tree", selection and dragging of connection lines, adding and removing connection points and more.

Editor Changes:

The Tree properties tabcontrol is not visible by default. (It was visible in version 1)


OnShowHint event

The Tree OnShowHint event is called just when the Tree is going to show a hint for nodes that are partially obscured.
The event supplies the string to display. This text can be replaced, or set to empty to disable showing the hint.
The hint is shown using the default VCL Application hint properties and methods.


New shapes

Several new shapes have been added to TeeTree.
They show by default at design-time at TeeTree editor dialog toolbar.

At run-time, you can control which shapes should be included by using the appropiate unit.

Grid shape

This shape defines and maintains an array of shapes ( in "grid" or "table" format ).
Every shape is accessible through the Cells[Row,Col] property.

Polygon shape

The polygon shape is used to draw shapes with a custom number of points. (A polygon).
The editor dialog allows manually drawing polygons and displays handles at each polygon's point to move them.

Image shape

This shape shows its Image property centered inside the shape bounds.


New "stock" images

Several new images have been added to the default global "pool" of bitmaps.
A new set of "ImageIndex" constants refers to each new node image:




Also, new custom images can be added to the global TreeImagePool array using the TreeImagePoolAdd method:

TreeImagePoolAdd( MyPicture );

The advantadge of using the global array of images is that when several nodes share the same image, the image is allocated into memory only once.

Custom images are also displayed at the Tree editor dialog image toolbar.

Requests to include a native VCL TImageList property in TeeTree will be considered in future releases. However, using standard image lists really degrades display performance compared to using a dynamic array of pictures.


Children Manager object

When nodes have their AutoPosition properties set to True (the default), the "children manager" class controls the following things:

How to position each node automatically.
How to calculate point coordinates for connections between parent and child nodes.
How to display these connections lines.
How to navigate through nodes when using the arrow keys and other keys like Home, End, etc.

This "manager" is stored at TTree.GlobalFormat.ChildManager property.

By default the TeeTree comes with one "child manager" class (Explorer), which aligns nodes from top to bottom and left to right, and draws sided connection lines between parent and children nodes.
This "Explorer manager" acts exactly as Windows TreeView control.

It should be possible to create derived classes from the base ChildManager class to emulate different kinds of Tree diagrams.
Examples will come in the near future.


New TTreeEdit component

This non-visual component can be used to modally show the Tree editor dialog at runtime:


This component also includes properties to control several aspects of the editor dialog, such as how many windows will be visible by default when entering the editor, if the editor layout settings will be saved to the registry and so on.


Flat Scrollbars

A new TeeTree property to display scrollbars in normal or "flat" visual aspect.

Tree1.FlatScrollBars := True;


Mouse Wheel scrolling / navigation

The Tree WheelNavigation property controls what to do when the user at runtime moves the mouse wheel.
There are five possible actions:

wnSelection Nodes are selected as if the user pressed the Up and Down arrow keys.
wnScrollHoriz The Tree is scrolled horizontally.
wnScrollVert The Tree is scrolled vertically up and down.
wnZoom The Tree is zoomed in and out.
wnNone Nothing happens. Mouse wheel movements are not used.


Automatic dragging of nodes

A new Tree subproperty DragAndDrop contains several properties to help automatize drag and drop of nodes.

The Automatic (boolean) property enables drag and drop of nodes:


Just by setting Automatic to True, users at runtime can use the mouse to change the nodes parent-child relationships.
Existing VCL drag and drop methods and events (such as OnEndDrag, etc) can be used to control the drag-drop operation.

Other properties in DragAndDrop control if root nodes should be allowed to drag-drop, and if non-root nodes can be dragged to the Tree to convert them to root nodes.


Inline Text Editor

The new TeeTree subproperty TextEditor contains properties to determine how and when to show the inline text editor and the format of the TMemo control.


Tree1.TextEditor.Enabled := True;
Tree1.TextEditor.ShortCut := VK_F5;
Tree1.TextEditor.Mode := tteKey;
Tree1.TextEditor.MouseButton := mbRight;


New Image levels component

A new non-visual component TImageLevels is a custom derived ImageList component to be used to supply images to nodes.
Every image in the ImageLevels component corresponds to a different node level.

That is, root nodes (which have a level of zero), will use the first image in ImageLevels component.

Children nodes will use the corresponding image depending on its level.


Database Tree ( TDBTree )

Note: Important changes in DBTree component will be done before the final version is released.

Detail2 property

The DBTree component now support an additional detail dataset, so now its possible to create trees from datasets in master-detail-detail relationships.

DetailGrid property

This new property is used to display detail record values inside a Grid shape, instead of using individual nodes.

The Grid shape offers a similar functionality than Microsoft Word or FrontPage "Tables".

DBTree1.DetailGrid := True;


Page Layout

A new Tree subproperty includes properties to determine the dimensions of a Tree page and to optionally draw a border around page bounds.

By default the Tree page size is obtained from the current installed printer, if any:

Tree1.Page.UsePrinter := True;

To define a custom page size:


The Count property returns the number of pages.
It is calculated using the maximum size of all Tree nodes, after the Tree is displayed.

ShowMessage( IntToStr( Tree1.Page.Count ) );


New TeeTree events:


This new event is called whenever the end user clicks on a node to select it, or when the end-user uses the arrow keys to navigate from one node to another.
It allows to cancel the selection, setting the AllowChange event parameter to False.

This event does not happen when setting the Node Selected property is changed programatically.

If a selection is allowed, the Tree will then call the OnSelectShape and OnUnSelectShape events as usually.


This event is called when the end-user moves a node using either the mouse or the arrow keys in the Tree editor.
Parameters include the node to be moved and the horizontal and vertical amounts in pixels to move.
It gives the opportunity to disallow the movement by setting either the horizontal or vertical pixels to zero.


This event is called when the end-user resizes a node using either the mouse or the arrow keys in the Tree editor.
Parameters include the node to be resized, the node corner to resize, and the horizontal and vertical amounts in pixels to resize.
It gives the opportunity to disallow resizing the node by setting either the horizontal or vertical pixels to zero.

5. The OnSortCompare event might be use full to you for custom sorts.

6. With the childmanager object it is possible to create your own tree diagrams


Post Reply