gtkStatsChartMenu.cxx 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. // Filename: gtkStatsChartMenu.cxx
  2. // Created by: drose (16Jan06)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://etc.cmu.edu/panda3d/docs/license/ .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. #include "gtkStatsChartMenu.h"
  19. #include "gtkStatsMonitor.h"
  20. ////////////////////////////////////////////////////////////////////
  21. // Function: GtkStatsChartMenu::Constructor
  22. // Access: Public
  23. // Description:
  24. ////////////////////////////////////////////////////////////////////
  25. GtkStatsChartMenu::
  26. GtkStatsChartMenu(GtkStatsMonitor *monitor, int thread_index) :
  27. _monitor(monitor),
  28. _thread_index(thread_index)
  29. {
  30. _menu = gtk_menu_new();
  31. gtk_widget_show(_menu);
  32. do_update();
  33. }
  34. ////////////////////////////////////////////////////////////////////
  35. // Function: GtkStatsChartMenu::Destructor
  36. // Access: Public
  37. // Description:
  38. ////////////////////////////////////////////////////////////////////
  39. GtkStatsChartMenu::
  40. ~GtkStatsChartMenu() {
  41. }
  42. ////////////////////////////////////////////////////////////////////
  43. // Function: GtkStatsChartMenu::get_menu_widget
  44. // Access: Public
  45. // Description: Returns the gtk widget for this particular
  46. // menu.
  47. ////////////////////////////////////////////////////////////////////
  48. GtkWidget *GtkStatsChartMenu::
  49. get_menu_widget() {
  50. return _menu;
  51. }
  52. ////////////////////////////////////////////////////////////////////
  53. // Function: GtkStatsChartMenu::add_to_menu_bar
  54. // Access: Public
  55. // Description: Adds the menu to the end of the indicated menu bar.
  56. ////////////////////////////////////////////////////////////////////
  57. void GtkStatsChartMenu::
  58. add_to_menu_bar(GtkWidget *menu_bar, int before_menu_id) {
  59. const PStatClientData *client_data = _monitor->get_client_data();
  60. string thread_name;
  61. if (_thread_index == 0) {
  62. // A special case for the main thread.
  63. thread_name = "Graphs";
  64. } else {
  65. thread_name = client_data->get_thread_name(_thread_index);
  66. }
  67. GtkWidget *menu_item = gtk_menu_item_new_with_label(thread_name.c_str());
  68. gtk_widget_show(menu_item);
  69. gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), _menu);
  70. gtk_menu_bar_append(GTK_MENU_BAR(menu_bar), menu_item);
  71. }
  72. ////////////////////////////////////////////////////////////////////
  73. // Function: GtkStatsChartMenu::check_update
  74. // Access: Public
  75. // Description: Checks to see if the menu needs to be updated
  76. // (e.g. because of new data from the client), and
  77. // updates it if necessary.
  78. ////////////////////////////////////////////////////////////////////
  79. void GtkStatsChartMenu::
  80. check_update() {
  81. PStatView &view = _monitor->get_view(_thread_index);
  82. if (view.get_level_index() != _last_level_index) {
  83. do_update();
  84. }
  85. }
  86. ////////////////////////////////////////////////////////////////////
  87. // Function: GtkStatsChartMenu::do_update
  88. // Access: Public
  89. // Description: Unconditionally updates the menu with the latest data
  90. // from the client.
  91. ////////////////////////////////////////////////////////////////////
  92. void GtkStatsChartMenu::
  93. do_update() {
  94. PStatView &view = _monitor->get_view(_thread_index);
  95. _last_level_index = view.get_level_index();
  96. // First, remove all of the old entries from the menu.
  97. gtk_container_foreach(GTK_CONTAINER(_menu), remove_menu_child, _menu);
  98. // Now rebuild the menu with the new set of entries.
  99. // The menu item(s) for the thread's frame time goes first.
  100. add_view(_menu, view.get_top_level(), false);
  101. bool needs_separator = true;
  102. // And then the menu item(s) for each of the level values.
  103. const PStatClientData *client_data = _monitor->get_client_data();
  104. int num_toplevel_collectors = client_data->get_num_toplevel_collectors();
  105. for (int tc = 0; tc < num_toplevel_collectors; tc++) {
  106. int collector = client_data->get_toplevel_collector(tc);
  107. if (client_data->has_collector(collector) &&
  108. client_data->get_collector_has_level(collector)) {
  109. // We put a separator between the above frame collector and the
  110. // first level collector.
  111. if (needs_separator) {
  112. GtkWidget *sep = gtk_separator_menu_item_new();
  113. gtk_widget_show(sep);
  114. gtk_menu_shell_append(GTK_MENU_SHELL(_menu), sep);
  115. needs_separator = false;
  116. }
  117. PStatView &level_view = _monitor->get_level_view(collector, _thread_index);
  118. add_view(_menu, level_view.get_top_level(), true);
  119. }
  120. }
  121. /*
  122. // Also a menu item for a piano roll (following a separator).
  123. GtkWidget *sep = gtk_separator_menu_item_new();
  124. gtk_widget_show(sep);
  125. gtk_menu_shell_append(GTK_MENU_SHELL(_menu), sep);
  126. GtkStatsMonitor::MenuDef smd(_thread_index, -1, false);
  127. const GtkStatsMonitor::MenuDef *menu_def = _monitor->add_menu(smd);
  128. GtkWidget *menu_item = gtk_menu_item_new_with_label("Piano Roll");
  129. gtk_widget_show(menu_item);
  130. gtk_menu_shell_append(GTK_MENU_SHELL(_menu), menu_item);
  131. g_signal_connect_swapped(G_OBJECT(menu_item), "activate",
  132. G_CALLBACK(handle_menu), (void *)(const void *)menu_def);
  133. */
  134. }
  135. ////////////////////////////////////////////////////////////////////
  136. // Function: GtkStatsChartMenu::add_view
  137. // Access: Private
  138. // Description: Adds a new entry or entries to the menu for the
  139. // indicated view and its children.
  140. ////////////////////////////////////////////////////////////////////
  141. void GtkStatsChartMenu::
  142. add_view(GtkWidget *parent_menu, const PStatViewLevel *view_level,
  143. bool show_level) {
  144. int collector = view_level->get_collector();
  145. const PStatClientData *client_data = _monitor->get_client_data();
  146. string collector_name = client_data->get_collector_name(collector);
  147. GtkStatsMonitor::MenuDef smd(_thread_index, collector, show_level);
  148. const GtkStatsMonitor::MenuDef *menu_def = _monitor->add_menu(smd);
  149. GtkWidget *menu_item = gtk_menu_item_new_with_label(collector_name.c_str());
  150. gtk_widget_show(menu_item);
  151. gtk_menu_shell_append(GTK_MENU_SHELL(parent_menu), menu_item);
  152. g_signal_connect_swapped(G_OBJECT(menu_item), "activate",
  153. G_CALLBACK(handle_menu), (void *)(const void *)menu_def);
  154. int num_children = view_level->get_num_children();
  155. if (num_children > 1) {
  156. // If the collector has more than one child, add a menu entry to go
  157. // directly to each of its children.
  158. string submenu_name = collector_name + " components";
  159. GtkWidget *submenu_item = gtk_menu_item_new_with_label(submenu_name.c_str());
  160. gtk_widget_show(submenu_item);
  161. gtk_menu_shell_append(GTK_MENU_SHELL(parent_menu), submenu_item);
  162. GtkWidget *submenu = gtk_menu_new();
  163. gtk_widget_show(submenu);
  164. gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenu_item), submenu);
  165. // Reverse the order since the menus are listed from the top down;
  166. // we want to be visually consistent with the graphs, which list
  167. // these labels from the bottom up.
  168. for (int c = num_children - 1; c >= 0; c--) {
  169. add_view(submenu, view_level->get_child(c), show_level);
  170. }
  171. }
  172. }
  173. ////////////////////////////////////////////////////////////////////
  174. // Function: GtkStatsChartMenu::handle_menu
  175. // Access: Private, Static
  176. // Description: Callback when a menu item is selected.
  177. ////////////////////////////////////////////////////////////////////
  178. void GtkStatsChartMenu::
  179. handle_menu(gpointer data) {
  180. const GtkStatsMonitor::MenuDef *menu_def = (GtkStatsMonitor::MenuDef *)data;
  181. GtkStatsMonitor *monitor = menu_def->_monitor;
  182. if (monitor == NULL) {
  183. return;
  184. }
  185. if (menu_def->_collector_index < 0) {
  186. monitor->open_piano_roll(menu_def->_thread_index);
  187. } else {
  188. monitor->open_strip_chart(menu_def->_thread_index,
  189. menu_def->_collector_index,
  190. menu_def->_show_level);
  191. }
  192. }
  193. ////////////////////////////////////////////////////////////////////
  194. // Function: GtkStatsChartMenu::remove_menu_child
  195. // Access: Private, Static
  196. // Description: Removes a previous menu child from the menu.
  197. ////////////////////////////////////////////////////////////////////
  198. void GtkStatsChartMenu::
  199. remove_menu_child(GtkWidget *widget, gpointer data) {
  200. GtkWidget *menu = (GtkWidget *)data;
  201. gtk_container_remove(GTK_CONTAINER(menu), widget);
  202. }