00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00032 #include <gtk/gtk.h>
00033
00034 #include <graphviz/gvplugin_device.h>
00035 #include <graphviz/gvplugin_render.h>
00036 #include <graphviz/gvplugin.h>
00037 #include <graphviz/gvc.h>
00038 #include <graphviz/gvplugin_layout.h>
00039 #include <graphviz/gvcjob.h>
00040 #include <graphviz/gvcommon.h>
00041 #include <graphviz/gvcext.h>
00042 #include <graphviz/types.h>
00043 #include <graphviz/graph.h>
00044 #include <graphviz/geom.h>
00045
00046 #include "callbacks.h"
00047
00048 #include <iostream>
00049
00050
00051 #include <mtt/tree.hh>
00052 #include <mtt/types_declaration.h>
00053
00054 #include <boost/format.hpp>
00055
00056 #include <mtt/graph_wrapper.h>
00057
00058 using namespace std;
00059 using namespace boost;
00060
00062 extern GVGraph*graph_context;
00063
00065 extern tree<t_nodePtr> global_tree;
00066
00067 extern "C" {
00068 extern int agrelabel_node(Agnode_t * n, char *newname);
00069 }
00070
00071 ostream& operator<< (ostream &o, const pointf &i)
00072 {
00073 return o<<i.x<<" "<<i.y;
00074 }
00075
00076 ostream& operator<< (ostream &o, const boxf &i)
00077 {
00078 return o<<"LL: "<<i.LL<<" UR: "<<i.UR;
00079 }
00080
00081 gboolean DrawingareaExposeEvent(GtkWidget*widget,GdkEventExpose*event,gpointer user_data)
00082 {
00083 GVJ_t *job = (GVJ_t *)g_object_get_data(G_OBJECT(widget),"job");
00084 cairo_t *cr = gdk_cairo_create(widget->window);
00085
00086 (job->callbacks->motion)(job, job->pointer);
00087
00088 job->context = (void *)cr;
00089 job->external_context = true;
00090 job->width = widget->allocation.width;
00091 job->height = widget->allocation.height;
00092
00093
00094
00095
00096 tree<t_nodePtr>::iterator parent;
00097
00098 if(global_tree.ready_from_draw==false || global_tree.need_layout==false)
00099 {
00100 (job->callbacks->refresh)(job);
00101 cairo_destroy(cr);
00102 return false;
00103 }
00104
00105
00106
00107 graph_context->clearNodes();
00108
00109
00110
00111
00112 for(tree<t_nodePtr>::iterator it = global_tree.begin(); it != global_tree.end(); ++it)
00113 {
00114
00115
00116
00117 graph_context->addNode((*it)->GetName());
00118
00119 switch((*it)->mode)
00120 {
00121 case t_node::NEW:
00122 graph_context->setNodeAttribute((*it)->GetName(),string("color"),string("blue"));
00123 break;
00124
00125 case t_node::MAIN:
00126 graph_context->setNodeAttribute((*it)->GetName(),string("color"),string("black"));
00127 break;
00128
00129 case t_node::FAILED:
00130 graph_context->setNodeAttribute((*it)->GetName(),string("color"),string("red"));
00131 break;
00132
00133 default:
00134 break;
00135 }
00136
00137 parent=global_tree.parent(it);
00138
00139 if(parent!=NULL)
00140 graph_context->addEdge((*parent)->GetName(),(*it)->GetName());
00141 }
00142
00143
00144
00145
00146 graph_context->applyLayout();
00147 global_tree.need_layout=false;
00148
00149 (job->callbacks->refresh)(job);
00150
00151 cairo_destroy(cr);
00152
00153 return FALSE;
00154 }
00155
00156 gboolean DrawingareaButtonPressEvent(GtkWidget*widget,GdkEventButton *event,gpointer user_data)
00157 {
00158 static bool init=true;
00159 static bool dragging=false;
00160
00161 if(init)
00162 {
00163 g_object_set_data(G_OBJECT(widget),"dragging",&dragging);
00164 init=false;
00165 }
00166
00167 if(event->type==GDK_BUTTON_PRESS)
00168 dragging=true;
00169 else if(event->type==GDK_BUTTON_RELEASE)
00170 dragging=false;
00171
00172 return true;
00173 }
00174
00175 gboolean DrawingareaMotionNotifyEvent(GtkWidget*widget,GdkEventMotion*event,gpointer user_data)
00176 {
00177 static bool first_drag=true;
00178
00179 GVJ_t *job = (GVJ_t *)g_object_get_data(G_OBJECT(widget),"job");
00180
00181 bool *dragging_p = (bool*)g_object_get_data(G_OBJECT(widget),"dragging");
00182 if(!dragging_p)
00183 return FALSE;
00184
00185 bool dragging=*dragging_p;
00186
00187 static pointf diff;
00188
00189 double dpix=-1/job->devscale.x;
00190 double dpiy=-1/job->devscale.y;
00191
00192 diff.x=event->x-job->pointer.x;
00193 diff.y=event->y-job->pointer.y;
00194
00195 job->pointer.x = event->x;
00196 job->pointer.y = event->y;
00197
00198 gtk_widget_queue_draw(widget);
00199
00200 if(dragging)
00201 {
00202 if(first_drag)
00203 {
00204 diff.x=0;
00205 diff.y=0;
00206 first_drag=false;
00207 }
00208
00209 job->focus.x+= diff.x*dpix/job->zoom;
00210 job->focus.y+= diff.y*dpiy/job->zoom;
00211
00212 double x_lim = (0.37*job->width-1)/job->zoom;
00213 double y_lim = (0.37*job->height-1)/job->zoom;
00214
00215
00216
00217
00218
00219
00220
00221
00222 if(job->focus.x>= x_lim)
00223 job->focus.x= x_lim;
00224
00225 if(job->focus.y>= y_lim)
00226 job->focus.y= y_lim;
00227 }
00228
00229 return true;
00230 }
00231
00232 gboolean DrawingareaScrollEvent(GtkWidget*widget,GdkEventScroll *event,gpointer user_data)
00233 {
00234 if(event->type==GDK_SCROLL)
00235 {
00236 GVJ_t *job = (GVJ_t *)g_object_get_data(G_OBJECT(widget),"job");
00237
00238 pointf pointer;
00239 pointer.x=event->x;
00240 pointer.y=event->y;
00241
00242 if(event->direction==GDK_SCROLL_UP)
00243 (job->callbacks->button_press)(job,4, pointer);
00244 else if(event->direction==GDK_SCROLL_DOWN)
00245 (job->callbacks->button_press)(job,5, pointer);
00246
00247 double x_lim = (0.37*job->width-1)/job->zoom;
00248 double y_lim = (0.37*job->height-1)/job->zoom;
00249
00250 if(job->focus.x>= x_lim)
00251 job->focus.x= x_lim;
00252
00253 if(job->focus.y>= y_lim)
00254 job->focus.y= y_lim;
00255 }
00256
00257 return true;
00258 }
00259
00260 gboolean WindowDeleteEvent(GtkWidget*widget,GdkEvent*event,gpointer user_data)
00261 {
00262 gtk_main_quit();
00263 return true;
00264 }
00265
00266 gboolean DrawingareaConfigureEvent(GtkWidget*widget,GdkEventConfigure*event,gpointer user_data)
00267 {
00268 GVJ_t *job;
00269 double zoom_to_fit;
00270
00271
00272
00273
00274
00275
00276
00277 job = (GVJ_t *)g_object_get_data(G_OBJECT(widget),"job");
00278
00279 if (! job->has_been_rendered)
00280 {
00281 zoom_to_fit = MIN((double) event->width / (double) job->width,(double) event->height / (double) job->height);
00282 if (zoom_to_fit < 1.0)
00283 job->zoom *= zoom_to_fit;
00284 }else if(job->fit_mode)
00285 {
00286 zoom_to_fit = MIN((double) event->width / (double) job->width, (double) event->height / (double) job->height);
00287 job->zoom *= zoom_to_fit;
00288 }
00289
00290 if ((unsigned int)event->width > job->width || (unsigned int)event->height > job->height)
00291 job->has_grown = TRUE;
00292
00293 job->width = event->width;
00294 job->height = event->height;
00295 job->needs_refresh = TRUE;
00296
00297 return FALSE;
00298 }