00001 #ifndef vgui_parent_child_link_h_ 00002 #define vgui_parent_child_link_h_ 00003 //: 00004 // \file 00005 // \brief Describes the relationship between a parent and child tableau. 00006 // \author fsm 00007 // 00008 // Contains class vgui_parent_child_link 00009 // 00010 // \verbatim 00011 // Modifications 00012 // 17-Sep-2002 K.Y.McGaul - Added doxygen style comments. 00013 // \endverbatim 00014 00015 #include <vcl_iosfwd.h> 00016 #include <vcl_vector.h> 00017 00018 class vgui_event; 00019 class vgui_tableau; 00020 struct vgui_tableau_sptr; 00021 struct vgui_parent_child_link_impl; // implementation class. 00022 00023 //: Describes the relationship between a parent and child tableau. 00024 // 00025 // Q: what is a vgui_parent_child_link? 00026 // A: These are essentially specialized smart pointers. A parent_child_link 00027 // refers to an edge in the tableau [di]graph. A tableau acquires 00028 // a child by creating a parent_child_link with itself as parent and the child 00029 // as, er, child. The parent_child_links are responsible for storing this 00030 // relation behind the scenes so that it can be queried and used for, say, 00031 // propagating redraw requests. 00032 // 00033 // Semantics: 00034 // Assigning a parent_child_link to a parent_child_link 00035 // \code 00036 // lhs = rhs; 00037 // \endcode 00038 // doesn't change the graph, only the lhs which no longer refers 00039 // to the edge it used to refer to. 00040 // Calling set_child(t) on a parent_child_link changes the graph (the given 00041 // tableau *t becomes the new child of the parent_child_link). 00042 // E.g.: 00043 // \code 00044 // vgui_parent_child_link left (this,child); 00045 // vgui_parent_child_link right(this,child); 00046 // bool v = (left == right); // this is false 00047 // \endcode 00048 // or : 00049 // \code 00050 // vgui_parent_child_link e(this,child); 00051 // vgui_parent_child_link f=e; 00052 // bool v = (e == f); // this is true 00053 // \endcode 00054 // 00055 // You can use a parent_child_link much like a pointer to tableaux. It 00056 // will behave like the child of the parent_child_link : 00057 // \code 00058 // left->handle(e); // same as left.child()->handle(e); 00059 // right->method(); // same as right.child()->method(); 00060 // \endcode 00061 // In particular, you may put your parent_child_links into vectors, trees, 00062 // stacks etc if that is useful for your purposes. Repeat : 00063 // copying a parent_child_link does not create a new edge in the graph, only 00064 // another handle to the same edge. 00065 // 00066 // Attempting to create a non-empty parent_child_link whose parent and child 00067 // are the same tableau causes an abort(). 00068 struct vgui_parent_child_link 00069 { 00070 private: 00071 VCL_SAFE_BOOL_DEFINE; 00072 public: 00073 //: Constructor - creates a default vgui_parent_child_link. 00074 vgui_parent_child_link() : pimpl(0) {} 00075 00076 //: Constructor - creates a vgui_parent_child_link same as the given one. 00077 vgui_parent_child_link(vgui_parent_child_link const &); 00078 00079 //: Constructor - takes the parent tableau. 00080 // The 'parent' parameter is the self pointer ('this') of the tableau 00081 // which intends to hold the parent_child_link. It may \e not be a null 00082 // pointer. 00083 // To make an uninitialized parent_child_link, use the default constructor. 00084 vgui_parent_child_link(vgui_tableau * parent /* child is zero */); 00085 00086 //: Constructor - takes the parent and child tableaux. 00087 // The 'parent' parameter is the self pointer ('this') of the tableau 00088 // which intends to hold the parent_child_link. It may \e not be a null 00089 // pointer. 00090 // To make an uninitialized parent_child_link, use the default constructor. 00091 vgui_parent_child_link(vgui_tableau * parent, vgui_tableau_sptr const &child); 00092 00093 //: Destructor - delete this parent_child_link. 00094 ~vgui_parent_child_link(); 00095 00096 //: Make this parent_child_link equal to the given one. 00097 vgui_parent_child_link &operator=(vgui_parent_child_link const &); 00098 00099 //: Returns true if this parent_child_link is the same as the given link. 00100 // Links are equal if they have the same implementation. Merely having 00101 // the same parent and child does not imply equality. 00102 bool operator==(vgui_parent_child_link const &s) const { return pimpl == s.pimpl; } 00103 00104 //: Comparing a parent_child_link with a tableau compares the child. 00105 bool operator==(vgui_tableau_sptr const &t) const; 00106 00107 //: Returns the parent tableau for this parent_child_link. 00108 vgui_tableau_sptr parent() const; 00109 00110 //: Returns the child tableau for this parent_child_link. 00111 vgui_tableau_sptr child () const; 00112 00113 //: Return true if both parent and child tableaux exist. 00114 operator safe_bool () const; 00115 00116 //: Return false if both parent and child tableaux exist. 00117 bool operator!() const; 00118 00119 //: Return a pointer to the child tableau. 00120 // A parent_child_link behaves more like its child than its parent. 00121 operator vgui_tableau_sptr () const; 00122 00123 //: Return a pointer to the child tableau. 00124 // A parent_child_link behaves more like its child than its parent. 00125 vgui_tableau *operator -> () const; 00126 00127 //: Let the child tableau handle the event. 00128 // A parent_child_link behaves more like its child than its parent. 00129 bool handle(vgui_event const &e); 00130 00131 //: Make the given tableau the child tableau in this relationship. 00132 // A parent_child_link's parent pointer cannot be changed because there is no 00133 // legitimate use for that. 00134 // Attempting to set the child to be the same tableau as the parent will 00135 // cause an abort(). 00136 void assign(vgui_tableau_sptr const &); // sets child only 00137 00138 // ---------- statics ---------- 00139 00140 //: Push all children of 'tab' onto the vector. 00141 static void get_children_of(vgui_tableau_sptr const &tab, 00142 vcl_vector<vgui_tableau_sptr> *); 00143 00144 //: Push all parents of 'tab' onto the vector. 00145 static void get_parents_of (vgui_tableau_sptr const &tab, 00146 vcl_vector<vgui_tableau_sptr> *); 00147 00148 //: In all parent_child_links, replace old_child with new_child. 00149 static void replace_child_everywhere (vgui_tableau_sptr const &old_child, 00150 vgui_tableau_sptr const &new_child); 00151 00152 private: 00153 friend class vgui_tableau; 00154 // Pointer to implementation 00155 vgui_parent_child_link_impl *pimpl; 00156 }; 00157 00158 vcl_ostream & operator<<(vcl_ostream &, vgui_parent_child_link const &); 00159 00160 #endif // vgui_parent_child_link_h_