Panda3D
 All Classes Functions Variables Enumerations
winStatsLabelStack.cxx
1 // Filename: winStatsLabelStack.cxx
2 // Created by: drose (07Jan04)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "winStatsLabelStack.h"
16 #include "winStatsLabel.h"
17 #include "pnotify.h"
18 
19 bool WinStatsLabelStack::_window_class_registered = false;
20 const char * const WinStatsLabelStack::_window_class_name = "stack";
21 
22 ////////////////////////////////////////////////////////////////////
23 // Function: WinStatsLabelStack::Constructor
24 // Access: Public
25 // Description:
26 ////////////////////////////////////////////////////////////////////
27 WinStatsLabelStack::
28 WinStatsLabelStack() {
29  _x = 0;
30  _y = 0;
31  _width = 0;
32  _height = 0;
33  _ideal_width = 0;
34 
35  _highlight_label = -1;
36 }
37 
38 ////////////////////////////////////////////////////////////////////
39 // Function: WinStatsLabelStack::Destructor
40 // Access: Public
41 // Description:
42 ////////////////////////////////////////////////////////////////////
43 WinStatsLabelStack::
44 ~WinStatsLabelStack() {
45  clear_labels();
46  if (_window) {
47  DestroyWindow(_window);
48  _window = 0;
49  }
50 }
51 
52 ////////////////////////////////////////////////////////////////////
53 // Function: WinStatsLabelStack::setup
54 // Access: Public
55 // Description: Creates the actual window object.
56 ////////////////////////////////////////////////////////////////////
58 setup(HWND parent_window) {
59  if (_window) {
60  DestroyWindow(_window);
61  _window = 0;
62  }
63 
64  create_window(parent_window);
65 
66  _ideal_width = 0;
67  Labels::iterator li;
68  for (li = _labels.begin(); li != _labels.end(); ++li) {
69  WinStatsLabel *label = (*li);
70  label->setup(_window);
71  _ideal_width = max(_ideal_width, label->get_ideal_width());
72  }
73 }
74 
75 ////////////////////////////////////////////////////////////////////
76 // Function: WinStatsLabelStack::is_setup
77 // Access: Public
78 // Description: Returns true if the label stack has been set up,
79 // false otherwise.
80 ////////////////////////////////////////////////////////////////////
82 is_setup() const {
83  return (_window != 0);
84 }
85 
86 ////////////////////////////////////////////////////////////////////
87 // Function: WinStatsLabelStack::set_pos
88 // Access: Public
89 // Description: Sets the position and size of the label stack on its parent.
90 ////////////////////////////////////////////////////////////////////
92 set_pos(int x, int y, int width, int height) {
93  _x = x;
94  _y = y;
95  _width = width;
96  _height = height;
97  SetWindowPos(_window, 0, x, y, _width, _height,
98  SWP_NOZORDER | SWP_SHOWWINDOW);
99 
100  Labels::iterator li;
101  int yp = height;
102  for (li = _labels.begin(); li != _labels.end(); ++li) {
103  WinStatsLabel *label = (*li);
104  label->set_pos(0, yp, _width);
105  yp -= label->get_height();
106  }
107 }
108 
109 ////////////////////////////////////////////////////////////////////
110 // Function: WinStatsLabelStack::get_x
111 // Access: Public
112 // Description: Returns the x position of the stack on its parent.
113 ////////////////////////////////////////////////////////////////////
115 get_x() const {
116  return _x;
117 }
118 
119 ////////////////////////////////////////////////////////////////////
120 // Function: WinStatsLabelStack::get_y
121 // Access: Public
122 // Description: Returns the y position of the stack on its parent.
123 ////////////////////////////////////////////////////////////////////
125 get_y() const {
126  return _y;
127 }
128 
129 ////////////////////////////////////////////////////////////////////
130 // Function: WinStatsLabelStack::get_width
131 // Access: Public
132 // Description: Returns the width of the stack as we requested it.
133 ////////////////////////////////////////////////////////////////////
135 get_width() const {
136  return _width;
137 }
138 
139 ////////////////////////////////////////////////////////////////////
140 // Function: WinStatsLabelStack::get_height
141 // Access: Public
142 // Description: Returns the height of the stack as we requested it.
143 ////////////////////////////////////////////////////////////////////
145 get_height() const {
146  return _height;
147 }
148 
149 ////////////////////////////////////////////////////////////////////
150 // Function: WinStatsLabelStack::get_ideal_width
151 // Access: Public
152 // Description: Returns the width the stack would really prefer to be.
153 ////////////////////////////////////////////////////////////////////
156  return _ideal_width;
157 }
158 
159 ////////////////////////////////////////////////////////////////////
160 // Function: WinStatsLabelStack::get_label_y
161 // Access: Public
162 // Description: Returns the y position of the indicated label's bottom
163 // edge, relative to the label stack's parent window.
164 ////////////////////////////////////////////////////////////////////
166 get_label_y(int label_index) const {
167  nassertr(label_index >= 0 && label_index < (int)_labels.size(), 0);
168  return _labels[label_index]->get_y() + get_y();
169 }
170 
171 ////////////////////////////////////////////////////////////////////
172 // Function: WinStatsLabelStack::get_label_height
173 // Access: Public
174 // Description: Returns the height of the indicated label.
175 ////////////////////////////////////////////////////////////////////
177 get_label_height(int label_index) const {
178  nassertr(label_index >= 0 && label_index < (int)_labels.size(), 0);
179  return _labels[label_index]->get_height();
180 }
181 
182 ////////////////////////////////////////////////////////////////////
183 // Function: WinStatsLabelStack::get_label_collector_index
184 // Access: Public
185 // Description: Returns the collector index associated with the
186 // indicated label.
187 ////////////////////////////////////////////////////////////////////
189 get_label_collector_index(int label_index) const {
190  nassertr(label_index >= 0 && label_index < (int)_labels.size(), -1);
191  return _labels[label_index]->get_collector_index();
192 }
193 
194 ////////////////////////////////////////////////////////////////////
195 // Function: WinStatsLabelStack::clear_labels
196 // Access: Public
197 // Description: Removes the set of labels and starts a new set.
198 ////////////////////////////////////////////////////////////////////
201  Labels::iterator li;
202  for (li = _labels.begin(); li != _labels.end(); ++li) {
203  delete (*li);
204  }
205  _labels.clear();
206  _ideal_width = 0;
207 }
208 
209 ////////////////////////////////////////////////////////////////////
210 // Function: WinStatsLabelStack::add_label
211 // Access: Public
212 // Description: Adds a new label to the top of the stack; returns the
213 // new label index.
214 ////////////////////////////////////////////////////////////////////
217  int thread_index, int collector_index, bool use_fullname) {
218  int yp = _height;
219  if (!_labels.empty()) {
220  WinStatsLabel *top_label = _labels.back();
221  yp = top_label->get_y() - top_label->get_height();
222  }
223  WinStatsLabel *label =
224  new WinStatsLabel(monitor, graph, thread_index, collector_index, use_fullname);
225  if (_window) {
226  label->setup(_window);
227  label->set_pos(0, yp, _width);
228  }
229  _ideal_width = max(_ideal_width, label->get_ideal_width());
230 
231  int label_index = (int)_labels.size();
232  _labels.push_back(label);
233 
234  return label_index;
235 }
236 
237 ////////////////////////////////////////////////////////////////////
238 // Function: WinStatsLabelStack::get_num_labels
239 // Access: Public
240 // Description: Returns the number of labels in the stack.
241 ////////////////////////////////////////////////////////////////////
243 get_num_labels() const {
244  return _labels.size();
245 }
246 
247 ////////////////////////////////////////////////////////////////////
248 // Function: WinStatsLabelStack::highlight_label
249 // Access: Public
250 // Description: Draws a highlight around the label representing the
251 // indicated collector, and removes the highlight from
252 // any other label. Specify -1 to remove the highlight
253 // from all labels.
254 ////////////////////////////////////////////////////////////////////
256 highlight_label(int collector_index) {
257  if (_highlight_label != collector_index) {
258  _highlight_label = collector_index;
259  Labels::iterator li;
260  for (li = _labels.begin(); li != _labels.end(); ++li) {
261  WinStatsLabel *label = (*li);
262  label->set_highlight(label->get_collector_index() == _highlight_label);
263  }
264  }
265 }
266 
267 
268 ////////////////////////////////////////////////////////////////////
269 // Function: WinStatsLabelStack::create_window
270 // Access: Private
271 // Description: Creates the window for this stack.
272 ////////////////////////////////////////////////////////////////////
273 void WinStatsLabelStack::
274 create_window(HWND parent_window) {
275  if (_window) {
276  return;
277  }
278 
279  HINSTANCE application = GetModuleHandle(NULL);
280  register_window_class(application);
281 
282  _window =
283  CreateWindow(_window_class_name, "label stack", WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
284  0, 0, 0, 0,
285  parent_window, NULL, application, 0);
286  if (!_window) {
287  nout << "Could not create Label Stack window!\n";
288  exit(1);
289  }
290 
291  SetWindowLongPtr(_window, 0, (LONG_PTR)this);
292 }
293 
294 ////////////////////////////////////////////////////////////////////
295 // Function: WinStatsLabelStack::register_window_class
296 // Access: Private, Static
297 // Description: Registers the window class for the label window, if
298 // it has not already been registered.
299 ////////////////////////////////////////////////////////////////////
300 void WinStatsLabelStack::
301 register_window_class(HINSTANCE application) {
302  if (_window_class_registered) {
303  return;
304  }
305 
306  WNDCLASS wc;
307 
308  ZeroMemory(&wc, sizeof(WNDCLASS));
309  wc.style = 0;
310  wc.lpfnWndProc = (WNDPROC)static_window_proc;
311  wc.hInstance = application;
312  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
313  wc.lpszMenuName = NULL;
314  wc.lpszClassName = _window_class_name;
315 
316  // Reserve space to associate the this pointer with the window.
317  wc.cbWndExtra = sizeof(WinStatsLabelStack *);
318 
319  if (!RegisterClass(&wc)) {
320  nout << "Could not register Label Stack window class!\n";
321  exit(1);
322  }
323 
324  _window_class_registered = true;
325 }
326 
327 ////////////////////////////////////////////////////////////////////
328 // Function: WinStatsLabelStack::static_window_proc
329 // Access: Private, Static
330 // Description:
331 ////////////////////////////////////////////////////////////////////
332 LONG WINAPI WinStatsLabelStack::
333 static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
334  WinStatsLabelStack *self = (WinStatsLabelStack *)GetWindowLongPtr(hwnd, 0);
335  if (self != (WinStatsLabelStack *)NULL && self->_window == hwnd) {
336  return self->window_proc(hwnd, msg, wparam, lparam);
337  } else {
338  return DefWindowProc(hwnd, msg, wparam, lparam);
339  }
340 }
341 
342 ////////////////////////////////////////////////////////////////////
343 // Function: WinStatsLabelStack::window_proc
344 // Access: Private
345 // Description:
346 ////////////////////////////////////////////////////////////////////
347 LONG WinStatsLabelStack::
348 window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
349  switch (msg) {
350  case WM_PAINT:
351  {
352  PAINTSTRUCT ps;
353  HDC hdc = BeginPaint(hwnd, &ps);
354 
355  RECT rect = { 0, 0, _width, _height };
356  FillRect(hdc, &rect, (HBRUSH)COLOR_BACKGROUND);
357  EndPaint(hwnd, &ps);
358  return 0;
359  }
360 
361  default:
362  break;
363  }
364 
365  return DefWindowProc(hwnd, msg, wparam, lparam);
366 }
int get_ideal_width() const
Returns the width the label would really prefer to be.
int get_y() const
Returns the y position of the stack on its parent.
int get_label_collector_index(int label_index) const
Returns the collector index associated with the indicated label.
int get_y() const
Returns the y position of the label on its parent.
int get_collector_index() const
Returns the collector this label represents.
int get_ideal_width() const
Returns the width the stack would really prefer to be.
void setup(HWND parent_window)
Creates the actual window object.
A text label that will draw in color appropriate for a particular collector.
Definition: winStatsLabel.h:32
int get_height() const
Returns the height of the label as we requested it.
int get_num_labels() const
Returns the number of labels in the stack.
int get_x() const
Returns the x position of the stack on its parent.
void set_highlight(bool highlight)
Enables or disables the visual highlight for this label.
A window that contains a stack of labels from bottom to top.
int get_label_height(int label_index) const
Returns the height of the indicated label.
int get_label_y(int label_index) const
Returns the y position of the indicated label&#39;s bottom edge, relative to the label stack&#39;s parent win...
This is just an abstract base class to provide a common pointer type for the various kinds of graphs ...
Definition: winStatsGraph.h:32
void clear_labels()
Removes the set of labels and starts a new set.
bool is_setup() const
Returns true if the label stack has been set up, false otherwise.
This class represents a connection to a PStatsClient and manages the data exchange with the client...
int add_label(WinStatsMonitor *monitor, WinStatsGraph *graph, int thread_index, int collector_index, bool use_fullname)
Adds a new label to the top of the stack; returns the new label index.
int get_width() const
Returns the width of the stack as we requested it.
int get_height() const
Returns the height of the stack as we requested it.
void set_pos(int x, int y, int width, int height)
Sets the position and size of the label stack on its parent.
void setup(HWND parent_window)
Creates the actual window.
void set_pos(int x, int y, int width)
Sets the position of the label on its parent.
void highlight_label(int collector_index)
Draws a highlight around the label representing the indicated collector, and removes the highlight fr...