21 static const int default_strip_chart_width = 400;
22 static const int default_strip_chart_height = 100;
27 size_t WinStatsStripChart::_check_box_height = 13;
28 size_t WinStatsStripChart::_check_box_width = 13;
30 bool WinStatsStripChart::_window_class_registered =
false;
31 const char *
const WinStatsStripChart::_window_class_name =
"strip";
38 int collector_index,
bool show_level) :
40 show_level ? monitor->get_level_view(collector_index, thread_index) : monitor->get_view(thread_index),
43 default_strip_chart_width,
44 default_strip_chart_height),
56 if (_unit_name.empty()) {
57 set_guide_bar_units(GBU_named);
59 set_guide_bar_units(GBU_named | GBU_show_units);
64 set_guide_bar_units(get_guide_bar_units() | GBU_show_units);
67 _smooth_check_box = 0;
77 ~WinStatsStripChart() {
99 SetWindowText(_window, window_title.c_str());
107 if (_net_value_text != text) {
108 _net_value_text = text;
110 GetClientRect(_window, &rect);
111 rect.bottom = _top_margin;
112 InvalidateRect(_window, &rect, TRUE);
122 PStatStripChart::force_redraw();
130 PStatStripChart::changed_size(graph_xsize, graph_ysize);
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);
147 GetClientRect(_window, &rect);
148 rect.left = _right_margin;
149 InvalidateRect(_window, &rect, TRUE);
151 GetClientRect(_window, &rect);
152 rect.bottom = _top_margin;
153 InvalidateRect(_window, &rect, TRUE);
164 if (scroll_speed != 0.0f) {
174 if (collector_index < 0) {
187 if (def._parent_index == 0 &&
get_view().get_show_level()) {
209 GetClientRect(_window, &rect);
210 rect.left = _right_margin;
211 InvalidateRect(_window, &rect, TRUE);
217 void WinStatsStripChart::
219 PStatStripChart::update_labels();
221 _label_stack.clear_labels();
223 _label_stack.add_label(WinStatsGraph::_monitor,
this, _thread_index,
226 _labels_changed =
false;
232 void WinStatsStripChart::
235 FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
242 void WinStatsStripChart::
243 copy_region(
int start_x,
int end_x,
int dest_x) {
244 BitBlt(_bitmap_dc, dest_x, 0,
246 _bitmap_dc, start_x, 0,
250 _brush_origin += (dest_x - start_x);
251 SetBrushOrgEx(_bitmap_dc, _brush_origin, 0,
nullptr);
254 dest_x, 0, dest_x + end_x - start_x,
get_ysize()
256 InvalidateRect(_graph_window, &rect, FALSE);
263 void WinStatsStripChart::
266 RECT rect = { x, 0, x + w,
get_ysize() };
267 FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
269 double overall_time = 0.0;
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);
283 FillRect(_bitmap_dc, &rect, brush);
291 FillRect(_bitmap_dc, &rect, brush);
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));
308 void WinStatsStripChart::
310 RECT rect = { x, 0, x + 1,
get_ysize() };
311 FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH));
319 void WinStatsStripChart::
320 end_draw(
int from_x,
int to_x) {
323 for (
int i = 0; i < num_guide_bars; i++) {
330 InvalidateRect(_graph_window, &rect, FALSE);
336 LONG WinStatsStripChart::
337 window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
340 if (_potential_drag_mode == DM_new_guide_bar) {
341 set_drag_mode(DM_new_guide_bar);
342 SetCapture(_graph_window);
348 switch (LOWORD(wparam)) {
350 if ((HWND)lparam == _smooth_check_box) {
351 int result = SendMessage(_smooth_check_box, BM_GETCHECK, 0, 0);
363 return WinStatsGraph::window_proc(hwnd, msg, wparam, lparam);
369 LONG WinStatsStripChart::
370 graph_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
373 if (_potential_drag_mode == DM_none) {
374 set_drag_mode(DM_scale);
375 int16_t y = HIWORD(lparam);
377 SetCapture(_graph_window);
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);
384 SetCapture(_graph_window);
390 if (_drag_mode == DM_none && _potential_drag_mode == DM_none) {
392 int16_t x = LOWORD(lparam);
393 int16_t y = HIWORD(lparam);
398 TRACKMOUSEEVENT tme = {
399 sizeof(TRACKMOUSEEVENT),
404 TrackMouseEvent(&tme);
408 _label_stack.highlight_label(-1);
411 if (_drag_mode == DM_scale) {
412 int16_t y = HIWORD(lparam);
413 double ratio = 1.0f - ((double)y / (
double)
get_ysize());
419 }
else if (_drag_mode == DM_new_guide_bar) {
422 int16_t y = HIWORD(lparam);
424 set_drag_mode(DM_guide_bar);
429 }
else if (_drag_mode == DM_guide_bar) {
430 int16_t y = HIWORD(lparam);
438 _label_stack.highlight_label(-1);
442 if (_drag_mode == DM_scale) {
443 set_drag_mode(DM_none);
447 }
else if (_drag_mode == DM_guide_bar) {
448 int16_t y = HIWORD(lparam);
454 set_drag_mode(DM_none);
460 case WM_LBUTTONDBLCLK:
464 int16_t x = LOWORD(lparam);
465 int16_t y = HIWORD(lparam);
475 return WinStatsGraph::graph_window_proc(hwnd, msg, wparam, lparam);
483 void WinStatsStripChart::
484 additional_window_paint(HDC hdc) {
486 HFONT hfnt = (HFONT)GetStockObject(ANSI_VAR_FONT);
487 SelectObject(hdc, hfnt);
488 SetTextAlign(hdc, TA_LEFT | TA_TOP);
489 SetBkMode(hdc, TRANSPARENT);
492 GetClientRect(_window, &rect);
493 int x = rect.right - _right_margin + 2;
498 for (i = 0; i < num_guide_bars; i++) {
503 draw_guide_label(hdc, x, top_value, last_y);
507 for (i = 0; i < num_user_guide_bars; i++) {
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());
521 SetTextAlign(hdc, TA_LEFT | TA_BOTTOM);
522 TextOut(hdc, _left_margin + _check_box_width + 2, _top_margin,
"Smooth", 6);
530 void WinStatsStripChart::
531 additional_graph_window_paint(HDC hdc) {
533 for (
int i = 0; i < num_user_guide_bars; i++) {
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()) {
548 int y = mouse_y - _graph_top;
552 if (_drag_guide_bar >= 0) {
558 return DM_new_guide_bar;
562 return WinStatsGraph::consider_drag_start(mouse_x, mouse_y, width, height);
569 void WinStatsStripChart::
570 set_drag_mode(WinStatsGraph::DragMode drag_mode) {
571 WinStatsGraph::set_drag_mode(drag_mode);
573 switch (_drag_mode) {
576 case DM_right_margin:
584 int result = SendMessage(_smooth_check_box, BM_GETCHECK, 0, 0);
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,
600 SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
601 InvalidateRect(_smooth_check_box,
nullptr, TRUE);
608 void WinStatsStripChart::
609 draw_guide_bar(HDC hdc,
int from_x,
int to_x,
615 switch (bar._style) {
617 SelectObject(hdc, _light_pen);
621 SelectObject(hdc, _user_guide_bar_pen);
625 SelectObject(hdc, _dark_pen);
628 MoveToEx(hdc, from_x, y,
nullptr);
629 LineTo(hdc, to_x + 1, y);
638 int WinStatsStripChart::
640 switch (bar._style) {
642 SetTextColor(hdc, _light_color);
646 SetTextColor(hdc, _user_guide_bar_color);
650 SetTextColor(hdc, _dark_color);
655 const string &label = bar._label;
657 GetTextExtentPoint32(hdc, label.data(), label.length(), &size);
659 if (bar._style != GBS_user) {
668 int this_y = _graph_top + y - size.cy / 2;
670 (last_y < this_y || last_y > this_y + size.cy)) {
671 TextOut(hdc, x, this_y,
672 label.data(), label.length());
683 void WinStatsStripChart::
689 HINSTANCE application = GetModuleHandle(
nullptr);
690 register_window_class(application);
696 _left_margin +
get_xsize() + _right_margin,
697 _top_margin +
get_ysize() + _bottom_margin
701 AdjustWindowRect(&win_rect, graph_window_style, FALSE);
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);
710 nout <<
"Could not create StripChart window!\n";
714 SetWindowLongPtr(_window, 0, (LONG_PTR)
this);
718 CreateWindow(
"BUTTON",
"",
719 WS_CHILD | BS_AUTOCHECKBOX,
720 0, 0, _check_box_width, _check_box_height,
721 _window,
nullptr, application, 0);
724 SetWindowPos(_window, HWND_TOP, 0, 0, 0, 0,
725 SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
732 void WinStatsStripChart::
733 register_window_class(HINSTANCE application) {
734 if (_window_class_registered) {
740 ZeroMemory(&wc,
sizeof(WNDCLASS));
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;
752 if (!RegisterClass(&wc)) {
753 nout <<
"Could not register StripChart window class!\n";
757 _window_class_registered =
true;
763 LONG WINAPI WinStatsStripChart::
764 static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
766 if (
self !=
nullptr && self->_window == hwnd) {
767 return self->window_proc(hwnd, msg, wparam, lparam);
769 return DefWindowProc(hwnd, msg, wparam, lparam);
void set_horizontal_scale(double time_width)
Changes the amount of time the width of the horizontal axis represents.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void new_collector(int collector_index)
Called whenever a new Collector definition is received from the client.
int get_xsize() const
Returns the width of the chart in pixels.
A window that draws a strip chart, given a view.
int get_guide_bar_units() const
Returns the units that are displayed for the guide bar labels.
void set_guide_bar_units(int unit_mask)
Sets the units that are displayed for the guide bar labels.
int get_ysize() const
Returns the height of the chart in pixels.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_num_labels() const
Returns the number of labels to be drawn for this chart.
void move_user_guide_bar(int n, double height)
Adjusts the height of the nth user-defined guide bar.
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...
The data associated with a particular client, but not with any one particular frame or thread: the li...
void set_vertical_scale(double value_height)
Changes the value the height of the vertical axis represents.
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...
const PStatCollectorDef & get_collector_def(int index) const
Returns the nth collector definition.
double pixel_to_height(int y) const
Converts a vertical pixel offset to a value (a "height" in the strip chart).
This is an abstract class that presents the interface for drawing a basic strip-chart,...
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 ...
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...
This is our own Panda specialization on the default STL vector.
int get_collector_index() const
Returns the particular collector whose data this strip chart reflects.
bool has_collector(int index) const
Returns true if the indicated collector has been defined by the client already, false otherwise.
const GuideBar & get_guide_bar(int n) const
Returns the nth horizontal guide bar.
PStatView & get_view() const
Returns the View this chart represents.
void update()
Updates the chart with the latest data.
This is just an abstract base class to provide a common pointer type for the various kinds of graphs ...
int height_to_pixel(double value) const
Converts a value (i.e.
void set_vertical_scale(double value_height)
Changes the value the height of the vertical axis represents.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void new_data(int thread_index, int frame_number)
Called as each frame's data is made available.
int get_label_collector(int n) const
Returns the collector index associated with the nth label.
This class represents a connection to a PStatsClient and manages the data exchange with the client.
virtual void new_collector(int collector_index)
Called whenever a new Collector definition is received from the client.
int get_num_guide_bars() const
Returns the number of horizontal guide bars that should be drawn, based on the indicated target frame...
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...
bool is_title_unknown() const
Returns true if get_title_text() has never yet returned an answer, false if it has.
void set_average_mode(bool average_mode)
Changes the average_mode flag.
void set_collector_index(int collector_index)
Changes the collector represented by this strip chart.
double get_vertical_scale() const
Returns total value the height of the vertical axis represents.
virtual void clicked_label(int collector_index)
Called when the user single-clicks on a label.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const PStatClientData * get_client_data() const
Returns the client data associated with this monitor.
HWND get_window() const
Returns the window handle to the monitor's window.
int add_user_guide_bar(double height)
Creates a new user guide bar and returns its index number.
Defines the details about the Collectors: the name, the suggested color, etc.
static std::string format_number(double value)
Returns a string representing the value nicely formatted for its range.
GuideBar get_user_guide_bar(int n) const
Returns the nth user-defined guide bar.
virtual void force_redraw()
Called when it is necessary to redraw the entire graph.
int get_num_user_guide_bars() const
Returns the current number of user-defined guide bars.
std::string get_title_text()
Returns the text suitable for the title label on the top line.
void remove_user_guide_bar(int n)
Removes the user guide bar with the indicated index number.