Panda3D
winStatsStripChart.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 winStatsStripChart.cxx
10  * @author drose
11  * @date 2003-12-03
12  */
13 
14 #include "winStatsStripChart.h"
15 #include "winStatsMonitor.h"
16 #include "pStatCollectorDef.h"
17 #include "numeric_types.h"
18 
19 using std::string;
20 
21 static const int default_strip_chart_width = 400;
22 static const int default_strip_chart_height = 100;
23 
24 // Surely we aren't expected to hardcode the size of a normal checkbox. But
25 // Windows seems to require this data to be passed to CreateWindow(), so what
26 // else can I do?
27 size_t WinStatsStripChart::_check_box_height = 13;
28 size_t WinStatsStripChart::_check_box_width = 13;
29 
30 bool WinStatsStripChart::_window_class_registered = false;
31 const char * const WinStatsStripChart::_window_class_name = "strip";
32 
33 /**
34  *
35  */
36 WinStatsStripChart::
37 WinStatsStripChart(WinStatsMonitor *monitor, int thread_index,
38  int collector_index, bool show_level) :
39  PStatStripChart(monitor,
40  show_level ? monitor->get_level_view(collector_index, thread_index) : monitor->get_view(thread_index),
41  thread_index,
42  collector_index,
43  default_strip_chart_width,
44  default_strip_chart_height),
45  WinStatsGraph(monitor)
46 {
47  _brush_origin = 0;
48 
49  _left_margin = 96;
50  _right_margin = 32;
51  _top_margin = 16;
52  _bottom_margin = 8;
53 
54  if (show_level) {
55  // If it's a level-type graph, show the appropriate units.
56  if (_unit_name.empty()) {
57  set_guide_bar_units(GBU_named);
58  } else {
59  set_guide_bar_units(GBU_named | GBU_show_units);
60  }
61 
62  } else {
63  // If it's a time-type graph, show the msHz units.
64  set_guide_bar_units(get_guide_bar_units() | GBU_show_units);
65  }
66 
67  _smooth_check_box = 0;
68 
69  create_window();
70  clear_region();
71 }
72 
73 /**
74  *
75  */
76 WinStatsStripChart::
77 ~WinStatsStripChart() {
78 }
79 
80 /**
81  * Called whenever a new Collector definition is received from the client.
82  */
84 new_collector(int collector_index) {
85  WinStatsGraph::new_collector(collector_index);
86 }
87 
88 /**
89  * Called as each frame's data is made available. There is no gurantee the
90  * frames will arrive in order, or that all of them will arrive at all. The
91  * monitor should be prepared to accept frames received out-of-order or
92  * missing.
93  */
95 new_data(int thread_index, int frame_number) {
96  if (is_title_unknown()) {
97  string window_title = get_title_text();
98  if (!is_title_unknown()) {
99  SetWindowText(_window, window_title.c_str());
100  }
101  }
102 
103  if (!_pause) {
104  update();
105 
106  string text = format_number(get_average_net_value(), get_guide_bar_units(), get_guide_bar_unit_name());
107  if (_net_value_text != text) {
108  _net_value_text = text;
109  RECT rect;
110  GetClientRect(_window, &rect);
111  rect.bottom = _top_margin;
112  InvalidateRect(_window, &rect, TRUE);
113  }
114  }
115 }
116 
117 /**
118  * Called when it is necessary to redraw the entire graph.
119  */
121 force_redraw() {
122  PStatStripChart::force_redraw();
123 }
124 
125 /**
126  * Called when the user has resized the window, forcing a resize of the graph.
127  */
129 changed_graph_size(int graph_xsize, int graph_ysize) {
130  PStatStripChart::changed_size(graph_xsize, graph_ysize);
131 }
132 
133 /**
134  * Called when the user selects a new time units from the monitor pulldown
135  * menu, this should adjust the units for the graph to the indicated mask if
136  * it is a time-based graph.
137  */
139 set_time_units(int unit_mask) {
140  int old_unit_mask = get_guide_bar_units();
141  if ((old_unit_mask & (GBU_hz | GBU_ms)) != 0) {
142  unit_mask = unit_mask & (GBU_hz | GBU_ms);
143  unit_mask |= (old_unit_mask & GBU_show_units);
144  set_guide_bar_units(unit_mask);
145 
146  RECT rect;
147  GetClientRect(_window, &rect);
148  rect.left = _right_margin;
149  InvalidateRect(_window, &rect, TRUE);
150 
151  GetClientRect(_window, &rect);
152  rect.bottom = _top_margin;
153  InvalidateRect(_window, &rect, TRUE);
154  }
155 }
156 
157 /**
158  * Called when the user selects a new scroll speed from the monitor pulldown
159  * menu, this should adjust the speed for the graph to the indicated value.
160  */
162 set_scroll_speed(double scroll_speed) {
163  // The speed factor indicates chart widths per minute.
164  if (scroll_speed != 0.0f) {
165  set_horizontal_scale(60.0f / scroll_speed);
166  }
167 }
168 
169 /**
170  * Called when the user single-clicks on a label.
171  */
173 clicked_label(int collector_index) {
174  if (collector_index < 0) {
175  // Clicking on whitespace in the graph is the same as clicking on the top
176  // label.
177  collector_index = get_collector_index();
178  }
179 
180  if (collector_index == get_collector_index() && collector_index != 0) {
181  // Clicking on the top label means to go up to the parent level.
182  const PStatClientData *client_data =
183  WinStatsGraph::_monitor->get_client_data();
184  if (client_data->has_collector(collector_index)) {
185  const PStatCollectorDef &def =
186  client_data->get_collector_def(collector_index);
187  if (def._parent_index == 0 && get_view().get_show_level()) {
188  // Unless the parent is "Frame", and we're not a time collector.
189  } else {
190  set_collector_index(def._parent_index);
191  }
192  }
193 
194  } else {
195  // Clicking on any other label means to focus on that.
196  set_collector_index(collector_index);
197  }
198 }
199 
200 /**
201  * Changes the value the height of the vertical axis represents. This may
202  * force a redraw.
203  */
205 set_vertical_scale(double value_height) {
207 
208  RECT rect;
209  GetClientRect(_window, &rect);
210  rect.left = _right_margin;
211  InvalidateRect(_window, &rect, TRUE);
212 }
213 
214 /**
215  * Resets the list of labels.
216  */
217 void WinStatsStripChart::
218 update_labels() {
219  PStatStripChart::update_labels();
220 
221  _label_stack.clear_labels();
222  for (int i = 0; i < get_num_labels(); i++) {
223  _label_stack.add_label(WinStatsGraph::_monitor, this, _thread_index,
224  get_label_collector(i), false);
225  }
226  _labels_changed = false;
227 }
228 
229 /**
230  * Erases the chart area.
231  */
232 void WinStatsStripChart::
233 clear_region() {
234  RECT rect = { 0, 0, get_xsize(), get_ysize() };
235  FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
236 }
237 
238 /**
239  * Should be overridden by the user class to copy a region of the chart from
240  * one part of the chart to another. This is used to implement scrolling.
241  */
242 void WinStatsStripChart::
243 copy_region(int start_x, int end_x, int dest_x) {
244  BitBlt(_bitmap_dc, dest_x, 0,
245  end_x - start_x, get_ysize(),
246  _bitmap_dc, start_x, 0,
247  SRCCOPY);
248 
249  // Also shift the brush origin over, so we still get proper dithering.
250  _brush_origin += (dest_x - start_x);
251  SetBrushOrgEx(_bitmap_dc, _brush_origin, 0, nullptr);
252 
253  RECT rect = {
254  dest_x, 0, dest_x + end_x - start_x, get_ysize()
255  };
256  InvalidateRect(_graph_window, &rect, FALSE);
257 }
258 
259 /**
260  * Draws a single vertical slice of the strip chart, at the given pixel
261  * position, and corresponding to the indicated level data.
262  */
263 void WinStatsStripChart::
264 draw_slice(int x, int w, const PStatStripChart::FrameData &fdata) {
265  // Start by clearing the band first.
266  RECT rect = { x, 0, x + w, get_ysize() };
267  FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
268 
269  double overall_time = 0.0;
270  int y = get_ysize();
271 
272  FrameData::const_iterator fi;
273  for (fi = fdata.begin(); fi != fdata.end(); ++fi) {
274  const ColorData &cd = (*fi);
275  overall_time += cd._net_value;
276  HBRUSH brush = get_collector_brush(cd._collector_index);
277 
278  if (overall_time > get_vertical_scale()) {
279  // Off the top. Go ahead and clamp it by hand, in case it's so far off
280  // the top we'd overflow the 16-bit pixel value.
281  rect.top = 0;
282  rect.bottom = y;
283  FillRect(_bitmap_dc, &rect, brush);
284  // And we can consider ourselves done now.
285  return;
286  }
287 
288  int top_y = height_to_pixel(overall_time);
289  rect.top = top_y;
290  rect.bottom = y;
291  FillRect(_bitmap_dc, &rect, brush);
292  y = top_y;
293  }
294 }
295 
296 /**
297  * Draws a single vertical slice of background color.
298  */
299 void WinStatsStripChart::
300 draw_empty(int x, int w) {
301  RECT rect = { x, 0, x + w, get_ysize() };
302  FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
303 }
304 
305 /**
306  * Draws a single vertical slice of foreground color.
307  */
308 void WinStatsStripChart::
309 draw_cursor(int x) {
310  RECT rect = { x, 0, x + 1, get_ysize() };
311  FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH));
312 }
313 
314 /**
315  * Should be overridden by the user class. This hook will be called after
316  * drawing a series of color bars in the strip chart; it gives the pixel range
317  * that was just redrawn.
318  */
319 void WinStatsStripChart::
320 end_draw(int from_x, int to_x) {
321  // Draw in the guide bars.
322  int num_guide_bars = get_num_guide_bars();
323  for (int i = 0; i < num_guide_bars; i++) {
324  draw_guide_bar(_bitmap_dc, from_x, to_x, get_guide_bar(i));
325  }
326 
327  RECT rect = {
328  from_x, 0, to_x + 1, get_ysize()
329  };
330  InvalidateRect(_graph_window, &rect, FALSE);
331 }
332 
333 /**
334  *
335  */
336 LONG WinStatsStripChart::
337 window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
338  switch (msg) {
339  case WM_LBUTTONDOWN:
340  if (_potential_drag_mode == DM_new_guide_bar) {
341  set_drag_mode(DM_new_guide_bar);
342  SetCapture(_graph_window);
343  return 0;
344  }
345  break;
346 
347  case WM_COMMAND:
348  switch (LOWORD(wparam)) {
349  case BN_CLICKED:
350  if ((HWND)lparam == _smooth_check_box) {
351  int result = SendMessage(_smooth_check_box, BM_GETCHECK, 0, 0);
352  set_average_mode(result == BST_CHECKED);
353  return 0;
354  }
355  break;
356  }
357  break;
358 
359  default:
360  break;
361  }
362 
363  return WinStatsGraph::window_proc(hwnd, msg, wparam, lparam);
364 }
365 
366 /**
367  *
368  */
369 LONG WinStatsStripChart::
370 graph_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
371  switch (msg) {
372  case WM_LBUTTONDOWN:
373  if (_potential_drag_mode == DM_none) {
374  set_drag_mode(DM_scale);
375  int16_t y = HIWORD(lparam);
376  _drag_scale_start = pixel_to_height(y);
377  SetCapture(_graph_window);
378  return 0;
379 
380  } else if (_potential_drag_mode == DM_guide_bar && _drag_guide_bar >= 0) {
381  set_drag_mode(DM_guide_bar);
382  int16_t y = HIWORD(lparam);
383  _drag_start_y = y;
384  SetCapture(_graph_window);
385  return 0;
386  }
387  break;
388 
389  case WM_MOUSEMOVE:
390  if (_drag_mode == DM_none && _potential_drag_mode == DM_none) {
391  // When the mouse is over a color bar, highlight it.
392  int16_t x = LOWORD(lparam);
393  int16_t y = HIWORD(lparam);
394  _label_stack.highlight_label(get_collector_under_pixel(x, y));
395 
396  // Now we want to get a WM_MOUSELEAVE when the mouse leaves the graph
397  // window.
398  TRACKMOUSEEVENT tme = {
399  sizeof(TRACKMOUSEEVENT),
400  TME_LEAVE,
401  _graph_window,
402  0
403  };
404  TrackMouseEvent(&tme);
405 
406  } else {
407  // If the mouse is in some drag mode, stop highlighting.
408  _label_stack.highlight_label(-1);
409  }
410 
411  if (_drag_mode == DM_scale) {
412  int16_t y = HIWORD(lparam);
413  double ratio = 1.0f - ((double)y / (double)get_ysize());
414  if (ratio > 0.0f) {
415  set_vertical_scale(_drag_scale_start / ratio);
416  }
417  return 0;
418 
419  } else if (_drag_mode == DM_new_guide_bar) {
420  // We haven't created the new guide bar yet; we won't until the mouse
421  // comes within the graph's region.
422  int16_t y = HIWORD(lparam);
423  if (y >= 0 && y < get_ysize()) {
424  set_drag_mode(DM_guide_bar);
425  _drag_guide_bar = add_user_guide_bar(pixel_to_height(y));
426  return 0;
427  }
428 
429  } else if (_drag_mode == DM_guide_bar) {
430  int16_t y = HIWORD(lparam);
431  move_user_guide_bar(_drag_guide_bar, pixel_to_height(y));
432  return 0;
433  }
434  break;
435 
436  case WM_MOUSELEAVE:
437  // When the mouse leaves the graph, stop highlighting.
438  _label_stack.highlight_label(-1);
439  break;
440 
441  case WM_LBUTTONUP:
442  if (_drag_mode == DM_scale) {
443  set_drag_mode(DM_none);
444  ReleaseCapture();
445  return 0;
446 
447  } else if (_drag_mode == DM_guide_bar) {
448  int16_t y = HIWORD(lparam);
449  if (y < 0 || y >= get_ysize()) {
450  remove_user_guide_bar(_drag_guide_bar);
451  } else {
452  move_user_guide_bar(_drag_guide_bar, pixel_to_height(y));
453  }
454  set_drag_mode(DM_none);
455  ReleaseCapture();
456  return 0;
457  }
458  break;
459 
460  case WM_LBUTTONDBLCLK:
461  {
462  // Double-clicking on a color bar in the graph is the same as double-
463  // clicking on the corresponding label.
464  int16_t x = LOWORD(lparam);
465  int16_t y = HIWORD(lparam);
467  return 0;
468  }
469  break;
470 
471  default:
472  break;
473  }
474 
475  return WinStatsGraph::graph_window_proc(hwnd, msg, wparam, lparam);
476 }
477 
478 /**
479  * This is called during the servicing of WM_PAINT; it gives a derived class
480  * opportunity to do some further painting into the window (the outer window,
481  * not the graph window).
482  */
483 void WinStatsStripChart::
484 additional_window_paint(HDC hdc) {
485  // Draw in the labels for the guide bars.
486  HFONT hfnt = (HFONT)GetStockObject(ANSI_VAR_FONT);
487  SelectObject(hdc, hfnt);
488  SetTextAlign(hdc, TA_LEFT | TA_TOP);
489  SetBkMode(hdc, TRANSPARENT);
490 
491  RECT rect;
492  GetClientRect(_window, &rect);
493  int x = rect.right - _right_margin + 2;
494  int last_y = -100;
495 
496  int i;
497  int num_guide_bars = get_num_guide_bars();
498  for (i = 0; i < num_guide_bars; i++) {
499  last_y = draw_guide_label(hdc, x, get_guide_bar(i), last_y);
500  }
501 
502  GuideBar top_value = make_guide_bar(get_vertical_scale());
503  draw_guide_label(hdc, x, top_value, last_y);
504 
505  last_y = -100;
506  int num_user_guide_bars = get_num_user_guide_bars();
507  for (i = 0; i < num_user_guide_bars; i++) {
508  last_y = draw_guide_label(hdc, x, get_user_guide_bar(i), last_y);
509  }
510 
511  // Now draw the "net value" label at the top.
512  SetTextAlign(hdc, TA_RIGHT | TA_BOTTOM);
513  SetTextColor(hdc, RGB(0, 0, 0));
514  TextOut(hdc, rect.right - _right_margin, _top_margin,
515  _net_value_text.data(), _net_value_text.length());
516 
517  // Also draw the "Smooth" label on the check box. This isn't part of the
518  // check box itself, because doing that doesn't use the right font! Surely
519  // this isn't the correct Windows(tm) way to do this sort of thing, but I
520  // don't know any better for now.
521  SetTextAlign(hdc, TA_LEFT | TA_BOTTOM);
522  TextOut(hdc, _left_margin + _check_box_width + 2, _top_margin, "Smooth", 6);
523 }
524 
525 /**
526  * This is called during the servicing of WM_PAINT; it gives a derived class
527  * opportunity to do some further painting into the window (the outer window,
528  * not the graph window).
529  */
530 void WinStatsStripChart::
531 additional_graph_window_paint(HDC hdc) {
532  int num_user_guide_bars = get_num_user_guide_bars();
533  for (int i = 0; i < num_user_guide_bars; i++) {
534  draw_guide_bar(hdc, 0, get_xsize(), get_user_guide_bar(i));
535  }
536 }
537 
538 /**
539  * Based on the mouse position within the window's client area, look for
540  * draggable things the mouse might be hovering over and return the
541  * apprioprate DragMode enum or DM_none if nothing is indicated.
542  */
543 WinStatsGraph::DragMode WinStatsStripChart::
544 consider_drag_start(int mouse_x, int mouse_y, int width, int height) {
545  if (mouse_x >= _graph_left && mouse_x < _graph_left + get_xsize()) {
546  if (mouse_y >= _graph_top && mouse_y < _graph_top + get_ysize()) {
547  // See if the mouse is over a user-defined guide bar.
548  int y = mouse_y - _graph_top;
549  double from_height = pixel_to_height(y + 2);
550  double to_height = pixel_to_height(y - 2);
551  _drag_guide_bar = find_user_guide_bar(from_height, to_height);
552  if (_drag_guide_bar >= 0) {
553  return DM_guide_bar;
554  }
555 
556  } else {
557  // The mouse is above or below the graph; maybe create a new guide bar.
558  return DM_new_guide_bar;
559  }
560  }
561 
562  return WinStatsGraph::consider_drag_start(mouse_x, mouse_y, width, height);
563 }
564 
565 /**
566  * This should be called whenever the drag mode needs to change state. It
567  * provides hooks for a derived class to do something special.
568  */
569 void WinStatsStripChart::
570 set_drag_mode(WinStatsGraph::DragMode drag_mode) {
571  WinStatsGraph::set_drag_mode(drag_mode);
572 
573  switch (_drag_mode) {
574  case DM_scale:
575  case DM_left_margin:
576  case DM_right_margin:
577  case DM_sizing:
578  // Disable smoothing for these expensive operations.
579  set_average_mode(false);
580  break;
581 
582  default:
583  // Restore smoothing according to the current setting of the check box.
584  int result = SendMessage(_smooth_check_box, BM_GETCHECK, 0, 0);
585  set_average_mode(result == BST_CHECKED);
586  }
587 }
588 
589 /**
590  * Repositions the graph child window within the parent window according to
591  * the _margin variables.
592  */
593 void WinStatsStripChart::
594 move_graph_window(int graph_left, int graph_top, int graph_xsize, int graph_ysize) {
595  WinStatsGraph::move_graph_window(graph_left, graph_top, graph_xsize, graph_ysize);
596  if (_smooth_check_box != 0) {
597  SetWindowPos(_smooth_check_box, 0,
598  _left_margin, _top_margin - _check_box_height - 1,
599  0, 0,
600  SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
601  InvalidateRect(_smooth_check_box, nullptr, TRUE);
602  }
603 }
604 
605 /**
606  * Draws the line for the indicated guide bar on the graph.
607  */
608 void WinStatsStripChart::
609 draw_guide_bar(HDC hdc, int from_x, int to_x,
610  const PStatGraph::GuideBar &bar) {
611  int y = height_to_pixel(bar._height);
612 
613  if (y > 0) {
614  // Only draw it if it's not too close to the top.
615  switch (bar._style) {
616  case GBS_target:
617  SelectObject(hdc, _light_pen);
618  break;
619 
620  case GBS_user:
621  SelectObject(hdc, _user_guide_bar_pen);
622  break;
623 
624  case GBS_normal:
625  SelectObject(hdc, _dark_pen);
626  break;
627  }
628  MoveToEx(hdc, from_x, y, nullptr);
629  LineTo(hdc, to_x + 1, y);
630  }
631 }
632 
633 /**
634  * Draws the text for the indicated guide bar label to the right of the graph,
635  * unless it would overlap with the indicated last label, whose top pixel
636  * value is given. Returns the top pixel value of the new label.
637  */
638 int WinStatsStripChart::
639 draw_guide_label(HDC hdc, int x, const PStatGraph::GuideBar &bar, int last_y) {
640  switch (bar._style) {
641  case GBS_target:
642  SetTextColor(hdc, _light_color);
643  break;
644 
645  case GBS_user:
646  SetTextColor(hdc, _user_guide_bar_color);
647  break;
648 
649  case GBS_normal:
650  SetTextColor(hdc, _dark_color);
651  break;
652  }
653 
654  int y = height_to_pixel(bar._height);
655  const string &label = bar._label;
656  SIZE size;
657  GetTextExtentPoint32(hdc, label.data(), label.length(), &size);
658 
659  if (bar._style != GBS_user) {
660  double from_height = pixel_to_height(y + size.cy);
661  double to_height = pixel_to_height(y - size.cy);
662  if (find_user_guide_bar(from_height, to_height) >= 0) {
663  // Omit the label: there's a user-defined guide bar in the same space.
664  return last_y;
665  }
666  }
667 
668  int this_y = _graph_top + y - size.cy / 2;
669  if (y >= 0 && y < get_ysize() &&
670  (last_y < this_y || last_y > this_y + size.cy)) {
671  TextOut(hdc, x, this_y,
672  label.data(), label.length());
673  last_y = this_y;
674  }
675 
676  return last_y;
677 }
678 
679 
680 /**
681  * Creates the window for this strip chart.
682  */
683 void WinStatsStripChart::
684 create_window() {
685  if (_window) {
686  return;
687  }
688 
689  HINSTANCE application = GetModuleHandle(nullptr);
690  register_window_class(application);
691 
692  string window_title = get_title_text();
693 
694  RECT win_rect = {
695  0, 0,
696  _left_margin + get_xsize() + _right_margin,
697  _top_margin + get_ysize() + _bottom_margin
698  };
699 
700  // compute window size based on desired client area size
701  AdjustWindowRect(&win_rect, graph_window_style, FALSE);
702 
703  _window =
704  CreateWindow(_window_class_name, window_title.c_str(), graph_window_style,
705  CW_USEDEFAULT, CW_USEDEFAULT,
706  win_rect.right - win_rect.left,
707  win_rect.bottom - win_rect.top,
708  WinStatsGraph::_monitor->get_window(), nullptr, application, 0);
709  if (!_window) {
710  nout << "Could not create StripChart window!\n";
711  exit(1);
712  }
713 
714  SetWindowLongPtr(_window, 0, (LONG_PTR)this);
715  setup_label_stack();
716 
717  _smooth_check_box =
718  CreateWindow("BUTTON", "",
719  WS_CHILD | BS_AUTOCHECKBOX,
720  0, 0, _check_box_width, _check_box_height,
721  _window, nullptr, application, 0);
722 
723  // Ensure that the window is on top of the stack.
724  SetWindowPos(_window, HWND_TOP, 0, 0, 0, 0,
725  SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
726 }
727 
728 /**
729  * Registers the window class for the stripChart window, if it has not already
730  * been registered.
731  */
732 void WinStatsStripChart::
733 register_window_class(HINSTANCE application) {
734  if (_window_class_registered) {
735  return;
736  }
737 
738  WNDCLASS wc;
739 
740  ZeroMemory(&wc, sizeof(WNDCLASS));
741  wc.style = 0;
742  wc.lpfnWndProc = (WNDPROC)static_window_proc;
743  wc.hInstance = application;
744  wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
745  wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
746  wc.lpszMenuName = nullptr;
747  wc.lpszClassName = _window_class_name;
748 
749  // Reserve space to associate the this pointer with the window.
750  wc.cbWndExtra = sizeof(WinStatsStripChart *);
751 
752  if (!RegisterClass(&wc)) {
753  nout << "Could not register StripChart window class!\n";
754  exit(1);
755  }
756 
757  _window_class_registered = true;
758 }
759 
760 /**
761  *
762  */
763 LONG WINAPI WinStatsStripChart::
764 static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
765  WinStatsStripChart *self = (WinStatsStripChart *)GetWindowLongPtr(hwnd, 0);
766  if (self != nullptr && self->_window == hwnd) {
767  return self->window_proc(hwnd, msg, wparam, lparam);
768  } else {
769  return DefWindowProc(hwnd, msg, wparam, lparam);
770  }
771 }
WinStatsStripChart::new_data
virtual void new_data(int thread_index, int frame_number)
Called as each frame's data is made available.
Definition: winStatsStripChart.cxx:95
PStatStripChart::pixel_to_height
double pixel_to_height(int y) const
Converts a vertical pixel offset to a value (a "height" in the strip chart).
Definition: pStatStripChart.I:155
PStatStripChart::get_view
PStatView & get_view() const
Returns the View this chart represents.
Definition: pStatStripChart.I:18
PStatGraph::get_label_collector
int get_label_collector(int n) const
Returns the collector index associated with the nth label.
Definition: pStatGraph.I:34
PStatClientData::has_collector
bool has_collector(int index) const
Returns true if the indicated collector has been defined by the client already, false otherwise.
Definition: pStatClientData.cxx:81
pvector
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
WinStatsStripChart::set_time_units
virtual void set_time_units(int unit_mask)
Called when the user selects a new time units from the monitor pulldown menu, this should adjust the ...
Definition: winStatsStripChart.cxx:139
WinStatsGraph::new_collector
virtual void new_collector(int collector_index)
Called whenever a new Collector definition is received from the client.
Definition: winStatsGraph.cxx:90
PStatClientData::get_collector_def
const PStatCollectorDef & get_collector_def(int index) const
Returns the nth collector definition.
Definition: pStatClientData.cxx:90
WinStatsStripChart::force_redraw
virtual void force_redraw()
Called when it is necessary to redraw the entire graph.
Definition: winStatsStripChart.cxx:121
PStatStripChart::get_collector_under_pixel
int get_collector_under_pixel(int xpoint, int ypoint)
Return the collector index associated with the particular band of color at the indicated pixel locati...
Definition: pStatStripChart.cxx:201
numeric_types.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PStatStripChart::get_vertical_scale
double get_vertical_scale() const
Returns total value the height of the vertical axis represents.
Definition: pStatStripChart.I:72
PStatStripChart::get_collector_index
int get_collector_index() const
Returns the particular collector whose data this strip chart reflects.
Definition: pStatStripChart.I:26
PStatStripChart
This is an abstract class that presents the interface for drawing a basic strip-chart,...
Definition: pStatStripChart.h:38
WinStatsStripChart::new_collector
virtual void new_collector(int collector_index)
Called whenever a new Collector definition is received from the client.
Definition: winStatsStripChart.cxx:84
PStatGraph::add_user_guide_bar
int add_user_guide_bar(double height)
Creates a new user guide bar and returns its index number.
Definition: pStatGraph.cxx:125
WinStatsStripChart::set_scroll_speed
virtual void set_scroll_speed(double scroll_speed)
Called when the user selects a new scroll speed from the monitor pulldown menu, this should adjust th...
Definition: winStatsStripChart.cxx:162
WinStatsStripChart
A window that draws a strip chart, given a view.
Definition: winStatsStripChart.h:33
PStatCollectorDef
Defines the details about the Collectors: the name, the suggested color, etc.
Definition: pStatCollectorDef.h:29
PStatGraph::get_num_guide_bars
int get_num_guide_bars() const
Returns the number of horizontal guide bars that should be drawn, based on the indicated target frame...
Definition: pStatGraph.cxx:75
WinStatsStripChart::set_vertical_scale
void set_vertical_scale(double value_height)
Changes the value the height of the vertical axis represents.
Definition: winStatsStripChart.cxx:205
PStatGraph::GuideBar
Definition: pStatGraph.h:57
PStatClientData
The data associated with a particular client, but not with any one particular frame or thread: the li...
Definition: pStatClientData.h:36
PStatGraph::get_xsize
int get_xsize() const
Returns the width of the chart in pixels.
Definition: pStatGraph.I:82
WinStatsGraph
This is just an abstract base class to provide a common pointer type for the various kinds of graphs ...
Definition: winStatsGraph.h:32
PStatStripChart::update
void update()
Updates the chart with the latest data.
Definition: pStatStripChart.cxx:84
PStatGraph::get_user_guide_bar
GuideBar get_user_guide_bar(int n) const
Returns the nth user-defined guide bar.
Definition: pStatGraph.cxx:108
PStatGraph::get_guide_bar_units
int get_guide_bar_units() const
Returns the units that are displayed for the guide bar labels.
Definition: pStatGraph.I:111
PStatStripChart::set_average_mode
void set_average_mode(bool average_mode)
Changes the average_mode flag.
Definition: pStatStripChart.I:107
PStatGraph::get_ysize
int get_ysize() const
Returns the height of the chart in pixels.
Definition: pStatGraph.I:90
PStatGraph::get_num_user_guide_bars
int get_num_user_guide_bars() const
Returns the current number of user-defined guide bars.
Definition: pStatGraph.cxx:100
winStatsMonitor.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
WinStatsStripChart::changed_graph_size
virtual void changed_graph_size(int graph_xsize, int graph_ysize)
Called when the user has resized the window, forcing a resize of the graph.
Definition: winStatsStripChart.cxx:129
PStatGraph::format_number
static std::string format_number(double value)
Returns a string representing the value nicely formatted for its range.
Definition: pStatGraph.cxx:153
PStatGraph::get_num_labels
int get_num_labels() const
Returns the number of labels to be drawn for this chart.
Definition: pStatGraph.I:26
PStatStripChart::height_to_pixel
int height_to_pixel(double value) const
Converts a value (i.e.
Definition: pStatStripChart.I:146
PStatGraph::find_user_guide_bar
int find_user_guide_bar(double from_height, double to_height) const
Returns the index number of the first user guide bar found whose height is within the indicated range...
Definition: pStatGraph.cxx:144
PStatGraph::remove_user_guide_bar
void remove_user_guide_bar(int n)
Removes the user guide bar with the indicated index number.
Definition: pStatGraph.cxx:134
PStatStripChart::is_title_unknown
bool is_title_unknown() const
Returns true if get_title_text() has never yet returned an answer, false if it has.
Definition: pStatStripChart.cxx:291
PStatMonitor::get_client_data
const PStatClientData * get_client_data() const
Returns the client data associated with this monitor.
Definition: pStatMonitor.I:26
PStatStripChart::set_vertical_scale
void set_vertical_scale(double value_height)
Changes the value the height of the vertical axis represents.
Definition: pStatStripChart.I:60
PStatGraph::set_guide_bar_units
void set_guide_bar_units(int unit_mask)
Sets the units that are displayed for the guide bar labels.
Definition: pStatGraph.I:99
winStatsStripChart.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
WinStatsMonitor
This class represents a connection to a PStatsClient and manages the data exchange with the client.
Definition: winStatsMonitor.h:38
PStatGraph::move_user_guide_bar
void move_user_guide_bar(int n, double height)
Adjusts the height of the nth user-defined guide bar.
Definition: pStatGraph.cxx:117
pStatCollectorDef.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PStatStripChart::set_collector_index
void set_collector_index(int collector_index)
Changes the collector represented by this strip chart.
Definition: pStatStripChart.cxx:136
PStatStripChart::set_horizontal_scale
void set_horizontal_scale(double time_width)
Changes the amount of time the width of the horizontal axis represents.
Definition: pStatStripChart.I:35
PStatGraph::get_guide_bar
const GuideBar & get_guide_bar(int n) const
Returns the nth horizontal guide bar.
Definition: pStatGraph.cxx:87
WinStatsStripChart::clicked_label
virtual void clicked_label(int collector_index)
Called when the user single-clicks on a label.
Definition: winStatsStripChart.cxx:173
PStatStripChart::get_title_text
std::string get_title_text()
Returns the text suitable for the title label on the top line.
Definition: pStatStripChart.cxx:255
PStatGraph::get_guide_bar_unit_name
const std::string & get_guide_bar_unit_name() const
Returns the name of the units to be used for the guide bars if the units type is set to GBU_named | G...
Definition: pStatGraph.I:129