| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- /**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University. All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license. You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file winStatsLabel.cxx
- * @author drose
- * @date 2004-01-07
- */
- #include "winStatsLabel.h"
- #include "winStatsMonitor.h"
- #include "winStatsGraph.h"
- int WinStatsLabel::_left_margin = 2;
- int WinStatsLabel::_right_margin = 2;
- int WinStatsLabel::_top_margin = 2;
- int WinStatsLabel::_bottom_margin = 2;
- bool WinStatsLabel::_window_class_registered = false;
- const char * const WinStatsLabel::_window_class_name = "label";
- /**
- *
- */
- WinStatsLabel::
- WinStatsLabel(WinStatsMonitor *monitor, WinStatsGraph *graph,
- int thread_index, int collector_index, bool use_fullname) :
- _monitor(monitor),
- _graph(graph),
- _thread_index(thread_index),
- _collector_index(collector_index)
- {
- _window = 0;
- if (use_fullname) {
- _text = _monitor->get_client_data()->get_collector_fullname(_collector_index);
- } else {
- _text = _monitor->get_client_data()->get_collector_name(_collector_index);
- }
- LRGBColor rgb = _monitor->get_collector_color(_collector_index);
- int r = (int)(rgb[0] * 255.0f);
- int g = (int)(rgb[1] * 255.0f);
- int b = (int)(rgb[2] * 255.0f);
- _bg_color = RGB(r, g, b);
- _bg_brush = CreateSolidBrush(RGB(r, g, b));
- // Should our foreground be black or white?
- double bright =
- rgb[0] * 0.299 +
- rgb[1] * 0.587 +
- rgb[2] * 0.114;
- if (bright >= 0.5) {
- _fg_color = RGB(0, 0, 0);
- _highlight_brush = (HBRUSH)GetStockObject(BLACK_BRUSH);
- } else {
- _fg_color = RGB(255, 255, 255);
- _highlight_brush = (HBRUSH)GetStockObject(WHITE_BRUSH);
- }
- _x = 0;
- _y = 0;
- _width = 0;
- _height = 0;
- _ideal_width = 0;
- _highlight = false;
- _mouse_within = false;
- }
- /**
- *
- */
- WinStatsLabel::
- ~WinStatsLabel() {
- if (_window) {
- DestroyWindow(_window);
- _window = 0;
- }
- DeleteObject(_bg_brush);
- }
- /**
- * Creates the actual window.
- */
- void WinStatsLabel::
- setup(HWND parent_window) {
- if (_window) {
- DestroyWindow(_window);
- _window = 0;
- }
- create_window(parent_window);
- HDC hdc = GetDC(_window);
- HFONT hfnt = (HFONT)GetStockObject(ANSI_VAR_FONT);
- SelectObject(hdc, hfnt);
- SIZE size;
- GetTextExtentPoint32(hdc, _text.data(), _text.length(), &size);
- _height = size.cy + _top_margin + _bottom_margin;
- _ideal_width = size.cx + _left_margin + _right_margin;
- ReleaseDC(_window, hdc);
- }
- /**
- * Sets the position of the label on its parent. The position describes the
- * lower-left corner of the rectangle, not the upper-left.
- */
- void WinStatsLabel::
- set_pos(int x, int y, int width) {
- _x = x;
- _y = y;
- _width = width;
- SetWindowPos(_window, 0, x, y - _height, _width, _height,
- SWP_NOZORDER | SWP_SHOWWINDOW);
- }
- /**
- * Returns the x position of the label on its parent.
- */
- int WinStatsLabel::
- get_x() const {
- return _x;
- }
- /**
- * Returns the y position of the label on its parent.
- */
- int WinStatsLabel::
- get_y() const {
- return _y;
- }
- /**
- * Returns the width of the label as we requested it.
- */
- int WinStatsLabel::
- get_width() const {
- return _width;
- }
- /**
- * Returns the height of the label as we requested it.
- */
- int WinStatsLabel::
- get_height() const {
- return _height;
- }
- /**
- * Returns the width the label would really prefer to be.
- */
- int WinStatsLabel::
- get_ideal_width() const {
- return _ideal_width;
- }
- /**
- * Returns the collector this label represents.
- */
- int WinStatsLabel::
- get_collector_index() const {
- return _collector_index;
- }
- /**
- * Enables or disables the visual highlight for this label.
- */
- void WinStatsLabel::
- set_highlight(bool highlight) {
- if (_highlight != highlight) {
- _highlight = highlight;
- InvalidateRect(_window, nullptr, TRUE);
- }
- }
- /**
- * Returns true if the visual highlight for this label is enabled.
- */
- bool WinStatsLabel::
- get_highlight() const {
- return _highlight;
- }
- /**
- * Used internally to indicate whether the mouse is within the label's window.
- */
- void WinStatsLabel::
- set_mouse_within(bool mouse_within) {
- if (_mouse_within != mouse_within) {
- _mouse_within = mouse_within;
- InvalidateRect(_window, nullptr, TRUE);
- }
- }
- /**
- * Creates the window for this label.
- */
- void WinStatsLabel::
- create_window(HWND parent_window) {
- if (_window) {
- return;
- }
- HINSTANCE application = GetModuleHandle(nullptr);
- register_window_class(application);
- _window =
- CreateWindow(_window_class_name, _text.c_str(), WS_CHILD | WS_CLIPSIBLINGS,
- 0, 0, 0, 0,
- parent_window, nullptr, application, 0);
- if (!_window) {
- nout << "Could not create Label window!\n";
- exit(1);
- }
- SetWindowLongPtr(_window, 0, (LONG_PTR)this);
- }
- /**
- * Registers the window class for the label window, if it has not already been
- * registered.
- */
- void WinStatsLabel::
- register_window_class(HINSTANCE application) {
- if (_window_class_registered) {
- return;
- }
- WNDCLASS wc;
- ZeroMemory(&wc, sizeof(WNDCLASS));
- wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = (WNDPROC)static_window_proc;
- wc.hInstance = application;
- wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
- wc.hbrBackground = nullptr;
- wc.lpszMenuName = nullptr;
- wc.lpszClassName = _window_class_name;
- // Reserve space to associate the this pointer with the window.
- wc.cbWndExtra = sizeof(WinStatsLabel *);
- if (!RegisterClass(&wc)) {
- nout << "Could not register Label window class!\n";
- exit(1);
- }
- _window_class_registered = true;
- }
- /**
- *
- */
- LONG WINAPI WinStatsLabel::
- static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
- WinStatsLabel *self = (WinStatsLabel *)GetWindowLongPtr(hwnd, 0);
- if (self != nullptr && self->_window == hwnd) {
- return self->window_proc(hwnd, msg, wparam, lparam);
- } else {
- return DefWindowProc(hwnd, msg, wparam, lparam);
- }
- }
- /**
- *
- */
- LONG WinStatsLabel::
- window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
- switch (msg) {
- case WM_LBUTTONDBLCLK:
- _graph->clicked_label(_collector_index);
- return 0;
- case WM_MOUSEMOVE:
- {
- // When the mouse enters the label area, highlight the label.
- set_mouse_within(true);
- // Now we want to get a WM_MOUSELEAVE when the mouse leaves the label.
- TRACKMOUSEEVENT tme = {
- sizeof(TRACKMOUSEEVENT),
- TME_LEAVE,
- _window,
- 0
- };
- TrackMouseEvent(&tme);
- }
- break;
- case WM_MOUSELEAVE:
- set_mouse_within(false);
- break;
- case WM_PAINT:
- {
- PAINTSTRUCT ps;
- HDC hdc = BeginPaint(hwnd, &ps);
- RECT rect = { 0, 0, _width, _height };
- FillRect(hdc, &rect, _bg_brush);
- if (_highlight || _mouse_within) {
- FrameRect(hdc, &rect, _highlight_brush);
- }
- HFONT hfnt = (HFONT)GetStockObject(ANSI_VAR_FONT);
- SelectObject(hdc, hfnt);
- SetTextAlign(hdc, TA_RIGHT | TA_TOP);
- SetBkColor(hdc, _bg_color);
- SetBkMode(hdc, OPAQUE);
- SetTextColor(hdc, _fg_color);
- TextOut(hdc, _width - _right_margin, _top_margin,
- _text.data(), _text.length());
- EndPaint(hwnd, &ps);
- return 0;
- }
- default:
- break;
- }
- return DefWindowProc(hwnd, msg, wparam, lparam);
- }
|