Panda3D
Loading...
Searching...
No Matches
winStatsLabel.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file winStatsLabel.cxx
10 * @author drose
11 * @date 2004-01-07
12 */
13
14#include "winStatsLabel.h"
15#include "winStatsMonitor.h"
16#include "winStatsGraph.h"
17
18int WinStatsLabel::_left_margin = 2;
19int WinStatsLabel::_right_margin = 2;
20int WinStatsLabel::_top_margin = 2;
21int WinStatsLabel::_bottom_margin = 2;
22
23bool WinStatsLabel::_window_class_registered = false;
24const char * const WinStatsLabel::_window_class_name = "label";
25
26/**
27 *
28 */
29WinStatsLabel::
30WinStatsLabel(WinStatsMonitor *monitor, WinStatsGraph *graph,
31 int thread_index, int collector_index, bool use_fullname) :
32 _monitor(monitor),
33 _graph(graph),
34 _thread_index(thread_index),
35 _collector_index(collector_index)
36{
37 _window = 0;
38 if (use_fullname) {
39 _text = _monitor->get_client_data()->get_collector_fullname(_collector_index);
40 } else {
41 _text = _monitor->get_client_data()->get_collector_name(_collector_index);
42 }
43
44 LRGBColor rgb = _monitor->get_collector_color(_collector_index);
45 int r = (int)(rgb[0] * 255.0f);
46 int g = (int)(rgb[1] * 255.0f);
47 int b = (int)(rgb[2] * 255.0f);
48 _bg_color = RGB(r, g, b);
49 _bg_brush = CreateSolidBrush(RGB(r, g, b));
50
51 // Should our foreground be black or white?
52 double bright =
53 rgb[0] * 0.299 +
54 rgb[1] * 0.587 +
55 rgb[2] * 0.114;
56
57 if (bright >= 0.5) {
58 _fg_color = RGB(0, 0, 0);
59 _highlight_brush = (HBRUSH)GetStockObject(BLACK_BRUSH);
60 } else {
61 _fg_color = RGB(255, 255, 255);
62 _highlight_brush = (HBRUSH)GetStockObject(WHITE_BRUSH);
63 }
64
65 _x = 0;
66 _y = 0;
67 _width = 0;
68 _height = 0;
69 _ideal_width = 0;
70 _highlight = false;
71 _mouse_within = false;
72}
73
74/**
75 *
76 */
77WinStatsLabel::
78~WinStatsLabel() {
79 if (_window) {
80 DestroyWindow(_window);
81 _window = 0;
82 }
83 DeleteObject(_bg_brush);
84}
85
86/**
87 * Creates the actual window.
88 */
90setup(HWND parent_window) {
91 if (_window) {
92 DestroyWindow(_window);
93 _window = 0;
94 }
95
96 create_window(parent_window);
97
98 HDC hdc = GetDC(_window);
99 HFONT hfnt = (HFONT)GetStockObject(ANSI_VAR_FONT);
100 SelectObject(hdc, hfnt);
101
102 SIZE size;
103 GetTextExtentPoint32(hdc, _text.data(), _text.length(), &size);
104 _height = size.cy + _top_margin + _bottom_margin;
105 _ideal_width = size.cx + _left_margin + _right_margin;
106
107 ReleaseDC(_window, hdc);
108}
109
110/**
111 * Sets the position of the label on its parent. The position describes the
112 * lower-left corner of the rectangle, not the upper-left.
113 */
115set_pos(int x, int y, int width) {
116 _x = x;
117 _y = y;
118 _width = width;
119 SetWindowPos(_window, 0, x, y - _height, _width, _height,
120 SWP_NOZORDER | SWP_SHOWWINDOW);
121}
122
123/**
124 * Returns the x position of the label on its parent.
125 */
127get_x() const {
128 return _x;
129}
130
131/**
132 * Returns the y position of the label on its parent.
133 */
135get_y() const {
136 return _y;
137}
138
139/**
140 * Returns the width of the label as we requested it.
141 */
143get_width() const {
144 return _width;
145}
146
147/**
148 * Returns the height of the label as we requested it.
149 */
151get_height() const {
152 return _height;
153}
154
155/**
156 * Returns the width the label would really prefer to be.
157 */
159get_ideal_width() const {
160 return _ideal_width;
161}
162
163/**
164 * Returns the collector this label represents.
165 */
167get_collector_index() const {
168 return _collector_index;
169}
170
171/**
172 * Enables or disables the visual highlight for this label.
173 */
175set_highlight(bool highlight) {
176 if (_highlight != highlight) {
177 _highlight = highlight;
178 InvalidateRect(_window, nullptr, TRUE);
179 }
180}
181
182/**
183 * Returns true if the visual highlight for this label is enabled.
184 */
186get_highlight() const {
187 return _highlight;
188}
189
190/**
191 * Used internally to indicate whether the mouse is within the label's window.
192 */
193void WinStatsLabel::
194set_mouse_within(bool mouse_within) {
195 if (_mouse_within != mouse_within) {
196 _mouse_within = mouse_within;
197 InvalidateRect(_window, nullptr, TRUE);
198 }
199}
200
201/**
202 * Creates the window for this label.
203 */
204void WinStatsLabel::
205create_window(HWND parent_window) {
206 if (_window) {
207 return;
208 }
209
210 HINSTANCE application = GetModuleHandle(nullptr);
211 register_window_class(application);
212
213 _window =
214 CreateWindow(_window_class_name, _text.c_str(), WS_CHILD | WS_CLIPSIBLINGS,
215 0, 0, 0, 0,
216 parent_window, nullptr, application, 0);
217 if (!_window) {
218 nout << "Could not create Label window!\n";
219 exit(1);
220 }
221
222 SetWindowLongPtr(_window, 0, (LONG_PTR)this);
223}
224
225/**
226 * Registers the window class for the label window, if it has not already been
227 * registered.
228 */
229void WinStatsLabel::
230register_window_class(HINSTANCE application) {
231 if (_window_class_registered) {
232 return;
233 }
234
235 WNDCLASS wc;
236
237 ZeroMemory(&wc, sizeof(WNDCLASS));
238 wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
239 wc.lpfnWndProc = (WNDPROC)static_window_proc;
240 wc.hInstance = application;
241 wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
242 wc.hbrBackground = nullptr;
243 wc.lpszMenuName = nullptr;
244 wc.lpszClassName = _window_class_name;
245
246 // Reserve space to associate the this pointer with the window.
247 wc.cbWndExtra = sizeof(WinStatsLabel *);
248
249 if (!RegisterClass(&wc)) {
250 nout << "Could not register Label window class!\n";
251 exit(1);
252 }
253
254 _window_class_registered = true;
255}
256
257/**
258 *
259 */
260LONG WINAPI WinStatsLabel::
261static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
262 WinStatsLabel *self = (WinStatsLabel *)GetWindowLongPtr(hwnd, 0);
263 if (self != nullptr && self->_window == hwnd) {
264 return self->window_proc(hwnd, msg, wparam, lparam);
265 } else {
266 return DefWindowProc(hwnd, msg, wparam, lparam);
267 }
268}
269
270/**
271 *
272 */
273LONG WinStatsLabel::
274window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
275 switch (msg) {
276 case WM_LBUTTONDBLCLK:
277 _graph->clicked_label(_collector_index);
278 return 0;
279
280 case WM_MOUSEMOVE:
281 {
282 // When the mouse enters the label area, highlight the label.
283 set_mouse_within(true);
284
285 // Now we want to get a WM_MOUSELEAVE when the mouse leaves the label.
286 TRACKMOUSEEVENT tme = {
287 sizeof(TRACKMOUSEEVENT),
288 TME_LEAVE,
289 _window,
290 0
291 };
292 TrackMouseEvent(&tme);
293 }
294 break;
295
296 case WM_MOUSELEAVE:
297 set_mouse_within(false);
298 break;
299
300 case WM_PAINT:
301 {
302 PAINTSTRUCT ps;
303 HDC hdc = BeginPaint(hwnd, &ps);
304
305 RECT rect = { 0, 0, _width, _height };
306 FillRect(hdc, &rect, _bg_brush);
307
308 if (_highlight || _mouse_within) {
309 FrameRect(hdc, &rect, _highlight_brush);
310 }
311
312 HFONT hfnt = (HFONT)GetStockObject(ANSI_VAR_FONT);
313 SelectObject(hdc, hfnt);
314 SetTextAlign(hdc, TA_RIGHT | TA_TOP);
315
316 SetBkColor(hdc, _bg_color);
317 SetBkMode(hdc, OPAQUE);
318 SetTextColor(hdc, _fg_color);
319
320 TextOut(hdc, _width - _right_margin, _top_margin,
321 _text.data(), _text.length());
322 EndPaint(hwnd, &ps);
323 return 0;
324 }
325
326 default:
327 break;
328 }
329
330 return DefWindowProc(hwnd, msg, wparam, lparam);
331}
This is just an abstract base class to provide a common pointer type for the various kinds of graphs ...
virtual void clicked_label(int collector_index)
Called when the user single-clicks on a label.
A text label that will draw in color appropriate for a particular collector.
void setup(HWND parent_window)
Creates the actual window.
int get_y() const
Returns the y position of the label on its parent.
int get_ideal_width() const
Returns the width the label would really prefer to be.
int get_width() const
Returns the width of the label as we requested it.
int get_x() const
Returns the x position of the label on its parent.
bool get_highlight() const
Returns true if the visual highlight for this label is enabled.
int get_collector_index() const
Returns the collector this label represents.
int get_height() const
Returns the height of the label as we requested it.
void set_pos(int x, int y, int width)
Sets the position of the label on its parent.
void set_highlight(bool highlight)
Enables or disables the visual highlight for this label.
This class represents a connection to a PStatsClient and manages the data exchange with the client.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.