aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-12-16 16:52:57 -0500
committerSteven Rostedt <rostedt@goodmis.org>2009-12-17 22:51:03 -0500
commit5e524c549b3e3b8bbe596dacd71d74e32990a666 (patch)
treeab1b63f96dad5a7bb19acae00b2a5e64ea9c67e2
parent97495e5a901ab993ff84998ad07ad23bd103c89a (diff)
trace-graph: Add zoom in and zoom out ability
To zoom in, just press the left mouse button and slide right, and release. To zoom out, press the left mouse button and slide left and release. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--trace-graph.c248
-rw-r--r--trace-graph.h20
2 files changed, 181 insertions, 87 deletions
diff --git a/trace-graph.c b/trace-graph.c
index 7b7fcda..c9574b6 100644
--- a/trace-graph.c
+++ b/trace-graph.c
@@ -35,6 +35,7 @@
35#define TRACE_WIDTH 800 35#define TRACE_WIDTH 800
36#define TRACE_HEIGHT 600 36#define TRACE_HEIGHT 600
37 37
38#define MAX_WIDTH 10000
38#define input_file "trace.dat" 39#define input_file "trace.dat"
39 40
40#define CPU_MIDDLE(cpu) (80 * (cpu) + 80) 41#define CPU_MIDDLE(cpu) (80 * (cpu) + 80)
@@ -75,17 +76,11 @@ expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
75 return FALSE; 76 return FALSE;
76} 77}
77 78
78static void start_line(GtkWidget *widget, gint x, gint y, gpointer data) 79static void
80draw_line(GtkWidget *widget, gdouble x, struct graph_info *ginfo)
79{ 81{
80 struct graph_info *ginfo = data; 82 gdk_draw_line(widget->window, widget->style->black_gc,
81 83 x, 0, x, widget->allocation.width);
82 ginfo->last_x = x;
83 ginfo->last_y = y;
84
85 ginfo->mov_w = 0;
86 ginfo->mov_h = 0;
87
88 printf("x=%d y=%d\n", x, y);
89} 84}
90 85
91static gboolean 86static gboolean
@@ -95,64 +90,28 @@ button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
95 90
96 printf("button = %d\n", event->button); 91 printf("button = %d\n", event->button);
97 92
98 if ((event->button == 1 || event->button == 3) && 93 if (event->button != 1)
99 ginfo->curr_pixmap != NULL) { 94 return TRUE;
100 if (event->button == 3)
101 ginfo->save = TRUE;
102 else
103 ginfo->save = FALSE;
104 95
105 ginfo->draw_line = TRUE; 96 ginfo->start_x = event->x;
106 start_line(widget, event->x, event->y, data); 97 ginfo->last_x = 0;
107 }
108 98
109 return TRUE; 99 draw_line(widget, event->x, ginfo);
110}
111 100
112static void normalize_xywh(gint *x, gint *y, gint *w, gint *h) 101 ginfo->line_active = TRUE;
113{
114 if (*w < 0) {
115 *x = *x + *w;
116 *w *= -1;
117 }
118 102
119 if (*h < 0) { 103 return TRUE;
120 *y = *y + *h;
121 *h *= -1;
122 }
123} 104}
124 105
125static void clear_last_line(GtkWidget *widget, struct graph_info *ginfo) 106static void clear_last_line(GtkWidget *widget, struct graph_info *ginfo)
126{ 107{
127 gint x, y, w, h; 108 gint x;
128 109
129 x = ginfo->last_x; 110 x = ginfo->last_x;
130 y = ginfo->last_y; 111 if (x)
131 112 x--;
132 w = ginfo->mov_w;
133 h = ginfo->mov_h;
134
135 normalize_xywh(&x, &y, &w, &h);
136
137 w++;
138 h++;
139
140 update_with_backend(ginfo, x, y, w, h);
141}
142
143static void
144draw_line(GtkWidget *widget, gdouble x, gdouble y, struct graph_info *ginfo)
145{
146 clear_last_line(widget, ginfo);
147
148 ginfo->mov_w = x - ginfo->last_x;
149 ginfo->mov_h = y - ginfo->last_y;
150 113
151 printf("draw %f %f\n", x, y); 114 update_with_backend(ginfo, x, 0, x+2, widget->allocation.height);
152
153 gdk_draw_line(widget->window, widget->style->black_gc,
154 ginfo->last_x, ginfo->last_y,
155 x, y);
156} 115}
157 116
158static void 117static void
@@ -409,8 +368,18 @@ motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
409 if (!ginfo->curr_pixmap) 368 if (!ginfo->curr_pixmap)
410 return TRUE; 369 return TRUE;
411 370
371 if (ginfo->line_active) {
372 if (ginfo->last_x)
373 clear_last_line(widget, ginfo);
374 ginfo->last_x = x;
375 draw_line(widget, ginfo->start_x, ginfo);
376 draw_line(widget, x, ginfo);
377 return TRUE;
378 }
379
412 if (ginfo->draw_line) { 380 if (ginfo->draw_line) {
413 draw_line(widget, x, y, ginfo); 381 ginfo->last_x = x;
382// draw_line(widget, x, y, ginfo);
414 return TRUE; 383 return TRUE;
415 } 384 }
416 385
@@ -423,13 +392,115 @@ motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
423 return TRUE; 392 return TRUE;
424} 393}
425 394
395static void zoom_in_window(struct graph_info *ginfo, gint start, gint end)
396{
397 gdouble view_width;
398 gdouble new_width;
399 gdouble curr_width;
400// unsigned long long start_time;
401// unsigned long long end_time;
402
403 g_assert(start < end);
404 g_assert(ginfo->vadj);
405
406 view_width = gtk_adjustment_get_page_size(ginfo->vadj);
407
408 new_width = end - start;
409
410 curr_width = ginfo->draw->allocation.width;
411
412 ginfo->vadj_value = (gdouble)start * view_width / new_width;
413
414 new_width = curr_width * (view_width / new_width);
415
416 printf("width=%d\n", ginfo->draw->allocation.width);
417 if (ginfo->vadj) {
418 printf("adj:%f-%f\n", gtk_adjustment_get_upper(ginfo->vadj),
419 gtk_adjustment_get_lower(ginfo->vadj));
420 } else
421 printf("no adjustment\n");
422
423 ginfo->draw_width = new_width;
424
425 if (ginfo->draw_width > MAX_WIDTH)
426 ginfo->draw_width = MAX_WIDTH;
427
428 if (ginfo->vadj_value > (ginfo->draw_width - view_width))
429 ginfo->vadj_value = ginfo->draw_width - view_width;
430
431 printf("new width=%d\n", ginfo->draw_width);
432 gtk_widget_set_size_request(ginfo->draw, ginfo->draw_width, ginfo->draw_height);
433
434 printf("set val %f\n", ginfo->vadj_value);
435}
436
437static void zoom_out_window(struct graph_info *ginfo, gint start, gint end)
438{
439 gdouble view_width;
440 gdouble new_width;
441 gdouble curr_width;
442 gdouble value;
443// unsigned long long start_time;
444// unsigned long long end_time;
445
446 g_assert(start > end);
447 g_assert(ginfo->vadj);
448
449 view_width = gtk_adjustment_get_page_size(ginfo->vadj);
450
451 new_width = start - end;
452
453 curr_width = ginfo->draw->allocation.width;
454
455 new_width = curr_width / (view_width / new_width);
456
457 printf("width=%d\n", ginfo->draw->allocation.width);
458 if (ginfo->vadj) {
459 printf("adj:%f-%f\n", gtk_adjustment_get_upper(ginfo->vadj),
460 gtk_adjustment_get_lower(ginfo->vadj));
461 } else
462 printf("no adjustment\n");
463
464 ginfo->draw_width = new_width;
465
466 if (ginfo->draw_width < view_width)
467 ginfo->draw_width = 0;
468
469 printf("new width=%d\n", ginfo->draw_width);
470 gtk_widget_set_size_request(ginfo->draw, ginfo->draw_width, ginfo->draw_height);
471
472 value = gtk_adjustment_get_value(ginfo->vadj);
473 if (value > new_width - view_width)
474 ginfo->vadj_value = new_width - view_width;
475}
476
426static gboolean 477static gboolean
427button_release_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) 478button_release_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
428{ 479{
429 struct graph_info *ginfo = data; 480 struct graph_info *ginfo = data;
430 481
482 if (ginfo->line_active) {
483 ginfo->line_active = FALSE;
484 clear_last_line(widget, ginfo);
485 ginfo->last_x = ginfo->start_x;
486 clear_last_line(widget, ginfo);
487
488 if (event->x > ginfo->start_x) {
489 /* make a decent zoom */
490 if (event->x - ginfo->start_x < 10)
491 return TRUE;
492 zoom_in_window(ginfo, ginfo->start_x, event->x);
493 return TRUE;
494 } else {
495 /* make a decent zoom */
496 if (ginfo->start_x - event->x < 10)
497 return TRUE;
498 zoom_out_window(ginfo, ginfo->start_x, event->x);
499 return TRUE;
500 }
501 }
502
431 printf("RELEASE %s\n", ginfo->save ? "save" : ""); 503 printf("RELEASE %s\n", ginfo->save ? "save" : "");
432 clear_last_line(widget, ginfo);
433 504
434 ginfo->draw_line = FALSE; 505 ginfo->draw_line = FALSE;
435 506
@@ -532,8 +603,7 @@ static void draw_timeline(struct graph_info *ginfo, gint width)
532 unsigned long long time; 603 unsigned long long time;
533 gint mid; 604 gint mid;
534 gint w, h, height; 605 gint w, h, height;
535 606 gint view_width;
536 mid = width / 2;
537 607
538 /* --- draw timeline text --- */ 608 /* --- draw timeline text --- */
539 609
@@ -542,6 +612,7 @@ static void draw_timeline(struct graph_info *ginfo, gint width)
542 612
543 height = 10 + h; 613 height = 10 + h;
544 614
615 mid = width / 2;
545 gdk_draw_layout(ginfo->curr_pixmap, ginfo->draw->style->black_gc, 616 gdk_draw_layout(ginfo->curr_pixmap, ginfo->draw->style->black_gc,
546 mid - w / 2, 5, layout); 617 mid - w / 2, 5, layout);
547 g_object_unref(layout); 618 g_object_unref(layout);
@@ -560,11 +631,6 @@ static void draw_timeline(struct graph_info *ginfo, gint width)
560 gdk_draw_line(ginfo->curr_pixmap, ginfo->draw->style->black_gc, 631 gdk_draw_line(ginfo->curr_pixmap, ginfo->draw->style->black_gc,
561 width-1, height, width-1, height + 5); 632 width-1, height, width-1, height + 5);
562 633
563 gdk_draw_line(ginfo->curr_pixmap, ginfo->draw->style->black_gc,
564 mid, height, mid, height + 5);
565
566 height += 10;
567
568 /* --- draw starting time --- */ 634 /* --- draw starting time --- */
569 convert_nano(ginfo->start_time, &sec, &usec); 635 convert_nano(ginfo->start_time, &sec, &usec);
570 trace_seq_init(&s); 636 trace_seq_init(&s);
@@ -574,7 +640,7 @@ static void draw_timeline(struct graph_info *ginfo, gint width)
574 pango_layout_get_pixel_size(layout, &w, &h); 640 pango_layout_get_pixel_size(layout, &w, &h);
575 641
576 gdk_draw_layout(ginfo->curr_pixmap, ginfo->draw->style->black_gc, 642 gdk_draw_layout(ginfo->curr_pixmap, ginfo->draw->style->black_gc,
577 1, height, layout); 643 1, height+10, layout);
578 g_object_unref(layout); 644 g_object_unref(layout);
579 645
580 646
@@ -587,22 +653,31 @@ static void draw_timeline(struct graph_info *ginfo, gint width)
587 pango_layout_get_pixel_size(layout, &w, &h); 653 pango_layout_get_pixel_size(layout, &w, &h);
588 654
589 gdk_draw_layout(ginfo->curr_pixmap, ginfo->draw->style->black_gc, 655 gdk_draw_layout(ginfo->curr_pixmap, ginfo->draw->style->black_gc,
590 width - (w + 2), height, layout); 656 width - (w + 2), height+10, layout);
591 g_object_unref(layout); 657 g_object_unref(layout);
592 658
593 /* --- draw middle time --- */
594 time = mid / ginfo->resolution + ginfo->view_start_time;
595 659
596 convert_nano(time, &sec, &usec); 660 /* --- draw time at intervals --- */
597 trace_seq_init(&s); 661 view_width = gtk_adjustment_get_page_size(ginfo->vadj);
598 trace_seq_printf(&s, "%lu.%06lu", sec, usec);
599 662
600 layout = gtk_widget_create_pango_layout(ginfo->draw, s.buffer); 663 for (mid = view_width / 2; mid < (width - view_width / 2 + 10);
601 pango_layout_get_pixel_size(layout, &w, &h); 664 mid += view_width / 2) {
665 time = mid / ginfo->resolution + ginfo->view_start_time;
602 666
603 gdk_draw_layout(ginfo->curr_pixmap, ginfo->draw->style->black_gc, 667 convert_nano(time, &sec, &usec);
604 mid - (w / 2), height, layout); 668 trace_seq_init(&s);
605 g_object_unref(layout); 669 trace_seq_printf(&s, "%lu.%06lu", sec, usec);
670
671 gdk_draw_line(ginfo->curr_pixmap, ginfo->draw->style->black_gc,
672 mid, height, mid, height + 5);
673
674 layout = gtk_widget_create_pango_layout(ginfo->draw, s.buffer);
675 pango_layout_get_pixel_size(layout, &w, &h);
676
677 gdk_draw_layout(ginfo->curr_pixmap, ginfo->draw->style->black_gc,
678 mid - (w / 2), height+10, layout);
679 g_object_unref(layout);
680 }
606} 681}
607 682
608static void draw_info(struct graph_info *ginfo, gint old_width, gint old_height, 683static void draw_info(struct graph_info *ginfo, gint old_width, gint old_height,
@@ -635,8 +710,7 @@ configure_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
635 old_w = ginfo->max_width; 710 old_w = ginfo->max_width;
636 old_h = ginfo->max_height; 711 old_h = ginfo->max_height;
637 712
638 713// gtk_widget_set_size_request(widget, 0, ginfo->draw_height);
639 gtk_widget_set_size_request(widget, 0, CPU_SPACE(ginfo->cpus));
640 714
641 715
642 if (widget->allocation.width > ginfo->max_width) 716 if (widget->allocation.width > ginfo->max_width)
@@ -675,6 +749,13 @@ configure_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
675 g_object_unref(old_pix); 749 g_object_unref(old_pix);
676 } 750 }
677 751
752 if (!ginfo->vadj_value)
753 return TRUE;
754
755 gtk_adjustment_set_value(ginfo->vadj, ginfo->vadj_value);
756 ginfo->vadj_value = gtk_adjustment_get_value(ginfo->vadj);
757 printf("get val %f\n", ginfo->vadj_value);
758 ginfo->vadj_value = 0.0;
678 759
679 return TRUE; 760 return TRUE;
680} 761}
@@ -692,7 +773,7 @@ destroy_event(GtkWidget *widget, gpointer data)
692 773
693 774
694static GtkWidget * 775static GtkWidget *
695create_drawing_area(struct tracecmd_input *handle) 776create_drawing_area(struct tracecmd_input *handle, GtkScrolledWindow *scrollwin)
696{ 777{
697 struct graph_info *ginfo; 778 struct graph_info *ginfo;
698 unsigned long sec, usec; 779 unsigned long sec, usec;
@@ -709,6 +790,9 @@ create_drawing_area(struct tracecmd_input *handle)
709 ginfo->start_time = -1ULL; 790 ginfo->start_time = -1ULL;
710 ginfo->end_time = 0; 791 ginfo->end_time = 0;
711 792
793 ginfo->draw_height = CPU_SPACE(ginfo->cpus);
794 ginfo->vadj = gtk_scrolled_window_get_hadjustment(scrollwin);
795
712 for (cpu = 0; cpu < ginfo->cpus; cpu++) { 796 for (cpu = 0; cpu < ginfo->cpus; cpu++) {
713 struct record *record; 797 struct record *record;
714 798
@@ -865,7 +949,7 @@ void trace_graph(int argc, char **argv)
865 949
866 /* --- Set up Drawing --- */ 950 /* --- Set up Drawing --- */
867 951
868 draw = create_drawing_area(handle); 952 draw = create_drawing_area(handle, GTK_SCROLLED_WINDOW(scrollwin));
869 953
870 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollwin), 954 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollwin),
871 draw); 955 draw);
diff --git a/trace-graph.h b/trace-graph.h
index 18426e6..e45b37a 100644
--- a/trace-graph.h
+++ b/trace-graph.h
@@ -10,6 +10,7 @@ struct graph_info {
10 GtkWidget *draw; 10 GtkWidget *draw;
11 GdkPixmap *main_pixmap; 11 GdkPixmap *main_pixmap;
12 GdkPixmap *curr_pixmap; 12 GdkPixmap *curr_pixmap;
13 GtkAdjustment *vadj;
13 guint64 start_time; 14 guint64 start_time;
14 guint64 end_time; 15 guint64 end_time;
15 guint64 view_start_time; 16 guint64 view_start_time;
@@ -17,7 +18,21 @@ struct graph_info {
17 18
18 gdouble resolution; 19 gdouble resolution;
19 20
21 gint start_x;
20 gint last_x; 22 gint last_x;
23 gboolean line_active;
24 gdouble vadj_value;
25
26 gint draw_width;
27 gint draw_height;
28
29 gint cpu_data_x;
30 gint cpu_data_y;
31 gint cpu_data_w;
32 gint cpu_data_h;
33
34 /* not needed in future */
35
21 gint last_y; 36 gint last_y;
22 gint mov_w; 37 gint mov_w;
23 gint mov_h; 38 gint mov_h;
@@ -28,11 +43,6 @@ struct graph_info {
28 gboolean save; 43 gboolean save;
29 gboolean draw_line; 44 gboolean draw_line;
30 gchar *test; 45 gchar *test;
31
32 gint cpu_data_x;
33 gint cpu_data_y;
34 gint cpu_data_w;
35 gint cpu_data_h;
36}; 46};
37 47
38#endif /* _TRACE_GRAPH_H */ 48#endif /* _TRACE_GRAPH_H */