GenClass: 5.2 Generic Trees: Manipulating Children Directly

Up: GEOS SDK TechDocs | Up | Prev: 5.1 Child/Parent Searches | Next: 5.3 Branch Construction/Destruction
MSG_GEN_ADD_CHILD, MSG_GEN_REMOVE, MSG_GEN_REMOVE_CHILD, MSG_GEN_MOVE_CHILD, MSG_GEN_ADD_CHILD_UPWARD_LINK_ONLY

The following messages create, move, and remove objects set up directly in your .goc file or created with ObjInstantiate() , ObjInstantiateForThread() or ObjDuplicateResource() . These objects may have children, in which case those children will travel with their parent (and be moved and destroyed with the parent).

When adding or removing children, you typically have to use a CompChildFlags record. This record has two fields, one of which is a dirty flag; the other is a position number indicating a child's position. The record has the following structure:

typedef WordFlags CompChildFlags;
#define CCF_MARK_DIRTY				0x8000 /* high bit */
#define CCF_REFERENCE				0x7FFF /* low 15 bits */
#define CCF_REFERENCE_OFFSET					0
 /* The CCF_REFERENCE field may have any integral
 * number or may be set to one of the following
 * constants:
 *	CCO_FIRST			first child's position
 *	CCO_LAST			last child's position */

The CompChildFlags fields are

CCF_MARK_DIRTY
If set, this flag indicates that the operation in progress should mark the affected objects dirty. Any objects marked dirty will be saved to the state file upon shutdown.
CCF_REFERENCE
This field consists of the lower 15 bits of the word and is a zero-based integer representing the position of the child in its parent's child list. This number cannot be greater than 32767 (0x7fff hex). If the number given is greater than the number of current children, the child will be assumed to be last. For example, a CCF_REFERENCE of four would specify the fifth child of the parent object, or the last child if there are fewer than five children currently. When specifying a position for CCF_REFERENCE, use the CCF_REFERENCE_OFFSET (using the shift operator).

CCO_FIRST and CCO_LAST specify either the first or last child of the parent, respectively. There is no need to use the CCF_REFERENCE_OFFSET in these cases.

MSG_GEN_ADD_CHILD

void	MSG_GEN_ADD_CHILD(
        optr		child,
        CompChildFlags		flags);

This message adds the passed object as a child of the recipient. The child object must not be GS_USABLE before being added to the generic tree. Make sure not to add a child that is already a child of some other parent. It is also illegal to add an object that is already a child of the parent. If necessary, check first if the specific child currently exists using MSG_GEN_FIND_CHILD .

In most cases a routine that adds a new child will follow three phases: checking whether the child exists, adding the child, and setting the child GS_USABLE.

The child object, if already specifically initialized, must be unbuilt before being added to the parent. This ensures that the object will be built out correctly. The internal keyboard search path attribute, GA_KBD_SEARCH_PATH, is also cleared and reset for the child.

Pass this message the optr of the child object to add, along with the CompChildFlags to use. If CCF_MARK_DIRTY is specified, the new linkage will be saved to state when the application is detached. You must pass a CCF_REFERENCE in CompChildFlags to specify the position to add the child. The special constants CCO_FIRST and CCO_LAST, which are special cases of CCF_REFERENCE, will add the object as the first or last child of the parent, respectively.

Note that the object must currently exist. MSG_GEN_ADD_CHILD merely sets up the correct linkage and reconfigures your UI. Note also that successive additions of children using the flag CCO_FIRST will result in a "reverse order" of children (the last added will be the first child, the first added will be the last).

Source: Unrestricted.

Destination: Any generic object.

Parameters: child The optr of the object to add to the current object's children. This child must not be usable.

flags
CompChildFlags to use when adding the child.

Interception: Generally not intercepted. Custom gadgets may intercept to supplement or supersede default functionality.

Code Display 2-20 ObjDuplicateResource() with MSG_GEN_ADD_CHILD

/* This method duplicates a pre-instantiated version of MyMenu.
 * A duplicated object block may also be added using MSG_GEN_ADD_CHILD.*/
@method MyProcessClass, MSG_DUPLICATE_MY_MENU {
    MemHandle newBlock;				/* The handle of the Duplicate block. */
    optr newMenu;				/* The optr of the new menu. */
    GeodeHandle procHan;				/* The geode handle of the process. */
    procHan = GeodeGetProcessHandle();
    newBlock = ObjDuplicateResource(OptrToHandle(@MyMenu), procHan, -1);
			/* Pass the handle of MyMenu's resource as well as the
			 * GeodeHandle of the process. Leave the burden thread 
			 * the same.*/
	/* The new optr is created from the newly created block. */
    newMenu = ConstructOptr(newBlock, OptrToChunk(MyMenu));
	/* Add the duplicated object tree (MyMenu) as the
	 * first child of MyPrimary. */
    @call @MyPrimary::MSG_GEN_ADD_CHILD(newMenu, (CCF_MARK_DIRTY | CCO_FIRST));
	/* Then set it usable. Remember, you cannot add a child
	 * that is already GS_USABLE. */
    @call @newMenu::MSG_GEN_SET_USABLE(VUM_NOW);
}

MSG_GEN_ADD_CHILD_UPWARD_LINK_ONLY

void	MSG_GEN_ADD_CHILD_UPWARD_LINK_ONLY(
        optr		child);

This message sets a parent link to a passed child object without adding a composite link from the parent to the child. This is a "one way" link in that the parent does not have knowledge of its new child. Therefore, it must be used with caution.

Source: Unrestricted.

Destination: Any generic object.

Parameters: child optr of the child to add with an upward link.

Interception: Generally not intercepted.

MSG_GEN_REMOVE

void 	MSG_GEN_REMOVE(
        VisUpdateMode 		updateMode,
        CompChildFlags 		flags) 

This message removes the receiving object from the generic tree. The object to be removed need not be set not usable. Note that all objects below this object will also be removed.

Source: Anyone.

Destination: Any generic object.

Parameters: updateMode Visual update mode. VUM_MANUAL is not allowed.

flags
Set CCF_MARK_DIRTY to mark links dirty.

Return: Nothing.

Interception: Generally not intercepted.

MSG_GEN_REMOVE_CHILD

void	MSG_GEN_REMOVE_CHILD(
        optr		child,
        CompChildFlags		flags);

This message removes the passed object from the recipient. A child must be marked not GS_USABLE in order to be removed. The child must currently exist, so your routine should check this using MSG_GEN_FIND_CHILD .

Pass this message the optr of the child object to be removed along with a word of CompChildFlags . If CCF_MARK_DIRTY is specified, the updated linkage will be saved to state when the application is detached.

Source: Unrestricted.

Destination: Any generic object.

Parameters: child The optr of child to remove. This child must be non-usable in order to be removed. The child must also exist as a child of the recipient.

flags
CompChildFlags to use when removing the child.

Interception: Generally not intercepted. Custom gadgets may intercept to supplement or supersede default functionality.

Code Display 2-21 MSG_GEN_REMOVE_CHILD

/* This sample method removes the MyChild object from its parent, MyParent. */
@method MyProcessClass, MSG_REMOVE_MY_CHILD {
	/* If the child currently exists, mark it not usable and remove it. */
    if (@call @MyParent::MSG_GEN_FIND_CHILD(@MyChild) != -1) {
	@call @MyChild::MSG_GEN_SET_NOT_USABLE(VUM_NOW);
	@call @MyParent::MSG_GEN_REMOVE_CHILD(@MyChild, CCF_MARK_DIRTY);
    }
}

MSG_GEN_MOVE_CHILD

void	MSG_GEN_MOVE_CHILD(
        optr		child,
        CompChildFlags		flags);

This message moves the given object from the location it currently occupies among its siblings to another location among its siblings. The object will still remain a child of the same parent.

Pass this message the optr of the child to move along with a word of CompChildFlags . If you pass the flag CCF_MARK_DIRTY, the new linkage will be saved to state when the application is detached. You must also pass a CCF_REFERENCE so the object will be moved to the position specified. CCO_FIRST and CCO_LAST will move the object to the first or last position, respectively.

If no flags are specified, the object will be moved to the parent object's first position without marking the linkages dirty. Note that for successive moves of children this will result in a "reverse order" of the children.

Note that this message only moves a child among its siblings. To move an object from one parent of the generic tree to another (different) parent, you must use MSG_GEN_REMOVE (or MSG_GEN_REMOVE_CHILD ) and MSG_GEN_ADD_CHILD .

Source: Unrestricted.

Destination: Any generic object.

Parameters: child The optr of the child to move.

flags
CompChildFlags to use when moving the child.

Interception: Generally not intercepted.


Up: GEOS SDK TechDocs | Up | Prev: 5.1 Child/Parent Searches | Next: 5.3 Branch Construction/Destruction