Panda3D
 All Classes Functions Variables Enumerations
winStatsLabelStack.cxx
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 }
 All Classes Functions Variables Enumerations