# # $Id: node.icn,v 1.3 2004/01/25 23:04:36 rparlett Exp $ # # This file is in the public domain. # # Author: Robert Parlett (parlett@dial.pipex.com) # package gui link graphics import lang import util $include "guih.icn" # # This class represents a node in a {Tree} object. # class Node : SetFields : Object( label, bmps, always_expandable_flag, depth, is_expanded_flag, subnodes, draw_line, parent_node ) # # Generate all the {Nodes} in this subtree, including this {Node}, # in preorder ordering. # method generate_all_preorder() suspend self | (!subnodes).generate_all_preorder() end # # Generate all the {Nodes} in this subtree, including this {Node}, # in postorder ordering. # method generate_all_postorder() suspend (!subnodes).generate_all_postorder() | self end # # Generate all the open {Nodes} in this subtree, including this {Node}, # in preorder ordering. # method generate_open_preorder() suspend self if \self.is_expanded_flag then suspend (!subnodes).generate_open_preorder() end # # Generate all open {Nodes} in this subtree, including this {Node}, # in postorder ordering. # method generate_open_postorder() if \self.is_expanded_flag then suspend (!subnodes).generate_open_postorder() suspend self end # # Expand all the {Nodes} below this node. # method expand() every n := generate_all_postorder() do if *n.subnodes > 0 then n.is_expanded_flag := 1 end # # Set the label for this node. # method set_label(x) return self.label := x end # # Return the label # method get_label() return self.label end # # Set the bitmaps for this node. The parameter should provide a list of 3 # bitmaps. The first is displayed if the {Node} is open and has subnodes, the # second is displayed if the {Node} is closed and has subnodes, and the third is # displayed if the node has no subnodes. # @param x A list of 3 bitmaps. # method set_bmps(x) return self.bmps := x end # # Add the given {Node} to this {Node}'s list of subnodes. # @param The {Node} to add. # method add(n) n.parent_node := self return put(subnodes, n) end # # Get the parent node, or fail if there is none. # method get_parent_node() return \self.parent_node end # # Get the child nodes # method get_children() return subnodes end # # This configures the {Node} so that it is always treated as though it has subnodes # for display purposes, event though it may in fact have no subnodes. # method set_always_expandable() return always_expandable_flag := 1 end # # This turns off the always_expandable feature (the default). # method clear_always_expandable() return always_expandable_flag := &null end # # Toggle the opened status of the {Node}. # method toggle_expanded() return is_expanded_flag := if /is_expanded_flag then 1 else &null end # # Succeed iff the node is opened # method is_expanded() return \is_expanded_flag end # # Clear all the subnodes # method clear_children() subnodes := [] end # # Delete the given {Node} from the subnodes. # method delete_node(n) every i := 1 to *self.subnodes do { if n === self.subnodes[i] then { delete(self.subnodes, i) return } } end method set_one(attr, val) case attr of { "label" : set_label(string_val(attr, val)) "always_expandable" : if test_flag(attr, val) then set_always_expandable() else clear_always_expandable() default : field_error("Unknown attribute " || attr) } end initially(a[]) subnodes := [] set_fields(a) end