Panda3D
|
00001 // Filename: winStatsChartMenu.cxx 00002 // Created by: drose (08Jan04) 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 "winStatsChartMenu.h" 00016 #include "winStatsMonitor.h" 00017 00018 //////////////////////////////////////////////////////////////////// 00019 // Function: WinStatsChartMenu::Constructor 00020 // Access: Public 00021 // Description: 00022 //////////////////////////////////////////////////////////////////// 00023 WinStatsChartMenu:: 00024 WinStatsChartMenu(WinStatsMonitor *monitor, int thread_index) : 00025 _monitor(monitor), 00026 _thread_index(thread_index) 00027 { 00028 _menu = CreatePopupMenu(); 00029 do_update(); 00030 } 00031 00032 //////////////////////////////////////////////////////////////////// 00033 // Function: WinStatsChartMenu::Destructor 00034 // Access: Public 00035 // Description: 00036 //////////////////////////////////////////////////////////////////// 00037 WinStatsChartMenu:: 00038 ~WinStatsChartMenu() { 00039 } 00040 00041 //////////////////////////////////////////////////////////////////// 00042 // Function: WinStatsChartMenu::get_menu_handle 00043 // Access: Public 00044 // Description: Returns the Windows menu handle for this particular 00045 // menu. 00046 //////////////////////////////////////////////////////////////////// 00047 HMENU WinStatsChartMenu:: 00048 get_menu_handle() { 00049 return _menu; 00050 } 00051 00052 //////////////////////////////////////////////////////////////////// 00053 // Function: WinStatsChartMenu::add_to_menu_bar 00054 // Access: Public 00055 // Description: Adds the menu to the end of the indicated menu bar. 00056 //////////////////////////////////////////////////////////////////// 00057 void WinStatsChartMenu:: 00058 add_to_menu_bar(HMENU menu_bar, int before_menu_id) { 00059 const PStatClientData *client_data = _monitor->get_client_data(); 00060 string thread_name; 00061 if (_thread_index == 0) { 00062 // A special case for the main thread. 00063 thread_name = "Graphs"; 00064 } else { 00065 thread_name = client_data->get_thread_name(_thread_index); 00066 } 00067 00068 MENUITEMINFO mii; 00069 memset(&mii, 0, sizeof(mii)); 00070 mii.cbSize = sizeof(mii); 00071 00072 mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU; 00073 mii.fType = MFT_STRING; 00074 mii.hSubMenu = _menu; 00075 mii.dwTypeData = (char *)thread_name.c_str(); 00076 InsertMenuItem(menu_bar, before_menu_id, FALSE, &mii); 00077 } 00078 00079 //////////////////////////////////////////////////////////////////// 00080 // Function: WinStatsChartMenu::check_update 00081 // Access: Public 00082 // Description: Checks to see if the menu needs to be updated 00083 // (e.g. because of new data from the client), and 00084 // updates it if necessary. 00085 //////////////////////////////////////////////////////////////////// 00086 void WinStatsChartMenu:: 00087 check_update() { 00088 PStatView &view = _monitor->get_view(_thread_index); 00089 if (view.get_level_index() != _last_level_index) { 00090 do_update(); 00091 } 00092 } 00093 00094 //////////////////////////////////////////////////////////////////// 00095 // Function: WinStatsChartMenu::do_update 00096 // Access: Public 00097 // Description: Unconditionally updates the menu with the latest data 00098 // from the client. 00099 //////////////////////////////////////////////////////////////////// 00100 void WinStatsChartMenu:: 00101 do_update() { 00102 PStatView &view = _monitor->get_view(_thread_index); 00103 _last_level_index = view.get_level_index(); 00104 00105 // First, remove all of the old entries from the menu. 00106 int num_items = GetMenuItemCount(_menu); 00107 for (int i = num_items - 1; i >= 0; i--) { 00108 DeleteMenu(_menu, i, MF_BYPOSITION); 00109 } 00110 00111 // Now rebuild the menu with the new set of entries. 00112 00113 // The menu item(s) for the thread's frame time goes first. 00114 add_view(_menu, view.get_top_level(), false); 00115 00116 bool needs_separator = true; 00117 MENUITEMINFO mii; 00118 memset(&mii, 0, sizeof(mii)); 00119 mii.cbSize = sizeof(mii); 00120 00121 // And then the menu item(s) for each of the level values. 00122 const PStatClientData *client_data = _monitor->get_client_data(); 00123 int num_toplevel_collectors = client_data->get_num_toplevel_collectors(); 00124 for (int tc = 0; tc < num_toplevel_collectors; tc++) { 00125 int collector = client_data->get_toplevel_collector(tc); 00126 if (client_data->has_collector(collector) && 00127 client_data->get_collector_has_level(collector, _thread_index)) { 00128 00129 // We put a separator between the above frame collector and the 00130 // first level collector. 00131 if (needs_separator) { 00132 mii.fMask = MIIM_FTYPE; 00133 mii.fType = MFT_SEPARATOR; 00134 InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii); 00135 00136 needs_separator = false; 00137 } 00138 00139 PStatView &level_view = _monitor->get_level_view(collector, _thread_index); 00140 add_view(_menu, level_view.get_top_level(), true); 00141 } 00142 } 00143 00144 // Also a menu item for a piano roll (following a separator). 00145 mii.fMask = MIIM_FTYPE; 00146 mii.fType = MFT_SEPARATOR; 00147 InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii); 00148 00149 WinStatsMonitor::MenuDef menu_def(_thread_index, -1, false); 00150 int menu_id = _monitor->get_menu_id(menu_def); 00151 00152 mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID; 00153 mii.fType = MFT_STRING; 00154 mii.wID = menu_id; 00155 mii.dwTypeData = "Piano Roll"; 00156 InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii); 00157 } 00158 00159 //////////////////////////////////////////////////////////////////// 00160 // Function: WinStatsChartMenu::add_view 00161 // Access: Private 00162 // Description: Adds a new entry or entries to the menu for the 00163 // indicated view and its children. 00164 //////////////////////////////////////////////////////////////////// 00165 void WinStatsChartMenu:: 00166 add_view(HMENU parent_menu, const PStatViewLevel *view_level, bool show_level) { 00167 int collector = view_level->get_collector(); 00168 00169 const PStatClientData *client_data = _monitor->get_client_data(); 00170 string collector_name = client_data->get_collector_name(collector); 00171 00172 WinStatsMonitor::MenuDef menu_def(_thread_index, collector, show_level); 00173 int menu_id = _monitor->get_menu_id(menu_def); 00174 00175 MENUITEMINFO mii; 00176 memset(&mii, 0, sizeof(mii)); 00177 mii.cbSize = sizeof(mii); 00178 00179 mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID; 00180 mii.fType = MFT_STRING; 00181 mii.wID = menu_id; 00182 mii.dwTypeData = (char *)collector_name.c_str(); 00183 InsertMenuItem(parent_menu, GetMenuItemCount(parent_menu), TRUE, &mii); 00184 00185 int num_children = view_level->get_num_children(); 00186 if (num_children > 1) { 00187 // If the collector has more than one child, add a menu entry to go 00188 // directly to each of its children. 00189 HMENU submenu = CreatePopupMenu(); 00190 string submenu_name = collector_name + " components"; 00191 00192 mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU; 00193 mii.fType = MFT_STRING; 00194 mii.hSubMenu = submenu; 00195 mii.dwTypeData = (char *)submenu_name.c_str(); 00196 InsertMenuItem(parent_menu, GetMenuItemCount(parent_menu), TRUE, &mii); 00197 00198 // Reverse the order since the menus are listed from the top down; 00199 // we want to be visually consistent with the graphs, which list 00200 // these labels from the bottom up. 00201 for (int c = num_children - 1; c >= 0; c--) { 00202 add_view(submenu, view_level->get_child(c), show_level); 00203 } 00204 } 00205 }