00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "gtkStatsChartMenu.h"
00016 #include "gtkStatsMonitor.h"
00017
00018
00019
00020
00021
00022
00023 GtkStatsChartMenu::
00024 GtkStatsChartMenu(GtkStatsMonitor *monitor, int thread_index) :
00025 _monitor(monitor),
00026 _thread_index(thread_index)
00027 {
00028 _menu = gtk_menu_new();
00029 gtk_widget_show(_menu);
00030 do_update();
00031 }
00032
00033
00034
00035
00036
00037
00038 GtkStatsChartMenu::
00039 ~GtkStatsChartMenu() {
00040 }
00041
00042
00043
00044
00045
00046
00047
00048 GtkWidget *GtkStatsChartMenu::
00049 get_menu_widget() {
00050 return _menu;
00051 }
00052
00053
00054
00055
00056
00057
00058 void GtkStatsChartMenu::
00059 add_to_menu_bar(GtkWidget *menu_bar, int position) {
00060 const PStatClientData *client_data = _monitor->get_client_data();
00061 string thread_name;
00062 if (_thread_index == 0) {
00063
00064 thread_name = "Graphs";
00065 } else {
00066 thread_name = client_data->get_thread_name(_thread_index);
00067 }
00068
00069 GtkWidget *menu_item = gtk_menu_item_new_with_label(thread_name.c_str());
00070 gtk_widget_show(menu_item);
00071 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), _menu);
00072
00073 gtk_menu_shell_insert(GTK_MENU_SHELL(menu_bar), menu_item, position);
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083 void GtkStatsChartMenu::
00084 check_update() {
00085 PStatView &view = _monitor->get_view(_thread_index);
00086 if (view.get_level_index() != _last_level_index) {
00087 do_update();
00088 }
00089 }
00090
00091
00092
00093
00094
00095
00096
00097 void GtkStatsChartMenu::
00098 do_update() {
00099 PStatView &view = _monitor->get_view(_thread_index);
00100 _last_level_index = view.get_level_index();
00101
00102
00103 gtk_container_foreach(GTK_CONTAINER(_menu), remove_menu_child, _menu);
00104
00105
00106
00107
00108 add_view(_menu, view.get_top_level(), false);
00109
00110 bool needs_separator = true;
00111
00112
00113 const PStatClientData *client_data = _monitor->get_client_data();
00114 int num_toplevel_collectors = client_data->get_num_toplevel_collectors();
00115 for (int tc = 0; tc < num_toplevel_collectors; tc++) {
00116 int collector = client_data->get_toplevel_collector(tc);
00117 if (client_data->has_collector(collector) &&
00118 client_data->get_collector_has_level(collector, _thread_index)) {
00119
00120
00121
00122 if (needs_separator) {
00123 GtkWidget *sep = gtk_separator_menu_item_new();
00124 gtk_widget_show(sep);
00125 gtk_menu_shell_append(GTK_MENU_SHELL(_menu), sep);
00126
00127 needs_separator = false;
00128 }
00129
00130 PStatView &level_view = _monitor->get_level_view(collector, _thread_index);
00131 add_view(_menu, level_view.get_top_level(), true);
00132 }
00133 }
00134
00135
00136 GtkWidget *sep = gtk_separator_menu_item_new();
00137 gtk_widget_show(sep);
00138 gtk_menu_shell_append(GTK_MENU_SHELL(_menu), sep);
00139
00140 GtkStatsMonitor::MenuDef smd(_thread_index, -1, false);
00141 const GtkStatsMonitor::MenuDef *menu_def = _monitor->add_menu(smd);
00142
00143 GtkWidget *menu_item = gtk_menu_item_new_with_label("Piano Roll");
00144 gtk_widget_show(menu_item);
00145 gtk_menu_shell_append(GTK_MENU_SHELL(_menu), menu_item);
00146
00147 g_signal_connect_swapped(G_OBJECT(menu_item), "activate",
00148 G_CALLBACK(handle_menu), (void *)(const void *)menu_def);
00149 }
00150
00151
00152
00153
00154
00155
00156
00157 void GtkStatsChartMenu::
00158 add_view(GtkWidget *parent_menu, const PStatViewLevel *view_level,
00159 bool show_level) {
00160 int collector = view_level->get_collector();
00161
00162 const PStatClientData *client_data = _monitor->get_client_data();
00163 string collector_name = client_data->get_collector_name(collector);
00164
00165 GtkStatsMonitor::MenuDef smd(_thread_index, collector, show_level);
00166 const GtkStatsMonitor::MenuDef *menu_def = _monitor->add_menu(smd);
00167
00168 GtkWidget *menu_item = gtk_menu_item_new_with_label(collector_name.c_str());
00169 gtk_widget_show(menu_item);
00170 gtk_menu_shell_append(GTK_MENU_SHELL(parent_menu), menu_item);
00171
00172 g_signal_connect_swapped(G_OBJECT(menu_item), "activate",
00173 G_CALLBACK(handle_menu), (void *)(const void *)menu_def);
00174
00175 int num_children = view_level->get_num_children();
00176 if (num_children > 1) {
00177
00178
00179 string submenu_name = collector_name + " components";
00180
00181 GtkWidget *submenu_item = gtk_menu_item_new_with_label(submenu_name.c_str());
00182 gtk_widget_show(submenu_item);
00183 gtk_menu_shell_append(GTK_MENU_SHELL(parent_menu), submenu_item);
00184
00185 GtkWidget *submenu = gtk_menu_new();
00186 gtk_widget_show(submenu);
00187 gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenu_item), submenu);
00188
00189
00190
00191
00192 for (int c = num_children - 1; c >= 0; c--) {
00193 add_view(submenu, view_level->get_child(c), show_level);
00194 }
00195 }
00196 }
00197
00198
00199
00200
00201
00202
00203 void GtkStatsChartMenu::
00204 handle_menu(gpointer data) {
00205 const GtkStatsMonitor::MenuDef *menu_def = (GtkStatsMonitor::MenuDef *)data;
00206 GtkStatsMonitor *monitor = menu_def->_monitor;
00207
00208 if (monitor == NULL) {
00209 return;
00210 }
00211
00212 if (menu_def->_collector_index < 0) {
00213 monitor->open_piano_roll(menu_def->_thread_index);
00214 } else {
00215 monitor->open_strip_chart(menu_def->_thread_index,
00216 menu_def->_collector_index,
00217 menu_def->_show_level);
00218 }
00219 }
00220
00221
00222
00223
00224
00225
00226 void GtkStatsChartMenu::
00227 remove_menu_child(GtkWidget *widget, gpointer data) {
00228 GtkWidget *menu = (GtkWidget *)data;
00229 gtk_container_remove(GTK_CONTAINER(menu), widget);
00230 }