00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "gtkStatsGraph.h"
00016 #include "gtkStatsMonitor.h"
00017 #include "gtkStatsLabelStack.h"
00018
00019 const GdkColor GtkStatsGraph::rgb_white = {
00020 0, 0xffff, 0xffff, 0xffff
00021 };
00022 const GdkColor GtkStatsGraph::rgb_light_gray = {
00023 0, 0x9a9a, 0x9a9a, 0x9a9a,
00024 };
00025 const GdkColor GtkStatsGraph::rgb_dark_gray = {
00026 0, 0x3333, 0x3333, 0x3333,
00027 };
00028 const GdkColor GtkStatsGraph::rgb_black = {
00029 0, 0x0000, 0x0000, 0x0000
00030 };
00031 const GdkColor GtkStatsGraph::rgb_user_guide_bar = {
00032 0, 0x8282, 0x9696, 0xffff
00033 };
00034
00035
00036
00037
00038
00039
00040 GtkStatsGraph::
00041 GtkStatsGraph(GtkStatsMonitor *monitor) :
00042 _monitor(monitor)
00043 {
00044 _parent_window = NULL;
00045 _window = NULL;
00046 _graph_window = NULL;
00047 _scale_area = NULL;
00048
00049 GtkWidget *parent_window = monitor->get_window();
00050
00051 GdkDisplay *display = gdk_drawable_get_display(parent_window->window);
00052 _hand_cursor = gdk_cursor_new_for_display(display, GDK_HAND2);
00053
00054 _pixmap = 0;
00055 _pixmap_gc = 0;
00056
00057 _pixmap_xsize = 0;
00058 _pixmap_ysize = 0;
00059
00060 _window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
00061
00062
00063
00064
00065
00066
00067 gtk_widget_add_events(_window,
00068 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
00069 GDK_POINTER_MOTION_MASK);
00070 g_signal_connect(G_OBJECT(_window), "delete_event",
00071 G_CALLBACK(window_delete_event), this);
00072 g_signal_connect(G_OBJECT(_window), "destroy",
00073 G_CALLBACK(window_destroy), this);
00074 g_signal_connect(G_OBJECT(_window), "button_press_event",
00075 G_CALLBACK(button_press_event_callback), this);
00076 g_signal_connect(G_OBJECT(_window), "button_release_event",
00077 G_CALLBACK(button_release_event_callback), this);
00078 g_signal_connect(G_OBJECT(_window), "motion_notify_event",
00079 G_CALLBACK(motion_notify_event_callback), this);
00080
00081 _graph_window = gtk_drawing_area_new();
00082 gtk_widget_add_events(_graph_window,
00083 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
00084 GDK_POINTER_MOTION_MASK);
00085 g_signal_connect(G_OBJECT(_graph_window), "expose_event",
00086 G_CALLBACK(graph_expose_callback), this);
00087 g_signal_connect(G_OBJECT(_graph_window), "configure_event",
00088 G_CALLBACK(configure_graph_callback), this);
00089 g_signal_connect(G_OBJECT(_graph_window), "button_press_event",
00090 G_CALLBACK(button_press_event_callback), this);
00091 g_signal_connect(G_OBJECT(_graph_window), "button_release_event",
00092 G_CALLBACK(button_release_event_callback), this);
00093 g_signal_connect(G_OBJECT(_graph_window), "motion_notify_event",
00094 G_CALLBACK(motion_notify_event_callback), this);
00095
00096
00097 GtkWidget *graph_frame = gtk_frame_new(NULL);
00098 gtk_frame_set_shadow_type(GTK_FRAME(graph_frame), GTK_SHADOW_IN);
00099 gtk_container_add(GTK_CONTAINER(graph_frame), _graph_window);
00100
00101
00102
00103 _graph_vbox = gtk_vbox_new(FALSE, 0);
00104 gtk_box_pack_end(GTK_BOX(_graph_vbox), graph_frame,
00105 TRUE, TRUE, 0);
00106
00107
00108
00109 _graph_hbox = gtk_hbox_new(FALSE, 0);
00110 gtk_box_pack_start(GTK_BOX(_graph_hbox), _graph_vbox,
00111 TRUE, TRUE, 0);
00112
00113
00114 _hpaned = gtk_hpaned_new();
00115 gtk_container_add(GTK_CONTAINER(_window), _hpaned);
00116 gtk_container_set_border_width(GTK_CONTAINER(_window), 8);
00117
00118 gtk_paned_pack1(GTK_PANED(_hpaned), _label_stack.get_widget(), TRUE, TRUE);
00119 gtk_paned_pack2(GTK_PANED(_hpaned), _graph_hbox, TRUE, TRUE);
00120
00121 _drag_mode = DM_none;
00122 _potential_drag_mode = DM_none;
00123 _drag_scale_start = 0.0f;
00124
00125 _pause = false;
00126 }
00127
00128
00129
00130
00131
00132
00133 GtkStatsGraph::
00134 ~GtkStatsGraph() {
00135 _monitor = (GtkStatsMonitor *)NULL;
00136 release_pixmap();
00137
00138 Brushes::iterator bi;
00139 for (bi = _brushes.begin(); bi != _brushes.end(); ++bi) {
00140 GdkGC *gc = (*bi).second;
00141 g_object_unref(gc);
00142 }
00143
00144 _label_stack.clear_labels();
00145
00146 if (_window != (GtkWidget *)NULL) {
00147 GtkWidget *window = _window;
00148 _window = NULL;
00149 gtk_widget_destroy(window);
00150 }
00151 }
00152
00153
00154
00155
00156
00157
00158
00159 void GtkStatsGraph::
00160 new_collector(int new_collector) {
00161 }
00162
00163
00164
00165
00166
00167
00168 void GtkStatsGraph::
00169 new_data(int thread_index, int frame_number) {
00170 }
00171
00172
00173
00174
00175
00176
00177 void GtkStatsGraph::
00178 force_redraw() {
00179 }
00180
00181
00182
00183
00184
00185
00186
00187 void GtkStatsGraph::
00188 changed_graph_size(int graph_xsize, int graph_ysize) {
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 void GtkStatsGraph::
00200 set_time_units(int unit_mask) {
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210 void GtkStatsGraph::
00211 set_scroll_speed(double scroll_speed) {
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221 void GtkStatsGraph::
00222 set_pause(bool pause) {
00223 _pause = pause;
00224 }
00225
00226
00227
00228
00229
00230
00231 void GtkStatsGraph::
00232 user_guide_bars_changed() {
00233 if (_scale_area != NULL) {
00234 gtk_widget_queue_draw(_scale_area);
00235 }
00236 gtk_widget_queue_draw(_graph_window);
00237 }
00238
00239
00240
00241
00242
00243
00244 void GtkStatsGraph::
00245 clicked_label(int collector_index) {
00246 }
00247
00248
00249
00250
00251
00252
00253
00254 void GtkStatsGraph::
00255 close() {
00256 _label_stack.clear_labels(false);
00257 if (_window != (GtkWidget *)NULL) {
00258 _window = NULL;
00259
00260 GtkStatsMonitor *monitor = _monitor;
00261 _monitor = (GtkStatsMonitor *)NULL;
00262 if (monitor != (GtkStatsMonitor *)NULL) {
00263 monitor->remove_graph(this);
00264 }
00265 }
00266 }
00267
00268
00269
00270
00271
00272
00273
00274 GdkGC *GtkStatsGraph::
00275 get_collector_gc(int collector_index) {
00276 Brushes::iterator bi;
00277 bi = _brushes.find(collector_index);
00278 if (bi != _brushes.end()) {
00279 return (*bi).second;
00280 }
00281
00282
00283 LRGBColor rgb = _monitor->get_collector_color(collector_index);
00284
00285 GdkColor c;
00286 c.red = (int)(rgb[0] * 65535.0f);
00287 c.green = (int)(rgb[1] * 65535.0f);
00288 c.blue = (int)(rgb[2] * 65535.0f);
00289 GdkGC *gc = gdk_gc_new(_pixmap);
00290
00291 gdk_gc_set_rgb_fg_color(gc, &c);
00292
00293 _brushes[collector_index] = gc;
00294 return gc;
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304 void GtkStatsGraph::
00305 additional_graph_window_paint() {
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 GtkStatsGraph::DragMode GtkStatsGraph::
00317 consider_drag_start(int graph_x, int graph_y) {
00318 return DM_none;
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328 void GtkStatsGraph::
00329 set_drag_mode(GtkStatsGraph::DragMode drag_mode) {
00330 _drag_mode = drag_mode;
00331 }
00332
00333
00334
00335
00336
00337
00338
00339 gboolean GtkStatsGraph::
00340 handle_button_press(GtkWidget *widget, int graph_x, int graph_y,
00341 bool double_click) {
00342 if (_potential_drag_mode != DM_none) {
00343 set_drag_mode(_potential_drag_mode);
00344 _drag_start_x = graph_x;
00345 _drag_start_y = graph_y;
00346
00347 }
00348 return TRUE;
00349 }
00350
00351
00352
00353
00354
00355
00356
00357 gboolean GtkStatsGraph::
00358 handle_button_release(GtkWidget *widget, int graph_x, int graph_y) {
00359 set_drag_mode(DM_none);
00360
00361
00362 return handle_motion(widget, graph_x, graph_y);
00363 }
00364
00365
00366
00367
00368
00369
00370
00371 gboolean GtkStatsGraph::
00372 handle_motion(GtkWidget *widget, int graph_x, int graph_y) {
00373 _potential_drag_mode = consider_drag_start(graph_x, graph_y);
00374
00375 if (_potential_drag_mode == DM_guide_bar ||
00376 _drag_mode == DM_guide_bar) {
00377 gdk_window_set_cursor(_window->window, _hand_cursor);
00378
00379 } else {
00380 gdk_window_set_cursor(_window->window, NULL);
00381 }
00382
00383 return TRUE;
00384 }
00385
00386
00387
00388
00389
00390
00391 void GtkStatsGraph::
00392 setup_pixmap(int xsize, int ysize) {
00393 release_pixmap();
00394
00395 _pixmap_xsize = max(xsize, 0);
00396 _pixmap_ysize = max(ysize, 0);
00397
00398 _pixmap = gdk_pixmap_new(_graph_window->window, _pixmap_xsize, _pixmap_ysize, -1);
00399
00400 _pixmap_gc = gdk_gc_new(_pixmap);
00401
00402
00403 gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_white);
00404 gdk_draw_rectangle(_pixmap, _pixmap_gc, TRUE, 0, 0,
00405 _pixmap_xsize, _pixmap_ysize);
00406 }
00407
00408
00409
00410
00411
00412
00413
00414 void GtkStatsGraph::
00415 release_pixmap() {
00416 if (_pixmap != NULL) {
00417 g_object_unref(_pixmap);
00418 g_object_unref(_pixmap_gc);
00419 }
00420 }
00421
00422
00423
00424
00425
00426
00427 gboolean GtkStatsGraph::
00428 window_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) {
00429
00430
00431 return FALSE;
00432 }
00433
00434
00435
00436
00437
00438
00439
00440 void GtkStatsGraph::
00441 window_destroy(GtkWidget *widget, gpointer data) {
00442 GtkStatsGraph *self = (GtkStatsGraph *)data;
00443 self->close();
00444 }
00445
00446
00447
00448
00449
00450
00451 gboolean GtkStatsGraph::
00452 graph_expose_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
00453 GtkStatsGraph *self = (GtkStatsGraph *)data;
00454
00455 if (self->_pixmap != NULL) {
00456 gdk_draw_drawable(self->_graph_window->window,
00457 self->_graph_window->style->fg_gc[0],
00458 self->_pixmap, 0, 0, 0, 0,
00459 self->_pixmap_xsize, self->_pixmap_ysize);
00460 }
00461
00462 self->additional_graph_window_paint();
00463
00464 return TRUE;
00465 }
00466
00467
00468
00469
00470
00471
00472 gboolean GtkStatsGraph::
00473 configure_graph_callback(GtkWidget *widget, GdkEventConfigure *event,
00474 gpointer data) {
00475 GtkStatsGraph *self = (GtkStatsGraph *)data;
00476
00477 self->changed_graph_size(event->width, event->height);
00478 self->setup_pixmap(event->width, event->height);
00479 self->force_redraw();
00480
00481 return TRUE;
00482 }
00483
00484
00485
00486
00487
00488
00489
00490 gboolean GtkStatsGraph::
00491 button_press_event_callback(GtkWidget *widget, GdkEventButton *event,
00492 gpointer data) {
00493 GtkStatsGraph *self = (GtkStatsGraph *)data;
00494 int graph_x, graph_y;
00495 gtk_widget_translate_coordinates(widget, self->_graph_window,
00496 (int)event->x, (int)event->y,
00497 &graph_x, &graph_y);
00498
00499 bool double_click = (event->type == GDK_2BUTTON_PRESS);
00500
00501 return self->handle_button_press(widget, graph_x, graph_y, double_click);
00502 }
00503
00504
00505
00506
00507
00508
00509
00510 gboolean GtkStatsGraph::
00511 button_release_event_callback(GtkWidget *widget, GdkEventButton *event,
00512 gpointer data) {
00513 GtkStatsGraph *self = (GtkStatsGraph *)data;
00514 int graph_x, graph_y;
00515 gtk_widget_translate_coordinates(widget, self->_graph_window,
00516 (int)event->x, (int)event->y,
00517 &graph_x, &graph_y);
00518
00519 return self->handle_button_release(widget, graph_x, graph_y);
00520 }
00521
00522
00523
00524
00525
00526
00527
00528 gboolean GtkStatsGraph::
00529 motion_notify_event_callback(GtkWidget *widget, GdkEventMotion *event,
00530 gpointer data) {
00531 GtkStatsGraph *self = (GtkStatsGraph *)data;
00532 int graph_x, graph_y;
00533 gtk_widget_translate_coordinates(widget, self->_graph_window,
00534 (int)event->x, (int)event->y,
00535 &graph_x, &graph_y);
00536
00537 return self->handle_motion(widget, graph_x, graph_y);
00538 }