drawing arc and background color
[lttv.git] / ltt / branches / poly / lttv / modules / guiControlFlow / Drawing.c
1
2 #include "Drawing.h"
3 #include "CFV.h"
4 #include <gtk/gtk.h>
5 #include <gdk/gdk.h>
6
7 #include <lttv/processTrace.h>
8
9
10 #define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
11 #define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
12
13
14 /*****************************************************************************
15 * Drawing functions *
16 *****************************************************************************/
17
18 //FIXME Colors will need to be dynamic. Graphic context part not done so far.
19 typedef enum
20 {
21 RED,
22 GREEN,
23 BLUE,
24 WHITE,
25 BLACK
26
27 } ControlFlowColors;
28
29 /* Vector of unallocated colors */
30 static GdkColor CF_Colors [] =
31 {
32 { 0, 0xffff, 0x0000, 0x0000 }, // RED
33 { 0, 0x0000, 0xffff, 0x0000 }, // GREEN
34 { 0, 0x0000, 0x0000, 0xffff }, // BLUE
35 { 0, 0xffff, 0xffff, 0xffff }, // WHITE
36 { 0, 0x0000, 0x0000, 0x0000 } // BLACK
37 };
38
39
40 //struct _Drawing_t {
41 // GtkWidget *Drawing_Area_V;
42 // GdkPixmap *Pixmap;
43 // ControlFlowData *Control_Flow_Data;
44
45 // gint height, width, depth;
46
47 //};
48
49 /* Function responsible for updating the exposed area.
50 * It must call processTrace() to ask for this update.
51 */
52 void drawing_data_request(Drawing_t *Drawing,
53 GdkPixmap **Pixmap,
54 gint x, gint y,
55 gint width,
56 gint height)
57 {
58 if(width < 0) return ;
59 if(height < 0) return ;
60
61 gdk_draw_rectangle (*Pixmap,
62 Drawing->Drawing_Area_V->style->white_gc,
63 TRUE,
64 x, y,
65 width, // do not overlap
66 height);
67
68 send_test_process(
69 guicontrolflow_get_process_list(Drawing->Control_Flow_Data),
70 Drawing);
71 send_test_drawing(
72 guicontrolflow_get_process_list(Drawing->Control_Flow_Data),
73 Drawing, *Pixmap, x, y, width, height);
74
75 }
76
77 /* Callbacks */
78
79
80 /* Create a new backing pixmap of the appropriate size */
81 static gboolean
82 configure_event( GtkWidget *widget, GdkEventConfigure *event,
83 gpointer user_data)
84 {
85 Drawing_t *Drawing = (Drawing_t*)user_data;
86
87 /* New Pixmap, size of the configure event */
88 GdkPixmap *Pixmap = gdk_pixmap_new(widget->window,
89 widget->allocation.width,
90 widget->allocation.height,
91 -1);
92
93 g_critical("drawing configure event");
94
95 /* If no old Pixmap present */
96 if(Drawing->Pixmap == NULL)
97 {
98 Drawing->Pixmap = gdk_pixmap_new(
99 widget->window,
100 widget->allocation.width,
101 widget->allocation.height,
102 //ProcessList_get_height
103 // (GuiControlFlow_get_Process_List(Drawing->Control_Flow_Data)),
104 -1);
105 Drawing->width = widget->allocation.width;
106 Drawing->height = widget->allocation.height;
107 g_critical("init data");
108 /* Initial data request */
109 drawing_data_request(Drawing, &Drawing->Pixmap, 0, 0,
110 widget->allocation.width,
111 widget->allocation.height);
112
113 }
114 // /* Draw empty background */
115 // gdk_draw_rectangle (Pixmap,
116 // widget->style->black_gc,
117 // TRUE,
118 // 0, 0,
119 // widget->allocation.width,
120 // widget->allocation.height);
121
122 /* Copy old data to new pixmap */
123 gdk_draw_drawable (Pixmap,
124 widget->style->white_gc,
125 Drawing->Pixmap,
126 0, 0,
127 0, 0,
128 -1, -1);
129
130 /* Request data for missing space */
131 g_critical("missing data");
132 drawing_data_request(Drawing, &Pixmap, Drawing->width, 0,
133 widget->allocation.width - Drawing->width,
134 widget->allocation.height);
135 drawing_data_request(Drawing, &Pixmap, 0, Drawing->height,
136 Drawing->width,
137 widget->allocation.height - Drawing->height);
138
139 // gdk_draw_rectangle (Pixmap,
140 // widget->style->white_gc,
141 // TRUE,
142 // Drawing->width, 0,
143 // widget->allocation.width -
144 // Drawing->width,
145 // widget->allocation.height);
146
147 // gdk_draw_rectangle (Pixmap,
148 // widget->style->white_gc,
149 // TRUE,
150 // 0, Drawing->height,
151 // Drawing->width, // do not overlap
152 // widget->allocation.height -
153 // Drawing->height);
154
155
156
157
158 if (Drawing->Pixmap)
159 gdk_pixmap_unref(Drawing->Pixmap);
160
161 Drawing->Pixmap = Pixmap;
162 Drawing->width = widget->allocation.width;
163 Drawing->height = widget->allocation.height;
164
165 return TRUE;
166 }
167
168
169 /* Redraw the screen from the backing pixmap */
170 static gboolean
171 expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
172 {
173 Drawing_t *Drawing = (Drawing_t*)user_data;
174 g_critical("drawing expose event");
175
176 gdk_draw_pixmap(widget->window,
177 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
178 Drawing->Pixmap,
179 event->area.x, event->area.y,
180 event->area.x, event->area.y,
181 event->area.width, event->area.height);
182
183 return FALSE;
184 }
185
186 Drawing_t *drawing_construct(ControlFlowData *Control_Flow_Data)
187 {
188 Drawing_t *Drawing = g_new(Drawing_t, 1);
189
190 Drawing->Drawing_Area_V = gtk_drawing_area_new ();
191 Drawing->Control_Flow_Data = Control_Flow_Data;
192
193 //gtk_widget_set_size_request(Drawing->Drawing_Area_V->window, 50, 50);
194 g_object_set_data_full(
195 G_OBJECT(Drawing->Drawing_Area_V),
196 "Link_Drawing_Data",
197 Drawing,
198 (GDestroyNotify)drawing_destroy);
199
200 //gtk_widget_modify_bg( Drawing->Drawing_Area_V,
201 // GTK_STATE_NORMAL,
202 // &CF_Colors[BLACK]);
203
204 //gdk_window_get_geometry(Drawing->Drawing_Area_V->window,
205 // NULL, NULL,
206 // &(Drawing->width),
207 // &(Drawing->height),
208 // -1);
209
210 //Drawing->Pixmap = gdk_pixmap_new(
211 // Drawing->Drawing_Area_V->window,
212 // Drawing->width,
213 // Drawing->height,
214 // Drawing->depth);
215
216 Drawing->Pixmap = NULL;
217
218 // Drawing->Pixmap = gdk_pixmap_new(Drawing->Drawing_Area_V->window,
219 // Drawing->Drawing_Area_V->allocation.width,
220 // Drawing->Drawing_Area_V->allocation.height,
221 // -1);
222
223 g_signal_connect (G_OBJECT(Drawing->Drawing_Area_V),
224 "configure_event",
225 G_CALLBACK (configure_event),
226 (gpointer)Drawing);
227
228 g_signal_connect (G_OBJECT(Drawing->Drawing_Area_V),
229 "expose_event",
230 G_CALLBACK (expose_event),
231 (gpointer)Drawing);
232
233 return Drawing;
234 }
235
236 void drawing_destroy(Drawing_t *Drawing)
237 {
238
239 // Do not unref here, Drawing_t destroyed by it's widget.
240 //g_object_unref( G_OBJECT(Drawing->Drawing_Area_V));
241
242 g_free(Drawing);
243 }
244
245 GtkWidget *drawing_get_widget(Drawing_t *Drawing)
246 {
247 return Drawing->Drawing_Area_V;
248 }
249
250 /* get_time_from_pixels
251 *
252 * Get the time interval from window time and pixels, and pixels requested.
253 */
254 void convert_pixels_to_time(
255 Drawing_t *Drawing,
256 guint x,
257 LttTime *window_time_begin,
258 LttTime *window_time_end,
259 LttTime *time)
260 {
261 LttTime window_time_interval;
262
263 window_time_interval = ltt_time_sub(*window_time_end,
264 *window_time_begin);
265 *time = ltt_time_mul(window_time_interval, (x/(float)Drawing->width));
266 *time = ltt_time_add(*window_time_begin, *time);
267 }
268
269
270
271 void convert_time_to_pixels(
272 LttTime window_time_begin,
273 LttTime window_time_end,
274 LttTime time,
275 Drawing_t *Drawing,
276 guint *x)
277 {
278 LttTime window_time_interval;
279 float interval_float, time_float;
280
281 window_time_interval = ltt_time_sub(window_time_end,window_time_begin);
282
283 time = ltt_time_sub(time, window_time_begin);
284
285 interval_float = ltt_time_to_double(window_time_interval);
286 time_float = ltt_time_to_double(time);
287
288 *x = (guint)(time_float/interval_float * Drawing->width);
289
290 }
291
292 void drawing_refresh ( Drawing_t *Drawing,
293 guint x, guint y,
294 guint width, guint height)
295 {
296 g_info("Drawing.c : drawing_refresh %u, %u, %u, %u", x, y, width, height);
297 GdkRectangle update_rect;
298
299 gdk_draw_drawable(
300 Drawing->Drawing_Area_V->window,
301 Drawing->Drawing_Area_V->
302 style->fg_gc[GTK_WIDGET_STATE (Drawing->Drawing_Area_V)],
303 GDK_DRAWABLE(Drawing->Pixmap),
304 x, y,
305 x, y,
306 width, height);
307
308 update_rect.x = 0 ;
309 update_rect.y = 0 ;
310 update_rect.width = Drawing->width;
311 update_rect.height = Drawing->height ;
312 gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);
313
314 }
315
316
317 void drawing_draw_line( Drawing_t *Drawing,
318 GdkPixmap *Pixmap,
319 guint x1, guint y1,
320 guint x2, guint y2,
321 GdkGC *GC)
322 {
323 gdk_draw_line (Pixmap,
324 GC,
325 x1, y1, x2, y2);
326 }
327
328
329
330
331 void drawing_resize(Drawing_t *Drawing, guint h, guint w)
332 {
333 Drawing->height = h ;
334 Drawing->width = w ;
335
336 gtk_widget_set_size_request ( Drawing->Drawing_Area_V,
337 Drawing->width,
338 Drawing->height);
339
340
341 }
342
343
344 /* Insert a square corresponding to a new process in the list */
345 /* Applies to whole Drawing->width */
346 void drawing_insert_square(Drawing_t *Drawing,
347 guint y,
348 guint height)
349 {
350 GdkRectangle update_rect;
351
352 /* Allocate a new pixmap with new height */
353 GdkPixmap *Pixmap = gdk_pixmap_new(Drawing->Drawing_Area_V->window,
354 Drawing->width,
355 Drawing->height + height,
356 -1);
357
358 /* Copy the high region */
359 gdk_draw_drawable (Pixmap,
360 Drawing->Drawing_Area_V->style->black_gc,
361 Drawing->Pixmap,
362 0, 0,
363 0, 0,
364 Drawing->width, y);
365
366
367
368
369 /* add an empty square */
370 gdk_draw_rectangle (Pixmap,
371 Drawing->Drawing_Area_V->style->black_gc,
372 TRUE,
373 0, y,
374 Drawing->width, // do not overlap
375 height);
376
377
378
379 /* copy the bottom of the region */
380 gdk_draw_drawable (Pixmap,
381 Drawing->Drawing_Area_V->style->black_gc,
382 Drawing->Pixmap,
383 0, y,
384 0, y + height,
385 Drawing->width, Drawing->height - y);
386
387
388
389
390 if (Drawing->Pixmap)
391 gdk_pixmap_unref(Drawing->Pixmap);
392
393 Drawing->Pixmap = Pixmap;
394
395 Drawing->height+=height;
396
397 /* Rectangle to update, from new Drawing dimensions */
398 update_rect.x = 0 ;
399 update_rect.y = y ;
400 update_rect.width = Drawing->width;
401 update_rect.height = Drawing->height - y ;
402 gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);
403 }
404
405
406 /* Remove a square corresponding to a removed process in the list */
407 void drawing_remove_square(Drawing_t *Drawing,
408 guint y,
409 guint height)
410 {
411 GdkRectangle update_rect;
412
413 /* Allocate a new pixmap with new height */
414 GdkPixmap *Pixmap = gdk_pixmap_new(
415 Drawing->Drawing_Area_V->window,
416 Drawing->width,
417 Drawing->height - height,
418 -1);
419
420 /* Copy the high region */
421 gdk_draw_drawable (Pixmap,
422 Drawing->Drawing_Area_V->style->black_gc,
423 Drawing->Pixmap,
424 0, 0,
425 0, 0,
426 Drawing->width, y);
427
428
429
430 /* Copy up the bottom of the region */
431 gdk_draw_drawable (Pixmap,
432 Drawing->Drawing_Area_V->style->black_gc,
433 Drawing->Pixmap,
434 0, y + height,
435 0, y,
436 Drawing->width, Drawing->height - y - height);
437
438
439 if (Drawing->Pixmap)
440 gdk_pixmap_unref(Drawing->Pixmap);
441
442 Drawing->Pixmap = Pixmap;
443
444 Drawing->height-=height;
445
446 /* Rectangle to update, from new Drawing dimensions */
447 update_rect.x = 0 ;
448 update_rect.y = y ;
449 update_rect.width = Drawing->width;
450 update_rect.height = Drawing->height - y ;
451 gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);
452 }
453
454
This page took 0.041916 seconds and 4 git commands to generate.