VisClass: 5.2 Working with Visible Object Trees: Adding and Removing

Up: GEOS SDK TechDocs | Up | Prev: 5.1 Creating and Destroying | Next: 5.3 Getting Visible Tree Information
MSG_VIS_ADD_CHILD, MSG_VIS_REMOVE, MSG_VIS_REMOVE_CHILD, MSG_VIS_MOVE_CHILD, MSG_VIS_ADD_NON_DISCARDABLE_VM_CHILD, MSG_VIS_REMOVE_NON_DISCARDABLE_VM_CHILD, MSG_VIS_REMOVE_NON_DISCARDABLE

Once you have objects instantiated, you can connect them together into an object tree. If you know the structure of your tree beforehand, you can create the tree explicitly in your .goc file, just as you would create your generic object tree.

For many purposes, however, a dynamic object tree is much more useful. To use it, you must be able to add and remove objects easily as well as move them within the tree easily.

Adding and Removing Normally

To add an object to a branch of a visible tree, use the message MSG_VIS_ADD_CHILD . This message adds a visible object as the child of a composite; if the new child is a composite with its own children, the entire branch is added to the tree. You can add a child at any position in the composite's child list (e.g., as the first child, as the second child, as the last child, etc.), and you can mark the child dirty after addition if you want.

For example, if you have a composite visible object with two children that is currently unattached to any visible tree, you can attach it to a tree with MSG_VIS_ADD_CHILD . The figure above shows this process and the line of code used to add the composite as the second child of an object in the tree.

Note that the child in the example is added as child one. The child list of a composite is zero-based, so the first child is referred to as number zero, the second is number one, and so on. The last child may always be referred to as CCO_LAST; likewise, the first child may always be referred to as CCO_FIRST.

To remove an object or branch from a visible tree, you can use either MSG_VIS_REMOVE or MSG_VIS_REMOVE_CHILD . MSG_VIS_DESTROY may also be used, but only if the entire branch should be destroyed after being removed from the tree. Both MSG_VIS_REMOVE and MSG_VIS_REMOVE_CHILD detach the object from the visible tree and visually update the parent immediately. MSG_VIS_REMOVE , however, should be sent directly to the object being removed, while MSG_VIS_REMOVE_CHILD is sent to the parent of the object being removed. When removing a child from its parent, you can specify the child by position number (e.g., remove the last child or the first child).

You can move a child within its child list with MSG_VIS_MOVE_CHILD . This message is sent to the parent and simply moves the child within the parent's child list. To move a child from one parent to another, you must first remove it and then add it to the other parent with MSG_VIS_REMOVE_CHILD and MSG_VIS_ADD_CHILD . This message, as the others, will move the child's entire branch with it.

Adding and Removing Objects Not Saved to Documents

In many cases, you may save visible objects directly to VM documents using GenDocument objects and the document controllers. In cases like this, the objects you save to the file must not be discarded by the UI if the visible object is taken off the tree or removed. These objects are known as "non-discardable" visible objects stored in a VM file, and unless they're handled specially, they can cause your documents to crash your application.

Any top-level object you save directly to a file must be treated as non-discardable. That is, any object that gets dynamically added to or removed from a visible tree (such as a vis object that gets added as the child of a GenDocument when the document is opened) must be added, removed, and managed as a non-discardable object. There are three messages that deal specifically with non-discardable visible objects; these are detailed below and are MSG_VIS_ADD_NON_DISCARDABLE_VM_CHILD , MSG_VIS_REMOVE_NON_DISCARDABLE_VM_CHILD , and MSG_VIS_REMOVE_NON_DISCARDABLE .

MSG_VIS_ADD_CHILD

void	MSG_VIS_ADD_CHILD(
        optr		child,
        CompChildFlags		flags);

This message attaches the passed object as a child of the composite handling the message. If the parent is already opened and on the screen, you must invalidate the child with MSG_VIS_MARK_INVALID , passing the invalidation VOF_WINDOW_INVALID; the composite and child will be updated appropriately according to the VisUpdateMode passed with the invalidation. If, however, the parent is not opened, the child will automatically be opened when the parent is opened.

Source: Unrestricted.

Destination: Any visible composite object.

Parameters: child The optr of the visible object to be added as a child.

flags
A structure of CompChildFlags , described below.

Return: Nothing.

Interception: You should not subclass this message.

Structures: The CompChildFlags structure contains one one-bit flag and one 15-bit unsigned numerical field. These are described below and can be found in metaC.goh .

 typedef WordFlags  CompChildFlags;
#define CCF_MARK_DIRTY					0x8000
#define CCF_REFERENCE					0x7fff
#define CCO_FIRST					0x0000
#define CCO_LAST					0x7FFF
#define CCF_REFERENCE_OFFSET					     0
CCF_MARK_DIRTY
If this flag is set, the object will be marked dirty when added to the tree.
CCF_REFERENCE
The zero-based position of the new child. Other children will be shuffled forward in the child list as necessary. If greater than the number of children, it will be taken to be CCO_LAST.
Two special numbers may be used in the CCF_REFERENCE field:
CCO_FIRST
Add as the first child.
CCO_LAST
Add as the last child.

Warnings: Do not pass the optr of an object that is already the child of another object. The results are unpredictable and will likely result in an error.

MSG_VIS_REMOVE

void	MSG_VIS_REMOVE(
        VisUpdateMode updateMode);

This is the high-level message that closes (if necessary) and removes a visible branch from the object tree. The parent of the branch is marked invalid for visual update according to the passed VisUpdateMode .

Unlike MSG_VIS_DESTROY , this message does not destroy the visible branch but only unlinks it from the tree. This message may not be subclassed by any object. This message is useful for hiding visible branches which may be added again later with MSG_VIS_ADD_CHILD .

Source: Unrestricted.

Destination: Any visible composite object.

Parameters: updateMode The VisUpdateMode used to update the composite from which the child is removed. VUM_MANUAL is not allowed.

Return: Nothing.

Interception: Do not subclass this message.

Warnings: This message will not allow VUM_MANUAL to be passed as the updateMode .

MSG_VIS_REMOVE_CHILD

void	MSG_VIS_REMOVE_CHILD(
        optr		child,
        CompChildFlags		flags);

This message removes the specified child from the object tree. This message should be rarely used and used with care; it does not close the visible branch but simply removes it. Consider using the higher-level MSG_VIS_REMOVE instead. Note that all grabs (focus, gadget, mouse, etc.) must be released by the child and all its children before the branch can be removed safely.

Source: Unrestricted.

Destination: The parent composite of the passed object.

Parameters: child The optr of the child to be removed. If this optr is not among the recipient's children, an error will likely occur.

flags
The CompChildFlags as described in MSG_VIS_ADD_CHILD on typedef WordFlags CompChildFlags; #define CCF_MARK_DIRTY 0x8000 #define CCF_REFERENCE 0x7fff .

Return: Nothing.

Interception: You should not subclass this message.

Warnings: Most likely you should use MSG_VIS_REMOVE instead of this message. MSG_VIS_REMOVE takes care of extra bookkeeping automatically that can be difficult.

MSG_VIS_MOVE_CHILD

void	MSG_VIS_MOVE_CHILD(
        optr		child,
        CompChildFlags		flags);

This message moves a child of the recipient to another location among its siblings. It essentially removes the child from the branch and then re-adds it in the same manner as MSG_VIS_ADD_CHILD . This message does not move the child from one parent to another; you must use a combination of MSG_VIS_REMOVE and MSG_VIS_ADD_CHILD to achieve that.

Source: Unrestricted.

Destination: The parent composite of the passed object.

Parameters: child The optr of the child to be removed. If this optr is not among the recipient's children, an error will likely occur.

flags
The CompChildFlags as described in MSG_VIS_ADD_CHILD on typedef WordFlags CompChildFlags; #define CCF_MARK_DIRTY 0x8000 #define CCF_REFERENCE 0x7fff .

Return: Nothing.

Interception: You should not subclass this message.

MSG_VIS_ADD_NON_DISCARDABLE_VM_CHILD

void	MSG_VIS_ADD_NON_DISCARDABLE_VM_CHILD(
        optr		child,
        CompChildFlags		flags);

This message performs exactly the same as MSG_VIS_ADD_CHILD except that it also increments the object's in-use count so it will never be discarded. This is used on top objects in visible sub-trees that are saved to document files: The object is added as a non-discardable file when the document is opened, and it is removed as a non-discardable child (with MSG_VIS_REMOVE_NON_DISCARDABLE_VM_CHILD or MSG_VIS_REMOVE_NON_DISCARDABLE ) when the document is closed.

Source: Unrestricted--typically a document object when opening the file.

Destination: The new parent of the visible object being added to the tree.

Parameters: child The optr of the new child being added to the tree.

flags
A record of CompChildFlags indicating where the child should be added. CCF_MARK_DIRTY is ignored in this record.

Return: Nothing.

Interception: Generally not intercepted.

MSG_VIS_REMOVE_NON_DISCARDABLE_VM_CHILD

void	MSG_VIS_REMOVE_NON_DISCARDABLE_VM_CHILD(
        optr	child);

This message performs exactly the same as MSG_VIS_REMOVE_CHILD except that it is used with MSG_VIS_ADD_NON_DISCARDABLE_VM_CHILD rather than with MSG_VIS_ADD_CHILD . This message decrements the in-use count before removing the child, thereby undoing the extra increment performed by MSG_VIS_ADD_NON_DISCARDABLE_VM_CHILD .

Source: Unrestricted--typically a document object when closing the file.

Destination: The parent of the visible object being removed from the tree.

Parameters: child The optr of the child being removed.

Return: Nothing.

Interception: Generally not intercepted.

MSG_VIS_REMOVE_NON_DISCARDABLE

void	MSG_VIS_REMOVE_NON_DISCARDABLE(
        VisUpdateMode		updateMode)

This message performs exactly the same as MSG_VIS_REMOVE except that it decrements the object's in-use count before removing it. This message should therefore be used in conjunction with the adding message MSG_VIS_ADD_NON_DISCARDABLE_VM_CHILD and should not be used with MSG_VIS_ADD_CHILD. Likewise, MSG_VIS_REMOVE should not be used with this MSG_VIS_ADD_NON_DISCARDABLE_VM_CHILD.

Source: Unrestricted--typically a document object when closing the file.

Destination: The visible object being removed from the tree.

Parameters: updateMode A VisUpdateMode value indicating when the object should be visibly removed from the tree. VUM_MANUAL is not allowed.

Return: Nothing.

Interception: Generally not intercepted.


Up: GEOS SDK TechDocs | Up | Prev: 5.1 Creating and Destroying | Next: 5.3 Getting Visible Tree Information