18 static const int default_piano_roll_width = 400;
19 static const int default_piano_roll_height = 200;
21 bool WinStatsPianoRoll::_window_class_registered =
false;
22 const char *
const WinStatsPianoRoll::_window_class_name =
"piano";
30 default_piano_roll_width,
31 default_piano_roll_height),
40 set_guide_bar_units(get_guide_bar_units() | GBU_show_units);
50 ~WinStatsPianoRoll() {
60 new_data(
int thread_index,
int frame_number) {
71 PStatPianoRoll::force_redraw();
79 PStatPianoRoll::changed_size(graph_xsize, graph_ysize);
90 if ((old_unit_mask & (GBU_hz | GBU_ms)) != 0) {
91 unit_mask = unit_mask & (GBU_hz | GBU_ms);
92 unit_mask |= (old_unit_mask & GBU_show_units);
96 GetClientRect(_window, &rect);
97 rect.left = _right_margin;
98 InvalidateRect(_window, &rect, TRUE);
107 if (collector_index >= 0) {
108 WinStatsGraph::_monitor->
open_strip_chart(_thread_index, collector_index,
false);
121 GetClientRect(_window, &rect);
122 rect.bottom = _top_margin;
123 InvalidateRect(_window, &rect, TRUE);
129 void WinStatsPianoRoll::
132 FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
138 void WinStatsPianoRoll::
144 for (
int i = 0; i < num_guide_bars; i++) {
152 void WinStatsPianoRoll::
153 draw_bar(
int row,
int from_x,
int to_x) {
154 if (row >= 0 && row < _label_stack.get_num_labels()) {
155 int y = _label_stack.get_label_y(row) - _graph_top;
156 int height = _label_stack.get_label_height(row);
159 from_x, y - height + 2,
163 HBRUSH brush = get_collector_brush(collector_index);
164 FillRect(_bitmap_dc, &rect, brush);
172 void WinStatsPianoRoll::
174 InvalidateRect(_graph_window,
nullptr, FALSE);
180 void WinStatsPianoRoll::
182 if (_labels_changed) {
190 LONG WinStatsPianoRoll::
191 window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
194 if (_potential_drag_mode == DM_new_guide_bar) {
195 set_drag_mode(DM_new_guide_bar);
196 SetCapture(_graph_window);
205 return WinStatsGraph::window_proc(hwnd, msg, wparam, lparam);
211 LONG WinStatsPianoRoll::
212 graph_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
215 if (_potential_drag_mode == DM_none) {
216 set_drag_mode(DM_scale);
217 int16_t x = LOWORD(lparam);
219 SetCapture(_graph_window);
222 }
else if (_potential_drag_mode == DM_guide_bar && _drag_guide_bar >= 0) {
223 set_drag_mode(DM_guide_bar);
224 int16_t x = LOWORD(lparam);
226 SetCapture(_graph_window);
232 if (_drag_mode == DM_none && _potential_drag_mode == DM_none) {
234 int16_t x = LOWORD(lparam);
235 int16_t y = HIWORD(lparam);
236 _label_stack.highlight_label(get_collector_under_pixel(x, y));
240 TRACKMOUSEEVENT tme = {
241 sizeof(TRACKMOUSEEVENT),
246 TrackMouseEvent(&tme);
250 _label_stack.highlight_label(-1);
253 if (_drag_mode == DM_scale) {
254 int16_t x = LOWORD(lparam);
255 double ratio = (double)x / (
double)
get_xsize();
261 }
else if (_drag_mode == DM_new_guide_bar) {
264 int16_t x = LOWORD(lparam);
266 set_drag_mode(DM_guide_bar);
271 }
else if (_drag_mode == DM_guide_bar) {
272 int16_t x = LOWORD(lparam);
280 _label_stack.highlight_label(-1);
284 if (_drag_mode == DM_scale) {
285 set_drag_mode(DM_none);
289 }
else if (_drag_mode == DM_guide_bar) {
290 int16_t x = LOWORD(lparam);
296 set_drag_mode(DM_none);
302 case WM_LBUTTONDBLCLK:
306 int16_t x = LOWORD(lparam);
307 int16_t y = HIWORD(lparam);
317 return WinStatsGraph::graph_window_proc(hwnd, msg, wparam, lparam);
325 void WinStatsPianoRoll::
326 additional_window_paint(HDC hdc) {
328 HFONT hfnt = (HFONT)GetStockObject(ANSI_VAR_FONT);
329 SelectObject(hdc, hfnt);
330 SetTextAlign(hdc, TA_LEFT | TA_BOTTOM);
331 SetBkMode(hdc, TRANSPARENT);
337 for (i = 0; i < num_guide_bars; i++) {
342 for (i = 0; i < num_user_guide_bars; i++) {
352 void WinStatsPianoRoll::
353 additional_graph_window_paint(HDC hdc) {
355 for (
int i = 0; i < num_user_guide_bars; i++) {
365 WinStatsGraph::DragMode WinStatsPianoRoll::
366 consider_drag_start(
int mouse_x,
int mouse_y,
int width,
int height) {
367 if (mouse_y >= _graph_top && mouse_y < _graph_top +
get_ysize()) {
368 if (mouse_x >= _graph_left && mouse_x < _graph_left +
get_xsize()) {
370 int x = mouse_x - _graph_left;
374 if (_drag_guide_bar >= 0) {
378 }
else if (mouse_x < _left_margin - 2 ||
379 mouse_x > width - _right_margin + 2) {
382 return DM_new_guide_bar;
386 return WinStatsGraph::consider_drag_start(mouse_x, mouse_y, width, height);
393 int WinStatsPianoRoll::
394 get_collector_under_pixel(
int xpoint,
int ypoint) {
395 if (_label_stack.get_num_labels() == 0) {
400 int height = _label_stack.get_label_height(0);
401 int row = (
get_ysize() - ypoint) / height;
402 if (row >= 0 && row < _label_stack.get_num_labels()) {
403 return _label_stack.get_label_collector_index(row);
412 void WinStatsPianoRoll::
414 _label_stack.clear_labels();
417 _label_stack.add_label(WinStatsGraph::_monitor,
this,
421 _labels_changed =
false;
427 void WinStatsPianoRoll::
433 switch (bar._style) {
435 SelectObject(hdc, _light_pen);
439 SelectObject(hdc, _user_guide_bar_pen);
443 SelectObject(hdc, _dark_pen);
446 MoveToEx(hdc, x, 0,
nullptr);
454 void WinStatsPianoRoll::
456 switch (bar._style) {
458 SetTextColor(hdc, _light_color);
462 SetTextColor(hdc, _user_guide_bar_color);
466 SetTextColor(hdc, _dark_color);
471 const std::string &label = bar._label;
473 GetTextExtentPoint32(hdc, label.data(), label.length(), &size);
475 if (bar._style != GBS_user) {
484 int this_x = _graph_left + x - size.cx / 2;
486 TextOut(hdc, this_x, y,
487 label.data(), label.length());
494 void WinStatsPianoRoll::
500 HINSTANCE application = GetModuleHandle(
nullptr);
501 register_window_class(application);
506 std::string window_title = thread_name +
" thread piano roll";
511 _left_margin +
get_xsize() + _right_margin,
512 _top_margin +
get_ysize() + _bottom_margin
516 AdjustWindowRect(&win_rect, graph_window_style, FALSE);
519 CreateWindow(_window_class_name, window_title.c_str(), graph_window_style,
520 CW_USEDEFAULT, CW_USEDEFAULT,
521 win_rect.right - win_rect.left,
522 win_rect.bottom - win_rect.top,
523 WinStatsGraph::_monitor->get_window(),
nullptr, application, 0);
525 nout <<
"Could not create PianoRoll window!\n";
529 SetWindowLongPtr(_window, 0, (LONG_PTR)
this);
533 SetWindowPos(_window, HWND_TOP, 0, 0, 0, 0,
534 SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
541 void WinStatsPianoRoll::
542 register_window_class(HINSTANCE application) {
543 if (_window_class_registered) {
549 ZeroMemory(&wc,
sizeof(WNDCLASS));
551 wc.lpfnWndProc = (WNDPROC)static_window_proc;
552 wc.hInstance = application;
553 wc.hCursor = LoadCursor(
nullptr, IDC_ARROW);
554 wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
555 wc.lpszMenuName =
nullptr;
556 wc.lpszClassName = _window_class_name;
561 if (!RegisterClass(&wc)) {
562 nout <<
"Could not register PianoRoll window class!\n";
566 _window_class_registered =
true;
572 LONG WINAPI WinStatsPianoRoll::
573 static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
575 if (
self !=
nullptr && self->_window == hwnd) {
576 return self->window_proc(hwnd, msg, wparam, lparam);
578 return DefWindowProc(hwnd, msg, wparam, lparam);
The data associated with a particular client, but not with any one particular frame or thread: the li...
std::string get_thread_name(int index) const
Returns the name of the indicated thread.
GuideBar get_user_guide_bar(int n) const
Returns the nth user-defined 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...
int get_num_user_guide_bars() const
Returns the current number of user-defined guide bars.
int add_user_guide_bar(double height)
Creates a new user guide bar and returns its index number.
void move_user_guide_bar(int n, double height)
Adjusts the height of the nth user-defined guide bar.
void set_guide_bar_units(int unit_mask)
Sets the units that are displayed for the guide bar labels.
int get_guide_bar_units() const
Returns the units that are displayed for the guide bar labels.
void remove_user_guide_bar(int n)
Removes the user guide bar with the indicated index number.
int get_num_guide_bars() const
Returns the number of horizontal guide bars that should be drawn, based on the indicated target frame...
int get_num_labels() const
Returns the number of labels to be drawn for this chart.
int get_label_collector(int n) const
Returns the collector index associated with the nth label.
int get_xsize() const
Returns the width of the chart in pixels.
int get_ysize() const
Returns the height of the chart in pixels.
const GuideBar & get_guide_bar(int n) const
Returns the nth horizontal guide bar.
const PStatClientData * get_client_data() const
Returns the client data associated with this monitor.
This is an abstract class that presents the interface for drawing a piano- roll type chart: it shows ...
void set_horizontal_scale(double time_width)
Changes the amount of time the width of the horizontal axis represents.
void update()
Updates the chart with the latest data.
double pixel_to_height(int y) const
Converts a horizontal pixel offset to a value (a "height" in the strip chart).
int height_to_pixel(double value) const
Converts a value (i.e.
This is just an abstract base class to provide a common pointer type for the various kinds of graphs ...
This class represents a connection to a PStatsClient and manages the data exchange with the client.
void open_strip_chart(int thread_index, int collector_index, bool show_level)
Opens a new strip chart showing the indicated data.
A window that draws a piano-roll style chart, which shows the collectors explicitly stopping and star...
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.
void set_horizontal_scale(double time_width)
Changes the amount of time the width of the horizontal axis represents.
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 ...
virtual void clicked_label(int collector_index)
Called when the user single-clicks on a label.
virtual void new_data(int thread_index, int frame_number)
Called as each frame's data is made available.
virtual void force_redraw()
Called when it is necessary to redraw the entire graph.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.