15 #include "winStatsPianoRoll.h" 16 #include "winStatsMonitor.h" 17 #include "numeric_types.h" 19 static const int default_piano_roll_width = 400;
20 static const int default_piano_roll_height = 200;
22 bool WinStatsPianoRoll::_window_class_registered =
false;
23 const char *
const WinStatsPianoRoll::_window_class_name =
"piano";
33 default_piano_roll_width,
34 default_piano_roll_height),
55 ~WinStatsPianoRoll() {
81 PStatPianoRoll::force_redraw();
92 PStatPianoRoll::changed_size(graph_xsize, graph_ysize);
106 if ((old_unit_mask & (GBU_hz | GBU_ms)) != 0) {
107 unit_mask = unit_mask & (GBU_hz | GBU_ms);
108 unit_mask |= (old_unit_mask & GBU_show_units);
112 GetClientRect(_window, &rect);
113 rect.left = _right_margin;
114 InvalidateRect(_window, &rect, TRUE);
125 if (collector_index >= 0) {
126 WinStatsGraph::_monitor->
open_strip_chart(_thread_index, collector_index,
false);
141 GetClientRect(_window, &rect);
142 rect.bottom = _top_margin;
143 InvalidateRect(_window, &rect, TRUE);
151 void WinStatsPianoRoll::
154 FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
163 void WinStatsPianoRoll::
169 for (
int i = 0; i < num_guide_bars; i++) {
179 void WinStatsPianoRoll::
180 draw_bar(
int row,
int from_x,
int to_x) {
181 if (row >= 0 && row < _label_stack.get_num_labels()) {
182 int y = _label_stack.get_label_y(row) - _graph_top;
183 int height = _label_stack.get_label_height(row);
186 from_x, y - height + 2,
190 HBRUSH brush = get_collector_brush(collector_index);
191 FillRect(_bitmap_dc, &rect, brush);
201 void WinStatsPianoRoll::
203 InvalidateRect(_graph_window, NULL, FALSE);
211 void WinStatsPianoRoll::
213 if (_labels_changed) {
223 LONG WinStatsPianoRoll::
224 window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
227 if (_potential_drag_mode == DM_new_guide_bar) {
228 set_drag_mode(DM_new_guide_bar);
229 SetCapture(_graph_window);
238 return WinStatsGraph::window_proc(hwnd, msg, wparam, lparam);
246 LONG WinStatsPianoRoll::
247 graph_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
250 if (_potential_drag_mode == DM_none) {
251 set_drag_mode(DM_scale);
252 PN_int16 x = LOWORD(lparam);
254 SetCapture(_graph_window);
257 }
else if (_potential_drag_mode == DM_guide_bar && _drag_guide_bar >= 0) {
258 set_drag_mode(DM_guide_bar);
259 PN_int16 x = LOWORD(lparam);
261 SetCapture(_graph_window);
267 if (_drag_mode == DM_none && _potential_drag_mode == DM_none) {
269 PN_int16 x = LOWORD(lparam);
270 PN_int16 y = HIWORD(lparam);
271 _label_stack.highlight_label(get_collector_under_pixel(x, y));
275 TRACKMOUSEEVENT tme = {
276 sizeof(TRACKMOUSEEVENT),
281 TrackMouseEvent(&tme);
285 _label_stack.highlight_label(-1);
288 if (_drag_mode == DM_scale) {
289 PN_int16 x = LOWORD(lparam);
290 double ratio = (double)x / (
double)
get_xsize();
296 }
else if (_drag_mode == DM_new_guide_bar) {
299 PN_int16 x = LOWORD(lparam);
301 set_drag_mode(DM_guide_bar);
306 }
else if (_drag_mode == DM_guide_bar) {
307 PN_int16 x = LOWORD(lparam);
315 _label_stack.highlight_label(-1);
319 if (_drag_mode == DM_scale) {
320 set_drag_mode(DM_none);
324 }
else if (_drag_mode == DM_guide_bar) {
325 PN_int16 x = LOWORD(lparam);
331 set_drag_mode(DM_none);
337 case WM_LBUTTONDBLCLK:
341 PN_int16 x = LOWORD(lparam);
342 PN_int16 y = HIWORD(lparam);
352 return WinStatsGraph::graph_window_proc(hwnd, msg, wparam, lparam);
363 void WinStatsPianoRoll::
364 additional_window_paint(HDC hdc) {
366 HFONT hfnt = (HFONT)GetStockObject(ANSI_VAR_FONT);
367 SelectObject(hdc, hfnt);
368 SetTextAlign(hdc, TA_LEFT | TA_BOTTOM);
369 SetBkMode(hdc, TRANSPARENT);
375 for (i = 0; i < num_guide_bars; i++) {
380 for (i = 0; i < num_user_guide_bars; i++) {
393 void WinStatsPianoRoll::
394 additional_graph_window_paint(HDC hdc) {
396 for (
int i = 0; i < num_user_guide_bars; i++) {
409 WinStatsGraph::DragMode WinStatsPianoRoll::
410 consider_drag_start(
int mouse_x,
int mouse_y,
int width,
int height) {
411 if (mouse_y >= _graph_top && mouse_y < _graph_top +
get_ysize()) {
412 if (mouse_x >= _graph_left && mouse_x < _graph_left +
get_xsize()) {
414 int x = mouse_x - _graph_left;
418 if (_drag_guide_bar >= 0) {
422 }
else if (mouse_x < _left_margin - 2 ||
423 mouse_x > width - _right_margin + 2) {
426 return DM_new_guide_bar;
430 return WinStatsGraph::consider_drag_start(mouse_x, mouse_y, width, height);
439 int WinStatsPianoRoll::
440 get_collector_under_pixel(
int xpoint,
int ypoint) {
441 if (_label_stack.get_num_labels() == 0) {
446 int height = _label_stack.get_label_height(0);
447 int row = (
get_ysize() - ypoint) / height;
448 if (row >= 0 && row < _label_stack.get_num_labels()) {
449 return _label_stack.get_label_collector_index(row);
460 void WinStatsPianoRoll::
462 _label_stack.clear_labels();
465 _label_stack.add_label(WinStatsGraph::_monitor,
this,
469 _labels_changed =
false;
478 void WinStatsPianoRoll::
484 switch (bar._style) {
486 SelectObject(hdc, _light_pen);
490 SelectObject(hdc, _user_guide_bar_pen);
494 SelectObject(hdc, _dark_pen);
497 MoveToEx(hdc, x, 0, NULL);
508 void WinStatsPianoRoll::
510 switch (bar._style) {
512 SetTextColor(hdc, _light_color);
516 SetTextColor(hdc, _user_guide_bar_color);
520 SetTextColor(hdc, _dark_color);
525 const string &label = bar._label;
527 GetTextExtentPoint32(hdc, label.data(), label.length(), &size);
529 if (bar._style != GBS_user) {
538 int this_x = _graph_left + x - size.cx / 2;
540 TextOut(hdc, this_x, y,
541 label.data(), label.length());
550 void WinStatsPianoRoll::
556 HINSTANCE application = GetModuleHandle(NULL);
557 register_window_class(application);
562 string window_title = thread_name +
" thread piano roll";
567 _left_margin +
get_xsize() + _right_margin,
568 _top_margin +
get_ysize() + _bottom_margin
572 AdjustWindowRect(&win_rect, graph_window_style, FALSE);
575 CreateWindow(_window_class_name, window_title.c_str(), graph_window_style,
576 CW_USEDEFAULT, CW_USEDEFAULT,
577 win_rect.right - win_rect.left,
578 win_rect.bottom - win_rect.top,
579 WinStatsGraph::_monitor->
get_window(), NULL, application, 0);
581 nout <<
"Could not create PianoRoll window!\n";
585 SetWindowLongPtr(_window, 0, (LONG_PTR)
this);
589 SetWindowPos(_window, HWND_TOP, 0, 0, 0, 0,
590 SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
599 void WinStatsPianoRoll::
600 register_window_class(HINSTANCE application) {
601 if (_window_class_registered) {
607 ZeroMemory(&wc,
sizeof(WNDCLASS));
609 wc.lpfnWndProc = (WNDPROC)static_window_proc;
610 wc.hInstance = application;
611 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
612 wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
613 wc.lpszMenuName = NULL;
614 wc.lpszClassName = _window_class_name;
619 if (!RegisterClass(&wc)) {
620 nout <<
"Could not register PianoRoll window class!\n";
624 _window_class_registered =
true;
632 LONG WINAPI WinStatsPianoRoll::
633 static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
636 return self->window_proc(hwnd, msg, wparam, lparam);
638 return DefWindowProc(hwnd, msg, wparam, lparam);
virtual void clicked_label(int collector_index)
Called when the user single-clicks on a label.
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.
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.
int get_num_labels() const
Returns the number of labels to be drawn for this chart.
This is an abstract class that presents the interface for drawing a piano-roll type chart: it shows t...
void move_user_guide_bar(int n, double height)
Adjusts the height of the nth user-defined guide bar.
void set_horizontal_scale(double time_width)
Changes the amount of time the width of the horizontal axis represents.
The data associated with a particular client, but not with any one particular frame or thread: the li...
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...
void update()
Updates the chart with the latest data.
void open_strip_chart(int thread_index, int collector_index, bool show_level)
Opens a new strip chart showing the indicated data.
virtual void new_data(int thread_index, int frame_number)
Called as each frame's data is made available.
const GuideBar & get_guide_bar(int n) const
Returns the nth horizontal guide bar.
virtual void force_redraw()
Called when it is necessary to redraw the entire graph.
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.
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.
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_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...
int get_num_guide_bars() const
Returns the number of horizontal guide bars that should be drawn, based on the indicated target frame...
A window that draws a piano-roll style chart, which shows the collectors explicitly stopping and star...
void set_horizontal_scale(double time_width)
Changes the amount of time the width of the horizontal axis represents.
double pixel_to_height(int y) const
Converts a horizontal pixel offset to a value (a "height" in the strip chart).
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.
GuideBar get_user_guide_bar(int n) const
Returns the nth user-defined guide bar.
int get_num_user_guide_bars() const
Returns the current number of user-defined guide bars.
string get_thread_name(int index) const
Returns the name of the indicated thread.
void remove_user_guide_bar(int n)
Removes the user guide bar with the indicated index number.