00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "gtkStatsStripWindow.h"
00020 #include "gtkStatsStripChart.h"
00021 #include "gtkStatsGuide.h"
00022
00023 #include <pStatCollectorDef.h>
00024 #include <string_utils.h>
00025
00026 #include <stdio.h>
00027
00028
00029 using Gtk::Menu_Helpers::MenuElem;
00030 using Gtk::Menu_Helpers::SeparatorElem;
00031
00032
00033
00034
00035
00036
00037 GtkStatsStripWindow::
00038 GtkStatsStripWindow(GtkStatsMonitor *monitor, int thread_index,
00039 int collector_index, bool show_level,
00040 int chart_xsize, int chart_ysize) :
00041 GtkStatsWindow(monitor),
00042 _thread_index(thread_index),
00043 _collector_index(collector_index),
00044 _show_level(show_level)
00045 {
00046 _title_unknown = false;
00047 _setup_scale_menu = false;
00048
00049 setup_menu();
00050 layout_window(chart_xsize, chart_ysize);
00051
00052 new_collector();
00053 show();
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 void GtkStatsStripWindow::
00065 mark_dead() {
00066 GtkStatsWindow::mark_dead();
00067 _chart->mark_dead();
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 void GtkStatsStripWindow::
00080 new_collector() {
00081 const PStatClientData *client_data = _monitor->get_client_data();
00082
00083
00084
00085
00086 pset<int> levels;
00087
00088 int num_collectors = client_data->get_num_collectors();
00089 for (int i = 0; i < num_collectors; i++) {
00090 if (client_data->has_collector(i) &&
00091 client_data->get_collector_has_level(i)) {
00092
00093
00094 int collector_index = i;
00095 const PStatCollectorDef &def =
00096 client_data->get_collector_def(collector_index);
00097 int parent_index = def._parent_index;
00098
00099 while (parent_index != 0) {
00100 collector_index = parent_index;
00101 const PStatCollectorDef &def =
00102 client_data->get_collector_def(collector_index);
00103 parent_index = def._parent_index;
00104 }
00105
00106 levels.insert(collector_index);
00107 }
00108 }
00109
00110
00111 _levels_menu->items().clear();
00112 pset<int>::const_iterator li;
00113 for (li = levels.begin(); li != levels.end(); ++li) {
00114 int collector_index = (*li);
00115 _levels_menu->items().push_back
00116 (MenuElem(client_data->get_collector_name(collector_index),
00117 bind(slot(this, &GtkStatsStripWindow::menu_show_levels), collector_index)));
00118 }
00119
00120
00121 setup_scale_menu();
00122 }
00123
00124
00125
00126
00127
00128
00129 void GtkStatsStripWindow::
00130 idle() {
00131 GtkStatsWindow::idle();
00132 _chart->update();
00133
00134 const PStatThreadData *thread_data = _chart->get_view().get_thread_data();
00135 if (!thread_data->is_empty()) {
00136 float frame_rate = thread_data->get_frame_rate();
00137 char buffer[128];
00138 sprintf(buffer, "Frame rate: %0.1f Hz", frame_rate);
00139 _frame_rate_label->set_text(buffer);
00140 }
00141
00142 if (_title_unknown) {
00143 _title_label->set_text(get_title_text());
00144 }
00145 }
00146
00147
00148
00149
00150
00151
00152 void GtkStatsStripWindow::
00153 setup_menu() {
00154 GtkStatsWindow::setup_menu();
00155
00156 Gtk::Menu *speed_menu = new Gtk::Menu;
00157
00158 speed_menu->items().push_back
00159 (MenuElem("1",
00160 bind(slot(this, &GtkStatsStripWindow::menu_hscale), 1.0f)));
00161 speed_menu->items().push_back
00162 (MenuElem("2",
00163 bind(slot(this, &GtkStatsStripWindow::menu_hscale), 2.0f)));
00164 speed_menu->items().push_back
00165 (MenuElem("3",
00166 bind(slot(this, &GtkStatsStripWindow::menu_hscale), 3.0f)));
00167 speed_menu->items().push_back
00168 (MenuElem("6",
00169 bind(slot(this, &GtkStatsStripWindow::menu_hscale), 6.0f)));
00170 speed_menu->items().push_back
00171 (MenuElem("12",
00172 bind(slot(this, &GtkStatsStripWindow::menu_hscale), 12.0f)));
00173
00174 _menu->items().push_back(MenuElem("Speed", *manage(speed_menu)));
00175
00176
00177 _scale_menu = new Gtk::Menu;
00178 _scale_menu->items().push_back
00179 (MenuElem("Auto scale",
00180 slot(this, &GtkStatsStripWindow::menu_auto_vscale)));
00181
00182 _menu->items().push_back(MenuElem("Scale", *manage(_scale_menu)));
00183
00184 _levels_menu = new Gtk::Menu;
00185 _menu->items().push_back(MenuElem("Levels", *manage(_levels_menu)));
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 void GtkStatsStripWindow::
00197 setup_scale_menu() {
00198 if (_setup_scale_menu) {
00199
00200 return;
00201 }
00202
00203 const PStatClientData *client_data = _monitor->get_client_data();
00204 if (!client_data->has_collector(_collector_index)) {
00205
00206 return;
00207 }
00208
00209 const PStatCollectorDef &def = client_data->get_collector_def(_collector_index);
00210 float base_scale = 1.0;
00211 string unit_name = def._level_units;
00212
00213 if (_show_level) {
00214 _chart->set_guide_bar_unit_name(unit_name);
00215 _chart->set_guide_bar_units(PStatGraph::GBU_named);
00216
00217 } else {
00218 _chart->set_guide_bar_units(PStatGraph::GBU_ms);
00219 }
00220
00221 if (def._suggested_scale != 0.0) {
00222 base_scale = def._suggested_scale;
00223 } else if (!_show_level) {
00224 base_scale = 1.0 / _chart->get_target_frame_rate();
00225 }
00226
00227 static const float scales[] = {
00228 50.0,
00229 10.0,
00230 5.0,
00231 2.0,
00232 1.0,
00233 0.5,
00234 0.2,
00235 0.1,
00236 0.02,
00237 };
00238 static const int num_scales = sizeof(scales) / sizeof(float);
00239
00240 for (int i = 0; i < num_scales; i++) {
00241 float scale = base_scale * scales[i];
00242 string label;
00243
00244 if (_show_level) {
00245 label = _chart->format_number(scale, PStatGraph::GBU_named | PStatGraph::GBU_show_units, unit_name);
00246 } else {
00247 label = _chart->format_number(scale, PStatGraph::GBU_ms | PStatGraph::GBU_hz | PStatGraph::GBU_show_units);
00248 }
00249
00250 _scale_menu->items().push_back
00251 (MenuElem(label,
00252 bind(slot(this, &GtkStatsStripWindow::menu_vscale), scale)));
00253 }
00254
00255 _setup_scale_menu = true;
00256 }
00257
00258
00259
00260
00261
00262
00263 void GtkStatsStripWindow::
00264 menu_new_window() {
00265 new GtkStatsStripWindow(_monitor, _thread_index, _collector_index,
00266 _show_level,
00267 _chart->get_xsize(), _chart->get_ysize());
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 void GtkStatsStripWindow::
00281 menu_hscale(float wpm) {
00282 _chart->set_horizontal_scale(60.0 / wpm);
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 void GtkStatsStripWindow::
00295 menu_vscale(float max_height) {
00296 _chart->set_vertical_scale(max_height);
00297 }
00298
00299
00300
00301
00302
00303
00304
00305 void GtkStatsStripWindow::
00306 menu_auto_vscale() {
00307 _chart->set_auto_vertical_scale();
00308 }
00309
00310
00311
00312
00313
00314
00315
00316 void GtkStatsStripWindow::
00317 menu_show_levels(int collector_index) {
00318 new GtkStatsStripWindow(_monitor, _thread_index, collector_index,
00319 true,
00320 _chart->get_xsize(), _chart->get_ysize());
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 void GtkStatsStripWindow::
00334 open_subchart(int collector_index) {
00335 new GtkStatsStripWindow(_monitor, _thread_index, collector_index,
00336 _show_level,
00337 _chart->get_xsize(), _chart->get_ysize());
00338 }
00339
00340
00341
00342
00343
00344
00345 void GtkStatsStripWindow::
00346 layout_window(int chart_xsize, int chart_ysize) {
00347 Gtk::HBox *hbox = new Gtk::HBox;
00348 hbox = new Gtk::HBox;
00349 hbox->show();
00350 _main_box->pack_start(*manage(hbox), true, true, 8);
00351
00352 Gtk::Table *chart_table = new Gtk::Table(3, 2);
00353 chart_table->show();
00354 hbox->pack_start(*manage(chart_table), true, true, 8);
00355
00356 Gtk::HBox *title_hbox = new Gtk::HBox;
00357 title_hbox->show();
00358 chart_table->attach(*manage(title_hbox), 1, 2, 0, 1,
00359 (GTK_FILL|GTK_EXPAND), 0);
00360
00361 _title_label = new Gtk::Label(get_title_text());
00362 if (_collector_index != 0 || _thread_index != 0) {
00363 _title_label->show();
00364 _title_label->set_alignment(0.0, 0.5);
00365 title_hbox->pack_start(*manage(_title_label), true, true);
00366 }
00367
00368 _frame_rate_label = new Gtk::Label;
00369 if (_collector_index == 0) {
00370 _frame_rate_label->show();
00371 _frame_rate_label->set_alignment(1.0, 0.5);
00372 title_hbox->pack_start(*manage(_frame_rate_label), true, true);
00373 }
00374
00375 Gtk::Frame *frame = new Gtk::Frame;
00376 frame->set_shadow_type(GTK_SHADOW_ETCHED_OUT);
00377 frame->show();
00378 chart_table->attach(*manage(frame), 1, 2, 1, 2);
00379
00380 if (_show_level) {
00381 _chart = new GtkStatsStripChart(_monitor,
00382 _monitor->get_level_view(_collector_index, _thread_index),
00383 _collector_index,
00384 chart_xsize, chart_ysize);
00385 } else {
00386 _chart = new GtkStatsStripChart(_monitor,
00387 _monitor->get_view(_thread_index),
00388 _collector_index,
00389 chart_xsize, chart_ysize);
00390 }
00391
00392 _chart->collector_picked.
00393 connect(slot(this, &GtkStatsStripWindow::open_subchart));
00394 frame->add(*manage(_chart));
00395
00396 chart_table->attach(*_chart->get_labels(), 0, 1, 1, 2,
00397 0, (GTK_FILL|GTK_EXPAND), 4, 0);
00398 chart_table->attach(*_chart->get_guide(), 2, 3, 1, 2,
00399 0, (GTK_FILL|GTK_EXPAND), 4, 0);
00400 _chart->show();
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410 string GtkStatsStripWindow::
00411 get_title_text() {
00412 string text;
00413
00414 _title_unknown = false;
00415
00416 const PStatClientData *client_data = _monitor->get_client_data();
00417 if (client_data->has_collector(_collector_index)) {
00418 const PStatCollectorDef &def = client_data->get_collector_def(_collector_index);
00419 if (_show_level) {
00420 if (def._level_units.empty()) {
00421 text = def._name;
00422 } else {
00423 text = def._name + " (" + def._level_units + ")";
00424 }
00425 } else {
00426 text = def._name + " time";
00427 }
00428 } else {
00429 _title_unknown = true;
00430 }
00431
00432 if (_thread_index != 0) {
00433 if (client_data->has_thread(_thread_index)) {
00434 text += "(" + client_data->get_thread_name(_thread_index) + " thread)";
00435 } else {
00436 _title_unknown = true;
00437 }
00438 }
00439
00440 return text;
00441 }
00442