15 #include "winStatsStripChart.h"
16 #include "winStatsMonitor.h"
17 #include "pStatCollectorDef.h"
18 #include "numeric_types.h"
20 static const int default_strip_chart_width = 400;
21 static const int default_strip_chart_height = 100;
26 size_t WinStatsStripChart::_check_box_height = 13;
27 size_t WinStatsStripChart::_check_box_width = 13;
29 bool WinStatsStripChart::_window_class_registered =
false;
30 const char *
const WinStatsStripChart::_window_class_name =
"strip";
39 int collector_index,
bool show_level) :
41 show_level ? monitor->get_level_view(collector_index, thread_index) : monitor->get_view(thread_index),
44 default_strip_chart_width,
45 default_strip_chart_height),
57 if (_unit_name.empty()) {
58 set_guide_bar_units(GBU_named);
60 set_guide_bar_units(GBU_named | GBU_show_units);
65 set_guide_bar_units(get_guide_bar_units() | GBU_show_units);
68 _smooth_check_box = 0;
80 ~WinStatsStripChart() {
108 SetWindowText(_window, window_title.c_str());
116 if (_net_value_text != text) {
117 _net_value_text = text;
119 GetClientRect(_window, &rect);
120 rect.bottom = _top_margin;
121 InvalidateRect(_window, &rect, TRUE);
133 PStatStripChart::force_redraw();
144 PStatStripChart::changed_size(graph_xsize, graph_ysize);
158 if ((old_unit_mask & (GBU_hz | GBU_ms)) != 0) {
159 unit_mask = unit_mask & (GBU_hz | GBU_ms);
160 unit_mask |= (old_unit_mask & GBU_show_units);
164 GetClientRect(_window, &rect);
165 rect.left = _right_margin;
166 InvalidateRect(_window, &rect, TRUE);
168 GetClientRect(_window, &rect);
169 rect.bottom = _top_margin;
170 InvalidateRect(_window, &rect, TRUE);
184 if (scroll_speed != 0.0f) {
196 if (collector_index < 0) {
209 if (def._parent_index == 0 &&
get_view().get_show_level()) {
233 GetClientRect(_window, &rect);
234 rect.left = _right_margin;
235 InvalidateRect(_window, &rect, TRUE);
243 void WinStatsStripChart::
245 PStatStripChart::update_labels();
247 _label_stack.clear_labels();
249 _label_stack.add_label(WinStatsGraph::_monitor,
this, _thread_index,
252 _labels_changed =
false;
260 void WinStatsStripChart::
263 FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
273 void WinStatsStripChart::
274 copy_region(
int start_x,
int end_x,
int dest_x) {
275 BitBlt(_bitmap_dc, dest_x, 0,
277 _bitmap_dc, start_x, 0,
282 _brush_origin += (dest_x - start_x);
283 SetBrushOrgEx(_bitmap_dc, _brush_origin, 0, NULL);
286 dest_x, 0, dest_x + end_x - start_x,
get_ysize()
288 InvalidateRect(_graph_window, &rect, FALSE);
298 void WinStatsStripChart::
301 RECT rect = { x, 0, x + w,
get_ysize() };
302 FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
304 double overall_time = 0.0;
307 FrameData::const_iterator fi;
308 for (fi = fdata.begin(); fi != fdata.end(); ++fi) {
309 const ColorData &cd = (*fi);
310 overall_time += cd._net_value;
311 HBRUSH brush = get_collector_brush(cd._collector_index);
318 FillRect(_bitmap_dc, &rect, brush);
326 FillRect(_bitmap_dc, &rect, brush);
336 void WinStatsStripChart::
337 draw_empty(
int x,
int w) {
338 RECT rect = { x, 0, x + w,
get_ysize() };
339 FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
347 void WinStatsStripChart::
349 RECT rect = { x, 0, x + 1,
get_ysize() };
350 FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH));
361 void WinStatsStripChart::
362 end_draw(
int from_x,
int to_x) {
365 for (
int i = 0; i < num_guide_bars; i++) {
372 InvalidateRect(_graph_window, &rect, FALSE);
380 LONG WinStatsStripChart::
381 window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
384 if (_potential_drag_mode == DM_new_guide_bar) {
385 set_drag_mode(DM_new_guide_bar);
386 SetCapture(_graph_window);
392 switch (LOWORD(wparam)) {
394 if ((HWND)lparam == _smooth_check_box) {
395 int result = SendMessage(_smooth_check_box, BM_GETCHECK, 0, 0);
407 return WinStatsGraph::window_proc(hwnd, msg, wparam, lparam);
415 LONG WinStatsStripChart::
416 graph_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
419 if (_potential_drag_mode == DM_none) {
420 set_drag_mode(DM_scale);
421 PN_int16 y = HIWORD(lparam);
423 SetCapture(_graph_window);
426 }
else if (_potential_drag_mode == DM_guide_bar && _drag_guide_bar >= 0) {
427 set_drag_mode(DM_guide_bar);
428 PN_int16 y = HIWORD(lparam);
430 SetCapture(_graph_window);
436 if (_drag_mode == DM_none && _potential_drag_mode == DM_none) {
438 PN_int16 x = LOWORD(lparam);
439 PN_int16 y = HIWORD(lparam);
444 TRACKMOUSEEVENT tme = {
445 sizeof(TRACKMOUSEEVENT),
450 TrackMouseEvent(&tme);
454 _label_stack.highlight_label(-1);
457 if (_drag_mode == DM_scale) {
458 PN_int16 y = HIWORD(lparam);
459 double ratio = 1.0f - ((double)y / (
double)
get_ysize());
465 }
else if (_drag_mode == DM_new_guide_bar) {
468 PN_int16 y = HIWORD(lparam);
470 set_drag_mode(DM_guide_bar);
475 }
else if (_drag_mode == DM_guide_bar) {
476 PN_int16 y = HIWORD(lparam);
484 _label_stack.highlight_label(-1);
488 if (_drag_mode == DM_scale) {
489 set_drag_mode(DM_none);
493 }
else if (_drag_mode == DM_guide_bar) {
494 PN_int16 y = HIWORD(lparam);
500 set_drag_mode(DM_none);
506 case WM_LBUTTONDBLCLK:
510 PN_int16 x = LOWORD(lparam);
511 PN_int16 y = HIWORD(lparam);
521 return WinStatsGraph::graph_window_proc(hwnd, msg, wparam, lparam);
532 void WinStatsStripChart::
533 additional_window_paint(HDC hdc) {
535 HFONT hfnt = (HFONT)GetStockObject(ANSI_VAR_FONT);
536 SelectObject(hdc, hfnt);
537 SetTextAlign(hdc, TA_LEFT | TA_TOP);
538 SetBkMode(hdc, TRANSPARENT);
541 GetClientRect(_window, &rect);
542 int x = rect.right - _right_margin + 2;
547 for (i = 0; i < num_guide_bars; i++) {
552 draw_guide_label(hdc, x, top_value, last_y);
556 for (i = 0; i < num_user_guide_bars; i++) {
561 SetTextAlign(hdc, TA_RIGHT | TA_BOTTOM);
562 SetTextColor(hdc, RGB(0, 0, 0));
563 TextOut(hdc, rect.right - _right_margin, _top_margin,
564 _net_value_text.data(), _net_value_text.length());
570 SetTextAlign(hdc, TA_LEFT | TA_BOTTOM);
571 TextOut(hdc, _left_margin + _check_box_width + 2, _top_margin,
"Smooth", 6);
582 void WinStatsStripChart::
583 additional_graph_window_paint(HDC hdc) {
585 for (
int i = 0; i < num_user_guide_bars; i++) {
598 WinStatsGraph::DragMode WinStatsStripChart::
599 consider_drag_start(
int mouse_x,
int mouse_y,
int width,
int height) {
600 if (mouse_x >= _graph_left && mouse_x < _graph_left +
get_xsize()) {
601 if (mouse_y >= _graph_top && mouse_y < _graph_top +
get_ysize()) {
603 int y = mouse_y - _graph_top;
607 if (_drag_guide_bar >= 0) {
614 return DM_new_guide_bar;
618 return WinStatsGraph::consider_drag_start(mouse_x, mouse_y, width, height);
628 void WinStatsStripChart::
629 set_drag_mode(WinStatsGraph::DragMode drag_mode) {
630 WinStatsGraph::set_drag_mode(drag_mode);
632 switch (_drag_mode) {
635 case DM_right_margin:
644 int result = SendMessage(_smooth_check_box, BM_GETCHECK, 0, 0);
655 void WinStatsStripChart::
656 move_graph_window(
int graph_left,
int graph_top,
int graph_xsize,
int graph_ysize) {
657 WinStatsGraph::move_graph_window(graph_left, graph_top, graph_xsize, graph_ysize);
658 if (_smooth_check_box != 0) {
659 SetWindowPos(_smooth_check_box, 0,
660 _left_margin, _top_margin - _check_box_height - 1,
662 SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
663 InvalidateRect(_smooth_check_box, NULL, TRUE);
673 void WinStatsStripChart::
674 draw_guide_bar(HDC hdc,
int from_x,
int to_x,
680 switch (bar._style) {
682 SelectObject(hdc, _light_pen);
686 SelectObject(hdc, _user_guide_bar_pen);
690 SelectObject(hdc, _dark_pen);
693 MoveToEx(hdc, from_x, y, NULL);
694 LineTo(hdc, to_x + 1, y);
706 int WinStatsStripChart::
708 switch (bar._style) {
710 SetTextColor(hdc, _light_color);
714 SetTextColor(hdc, _user_guide_bar_color);
718 SetTextColor(hdc, _dark_color);
723 const string &label = bar._label;
725 GetTextExtentPoint32(hdc, label.data(), label.length(), &size);
727 if (bar._style != GBS_user) {
736 int this_y = _graph_top + y - size.cy / 2;
738 (last_y < this_y || last_y > this_y + size.cy)) {
739 TextOut(hdc, x, this_y,
740 label.data(), label.length());
753 void WinStatsStripChart::
759 HINSTANCE application = GetModuleHandle(NULL);
760 register_window_class(application);
766 _left_margin +
get_xsize() + _right_margin,
767 _top_margin +
get_ysize() + _bottom_margin
771 AdjustWindowRect(&win_rect, graph_window_style, FALSE);
774 CreateWindow(_window_class_name, window_title.c_str(), graph_window_style,
775 CW_USEDEFAULT, CW_USEDEFAULT,
776 win_rect.right - win_rect.left,
777 win_rect.bottom - win_rect.top,
778 WinStatsGraph::_monitor->
get_window(), NULL, application, 0);
780 nout <<
"Could not create StripChart window!\n";
784 SetWindowLongPtr(_window, 0, (LONG_PTR)
this);
788 CreateWindow(
"BUTTON",
"",
789 WS_CHILD | BS_AUTOCHECKBOX,
790 0, 0, _check_box_width, _check_box_height,
791 _window, NULL, application, 0);
794 SetWindowPos(_window, HWND_TOP, 0, 0, 0, 0,
795 SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
804 void WinStatsStripChart::
805 register_window_class(HINSTANCE application) {
806 if (_window_class_registered) {
812 ZeroMemory(&wc,
sizeof(WNDCLASS));
814 wc.lpfnWndProc = (WNDPROC)static_window_proc;
815 wc.hInstance = application;
816 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
817 wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
818 wc.lpszMenuName = NULL;
819 wc.lpszClassName = _window_class_name;
824 if (!RegisterClass(&wc)) {
825 nout <<
"Could not register StripChart window class!\n";
829 _window_class_registered =
true;
837 LONG WINAPI WinStatsStripChart::
838 static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
841 return self->window_proc(hwnd, msg, wparam, lparam);
843 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.
int height_to_pixel(double value) const
Converts a value (i.e.
virtual void new_collector(int collector_index)
Called whenever a new Collector definition is received from the client.
double pixel_to_height(int y) const
Converts a vertical pixel offset to a value (a "height" in the strip chart).
bool is_title_unknown() const
Returns true if get_title_text() has never yet returned an answer, false if it has.
A window that draws a strip chart, given a view.
int get_ysize() const
Returns the height of the chart in pixels.
void set_guide_bar_units(int unit_mask)
Sets the units that are displayed for the guide bar labels.
int get_label_collector(int n) const
Returns the collector index associated with the nth label.
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.
This is an abstract class that presents the interface for drawing a basic strip-chart, showing the relative value over an interval of time for several different collectors, differentiated by bands of color.
bool has_collector(int index) const
Returns true if the indicated collector has been defined by the client already, false otherwise...
int get_num_guide_bars() const
Returns the number of horizontal guide bars that should be drawn, based on the indicated target frame...
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.
void update()
Updates the chart with the latest data.
const PStatCollectorDef & get_collector_def(int index) const
Returns the nth collector definition.
This is just an abstract base class to provide a common pointer type for the various kinds of graphs ...
const GuideBar & get_guide_bar(int n) const
Returns the nth horizontal guide bar.
int get_collector_index() const
Returns the particular collector whose data this strip chart reflects.
string get_title_text()
Returns the text suitable for the title label on the top line.
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.
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...
GuideBar get_user_guide_bar(int n) const
Returns the nth user-defined guide bar.
virtual void new_data(int thread_index, int frame_number)
Called as each frame's data is made available.
int get_num_labels() const
Returns the number of labels to be drawn for this chart.
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_xsize() const
Returns the width of the chart in pixels.
int get_guide_bar_units() const
Returns the units that are displayed for the guide bar labels.
const PStatClientData * get_client_data() const
Returns the client data associated with this monitor.
const 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...
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.
PStatView & get_view() const
Returns the View this chart represents.
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 string format_number(double value)
Returns a string representing the value nicely formatted for its range.
HWND get_window() const
Returns the window handle to the monitor's window.
int get_num_user_guide_bars() const
Returns the current number of user-defined guide bars.
virtual void force_redraw()
Called when it is necessary to redraw the entire graph.
void remove_user_guide_bar(int n)
Removes the user guide bar with the indicated index number.