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