18 bool WinStatsGraph::_graph_window_class_registered =
false;
19 const char *
const WinStatsGraph::_graph_window_class_name =
"graph";
21 DWORD WinStatsGraph::graph_window_style =
22 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW | WS_VISIBLE;
33 _sizewe_cursor = LoadCursor(
nullptr, IDC_SIZEWE);
34 _hand_cursor = LoadCursor(
nullptr, IDC_HAND);
43 _dark_color = RGB(51, 51, 51);
44 _light_color = RGB(154, 154, 154);
45 _user_guide_bar_color = RGB(130, 150, 255);
46 _dark_pen = CreatePen(PS_SOLID, 1, _dark_color);
47 _light_pen = CreatePen(PS_SOLID, 1, _light_color);
48 _user_guide_bar_pen = CreatePen(PS_DASH, 1, _user_guide_bar_color);
51 _potential_drag_mode = DM_none;
52 _drag_scale_start = 0.0f;
65 DeleteObject(_dark_pen);
66 DeleteObject(_light_pen);
67 DeleteObject(_user_guide_bar_pen);
70 for (bi = _brushes.begin(); bi != _brushes.end(); ++bi) {
71 HBRUSH brush = (*bi).second;
76 DestroyWindow(_graph_window);
81 DestroyWindow(_window);
145 InvalidateRect(_window,
nullptr, TRUE);
146 InvalidateRect(_graph_window,
nullptr, TRUE);
164 if (monitor !=
nullptr) {
165 monitor->remove_graph(
this);
173 setup_label_stack() {
174 _label_stack.
setup(_window);
185 GetClientRect(_window, &rect);
188 rect.right = _left_margin - 8;
189 rect.bottom -= _bottom_margin;
191 _label_stack.
set_pos(rect.left, rect.top,
192 rect.right - rect.left, rect.bottom - rect.top);
199 HBRUSH WinStatsGraph::
200 get_collector_brush(
int collector_index) {
201 Brushes::iterator bi;
202 bi = _brushes.find(collector_index);
203 if (bi != _brushes.end()) {
209 int r = (int)(rgb[0] * 255.0f);
210 int g = (int)(rgb[1] * 255.0f);
211 int b = (int)(rgb[2] * 255.0f);
212 HBRUSH brush = CreateSolidBrush(RGB(r, g, b));
214 _brushes[collector_index] = brush;
223 window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
231 InvalidateRect(hwnd,
nullptr, TRUE);
235 set_drag_mode(DM_sizing);
238 case WM_EXITSIZEMOVE:
239 set_drag_mode(DM_none);
247 GetCursorPos(&point);
249 GetWindowInfo(hwnd, &winfo);
250 const RECT &rect = winfo.rcClient;
251 int x = point.x - rect.left;
252 int y = point.y - rect.top;
253 int width = rect.right - rect.left;
254 int height = rect.bottom - rect.top;
256 _potential_drag_mode = consider_drag_start(x, y, width, height);
258 switch (_potential_drag_mode) {
260 case DM_right_margin:
261 SetCursor(_sizewe_cursor);
265 SetCursor(_hand_cursor);
276 if (_potential_drag_mode != DM_none) {
277 set_drag_mode(_potential_drag_mode);
278 _drag_start_x = (int16_t)LOWORD(lparam);
279 _drag_start_y = (int16_t)HIWORD(lparam);
285 if (_drag_mode == DM_left_margin) {
286 int16_t x = LOWORD(lparam);
287 _left_margin += (x - _drag_start_x);
289 InvalidateRect(hwnd,
nullptr, TRUE);
293 }
else if (_drag_mode == DM_right_margin) {
294 int16_t x = LOWORD(lparam);
295 _right_margin += (_drag_start_x - x);
297 InvalidateRect(hwnd,
nullptr, TRUE);
303 set_drag_mode(DM_none);
310 HDC hdc = BeginPaint(hwnd, &ps);
314 GetClientRect(hwnd, &rect);
316 rect.left += _left_margin;
317 rect.top += _top_margin;
318 rect.right -= _right_margin;
319 rect.bottom -= _bottom_margin;
321 if (rect.right > rect.left && rect.bottom > rect.top) {
322 DrawEdge(hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
324 int graph_xsize = rect.right - rect.left;
325 int graph_ysize = rect.bottom - rect.top;
326 if (_bitmap_dc == 0 ||
327 graph_xsize != _bitmap_xsize ||
328 graph_ysize != _bitmap_ysize) {
331 move_graph_window(rect.left, rect.top, graph_xsize, graph_ysize);
336 additional_window_paint(hdc);
346 return DefWindowProc(hwnd, msg, wparam, lparam);
353 graph_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
355 case WM_DISPLAYCHANGE:
356 setup_bitmap(_bitmap_xsize, _bitmap_ysize);
363 if (_potential_drag_mode != DM_none) {
364 int16_t x = LOWORD(lparam) + _graph_left;
365 int16_t y = HIWORD(lparam) + _graph_top;
366 return window_proc(_window, msg, wparam, MAKELPARAM(x, y));
371 set_drag_mode(DM_none);
379 HDC hdc = BeginPaint(hwnd, &ps);
382 _bitmap_xsize, _bitmap_ysize,
386 additional_graph_window_paint(hdc);
396 return DefWindowProc(hwnd, msg, wparam, lparam);
405 additional_window_paint(HDC hdc) {
413 additional_graph_window_paint(HDC hdc) {
421 WinStatsGraph::DragMode WinStatsGraph::
422 consider_drag_start(
int mouse_x,
int mouse_y,
int width,
int height) {
423 if (mouse_x >= _left_margin - 2 && mouse_x <= _left_margin + 2) {
424 return DM_left_margin;
425 }
else if (mouse_x >= width - _right_margin - 2 && mouse_x <= width - _right_margin + 2) {
426 return DM_right_margin;
437 set_drag_mode(WinStatsGraph::DragMode drag_mode) {
438 _drag_mode = drag_mode;
446 move_graph_window(
int graph_left,
int graph_top,
int graph_xsize,
int graph_ysize) {
447 if (_graph_window == 0) {
448 create_graph_window();
451 _graph_left = graph_left;
452 _graph_top = graph_top;
454 SetWindowPos(_graph_window, 0,
455 _graph_left, _graph_top,
456 graph_xsize, graph_ysize,
457 SWP_NOZORDER | SWP_SHOWWINDOW);
459 if (graph_xsize != _bitmap_xsize || graph_ysize != _bitmap_ysize) {
460 setup_bitmap(graph_xsize, graph_ysize);
468 setup_bitmap(
int xsize,
int ysize) {
470 _bitmap_xsize = std::max(xsize, 0);
471 _bitmap_ysize = std::max(ysize, 0);
473 HDC hdc = GetDC(_graph_window);
474 _bitmap_dc = CreateCompatibleDC(hdc);
475 _bitmap = CreateCompatibleBitmap(hdc, _bitmap_xsize, _bitmap_ysize);
476 SelectObject(_bitmap_dc, _bitmap);
478 RECT rect = { 0, 0, _bitmap_xsize, _bitmap_ysize };
479 FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
481 ReleaseDC(_window, hdc);
490 DeleteObject(_bitmap);
494 DeleteDC(_bitmap_dc);
503 create_graph_window() {
508 HINSTANCE application = GetModuleHandle(
nullptr);
509 register_graph_window_class(application);
511 std::string window_title =
"graph";
512 DWORD window_style = WS_CHILD | WS_CLIPSIBLINGS;
515 CreateWindow(_graph_window_class_name, window_title.c_str(), window_style,
517 _window,
nullptr, application, 0);
518 if (!_graph_window) {
519 nout <<
"Could not create graph window!\n";
523 SetWindowLongPtr(_graph_window, 0, (LONG_PTR)
this);
531 register_graph_window_class(HINSTANCE application) {
532 if (_graph_window_class_registered) {
538 ZeroMemory(&wc,
sizeof(WNDCLASS));
539 wc.style = CS_DBLCLKS;
540 wc.lpfnWndProc = (WNDPROC)static_graph_window_proc;
541 wc.hInstance = application;
542 wc.hCursor = LoadCursor(
nullptr, IDC_ARROW);
543 wc.hbrBackground =
nullptr;
544 wc.lpszMenuName =
nullptr;
545 wc.lpszClassName = _graph_window_class_name;
550 if (!RegisterClass(&wc)) {
551 nout <<
"Could not register graph window class!\n";
555 _graph_window_class_registered =
true;
561 LONG WINAPI WinStatsGraph::
562 static_graph_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
564 if (
self !=
nullptr && self->_graph_window == hwnd) {
565 return self->graph_window_proc(hwnd, msg, wparam, lparam);
567 return DefWindowProc(hwnd, msg, wparam, lparam);
virtual void new_collector(int collector_index)
Called whenever a new Collector definition is received from the client.
bool is_setup() const
Returns true if the label stack has been set up, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const LRGBColor & get_collector_color(int collector_index)
Returns the color associated with the indicated collector.
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 ...
void user_guide_bars_changed()
Called when the user guide bars have been changed.
void setup(HWND parent_window)
Creates the actual window object.
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_scroll_speed(double scroll_speed)
Called when the user selects a new scroll speed from the monitor pulldown menu, this should adjust th...
This is just an abstract base class to provide a common pointer type for the various kinds of graphs ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class represents a connection to a PStatsClient and manages the data exchange with the client.
void set_pause(bool pause)
Changes the pause flag for the graph.
virtual void new_data(int thread_index, int frame_number)
Called whenever new data arrives.
virtual void force_redraw()
Called when it is necessary to redraw the entire graph.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_pos(int x, int y, int width, int height)
Sets the position and size of the label stack on its parent.
virtual void clicked_label(int collector_index)
Called when the user single-clicks on a label.