Panda3D
|
00001 // Filename: winStatsLabelStack.cxx 00002 // Created by: drose (07Jan04) 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 "winStatsLabelStack.h" 00016 #include "winStatsLabel.h" 00017 #include "pnotify.h" 00018 00019 bool WinStatsLabelStack::_window_class_registered = false; 00020 const char * const WinStatsLabelStack::_window_class_name = "stack"; 00021 00022 //////////////////////////////////////////////////////////////////// 00023 // Function: WinStatsLabelStack::Constructor 00024 // Access: Public 00025 // Description: 00026 //////////////////////////////////////////////////////////////////// 00027 WinStatsLabelStack:: 00028 WinStatsLabelStack() { 00029 _x = 0; 00030 _y = 0; 00031 _width = 0; 00032 _height = 0; 00033 _ideal_width = 0; 00034 00035 _highlight_label = -1; 00036 } 00037 00038 //////////////////////////////////////////////////////////////////// 00039 // Function: WinStatsLabelStack::Destructor 00040 // Access: Public 00041 // Description: 00042 //////////////////////////////////////////////////////////////////// 00043 WinStatsLabelStack:: 00044 ~WinStatsLabelStack() { 00045 clear_labels(); 00046 if (_window) { 00047 DestroyWindow(_window); 00048 _window = 0; 00049 } 00050 } 00051 00052 //////////////////////////////////////////////////////////////////// 00053 // Function: WinStatsLabelStack::setup 00054 // Access: Public 00055 // Description: Creates the actual window object. 00056 //////////////////////////////////////////////////////////////////// 00057 void WinStatsLabelStack:: 00058 setup(HWND parent_window) { 00059 if (_window) { 00060 DestroyWindow(_window); 00061 _window = 0; 00062 } 00063 00064 create_window(parent_window); 00065 00066 _ideal_width = 0; 00067 Labels::iterator li; 00068 for (li = _labels.begin(); li != _labels.end(); ++li) { 00069 WinStatsLabel *label = (*li); 00070 label->setup(_window); 00071 _ideal_width = max(_ideal_width, label->get_ideal_width()); 00072 } 00073 } 00074 00075 //////////////////////////////////////////////////////////////////// 00076 // Function: WinStatsLabelStack::is_setup 00077 // Access: Public 00078 // Description: Returns true if the label stack has been set up, 00079 // false otherwise. 00080 //////////////////////////////////////////////////////////////////// 00081 bool WinStatsLabelStack:: 00082 is_setup() const { 00083 return (_window != 0); 00084 } 00085 00086 //////////////////////////////////////////////////////////////////// 00087 // Function: WinStatsLabelStack::set_pos 00088 // Access: Public 00089 // Description: Sets the position and size of the label stack on its parent. 00090 //////////////////////////////////////////////////////////////////// 00091 void WinStatsLabelStack:: 00092 set_pos(int x, int y, int width, int height) { 00093 _x = x; 00094 _y = y; 00095 _width = width; 00096 _height = height; 00097 SetWindowPos(_window, 0, x, y, _width, _height, 00098 SWP_NOZORDER | SWP_SHOWWINDOW); 00099 00100 Labels::iterator li; 00101 int yp = height; 00102 for (li = _labels.begin(); li != _labels.end(); ++li) { 00103 WinStatsLabel *label = (*li); 00104 label->set_pos(0, yp, _width); 00105 yp -= label->get_height(); 00106 } 00107 } 00108 00109 //////////////////////////////////////////////////////////////////// 00110 // Function: WinStatsLabelStack::get_x 00111 // Access: Public 00112 // Description: Returns the x position of the stack on its parent. 00113 //////////////////////////////////////////////////////////////////// 00114 int WinStatsLabelStack:: 00115 get_x() const { 00116 return _x; 00117 } 00118 00119 //////////////////////////////////////////////////////////////////// 00120 // Function: WinStatsLabelStack::get_y 00121 // Access: Public 00122 // Description: Returns the y position of the stack on its parent. 00123 //////////////////////////////////////////////////////////////////// 00124 int WinStatsLabelStack:: 00125 get_y() const { 00126 return _y; 00127 } 00128 00129 //////////////////////////////////////////////////////////////////// 00130 // Function: WinStatsLabelStack::get_width 00131 // Access: Public 00132 // Description: Returns the width of the stack as we requested it. 00133 //////////////////////////////////////////////////////////////////// 00134 int WinStatsLabelStack:: 00135 get_width() const { 00136 return _width; 00137 } 00138 00139 //////////////////////////////////////////////////////////////////// 00140 // Function: WinStatsLabelStack::get_height 00141 // Access: Public 00142 // Description: Returns the height of the stack as we requested it. 00143 //////////////////////////////////////////////////////////////////// 00144 int WinStatsLabelStack:: 00145 get_height() const { 00146 return _height; 00147 } 00148 00149 //////////////////////////////////////////////////////////////////// 00150 // Function: WinStatsLabelStack::get_ideal_width 00151 // Access: Public 00152 // Description: Returns the width the stack would really prefer to be. 00153 //////////////////////////////////////////////////////////////////// 00154 int WinStatsLabelStack:: 00155 get_ideal_width() const { 00156 return _ideal_width; 00157 } 00158 00159 //////////////////////////////////////////////////////////////////// 00160 // Function: WinStatsLabelStack::get_label_y 00161 // Access: Public 00162 // Description: Returns the y position of the indicated label's bottom 00163 // edge, relative to the label stack's parent window. 00164 //////////////////////////////////////////////////////////////////// 00165 int WinStatsLabelStack:: 00166 get_label_y(int label_index) const { 00167 nassertr(label_index >= 0 && label_index < (int)_labels.size(), 0); 00168 return _labels[label_index]->get_y() + get_y(); 00169 } 00170 00171 //////////////////////////////////////////////////////////////////// 00172 // Function: WinStatsLabelStack::get_label_height 00173 // Access: Public 00174 // Description: Returns the height of the indicated label. 00175 //////////////////////////////////////////////////////////////////// 00176 int WinStatsLabelStack:: 00177 get_label_height(int label_index) const { 00178 nassertr(label_index >= 0 && label_index < (int)_labels.size(), 0); 00179 return _labels[label_index]->get_height(); 00180 } 00181 00182 //////////////////////////////////////////////////////////////////// 00183 // Function: WinStatsLabelStack::get_label_collector_index 00184 // Access: Public 00185 // Description: Returns the collector index associated with the 00186 // indicated label. 00187 //////////////////////////////////////////////////////////////////// 00188 int WinStatsLabelStack:: 00189 get_label_collector_index(int label_index) const { 00190 nassertr(label_index >= 0 && label_index < (int)_labels.size(), -1); 00191 return _labels[label_index]->get_collector_index(); 00192 } 00193 00194 //////////////////////////////////////////////////////////////////// 00195 // Function: WinStatsLabelStack::clear_labels 00196 // Access: Public 00197 // Description: Removes the set of labels and starts a new set. 00198 //////////////////////////////////////////////////////////////////// 00199 void WinStatsLabelStack:: 00200 clear_labels() { 00201 Labels::iterator li; 00202 for (li = _labels.begin(); li != _labels.end(); ++li) { 00203 delete (*li); 00204 } 00205 _labels.clear(); 00206 _ideal_width = 0; 00207 } 00208 00209 //////////////////////////////////////////////////////////////////// 00210 // Function: WinStatsLabelStack::add_label 00211 // Access: Public 00212 // Description: Adds a new label to the top of the stack; returns the 00213 // new label index. 00214 //////////////////////////////////////////////////////////////////// 00215 int WinStatsLabelStack:: 00216 add_label(WinStatsMonitor *monitor, WinStatsGraph *graph, 00217 int thread_index, int collector_index, bool use_fullname) { 00218 int yp = _height; 00219 if (!_labels.empty()) { 00220 WinStatsLabel *top_label = _labels.back(); 00221 yp = top_label->get_y() - top_label->get_height(); 00222 } 00223 WinStatsLabel *label = 00224 new WinStatsLabel(monitor, graph, thread_index, collector_index, use_fullname); 00225 if (_window) { 00226 label->setup(_window); 00227 label->set_pos(0, yp, _width); 00228 } 00229 _ideal_width = max(_ideal_width, label->get_ideal_width()); 00230 00231 int label_index = (int)_labels.size(); 00232 _labels.push_back(label); 00233 00234 return label_index; 00235 } 00236 00237 //////////////////////////////////////////////////////////////////// 00238 // Function: WinStatsLabelStack::get_num_labels 00239 // Access: Public 00240 // Description: Returns the number of labels in the stack. 00241 //////////////////////////////////////////////////////////////////// 00242 int WinStatsLabelStack:: 00243 get_num_labels() const { 00244 return _labels.size(); 00245 } 00246 00247 //////////////////////////////////////////////////////////////////// 00248 // Function: WinStatsLabelStack::highlight_label 00249 // Access: Public 00250 // Description: Draws a highlight around the label representing the 00251 // indicated collector, and removes the highlight from 00252 // any other label. Specify -1 to remove the highlight 00253 // from all labels. 00254 //////////////////////////////////////////////////////////////////// 00255 void WinStatsLabelStack:: 00256 highlight_label(int collector_index) { 00257 if (_highlight_label != collector_index) { 00258 _highlight_label = collector_index; 00259 Labels::iterator li; 00260 for (li = _labels.begin(); li != _labels.end(); ++li) { 00261 WinStatsLabel *label = (*li); 00262 label->set_highlight(label->get_collector_index() == _highlight_label); 00263 } 00264 } 00265 } 00266 00267 00268 //////////////////////////////////////////////////////////////////// 00269 // Function: WinStatsLabelStack::create_window 00270 // Access: Private 00271 // Description: Creates the window for this stack. 00272 //////////////////////////////////////////////////////////////////// 00273 void WinStatsLabelStack:: 00274 create_window(HWND parent_window) { 00275 if (_window) { 00276 return; 00277 } 00278 00279 HINSTANCE application = GetModuleHandle(NULL); 00280 register_window_class(application); 00281 00282 _window = 00283 CreateWindow(_window_class_name, "label stack", WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 00284 0, 0, 0, 0, 00285 parent_window, NULL, application, 0); 00286 if (!_window) { 00287 nout << "Could not create Label Stack window!\n"; 00288 exit(1); 00289 } 00290 00291 SetWindowLongPtr(_window, 0, (LONG_PTR)this); 00292 } 00293 00294 //////////////////////////////////////////////////////////////////// 00295 // Function: WinStatsLabelStack::register_window_class 00296 // Access: Private, Static 00297 // Description: Registers the window class for the label window, if 00298 // it has not already been registered. 00299 //////////////////////////////////////////////////////////////////// 00300 void WinStatsLabelStack:: 00301 register_window_class(HINSTANCE application) { 00302 if (_window_class_registered) { 00303 return; 00304 } 00305 00306 WNDCLASS wc; 00307 00308 ZeroMemory(&wc, sizeof(WNDCLASS)); 00309 wc.style = 0; 00310 wc.lpfnWndProc = (WNDPROC)static_window_proc; 00311 wc.hInstance = application; 00312 wc.hCursor = LoadCursor(NULL, IDC_ARROW); 00313 wc.lpszMenuName = NULL; 00314 wc.lpszClassName = _window_class_name; 00315 00316 // Reserve space to associate the this pointer with the window. 00317 wc.cbWndExtra = sizeof(WinStatsLabelStack *); 00318 00319 if (!RegisterClass(&wc)) { 00320 nout << "Could not register Label Stack window class!\n"; 00321 exit(1); 00322 } 00323 00324 _window_class_registered = true; 00325 } 00326 00327 //////////////////////////////////////////////////////////////////// 00328 // Function: WinStatsLabelStack::static_window_proc 00329 // Access: Private, Static 00330 // Description: 00331 //////////////////////////////////////////////////////////////////// 00332 LONG WINAPI WinStatsLabelStack:: 00333 static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { 00334 WinStatsLabelStack *self = (WinStatsLabelStack *)GetWindowLongPtr(hwnd, 0); 00335 if (self != (WinStatsLabelStack *)NULL && self->_window == hwnd) { 00336 return self->window_proc(hwnd, msg, wparam, lparam); 00337 } else { 00338 return DefWindowProc(hwnd, msg, wparam, lparam); 00339 } 00340 } 00341 00342 //////////////////////////////////////////////////////////////////// 00343 // Function: WinStatsLabelStack::window_proc 00344 // Access: Private 00345 // Description: 00346 //////////////////////////////////////////////////////////////////// 00347 LONG WinStatsLabelStack:: 00348 window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { 00349 switch (msg) { 00350 case WM_PAINT: 00351 { 00352 PAINTSTRUCT ps; 00353 HDC hdc = BeginPaint(hwnd, &ps); 00354 00355 RECT rect = { 0, 0, _width, _height }; 00356 FillRect(hdc, &rect, (HBRUSH)COLOR_BACKGROUND); 00357 EndPaint(hwnd, &ps); 00358 return 0; 00359 } 00360 00361 default: 00362 break; 00363 } 00364 00365 return DefWindowProc(hwnd, msg, wparam, lparam); 00366 }