00001 /*-------------------------------------------------------------------- 00002 * vgraph.h 00003 * 00004 */ 00005 00006 #ifndef VGRAPH_H 00007 #define VGRAPH_H 00008 00009 #include "tcltk_calling_convention.h" 00010 #include "vwidget.h" 00011 #include <string.h> 00012 #include "common/suif_list.h" 00013 class binding; 00014 00015 #define NODE_TEXT_LEN 40 00016 00017 enum arrow_dir { 00018 ARROW_NONE = 0, 00019 ARROW_FORWARD, 00020 ARROW_BOTH 00021 }; 00022 00023 // layout methods 00024 #define LAYOUT_DEFAULT "default" 00025 #define LAYOUT_TREE "tree" 00026 #define LAYOUT_DOT "dot" 00027 00028 struct item_geom { 00029 int x1, y1; /* top left corner */ 00030 int x2, y2; /* bottom right corner */ 00031 }; 00032 00033 /* 00034 * gnode 00035 */ 00036 class gnode { 00037 private: 00038 friend class vgraph; 00039 00040 int canvas_id; 00041 char text[NODE_TEXT_LEN + 1]; 00042 00043 gnode(char *_text) { 00044 strncpy(text, _text, NODE_TEXT_LEN); 00045 text[NODE_TEXT_LEN] = '\0'; 00046 } 00047 00048 int x; /* for layout */ 00049 int y; 00050 00051 public: 00052 vnode *object; 00053 char *get_text(void) { return text; } 00054 00055 }; 00056 00057 /* 00058 * gedge 00059 */ 00060 class gedge { 00061 private: 00062 friend class vgraph; 00063 00064 int canvas_id; 00065 gnode *node1; 00066 gnode *node2; 00067 arrow_dir arrow; 00068 00069 gedge(gnode *_node1, gnode *_node2, arrow_dir _arrow) { 00070 node1 = _node1; 00071 node2 = _node2; 00072 arrow = _arrow; 00073 } 00074 public: 00075 vnode *object; 00076 gnode *get_node1(void) const { return node1; } 00077 gnode *get_node2(void) const { return node2; } 00078 arrow_dir get_arrow_dir(void) const { return arrow; } 00079 }; 00080 00081 //DECLARE_LIST_CLASS(gnode_list, gnode *); 00082 //typedef slist_tos<gnode*> gnode_list; 00083 //typedef slist_tos<gedge*> gedge_list; 00084 typedef list<gnode*> gnode_list; 00085 typedef list<gedge*> gedge_list; 00086 //DECLARE_LIST_CLASS(gedge_list, gedge *); 00087 00088 00089 /* 00090 * vgraph class 00091 * 00092 */ 00093 00094 class vgraph : public vwidget { 00095 00096 protected: 00097 gnode_list *nodes; 00098 gedge_list *edges; 00099 gnode *root_node; 00100 00101 binding *inv_binding; 00102 vnode *current_sel; 00103 00104 int current_layout; 00105 00106 void new_node_pos(int &x, int &y); 00107 void layout_graph(char *method_name); 00108 gnode *get_node(int canvas_id); 00109 void layout_dot(char *filename); 00110 00111 public: 00112 vgraph(vwidget *par); 00113 ~vgraph(void); 00114 void destroy(void); 00115 virtual int kind(void) { return WIDGET_GRAPH; } 00116 00117 void clear(void); 00118 00119 /* graph construction methods */ 00120 gnode *add_node(char *text, vnode *obj, 00121 int pos_x = -100, int pos_y = -100); 00122 gedge *add_edge(gnode *node1, gnode *node2, arrow_dir arrow, 00123 vnode *obj = 0); 00124 00125 gnode *get_root_node(void) { return root_node; } 00126 void set_root_node(gnode *node) { root_node = node; } 00127 00128 /* nodes, edges */ 00129 gnode *get_node(vnode *obj); 00130 gedge *get_edge(vnode *obj); 00131 00132 /* layout */ 00133 void layout(char *method_name = LAYOUT_DEFAULT); 00134 item_geom get_node_geometry(gnode *n); 00135 00136 void set_node_size(gnode *n, int width, int height, bool update_edges); 00137 void place_node(gnode *n, int x, int y, bool update_edges = true); 00138 void place_edge(gedge *e, int x1, int y1, int x2, int y2); 00139 void place_edge(gedge *e, int num_points, int *xarray, 00140 int *yarray); 00141 00142 /* bindings */ 00143 void set_binding(binding *b); 00144 void invoke(vnode *vn); 00145 00146 /* view */ 00147 void view(gnode *node); 00148 00149 /* selection */ 00150 virtual vnode *get_selection(void); 00151 void select(vnode *vn); 00152 void select_clear(void); 00153 00154 /* export */ 00155 void export_dot(FILE *fp); 00156 00157 /* interface with tcl/tk */ 00158 static int TCLTK_CALLING_CONVENTION vgraph_cmd(ClientData clientData, Tcl_Interp *interp, int argc, 00159 char *argv[]); 00160 00161 }; 00162 00163 #endif