Panda3D

gtkStatsMonitor.cxx

00001 // Filename: gtkStatsMonitor.cxx
00002 // Created by:  drose (16Jan06)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "gtkStatsMonitor.h"
00016 #include "gtkStats.h"
00017 #include "gtkStatsServer.h"
00018 #include "gtkStatsStripChart.h"
00019 #include "gtkStatsChartMenu.h"
00020 #include "gtkStatsPianoRoll.h"
00021 #include "gtkStatsMenuId.h"
00022 #include "pStatGraph.h"
00023 #include "pStatCollectorDef.h"
00024 #include "indent.h"
00025 
00026 typedef void vc();
00027 
00028 GtkItemFactoryEntry GtkStatsMonitor::menu_entries[] = {
00029   { "/Options", NULL, NULL, 0, "<Branch>" },
00030   { "/Options/Units", NULL, NULL, 0, "<Branch>" },
00031   { "/Options/Units/ms", NULL, (vc *)&handle_menu_command, MI_time_ms, "<RadioItem>" },
00032   { "/Options/Units/Hz", NULL, (vc *)&handle_menu_command, MI_time_hz, "/Options/Units/ms" },
00033   { "/Speed", NULL, NULL, 0, "<Branch>" },
00034   { "/Speed/1", NULL, (vc *)&handle_menu_command, MI_speed_1, "<RadioItem>" },
00035   { "/Speed/2", NULL, (vc *)&handle_menu_command, MI_speed_2, "/Speed/1" },
00036   { "/Speed/3", NULL, (vc *)&handle_menu_command, MI_speed_3, "/Speed/1" },
00037   { "/Speed/6", NULL, (vc *)&handle_menu_command, MI_speed_6, "/Speed/1" },
00038   { "/Speed/12", NULL, (vc *)&handle_menu_command, MI_speed_12, "/Speed/1" },
00039   { "/Speed/sep", NULL, NULL, 0, "<Separator>" },
00040   { "/Speed/pause", NULL, (vc *)&handle_menu_command, MI_pause, "<CheckItem>" },
00041 };
00042 int GtkStatsMonitor::num_menu_entries = sizeof(menu_entries) / sizeof(GtkItemFactoryEntry);
00043 
00044 
00045 ////////////////////////////////////////////////////////////////////
00046 //     Function: GtkStatsMonitor::Constructor
00047 //       Access: Public
00048 //  Description:
00049 ////////////////////////////////////////////////////////////////////
00050 GtkStatsMonitor::
00051 GtkStatsMonitor(GtkStatsServer *server) : PStatMonitor(server) {
00052   _window = NULL;
00053   _item_factory = NULL;
00054 
00055   // These will be filled in later when the menu is created.
00056   _time_units = 0;
00057   _scroll_speed = 0.0;
00058   _pause = false;
00059 }
00060 
00061 ////////////////////////////////////////////////////////////////////
00062 //     Function: GtkStatsMonitor::Destructor
00063 //       Access: Public, Virtual
00064 //  Description:
00065 ////////////////////////////////////////////////////////////////////
00066 GtkStatsMonitor::
00067 ~GtkStatsMonitor() {
00068   shutdown();
00069 }
00070 
00071 ////////////////////////////////////////////////////////////////////
00072 //     Function: GtkStatsMonitor::get_monitor_name
00073 //       Access: Public, Virtual
00074 //  Description: Should be redefined to return a descriptive name for
00075 //               the type of PStatsMonitor this is.
00076 ////////////////////////////////////////////////////////////////////
00077 string GtkStatsMonitor::
00078 get_monitor_name() {
00079   return "GtkStats";
00080 }
00081 
00082 ////////////////////////////////////////////////////////////////////
00083 //     Function: GtkStatsMonitor::initialized
00084 //       Access: Public, Virtual
00085 //  Description: Called after the monitor has been fully set up.  At
00086 //               this time, it will have a valid _client_data pointer,
00087 //               and things like is_alive() and close() will be
00088 //               meaningful.  However, we may not yet know who we're
00089 //               connected to (is_client_known() may return false),
00090 //               and we may not know anything about the threads or
00091 //               collectors we're about to get data on.
00092 ////////////////////////////////////////////////////////////////////
00093 void GtkStatsMonitor::
00094 initialized() {
00095 }
00096 
00097 ////////////////////////////////////////////////////////////////////
00098 //     Function: GtkStatsMonitor::got_hello
00099 //       Access: Public, Virtual
00100 //  Description: Called when the "hello" message has been received
00101 //               from the client.  At this time, the client's hostname
00102 //               and program name will be known.
00103 ////////////////////////////////////////////////////////////////////
00104 void GtkStatsMonitor::
00105 got_hello() {
00106   create_window();
00107   open_strip_chart(0, 0, false);
00108 }
00109 
00110 ////////////////////////////////////////////////////////////////////
00111 //     Function: GtkStatsMonitor::got_bad_version
00112 //       Access: Public, Virtual
00113 //  Description: Like got_hello(), this is called when the "hello"
00114 //               message has been received from the client.  At this
00115 //               time, the client's hostname and program name will be
00116 //               known.  However, the client appears to be an
00117 //               incompatible version and the connection will be
00118 //               terminated; the monitor should issue a message to
00119 //               that effect.
00120 ////////////////////////////////////////////////////////////////////
00121 void GtkStatsMonitor::
00122 got_bad_version(int client_major, int client_minor,
00123                 int server_major, int server_minor) {
00124   ostringstream str;
00125   str << "Unable to honor connection attempt from " 
00126       << get_client_progname() << " on " << get_client_hostname() 
00127       << ": unsupported PStats version " 
00128       << client_major << "." << client_minor;
00129 
00130   if (server_minor == 0) {
00131     str << " (server understands version " << server_major
00132         << "." << server_minor << " only).";
00133   } else {
00134     str << " (server understands versions " << server_major
00135         << ".0 through " << server_major << "." << server_minor << ").";
00136   }
00137     
00138   string message = str.str();
00139   GtkWidget *dialog = 
00140     gtk_message_dialog_new(GTK_WINDOW(main_window),
00141          GTK_DIALOG_DESTROY_WITH_PARENT,
00142          GTK_MESSAGE_ERROR,
00143          GTK_BUTTONS_CLOSE,
00144          message.c_str());
00145   gtk_dialog_run(GTK_DIALOG(dialog));
00146   gtk_widget_destroy(dialog);
00147 }
00148 
00149 ////////////////////////////////////////////////////////////////////
00150 //     Function: GtkStatsMonitor::new_collector
00151 //       Access: Public, Virtual
00152 //  Description: Called whenever a new Collector definition is
00153 //               received from the client.  Generally, the client will
00154 //               send all of its collectors over shortly after
00155 //               connecting, but there's no guarantee that they will
00156 //               all be received before the first frames are received.
00157 //               The monitor should be prepared to accept new Collector
00158 //               definitions midstream.
00159 ////////////////////////////////////////////////////////////////////
00160 void GtkStatsMonitor::
00161 new_collector(int collector_index) {
00162   Graphs::iterator gi;
00163   for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
00164     GtkStatsGraph *graph = (*gi);
00165     graph->new_collector(collector_index);
00166   }
00167 
00168   // We might need to update our menus.
00169   ChartMenus::iterator mi;
00170   for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
00171     (*mi)->do_update();
00172   }
00173 }
00174 
00175 ////////////////////////////////////////////////////////////////////
00176 //     Function: GtkStatsMonitor::new_thread
00177 //       Access: Public, Virtual
00178 //  Description: Called whenever a new Thread definition is
00179 //               received from the client.  Generally, the client will
00180 //               send all of its threads over shortly after
00181 //               connecting, but there's no guarantee that they will
00182 //               all be received before the first frames are received.
00183 //               The monitor should be prepared to accept new Thread
00184 //               definitions midstream.
00185 ////////////////////////////////////////////////////////////////////
00186 void GtkStatsMonitor::
00187 new_thread(int thread_index) {
00188   GtkStatsChartMenu *chart_menu = new GtkStatsChartMenu(this, thread_index);
00189   GtkWidget *menu_bar = gtk_item_factory_get_widget(_item_factory, "<PStats>");
00190   chart_menu->add_to_menu_bar(menu_bar, _next_chart_index);
00191   ++_next_chart_index;
00192   _chart_menus.push_back(chart_menu);
00193 }
00194 
00195 ////////////////////////////////////////////////////////////////////
00196 //     Function: GtkStatsMonitor::new_data
00197 //       Access: Public, Virtual
00198 //  Description: Called as each frame's data is made available.  There
00199 //               is no guarantee the frames will arrive in order, or
00200 //               that all of them will arrive at all.  The monitor
00201 //               should be prepared to accept frames received
00202 //               out-of-order or missing.
00203 ////////////////////////////////////////////////////////////////////
00204 void GtkStatsMonitor::
00205 new_data(int thread_index, int frame_number) {
00206   Graphs::iterator gi;
00207   for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
00208     GtkStatsGraph *graph = (*gi);
00209     graph->new_data(thread_index, frame_number);
00210   }
00211 }
00212 
00213 
00214 ////////////////////////////////////////////////////////////////////
00215 //     Function: GtkStatsMonitor::lost_connection
00216 //       Access: Public, Virtual
00217 //  Description: Called whenever the connection to the client has been
00218 //               lost.  This is a permanent state change.  The monitor
00219 //               should update its display to represent this, and may
00220 //               choose to close down automatically.
00221 ////////////////////////////////////////////////////////////////////
00222 void GtkStatsMonitor::
00223 lost_connection() {
00224   nout << "Lost connection to " << get_client_hostname() << "\n";
00225 
00226   shutdown();
00227 }
00228 
00229 ////////////////////////////////////////////////////////////////////
00230 //     Function: GtkStatsMonitor::idle
00231 //       Access: Public, Virtual
00232 //  Description: If has_idle() returns true, this will be called
00233 //               periodically to allow the monitor to update its
00234 //               display or whatever it needs to do.
00235 ////////////////////////////////////////////////////////////////////
00236 void GtkStatsMonitor::
00237 idle() {
00238   // Check if any of our chart menus need updating.
00239   ChartMenus::iterator mi;
00240   for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
00241     (*mi)->check_update();
00242   }
00243 
00244   // Update the frame rate label from the main thread (thread 0).
00245   const PStatThreadData *thread_data = get_client_data()->get_thread_data(0);
00246   double frame_rate = thread_data->get_frame_rate();
00247   if (frame_rate != 0.0f) {
00248     char buffer[128];
00249     sprintf(buffer, "%0.1f ms / %0.1f Hz", 1000.0f / frame_rate, frame_rate);
00250 
00251     gtk_label_set_text(GTK_LABEL(_frame_rate_label), buffer);
00252   }
00253 }
00254 
00255 ////////////////////////////////////////////////////////////////////
00256 //     Function: GtkStatsMonitor::has_idle
00257 //       Access: Public, Virtual
00258 //  Description: Should be redefined to return true if you want to
00259 //               redefine idle() and expect it to be called.
00260 ////////////////////////////////////////////////////////////////////
00261 bool GtkStatsMonitor::
00262 has_idle() {
00263   return true;
00264 }
00265 
00266 ////////////////////////////////////////////////////////////////////
00267 //     Function: GtkStatsMonitor::user_guide_bars_changed
00268 //       Access: Public, Virtual
00269 //  Description: Called when the user guide bars have been changed.
00270 ////////////////////////////////////////////////////////////////////
00271 void GtkStatsMonitor::
00272 user_guide_bars_changed() {
00273   Graphs::iterator gi;
00274   for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
00275     GtkStatsGraph *graph = (*gi);
00276     graph->user_guide_bars_changed();
00277   }
00278 }
00279 
00280 ////////////////////////////////////////////////////////////////////
00281 //     Function: GtkStatsMonitor::get_window
00282 //       Access: Public
00283 //  Description: Returns the window handle to the monitor's window.
00284 ////////////////////////////////////////////////////////////////////
00285 GtkWidget *GtkStatsMonitor::
00286 get_window() const {
00287   return _window;
00288 }
00289 
00290 ////////////////////////////////////////////////////////////////////
00291 //     Function: GtkStatsMonitor::open_strip_chart
00292 //       Access: Public
00293 //  Description: Opens a new strip chart showing the indicated data.
00294 ////////////////////////////////////////////////////////////////////
00295 void GtkStatsMonitor::
00296 open_strip_chart(int thread_index, int collector_index, bool show_level) {
00297   GtkStatsStripChart *graph = 
00298     new GtkStatsStripChart(this, thread_index, collector_index, show_level);
00299   add_graph(graph);
00300 
00301   graph->set_time_units(_time_units);
00302   graph->set_scroll_speed(_scroll_speed);
00303   graph->set_pause(_pause);
00304 }
00305 
00306 ////////////////////////////////////////////////////////////////////
00307 //     Function: GtkStatsMonitor::open_piano_roll
00308 //       Access: Public
00309 //  Description: Opens a new piano roll showing the indicated data.
00310 ////////////////////////////////////////////////////////////////////
00311 void GtkStatsMonitor::
00312 open_piano_roll(int thread_index) {
00313   GtkStatsPianoRoll *graph = new GtkStatsPianoRoll(this, thread_index);
00314   add_graph(graph);
00315 
00316   graph->set_time_units(_time_units);
00317   graph->set_scroll_speed(_scroll_speed);
00318   graph->set_pause(_pause);
00319 }
00320 
00321 ////////////////////////////////////////////////////////////////////
00322 //     Function: GtkStatsMonitor::add_menu
00323 //       Access: Public
00324 //  Description: Adds a new MenuDef to the monitor, or returns an
00325 //               existing one if there is already one just like it.
00326 ////////////////////////////////////////////////////////////////////
00327 const GtkStatsMonitor::MenuDef *GtkStatsMonitor::
00328 add_menu(const MenuDef &menu_def) {
00329   pair<Menus::iterator, bool> result = _menus.insert(menu_def);
00330   Menus::iterator mi = result.first;
00331   const GtkStatsMonitor::MenuDef &new_menu_def = (*mi);
00332   if (result.second) {
00333     // A new MenuDef was inserted.
00334     ((GtkStatsMonitor::MenuDef &)new_menu_def)._monitor = this;
00335   }
00336   return &new_menu_def;
00337 }
00338 
00339 ////////////////////////////////////////////////////////////////////
00340 //     Function: GtkStatsMonitor::set_time_units
00341 //       Access: Public
00342 //  Description: Called when the user selects a new time units from
00343 //               the monitor pulldown menu, this should adjust the
00344 //               units for all graphs to the indicated mask if it is a
00345 //               time-based graph.
00346 ////////////////////////////////////////////////////////////////////
00347 void GtkStatsMonitor::
00348 set_time_units(int unit_mask) {
00349   _time_units = unit_mask;
00350 
00351   // First, change all of the open graphs appropriately.
00352   Graphs::iterator gi;
00353   for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
00354     GtkStatsGraph *graph = (*gi);
00355     graph->set_time_units(_time_units);
00356   }
00357 }
00358 
00359 ////////////////////////////////////////////////////////////////////
00360 //     Function: GtkStatsMonitor::set_scroll_speed
00361 //       Access: Public
00362 //  Description: Called when the user selects a new scroll speed from
00363 //               the monitor pulldown menu, this should adjust the
00364 //               speeds for all graphs to the indicated value.
00365 ////////////////////////////////////////////////////////////////////
00366 void GtkStatsMonitor::
00367 set_scroll_speed(double scroll_speed) {
00368   _scroll_speed = scroll_speed;
00369 
00370   // First, change all of the open graphs appropriately.
00371   Graphs::iterator gi;
00372   for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
00373     GtkStatsGraph *graph = (*gi);
00374     graph->set_scroll_speed(_scroll_speed);
00375   }
00376 }
00377 
00378 ////////////////////////////////////////////////////////////////////
00379 //     Function: GtkStatsMonitor::set_pause
00380 //       Access: Public
00381 //  Description: Called when the user selects a pause on or pause off
00382 //               option from the menu.
00383 ////////////////////////////////////////////////////////////////////
00384 void GtkStatsMonitor::
00385 set_pause(bool pause) {
00386   _pause = pause;
00387 
00388   // First, change all of the open graphs appropriately.
00389   Graphs::iterator gi;
00390   for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
00391     GtkStatsGraph *graph = (*gi);
00392     graph->set_pause(_pause);
00393   }
00394 }
00395 
00396 ////////////////////////////////////////////////////////////////////
00397 //     Function: GtkStatsMonitor::add_graph
00398 //       Access: Private
00399 //  Description: Adds the newly-created graph to the list of managed
00400 //               graphs.
00401 ////////////////////////////////////////////////////////////////////
00402 void GtkStatsMonitor::
00403 add_graph(GtkStatsGraph *graph) {
00404   _graphs.insert(graph);
00405 }
00406 
00407 ////////////////////////////////////////////////////////////////////
00408 //     Function: GtkStatsMonitor::remove_graph
00409 //       Access: Private
00410 //  Description: Deletes the indicated graph.
00411 ////////////////////////////////////////////////////////////////////
00412 void GtkStatsMonitor::
00413 remove_graph(GtkStatsGraph *graph) {
00414   Graphs::iterator gi = _graphs.find(graph);
00415   if (gi != _graphs.end()) {
00416     _graphs.erase(gi);
00417     delete graph;
00418   }
00419 }
00420 
00421 ////////////////////////////////////////////////////////////////////
00422 //     Function: GtkStatsMonitor::create_window
00423 //       Access: Private
00424 //  Description: Creates the window for this monitor.
00425 ////////////////////////////////////////////////////////////////////
00426 void GtkStatsMonitor::
00427 create_window() {
00428   if (_window != NULL) {
00429     return;
00430   }
00431 
00432   _window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
00433 
00434   g_signal_connect(G_OBJECT(_window), "delete_event",
00435        G_CALLBACK(window_delete_event), this);
00436   g_signal_connect(G_OBJECT(_window), "destroy",
00437        G_CALLBACK(window_destroy), this);
00438 
00439   _window_title = get_client_progname() + " on " + get_client_hostname();
00440   gtk_window_set_title(GTK_WINDOW(_window), _window_title.c_str());
00441 
00442   gtk_window_set_default_size(GTK_WINDOW(_window), 500, 360);
00443 
00444   // Set up the menu.
00445   GtkAccelGroup *accel_group = gtk_accel_group_new();
00446   _item_factory = 
00447     gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<PStats>", accel_group);
00448   gtk_item_factory_create_items(_item_factory, num_menu_entries, menu_entries,
00449         this);
00450   gtk_window_add_accel_group(GTK_WINDOW(_window), accel_group);
00451   GtkWidget *menu_bar = gtk_item_factory_get_widget(_item_factory, "<PStats>");
00452   _next_chart_index = 2;
00453 
00454   setup_frame_rate_label();
00455 
00456   ChartMenus::iterator mi;
00457   for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
00458     (*mi)->add_to_menu_bar(menu_bar, _next_chart_index);
00459     ++_next_chart_index;
00460   }
00461 
00462   // Pack the menu into the window.
00463   GtkWidget *main_vbox = gtk_vbox_new(FALSE, 1);
00464   gtk_container_add(GTK_CONTAINER(_window), main_vbox);
00465   gtk_box_pack_start(GTK_BOX(main_vbox), menu_bar, FALSE, TRUE, 0);
00466 
00467   gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item(_item_factory, "/Speed/3")),
00468          TRUE);
00469   set_scroll_speed(3);
00470 
00471   gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item(_item_factory, "/Options/Units/ms")),
00472          TRUE);
00473   set_time_units(PStatGraph::GBU_ms);
00474 
00475   gtk_widget_show_all(_window);  
00476   gtk_widget_show(_window);
00477 
00478   set_pause(false);
00479 }
00480 
00481 ////////////////////////////////////////////////////////////////////
00482 //     Function: GtkStatsMonitor::shutdown
00483 //       Access: Private
00484 //  Description: Closes all the graphs associated with this monitor.
00485 ////////////////////////////////////////////////////////////////////
00486 void GtkStatsMonitor::
00487 shutdown() {
00488   Graphs::iterator gi;
00489   for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
00490     delete (*gi);
00491   }
00492   _graphs.clear();
00493 
00494   ChartMenus::iterator mi;
00495   for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
00496     delete (*mi);
00497   }
00498   _chart_menus.clear();
00499 
00500   if (_window != NULL) {
00501     gtk_widget_destroy(_window);
00502     _window = NULL;
00503   }
00504 
00505 #ifdef DEVELOP_GTKSTATS
00506   // For GtkStats developers, exit when the first monitor closes.
00507   gtk_main_quit();
00508 #endif
00509 }
00510 
00511 ////////////////////////////////////////////////////////////////////
00512 //     Function: GtkStatsMonitor::window_delete_event
00513 //       Access: Private, Static
00514 //  Description: Callback when the window is closed by the user.
00515 ////////////////////////////////////////////////////////////////////
00516 gboolean GtkStatsMonitor::
00517 window_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) {
00518   // Returning FALSE to indicate we should destroy the window
00519   // when the user selects "close".
00520   return FALSE;
00521 }
00522 
00523 ////////////////////////////////////////////////////////////////////
00524 //     Function: GtkStatsMonitor::window_destroy
00525 //       Access: Private, Static
00526 //  Description: Callback when the window is destroyed by the system
00527 //               (or by delete_event).
00528 ////////////////////////////////////////////////////////////////////
00529 void GtkStatsMonitor::
00530 window_destroy(GtkWidget *widget, gpointer data) {
00531   GtkStatsMonitor *self = (GtkStatsMonitor *)data;
00532   self->close();
00533 }
00534 
00535 ////////////////////////////////////////////////////////////////////
00536 //     Function: GtkStatsMonitor::setup_frame_rate_label
00537 //       Access: Private
00538 //  Description: Creates the frame rate label on the right end of the
00539 //               menu bar.  This is used as a text label to display
00540 //               the main thread's frame rate to the user, although it
00541 //               is implemented as a right-justified toplevel menu
00542 //               item that doesn't open to anything.
00543 ////////////////////////////////////////////////////////////////////
00544 void GtkStatsMonitor::
00545 setup_frame_rate_label() {
00546   GtkWidget *menu_bar = gtk_item_factory_get_widget(_item_factory, "<PStats>");
00547 
00548   _frame_rate_menu_item = gtk_menu_item_new();
00549   _frame_rate_label = gtk_label_new("");
00550   gtk_container_add(GTK_CONTAINER(_frame_rate_menu_item), _frame_rate_label);
00551 
00552   gtk_widget_show(_frame_rate_menu_item);
00553   gtk_widget_show(_frame_rate_label);
00554   gtk_menu_item_right_justify(GTK_MENU_ITEM(_frame_rate_menu_item));
00555 
00556   gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), _frame_rate_menu_item);
00557 }
00558 
00559 ////////////////////////////////////////////////////////////////////
00560 //     Function: GtkStatsMonitor::handle_menu_command
00561 //       Access: Private, Static
00562 //  Description: 
00563 ////////////////////////////////////////////////////////////////////
00564 void GtkStatsMonitor::
00565 handle_menu_command(gpointer callback_data, guint menu_id, GtkWidget *widget) {
00566   GtkStatsMonitor *self = (GtkStatsMonitor *)callback_data;
00567   switch (menu_id) {
00568   case MI_none:
00569     break;
00570 
00571   case MI_time_ms:
00572     self->set_time_units(PStatGraph::GBU_ms);
00573     break;
00574 
00575   case MI_time_hz:
00576     self->set_time_units(PStatGraph::GBU_hz);
00577     break;
00578 
00579   case MI_speed_1:
00580     self->set_scroll_speed(1);
00581     break;
00582 
00583   case MI_speed_2:
00584     self->set_scroll_speed(2);
00585     break;
00586 
00587   case MI_speed_3:
00588     self->set_scroll_speed(3);
00589     break;
00590 
00591   case MI_speed_6:
00592     self->set_scroll_speed(6);
00593     break;
00594 
00595   case MI_speed_12:
00596     self->set_scroll_speed(12);
00597     break;
00598 
00599   case MI_pause:
00600     self->set_pause(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)));
00601     break;
00602   }
00603 }
 All Classes Functions Variables Enumerations