gtkStatsChartMenu.cxx 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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 = CreatePopupMenu();
  31. do_update();
  32. }
  33. ////////////////////////////////////////////////////////////////////
  34. // Function: GtkStatsChartMenu::Destructor
  35. // Access: Public
  36. // Description:
  37. ////////////////////////////////////////////////////////////////////
  38. GtkStatsChartMenu::
  39. ~GtkStatsChartMenu() {
  40. }
  41. ////////////////////////////////////////////////////////////////////
  42. // Function: GtkStatsChartMenu::get_menu_handle
  43. // Access: Public
  44. // Description: Returns the Windows menu handle for this particular
  45. // menu.
  46. ////////////////////////////////////////////////////////////////////
  47. HMENU GtkStatsChartMenu::
  48. get_menu_handle() {
  49. return _menu;
  50. }
  51. ////////////////////////////////////////////////////////////////////
  52. // Function: GtkStatsChartMenu::add_to_menu_bar
  53. // Access: Public
  54. // Description: Adds the menu to the end of the indicated menu bar.
  55. ////////////////////////////////////////////////////////////////////
  56. void GtkStatsChartMenu::
  57. add_to_menu_bar(HMENU menu_bar, int before_menu_id) {
  58. const PStatClientData *client_data = _monitor->get_client_data();
  59. string thread_name;
  60. if (_thread_index == 0) {
  61. // A special case for the main thread.
  62. thread_name = "Graphs";
  63. } else {
  64. thread_name = client_data->get_thread_name(_thread_index);
  65. }
  66. MENUITEMINFO mii;
  67. memset(&mii, 0, sizeof(mii));
  68. mii.cbSize = sizeof(mii);
  69. mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU;
  70. mii.fType = MFT_STRING;
  71. mii.hSubMenu = _menu;
  72. mii.dwTypeData = (char *)thread_name.c_str();
  73. InsertMenuItem(menu_bar, before_menu_id, FALSE, &mii);
  74. }
  75. ////////////////////////////////////////////////////////////////////
  76. // Function: GtkStatsChartMenu::check_update
  77. // Access: Public
  78. // Description: Checks to see if the menu needs to be updated
  79. // (e.g. because of new data from the client), and
  80. // updates it if necessary.
  81. ////////////////////////////////////////////////////////////////////
  82. void GtkStatsChartMenu::
  83. check_update() {
  84. PStatView &view = _monitor->get_view(_thread_index);
  85. if (view.get_level_index() != _last_level_index) {
  86. do_update();
  87. }
  88. }
  89. ////////////////////////////////////////////////////////////////////
  90. // Function: GtkStatsChartMenu::do_update
  91. // Access: Public
  92. // Description: Unconditionally updates the menu with the latest data
  93. // from the client.
  94. ////////////////////////////////////////////////////////////////////
  95. void GtkStatsChartMenu::
  96. do_update() {
  97. PStatView &view = _monitor->get_view(_thread_index);
  98. _last_level_index = view.get_level_index();
  99. // First, remove all of the old entries from the menu.
  100. int num_items = GetMenuItemCount(_menu);
  101. for (int i = num_items - 1; i >= 0; i--) {
  102. DeleteMenu(_menu, i, MF_BYPOSITION);
  103. }
  104. // Now rebuild the menu with the new set of entries.
  105. // The menu item(s) for the thread's frame time goes first.
  106. add_view(_menu, view.get_top_level(), false);
  107. bool needs_separator = true;
  108. MENUITEMINFO mii;
  109. memset(&mii, 0, sizeof(mii));
  110. mii.cbSize = sizeof(mii);
  111. // And then the menu item(s) for each of the level values.
  112. const PStatClientData *client_data = _monitor->get_client_data();
  113. int num_toplevel_collectors = client_data->get_num_toplevel_collectors();
  114. for (int tc = 0; tc < num_toplevel_collectors; tc++) {
  115. int collector = client_data->get_toplevel_collector(tc);
  116. if (client_data->has_collector(collector) &&
  117. client_data->get_collector_has_level(collector)) {
  118. // We put a separator between the above frame collector and the
  119. // first level collector.
  120. if (needs_separator) {
  121. mii.fMask = MIIM_FTYPE;
  122. mii.fType = MFT_SEPARATOR;
  123. InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
  124. needs_separator = false;
  125. }
  126. PStatView &level_view = _monitor->get_level_view(collector, _thread_index);
  127. add_view(_menu, level_view.get_top_level(), true);
  128. }
  129. }
  130. // Also a menu item for a piano roll (following a separator).
  131. mii.fMask = MIIM_FTYPE;
  132. mii.fType = MFT_SEPARATOR;
  133. InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
  134. GtkStatsMonitor::MenuDef menu_def(_thread_index, -1, false);
  135. int menu_id = _monitor->get_menu_id(menu_def);
  136. mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID;
  137. mii.fType = MFT_STRING;
  138. mii.wID = menu_id;
  139. mii.dwTypeData = "Piano Roll";
  140. InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
  141. }
  142. ////////////////////////////////////////////////////////////////////
  143. // Function: GtkStatsChartMenu::add_view
  144. // Access: Private
  145. // Description: Adds a new entry or entries to the menu for the
  146. // indicated view and its children.
  147. ////////////////////////////////////////////////////////////////////
  148. void GtkStatsChartMenu::
  149. add_view(HMENU parent_menu, const PStatViewLevel *view_level, bool show_level) {
  150. int collector = view_level->get_collector();
  151. const PStatClientData *client_data = _monitor->get_client_data();
  152. string collector_name = client_data->get_collector_name(collector);
  153. GtkStatsMonitor::MenuDef menu_def(_thread_index, collector, show_level);
  154. int menu_id = _monitor->get_menu_id(menu_def);
  155. MENUITEMINFO mii;
  156. memset(&mii, 0, sizeof(mii));
  157. mii.cbSize = sizeof(mii);
  158. mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID;
  159. mii.fType = MFT_STRING;
  160. mii.wID = menu_id;
  161. mii.dwTypeData = (char *)collector_name.c_str();
  162. InsertMenuItem(parent_menu, GetMenuItemCount(parent_menu), TRUE, &mii);
  163. int num_children = view_level->get_num_children();
  164. if (num_children > 1) {
  165. // If the collector has more than one child, add a menu entry to go
  166. // directly to each of its children.
  167. HMENU submenu = CreatePopupMenu();
  168. string submenu_name = collector_name + " components";
  169. mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU;
  170. mii.fType = MFT_STRING;
  171. mii.hSubMenu = submenu;
  172. mii.dwTypeData = (char *)submenu_name.c_str();
  173. InsertMenuItem(parent_menu, GetMenuItemCount(parent_menu), TRUE, &mii);
  174. // Reverse the order since the menus are listed from the top down;
  175. // we want to be visually consistent with the graphs, which list
  176. // these labels from the bottom up.
  177. for (int c = num_children - 1; c >= 0; c--) {
  178. add_view(submenu, view_level->get_child(c), show_level);
  179. }
  180. }
  181. }