00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "winStatsLabelStack.h"
00016 #include "winStatsLabel.h"
00017 #include "pnotify.h"
00018
00019 bool WinStatsLabelStack::_window_class_registered = false;
00020 const char * const WinStatsLabelStack::_window_class_name = "stack";
00021
00022
00023
00024
00025
00026
00027 WinStatsLabelStack::
00028 WinStatsLabelStack() {
00029 _x = 0;
00030 _y = 0;
00031 _width = 0;
00032 _height = 0;
00033 _ideal_width = 0;
00034
00035 _highlight_label = -1;
00036 }
00037
00038
00039
00040
00041
00042
00043 WinStatsLabelStack::
00044 ~WinStatsLabelStack() {
00045 clear_labels();
00046 if (_window) {
00047 DestroyWindow(_window);
00048 _window = 0;
00049 }
00050 }
00051
00052
00053
00054
00055
00056
00057 void WinStatsLabelStack::
00058 setup(HWND parent_window) {
00059 if (_window) {
00060 DestroyWindow(_window);
00061 _window = 0;
00062 }
00063
00064 create_window(parent_window);
00065
00066 _ideal_width = 0;
00067 Labels::iterator li;
00068 for (li = _labels.begin(); li != _labels.end(); ++li) {
00069 WinStatsLabel *label = (*li);
00070 label->setup(_window);
00071 _ideal_width = max(_ideal_width, label->get_ideal_width());
00072 }
00073 }
00074
00075
00076
00077
00078
00079
00080
00081 bool WinStatsLabelStack::
00082 is_setup() const {
00083 return (_window != 0);
00084 }
00085
00086
00087
00088
00089
00090
00091 void WinStatsLabelStack::
00092 set_pos(int x, int y, int width, int height) {
00093 _x = x;
00094 _y = y;
00095 _width = width;
00096 _height = height;
00097 SetWindowPos(_window, 0, x, y, _width, _height,
00098 SWP_NOZORDER | SWP_SHOWWINDOW);
00099
00100 Labels::iterator li;
00101 int yp = height;
00102 for (li = _labels.begin(); li != _labels.end(); ++li) {
00103 WinStatsLabel *label = (*li);
00104 label->set_pos(0, yp, _width);
00105 yp -= label->get_height();
00106 }
00107 }
00108
00109
00110
00111
00112
00113
00114 int WinStatsLabelStack::
00115 get_x() const {
00116 return _x;
00117 }
00118
00119
00120
00121
00122
00123
00124 int WinStatsLabelStack::
00125 get_y() const {
00126 return _y;
00127 }
00128
00129
00130
00131
00132
00133
00134 int WinStatsLabelStack::
00135 get_width() const {
00136 return _width;
00137 }
00138
00139
00140
00141
00142
00143
00144 int WinStatsLabelStack::
00145 get_height() const {
00146 return _height;
00147 }
00148
00149
00150
00151
00152
00153
00154 int WinStatsLabelStack::
00155 get_ideal_width() const {
00156 return _ideal_width;
00157 }
00158
00159
00160
00161
00162
00163
00164
00165 int WinStatsLabelStack::
00166 get_label_y(int label_index) const {
00167 nassertr(label_index >= 0 && label_index < (int)_labels.size(), 0);
00168 return _labels[label_index]->get_y() + get_y();
00169 }
00170
00171
00172
00173
00174
00175
00176 int WinStatsLabelStack::
00177 get_label_height(int label_index) const {
00178 nassertr(label_index >= 0 && label_index < (int)_labels.size(), 0);
00179 return _labels[label_index]->get_height();
00180 }
00181
00182
00183
00184
00185
00186
00187
00188 int WinStatsLabelStack::
00189 get_label_collector_index(int label_index) const {
00190 nassertr(label_index >= 0 && label_index < (int)_labels.size(), -1);
00191 return _labels[label_index]->get_collector_index();
00192 }
00193
00194
00195
00196
00197
00198
00199 void WinStatsLabelStack::
00200 clear_labels() {
00201 Labels::iterator li;
00202 for (li = _labels.begin(); li != _labels.end(); ++li) {
00203 delete (*li);
00204 }
00205 _labels.clear();
00206 _ideal_width = 0;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215 int WinStatsLabelStack::
00216 add_label(WinStatsMonitor *monitor, WinStatsGraph *graph,
00217 int thread_index, int collector_index, bool use_fullname) {
00218 int yp = _height;
00219 if (!_labels.empty()) {
00220 WinStatsLabel *top_label = _labels.back();
00221 yp = top_label->get_y() - top_label->get_height();
00222 }
00223 WinStatsLabel *label =
00224 new WinStatsLabel(monitor, graph, thread_index, collector_index, use_fullname);
00225 if (_window) {
00226 label->setup(_window);
00227 label->set_pos(0, yp, _width);
00228 }
00229 _ideal_width = max(_ideal_width, label->get_ideal_width());
00230
00231 int label_index = (int)_labels.size();
00232 _labels.push_back(label);
00233
00234 return label_index;
00235 }
00236
00237
00238
00239
00240
00241
00242 int WinStatsLabelStack::
00243 get_num_labels() const {
00244 return _labels.size();
00245 }
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 void WinStatsLabelStack::
00256 highlight_label(int collector_index) {
00257 if (_highlight_label != collector_index) {
00258 _highlight_label = collector_index;
00259 Labels::iterator li;
00260 for (li = _labels.begin(); li != _labels.end(); ++li) {
00261 WinStatsLabel *label = (*li);
00262 label->set_highlight(label->get_collector_index() == _highlight_label);
00263 }
00264 }
00265 }
00266
00267
00268
00269
00270
00271
00272
00273 void WinStatsLabelStack::
00274 create_window(HWND parent_window) {
00275 if (_window) {
00276 return;
00277 }
00278
00279 HINSTANCE application = GetModuleHandle(NULL);
00280 register_window_class(application);
00281
00282 _window =
00283 CreateWindow(_window_class_name, "label stack", WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
00284 0, 0, 0, 0,
00285 parent_window, NULL, application, 0);
00286 if (!_window) {
00287 nout << "Could not create Label Stack window!\n";
00288 exit(1);
00289 }
00290
00291 SetWindowLongPtr(_window, 0, (LONG_PTR)this);
00292 }
00293
00294
00295
00296
00297
00298
00299
00300 void WinStatsLabelStack::
00301 register_window_class(HINSTANCE application) {
00302 if (_window_class_registered) {
00303 return;
00304 }
00305
00306 WNDCLASS wc;
00307
00308 ZeroMemory(&wc, sizeof(WNDCLASS));
00309 wc.style = 0;
00310 wc.lpfnWndProc = (WNDPROC)static_window_proc;
00311 wc.hInstance = application;
00312 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
00313 wc.lpszMenuName = NULL;
00314 wc.lpszClassName = _window_class_name;
00315
00316
00317 wc.cbWndExtra = sizeof(WinStatsLabelStack *);
00318
00319 if (!RegisterClass(&wc)) {
00320 nout << "Could not register Label Stack window class!\n";
00321 exit(1);
00322 }
00323
00324 _window_class_registered = true;
00325 }
00326
00327
00328
00329
00330
00331
00332 LONG WINAPI WinStatsLabelStack::
00333 static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
00334 WinStatsLabelStack *self = (WinStatsLabelStack *)GetWindowLongPtr(hwnd, 0);
00335 if (self != (WinStatsLabelStack *)NULL && self->_window == hwnd) {
00336 return self->window_proc(hwnd, msg, wparam, lparam);
00337 } else {
00338 return DefWindowProc(hwnd, msg, wparam, lparam);
00339 }
00340 }
00341
00342
00343
00344
00345
00346
00347 LONG WinStatsLabelStack::
00348 window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
00349 switch (msg) {
00350 case WM_PAINT:
00351 {
00352 PAINTSTRUCT ps;
00353 HDC hdc = BeginPaint(hwnd, &ps);
00354
00355 RECT rect = { 0, 0, _width, _height };
00356 FillRect(hdc, &rect, (HBRUSH)COLOR_BACKGROUND);
00357 EndPaint(hwnd, &ps);
00358 return 0;
00359 }
00360
00361 default:
00362 break;
00363 }
00364
00365 return DefWindowProc(hwnd, msg, wparam, lparam);
00366 }