OpenTTD Source: src/graph_gui.cpp Source File

OpenTTD Source 13.2.1

graph_gui.cpp
Go to the documentation of this file.
1 /*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10 #include "stdafx.h"
11 #include "graph_gui.h"
12 #include "window_gui.h"
13 #include "company_base.h"
14 #include "company_gui.h"
15 #include "economy_func.h"
16 #include "cargotype.h"
17 #include "strings_func.h"
18 #include "window_func.h"
19 #include "date_func.h"
20 #include "gfx_func.h"
21 #include "core/geometry_func.hpp"
22 #include "currency.h"
23 #include "zoom_func.h"
24
25 #include "widgets/graph_widget.h"
26
27 #include "table/strings.h"
28 #include "table/sprites.h"
29 #include <math.h>
30
31 #include "safeguards.h"
32
33 /* Bitmasks of company and cargo indices that shouldn't be drawn. */
34 static CompanyMask _legend_excluded_companies;
35 static CargoTypes _legend_excluded_cargo;
36
37 /* Apparently these don't play well with enums. */
38 static const OverflowSafeInt64 INVALID_DATAPOINT(INT64_MAX); // Value used for a datapoint that shouldn't be drawn.
39 static const uint INVALID_DATAPOINT_POS = UINT_MAX; // Used to determine if the previous point was drawn.
40
41 /****************/
42 /* GRAPH LEGEND */
43 /****************/
44
45 struct GraphLegendWindow : Window {
46 GraphLegendWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
47 {
48 this->InitNested(window_number);
49
50 for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
51 if (!HasBit(_legend_excluded_companies, c)) this->LowerWidget(c + WID_GL_FIRST_COMPANY);
52
53 this->OnInvalidateData(c);
54 }
55 }
56
57 void DrawWidget(const Rect &r, int widget) const override
58 {
59 if (!IsInsideMM(widget, WID_GL_FIRST_COMPANY, MAX_COMPANIES + WID_GL_FIRST_COMPANY)) return;
60
61 CompanyID cid = (CompanyID)(widget - WID_GL_FIRST_COMPANY);
62
63 if (!Company::IsValidID(cid)) return;
64
65 bool rtl = _current_text_dir == TD_RTL;
66
67 const Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
68 Dimension d = GetSpriteSize(SPR_COMPANY_ICON);
69 DrawCompanyIcon(cid, rtl ? ir.right - d.width : ir.left, CenterBounds(ir.top, ir.bottom, d.height));
70
71 const Rect tr = ir.Indent(d.width + WidgetDimensions::scaled.hsep_normal, rtl);
72 SetDParam(0, cid);
73 SetDParam(1, cid);
74 DrawString(tr.left, tr.right, CenterBounds(tr.top, tr.bottom, FONT_HEIGHT_NORMAL), STR_COMPANY_NAME_COMPANY_NUM, HasBit(_legend_excluded_companies, cid) ? TC_BLACK : TC_WHITE);
75 }
76
77 void OnClick(Point pt, int widget, int click_count) override
78 {
79 if (!IsInsideMM(widget, WID_GL_FIRST_COMPANY, MAX_COMPANIES + WID_GL_FIRST_COMPANY)) return;
80
81 ToggleBit(_legend_excluded_companies, widget - WID_GL_FIRST_COMPANY);
82 this->ToggleWidgetLoweredState(widget);
83 this->SetDirty();
84 InvalidateWindowData(WC_INCOME_GRAPH, 0);
85 InvalidateWindowData(WC_OPERATING_PROFIT, 0);
86 InvalidateWindowData(WC_DELIVERED_CARGO, 0);
87 InvalidateWindowData(WC_PERFORMANCE_HISTORY, 0);
88 InvalidateWindowData(WC_COMPANY_VALUE, 0);
89 }
90
96 void OnInvalidateData(int data = 0, bool gui_scope = true) override
97 {
98 if (!gui_scope) return;
99 if (Company::IsValidID(data)) return;
100
101 SetBit(_legend_excluded_companies, data);
102 this->RaiseWidget(data + WID_GL_FIRST_COMPANY);
103 }
104 };
105
112 static NWidgetBase *MakeNWidgetCompanyLines(int *biggest_index)
113 {
114 NWidgetVertical *vert = new NWidgetVertical(NC_EQUALSIZE);
115 vert->SetPadding(2, 2, 2, 2);
116 uint sprite_height = GetSpriteSize(SPR_COMPANY_ICON, nullptr, ZOOM_LVL_OUT_4X).height;
117
118 for (int widnum = WID_GL_FIRST_COMPANY; widnum <= WID_GL_LAST_COMPANY; widnum++) {
119 NWidgetBackground *panel = new NWidgetBackground(WWT_PANEL, COLOUR_BROWN, widnum);
120 panel->SetMinimalSize(246, sprite_height + WidgetDimensions::unscaled.framerect.Vertical());
121 panel->SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical(), FS_NORMAL);
122 panel->SetFill(1, 1);
123 panel->SetDataTip(0x0, STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP);
124 vert->Add(panel);
125 }
126 *biggest_index = WID_GL_LAST_COMPANY;
127 return vert;
128 }
129
130 static const NWidgetPart _nested_graph_legend_widgets[] = {
131 NWidget(NWID_HORIZONTAL),
132 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
133 NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_KEY_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
134 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
135 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
136 EndContainer(),
137 NWidget(WWT_PANEL, COLOUR_BROWN, WID_GL_BACKGROUND),
138 NWidgetFunction(MakeNWidgetCompanyLines),
139 EndContainer(),
140 };
141
142 static WindowDesc _graph_legend_desc(
143 WDP_AUTO, "graph_legend", 0, 0,
144 WC_GRAPH_LEGEND, WC_NONE,
145 0,
146 _nested_graph_legend_widgets, lengthof(_nested_graph_legend_widgets)
147 );
148
149 static void ShowGraphLegend()
150 {
151 AllocateWindowDescFront<GraphLegendWindow>(&_graph_legend_desc, 0);
152 }
153
155 struct ValuesInterval {
156 OverflowSafeInt64 highest;
157 OverflowSafeInt64 lowest;
158 };
159
160 /******************/
161 /* BASE OF GRAPHS */
162 /*****************/
163
164 struct BaseGraphWindow : Window {
165 protected:
166 static const int GRAPH_MAX_DATASETS = 64;
167 static const int GRAPH_BASE_COLOUR = GREY_SCALE(2);
168 static const int GRAPH_GRID_COLOUR = GREY_SCALE(3);
169 static const int GRAPH_AXIS_LINE_COLOUR = GREY_SCALE(1);
170 static const int GRAPH_ZERO_LINE_COLOUR = GREY_SCALE(8);
171 static const int GRAPH_YEAR_LINE_COLOUR = GREY_SCALE(5);
172 static const int GRAPH_NUM_MONTHS = 24;
173
174 static const TextColour GRAPH_AXIS_LABEL_COLOUR = TC_BLACK;
175
176 static const int MIN_GRAPH_NUM_LINES_Y = 9;
177 static const int MIN_GRID_PIXEL_SIZE = 20;
178
179 uint64 excluded_data;
180 byte num_dataset;
181 byte num_on_x_axis;
182 byte num_vert_lines;
183
184 /* The starting month and year that values are plotted against. If month is
185 * 0xFF, use x_values_start and x_values_increment below instead. */
186 byte month;
187 Year year;
188
189 /* These values are used if the graph is being plotted against values
190 * rather than the dates specified by month and year. */
191 uint16 x_values_start;
192 uint16 x_values_increment;
193
194 int graph_widget;
195 StringID format_str_y_axis;
196 byte colours[GRAPH_MAX_DATASETS];
197 OverflowSafeInt64 cost[GRAPH_MAX_DATASETS][GRAPH_NUM_MONTHS];
198
205 ValuesInterval GetValuesInterval(int num_hori_lines) const
206 {
207 assert(num_hori_lines > 0);
208
209 ValuesInterval current_interval;
210 current_interval.highest = INT64_MIN;
211 current_interval.lowest = INT64_MAX;
212
213 for (int i = 0; i < this->num_dataset; i++) {
214 if (HasBit(this->excluded_data, i)) continue;
215 for (int j = 0; j < this->num_on_x_axis; j++) {
216 OverflowSafeInt64 datapoint = this->cost[i][j];
217
218 if (datapoint != INVALID_DATAPOINT) {
219 current_interval.highest = std::max(current_interval.highest, datapoint);
220 current_interval.lowest = std::min(current_interval.lowest, datapoint);
221 }
222 }
223 }
224
225 /* Prevent showing values too close to the graph limits. */
226 current_interval.highest = (11 * current_interval.highest) / 10;
227 current_interval.lowest = (11 * current_interval.lowest) / 10;
228
229 /* Always include zero in the shown range. */
230 double abs_lower = (current_interval.lowest > 0) ? 0 : (double)abs(current_interval.lowest);
231 double abs_higher = (current_interval.highest < 0) ? 0 : (double)current_interval.highest;
232
233 int num_pos_grids;
234 int64 grid_size;
235
236 if (abs_lower != 0 || abs_higher != 0) {
237 /* The number of grids to reserve for the positive part is: */
238 num_pos_grids = (int)floor(0.5 + num_hori_lines * abs_higher / (abs_higher + abs_lower));
239
240 /* If there are any positive or negative values, force that they have at least one grid. */
241 if (num_pos_grids == 0 && abs_higher != 0) num_pos_grids++;
242 if (num_pos_grids == num_hori_lines && abs_lower != 0) num_pos_grids--;
243
244 /* Get the required grid size for each side and use the maximum one. */
245 int64 grid_size_higher = (abs_higher > 0) ? ((int64)abs_higher + num_pos_grids - 1) / num_pos_grids : 0;
246 int64 grid_size_lower = (abs_lower > 0) ? ((int64)abs_lower + num_hori_lines - num_pos_grids - 1) / (num_hori_lines - num_pos_grids) : 0;
247 grid_size = std::max(grid_size_higher, grid_size_lower);
248 } else {
249 /* If both values are zero, show an empty graph. */
250 num_pos_grids = num_hori_lines / 2;
251 grid_size = 1;
252 }
253
254 current_interval.highest = num_pos_grids * grid_size;
255 current_interval.lowest = -(num_hori_lines - num_pos_grids) * grid_size;
256 return current_interval;
257 }
258
264 uint GetYLabelWidth(ValuesInterval current_interval, int num_hori_lines) const
265 {
266 /* draw text strings on the y axis */
267 int64 y_label = current_interval.highest;
268 int64 y_label_separation = (current_interval.highest - current_interval.lowest) / num_hori_lines;
269
270 uint max_width = 0;
271
272 for (int i = 0; i < (num_hori_lines + 1); i++) {
273 SetDParam(0, this->format_str_y_axis);
274 SetDParam(1, y_label);
275 Dimension d = GetStringBoundingBox(STR_GRAPH_Y_LABEL);
276 if (d.width > max_width) max_width = d.width;
277
278 y_label -= y_label_separation;
279 }
280
281 return max_width;
282 }
283
288 void DrawGraph(Rect r) const
289 {
290 uint x, y;
291 ValuesInterval interval;
292 int x_axis_offset;
293
294 /* the colours and cost array of GraphDrawer must accommodate
295 * both values for cargo and companies. So if any are higher, quit */
296 static_assert(GRAPH_MAX_DATASETS >= (int)NUM_CARGO && GRAPH_MAX_DATASETS >= (int)MAX_COMPANIES);
297 assert(this->num_vert_lines > 0);
298
299 /* Rect r will be adjusted to contain just the graph, with labels being
300 * placed outside the area. */
301 r.top += ScaleGUITrad(5) + GetCharacterHeight(FS_SMALL) / 2;
302 r.bottom -= (this->month == 0xFF ? 1 : 2) * GetCharacterHeight(FS_SMALL) + ScaleGUITrad(4);
303 r.left += ScaleGUITrad(9);
304 r.right -= ScaleGUITrad(5);
305
306 /* Initial number of horizontal lines. */
307 int num_hori_lines = 160 / ScaleGUITrad(MIN_GRID_PIXEL_SIZE);
308 /* For the rest of the height, the number of horizontal lines will increase more slowly. */
309 int resize = (r.bottom - r.top - 160) / (2 * ScaleGUITrad(MIN_GRID_PIXEL_SIZE));
310 if (resize > 0) num_hori_lines += resize;
311
312 interval = GetValuesInterval(num_hori_lines);
313
314 int label_width = GetYLabelWidth(interval, num_hori_lines);
315
316 r.left += label_width;
317
318 int x_sep = (r.right - r.left) / this->num_vert_lines;
319 int y_sep = (r.bottom - r.top) / num_hori_lines;
320
321 /* Redetermine right and bottom edge of graph to fit with the integer
322 * separation values. */
323 r.right = r.left + x_sep * this->num_vert_lines;
324 r.bottom = r.top + y_sep * num_hori_lines;
325
326 OverflowSafeInt64 interval_size = interval.highest + abs(interval.lowest);
327 /* Where to draw the X axis. Use floating point to avoid overflowing and results of zero. */
328 x_axis_offset = (int)((r.bottom - r.top) * (double)interval.highest / (double)interval_size);
329
330 /* Draw the background of the graph itself. */
331 GfxFillRect(r.left, r.top, r.right, r.bottom, GRAPH_BASE_COLOUR);
332
333 /* Draw the vertical grid lines. */
334
335 /* Don't draw the first line, as that's where the axis will be. */
336 x = r.left + x_sep;
337
338 for (int i = 0; i < this->num_vert_lines; i++) {
339 GfxFillRect(x, r.top, x, r.bottom, GRAPH_GRID_COLOUR);
340 x += x_sep;
341 }
342
343 /* Draw the horizontal grid lines. */
344 y = r.bottom;
345
346 for (int i = 0; i < (num_hori_lines + 1); i++) {
347 GfxFillRect(r.left - ScaleGUITrad(3), y, r.left - 1, y, GRAPH_AXIS_LINE_COLOUR);
348 GfxFillRect(r.left, y, r.right, y, GRAPH_GRID_COLOUR);
349 y -= y_sep;
350 }
351
352 /* Draw the y axis. */
353 GfxFillRect(r.left, r.top, r.left, r.bottom, GRAPH_AXIS_LINE_COLOUR);
354
355 /* Draw the x axis. */
356 y = x_axis_offset + r.top;
357 GfxFillRect(r.left, y, r.right, y, GRAPH_ZERO_LINE_COLOUR);
358
359 /* Find the largest value that will be drawn. */
360 if (this->num_on_x_axis == 0) return;
361
362 assert(this->num_on_x_axis > 0);
363 assert(this->num_dataset > 0);
364
365 /* draw text strings on the y axis */
366 int64 y_label = interval.highest;
367 int64 y_label_separation = abs(interval.highest - interval.lowest) / num_hori_lines;
368
369 y = r.top - GetCharacterHeight(FS_SMALL) / 2;
370
371 for (int i = 0; i < (num_hori_lines + 1); i++) {
372 SetDParam(0, this->format_str_y_axis);
373 SetDParam(1, y_label);
374 DrawString(r.left - label_width - ScaleGUITrad(4), r.left - ScaleGUITrad(4), y, STR_GRAPH_Y_LABEL, GRAPH_AXIS_LABEL_COLOUR, SA_RIGHT);
375
376 y_label -= y_label_separation;
377 y += y_sep;
378 }
379
380 /* Draw x-axis labels and markings for graphs based on financial quarters and years. */
381 if (this->month != 0xFF) {
382 x = r.left;
383 y = r.bottom + ScaleGUITrad(2);
384 byte month = this->month;
385 Year year = this->year;
386 for (int i = 0; i < this->num_on_x_axis; i++) {
387 SetDParam(0, month + STR_MONTH_ABBREV_JAN);
388 SetDParam(1, year);
389 DrawStringMultiLine(x, x + x_sep, y, this->height, month == 0 ? STR_GRAPH_X_LABEL_MONTH_YEAR : STR_GRAPH_X_LABEL_MONTH, GRAPH_AXIS_LABEL_COLOUR, SA_LEFT);
390
391 month += 3;
392 if (month >= 12) {
393 month = 0;
394 year++;
395
396 /* Draw a lighter grid line between years. Top and bottom adjustments ensure we don't draw over top and bottom horizontal grid lines. */
397 GfxFillRect(x + x_sep, r.top + 1, x + x_sep, r.bottom - 1, GRAPH_YEAR_LINE_COLOUR);
398 }
399 x += x_sep;
400 }
401 } else {
402 /* Draw x-axis labels for graphs not based on quarterly performance (cargo payment rates). */
403 x = r.left;
404 y = r.bottom + ScaleGUITrad(2);
405 uint16 label = this->x_values_start;
406
407 for (int i = 0; i < this->num_on_x_axis; i++) {
408 SetDParam(0, label);
409 DrawString(x + 1, x + x_sep - 1, y, STR_GRAPH_Y_LABEL_NUMBER, GRAPH_AXIS_LABEL_COLOUR, SA_HOR_CENTER);
410
411 label += this->x_values_increment;
412 x += x_sep;
413 }
414 }
415
416 /* draw lines and dots */
417 uint linewidth = _settings_client.gui.graph_line_thickness;
418 uint pointoffs1 = (linewidth + 1) / 2;
419 uint pointoffs2 = linewidth + 1 - pointoffs1;
420 for (int i = 0; i < this->num_dataset; i++) {
421 if (!HasBit(this->excluded_data, i)) {
422 /* Centre the dot between the grid lines. */
423 x = r.left + (x_sep / 2);
424
425 byte colour = this->colours[i];
426 uint prev_x = INVALID_DATAPOINT_POS;
427 uint prev_y = INVALID_DATAPOINT_POS;
428
429 for (int j = 0; j < this->num_on_x_axis; j++) {
430 OverflowSafeInt64 datapoint = this->cost[i][j];
431
432 if (datapoint != INVALID_DATAPOINT) {
433 /*
434 * Check whether we need to reduce the 'accuracy' of the
435 * datapoint value and the highest value to split overflows.
436 * And when 'drawing' 'one million' or 'one million and one'
437 * there is no significant difference, so the least
438 * significant bits can just be removed.
439 *
440 * If there are more bits needed than would fit in a 32 bits
441 * integer, so at about 31 bits because of the sign bit, the
442 * least significant bits are removed.
443 */
444 int mult_range = FindLastBit(x_axis_offset) + FindLastBit(abs(datapoint));
445 int reduce_range = std::max(mult_range - 31, 0);
446
447 /* Handle negative values differently (don't shift sign) */
448 if (datapoint < 0) {
449 datapoint = -(abs(datapoint) >> reduce_range);
450 } else {
451 datapoint >>= reduce_range;
452 }
453 y = r.top + x_axis_offset - ((r.bottom - r.top) * datapoint) / (interval_size >> reduce_range);
454
455 /* Draw the point. */
456 GfxFillRect(x - pointoffs1, y - pointoffs1, x + pointoffs2, y + pointoffs2, colour);
457
458 /* Draw the line connected to the previous point. */
459 if (prev_x != INVALID_DATAPOINT_POS) GfxDrawLine(prev_x, prev_y, x, y, colour, linewidth);
460
461 prev_x = x;
462 prev_y = y;
463 } else {
464 prev_x = INVALID_DATAPOINT_POS;
465 prev_y = INVALID_DATAPOINT_POS;
466 }
467
468 x += x_sep;
469 }
470 }
471 }
472 }
473
474
475 BaseGraphWindow(WindowDesc *desc, int widget, StringID format_str_y_axis) :
476 Window(desc),
477 format_str_y_axis(format_str_y_axis)
478 {
479 SetWindowDirty(WC_GRAPH_LEGEND, 0);
480 this->num_vert_lines = 24;
481 this->graph_widget = widget;
482 }
483
484 void InitializeWindow(WindowNumber number)
485 {
486 /* Initialise the dataset */
487 this->UpdateStatistics(true);
488
489 this->InitNested(number);
490 }
491
492 public:
493 void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
494 {
495 if (widget != this->graph_widget) return;
496
497 uint x_label_width = 0;
498
499 /* Draw x-axis labels and markings for graphs based on financial quarters and years. */
500 if (this->month != 0xFF) {
501 byte month = this->month;
502 Year year = this->year;
503 for (int i = 0; i < this->num_on_x_axis; i++) {
504 SetDParam(0, month + STR_MONTH_ABBREV_JAN);
505 SetDParam(1, year);
506 x_label_width = std::max(x_label_width, GetStringBoundingBox(month == 0 ? STR_GRAPH_X_LABEL_MONTH_YEAR : STR_GRAPH_X_LABEL_MONTH).width);
507
508 month += 3;
509 if (month >= 12) {
510 month = 0;
511 year++;
512 }
513 }
514 } else {
515 /* Draw x-axis labels for graphs not based on quarterly performance (cargo payment rates). */
516 SetDParamMaxValue(0, this->x_values_start + this->num_on_x_axis * this->x_values_increment, 0, FS_SMALL);
517 x_label_width = GetStringBoundingBox(STR_GRAPH_Y_LABEL_NUMBER).width;
518 }
519
520 SetDParam(0, this->format_str_y_axis);
521 SetDParam(1, INT64_MAX);
522 uint y_label_width = GetStringBoundingBox(STR_GRAPH_Y_LABEL).width;
523
524 size->width = std::max<uint>(size->width, ScaleGUITrad(5) + y_label_width + this->num_on_x_axis * (x_label_width + ScaleGUITrad(5)) + ScaleGUITrad(9));
525 size->height = std::max<uint>(size->height, ScaleGUITrad(5) + (1 + MIN_GRAPH_NUM_LINES_Y * 2 + (this->month != 0xFF ? 3 : 1)) * FONT_HEIGHT_SMALL + ScaleGUITrad(4));
526 size->height = std::max<uint>(size->height, size->width / 3);
527 }
528
529 void DrawWidget(const Rect &r, int widget) const override
530 {
531 if (widget != this->graph_widget) return;
532
533 DrawGraph(r);
534 }
535
536 virtual OverflowSafeInt64 GetGraphData(const Company *c, int j)
537 {
538 return INVALID_DATAPOINT;
539 }
540
541 void OnClick(Point pt, int widget, int click_count) override
542 {
543 /* Clicked on legend? */
544 if (widget == WID_CV_KEY_BUTTON) ShowGraphLegend();
545 }
546
547 void OnGameTick() override
548 {
549 this->UpdateStatistics(false);
550 }
551
557 void OnInvalidateData(int data = 0, bool gui_scope = true) override
558 {
559 if (!gui_scope) return;
560 this->UpdateStatistics(true);
561 }
562
567 void UpdateStatistics(bool initialize)
568 {
569 CompanyMask excluded_companies = _legend_excluded_companies;
570
571 /* Exclude the companies which aren't valid */
572 for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
573 if (!Company::IsValidID(c)) SetBit(excluded_companies, c);
574 }
575
576 byte nums = 0;
577 for (const Company *c : Company::Iterate()) {
578 nums = std::min(this->num_vert_lines, std::max(nums, c->num_valid_stat_ent));
579 }
580
581 int mo = (_cur_month / 3 - nums) * 3;
582 int yr = _cur_year;
583 while (mo < 0) {
584 yr--;
585 mo += 12;
586 }
587
588 if (!initialize && this->excluded_data == excluded_companies && this->num_on_x_axis == nums &&
589 this->year == yr && this->month == mo) {
590 /* There's no reason to get new stats */
591 return;
592 }
593
594 this->excluded_data = excluded_companies;
595 this->num_on_x_axis = nums;
596 this->year = yr;
597 this->month = mo;
598
599 int numd = 0;
600 for (CompanyID k = COMPANY_FIRST; k < MAX_COMPANIES; k++) {
601 const Company *c = Company::GetIfValid(k);
602 if (c != nullptr) {
603 this->colours[numd] = _colour_gradient[c->colour][6];
604 for (int j = this->num_on_x_axis, i = 0; --j >= 0;) {
605 this->cost[numd][i] = (j >= c->num_valid_stat_ent) ? INVALID_DATAPOINT : GetGraphData(c, j);
606 i++;
607 }
608 }
609 numd++;
610 }
611
612 this->num_dataset = numd;
613 }
614 };
615
616
617 /********************/
618 /* OPERATING PROFIT */
619 /********************/
620
621 struct OperatingProfitGraphWindow : BaseGraphWindow {
622 OperatingProfitGraphWindow(WindowDesc *desc, WindowNumber window_number) :
623 BaseGraphWindow(desc, WID_CV_GRAPH, STR_JUST_CURRENCY_SHORT)
624 {
625 this->InitializeWindow(window_number);
626 }
627
628 OverflowSafeInt64 GetGraphData(const Company *c, int j) override
629 {
630 return c->old_economy[j].income + c->old_economy[j].expenses;
631 }
632 };
633
634 static const NWidgetPart _nested_operating_profit_widgets[] = {
635 NWidget(NWID_HORIZONTAL),
636 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
637 NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_OPERATING_PROFIT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
638 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
639 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
640 NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
641 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
642 EndContainer(),
643 NWidget(WWT_PANEL, COLOUR_BROWN, WID_CV_BACKGROUND),
644 NWidget(NWID_HORIZONTAL),
645 NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CV_GRAPH), SetMinimalSize(576, 160), SetFill(1, 1), SetResize(1, 1),
646 NWidget(NWID_VERTICAL),
647 NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
648 NWidget(WWT_RESIZEBOX, COLOUR_BROWN, WID_CV_RESIZE),
649 EndContainer(),
650 EndContainer(),
651 EndContainer(),
652 };
653
654 static WindowDesc _operating_profit_desc(
655 WDP_AUTO, "graph_operating_profit", 0, 0,
656 WC_OPERATING_PROFIT, WC_NONE,
657 0,
658 _nested_operating_profit_widgets, lengthof(_nested_operating_profit_widgets)
659 );
660
661
662 void ShowOperatingProfitGraph()
663 {
664 AllocateWindowDescFront<OperatingProfitGraphWindow>(&_operating_profit_desc, 0);
665 }
666
667
668 /****************/
669 /* INCOME GRAPH */
670 /****************/
671
672 struct IncomeGraphWindow : BaseGraphWindow {
673 IncomeGraphWindow(WindowDesc *desc, WindowNumber window_number) :
674 BaseGraphWindow(desc, WID_CV_GRAPH, STR_JUST_CURRENCY_SHORT)
675 {
676 this->InitializeWindow(window_number);
677 }
678
679 OverflowSafeInt64 GetGraphData(const Company *c, int j) override
680 {
681 return c->old_economy[j].income;
682 }
683 };
684
685 static const NWidgetPart _nested_income_graph_widgets[] = {
686 NWidget(NWID_HORIZONTAL),
687 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
688 NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_INCOME_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
689 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
690 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
691 NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
692 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
693 EndContainer(),
694 NWidget(WWT_PANEL, COLOUR_BROWN, WID_CV_BACKGROUND),
695 NWidget(NWID_HORIZONTAL),
696 NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CV_GRAPH), SetMinimalSize(576, 128), SetFill(1, 1), SetResize(1, 1),
697 NWidget(NWID_VERTICAL),
698 NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
699 NWidget(WWT_RESIZEBOX, COLOUR_BROWN, WID_CV_RESIZE),
700 EndContainer(),
701 EndContainer(),
702 EndContainer(),
703 };
704
705 static WindowDesc _income_graph_desc(
706 WDP_AUTO, "graph_income", 0, 0,
707 WC_INCOME_GRAPH, WC_NONE,
708 0,
709 _nested_income_graph_widgets, lengthof(_nested_income_graph_widgets)
710 );
711
712 void ShowIncomeGraph()
713 {
714 AllocateWindowDescFront<IncomeGraphWindow>(&_income_graph_desc, 0);
715 }
716
717 /*******************/
718 /* DELIVERED CARGO */
719 /*******************/
720
721 struct DeliveredCargoGraphWindow : BaseGraphWindow {
722 DeliveredCargoGraphWindow(WindowDesc *desc, WindowNumber window_number) :
723 BaseGraphWindow(desc, WID_CV_GRAPH, STR_JUST_COMMA)
724 {
725 this->InitializeWindow(window_number);
726 }
727
728 OverflowSafeInt64 GetGraphData(const Company *c, int j) override
729 {
730 return c->old_economy[j].delivered_cargo.GetSum<OverflowSafeInt64>();
731 }
732 };
733
734 static const NWidgetPart _nested_delivered_cargo_graph_widgets[] = {
735 NWidget(NWID_HORIZONTAL),
736 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
737 NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_CARGO_DELIVERED_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
738 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
739 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
740 NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
741 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
742 EndContainer(),
743 NWidget(WWT_PANEL, COLOUR_BROWN, WID_CV_BACKGROUND),
744 NWidget(NWID_HORIZONTAL),
745 NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CV_GRAPH), SetMinimalSize(576, 128), SetFill(1, 1), SetResize(1, 1),
746 NWidget(NWID_VERTICAL),
747 NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
748 NWidget(WWT_RESIZEBOX, COLOUR_BROWN, WID_CV_RESIZE),
749 EndContainer(),
750 EndContainer(),
751 EndContainer(),
752 };
753
754 static WindowDesc _delivered_cargo_graph_desc(
755 WDP_AUTO, "graph_delivered_cargo", 0, 0,
756 WC_DELIVERED_CARGO, WC_NONE,
757 0,
758 _nested_delivered_cargo_graph_widgets, lengthof(_nested_delivered_cargo_graph_widgets)
759 );
760
761 void ShowDeliveredCargoGraph()
762 {
763 AllocateWindowDescFront<DeliveredCargoGraphWindow>(&_delivered_cargo_graph_desc, 0);
764 }
765
766 /***********************/
767 /* PERFORMANCE HISTORY */
768 /***********************/
769
770 struct PerformanceHistoryGraphWindow : BaseGraphWindow {
771 PerformanceHistoryGraphWindow(WindowDesc *desc, WindowNumber window_number) :
772 BaseGraphWindow(desc, WID_PHG_GRAPH, STR_JUST_COMMA)
773 {
774 this->InitializeWindow(window_number);
775 }
776
777 OverflowSafeInt64 GetGraphData(const Company *c, int j) override
778 {
779 return c->old_economy[j].performance_history;
780 }
781
782 void OnClick(Point pt, int widget, int click_count) override
783 {
784 if (widget == WID_PHG_DETAILED_PERFORMANCE) ShowPerformanceRatingDetail();
785 this->BaseGraphWindow::OnClick(pt, widget, click_count);
786 }
787 };
788
789 static const NWidgetPart _nested_performance_history_widgets[] = {
790 NWidget(NWID_HORIZONTAL),
791 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
792 NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_COMPANY_PERFORMANCE_RATINGS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
793 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_PHG_DETAILED_PERFORMANCE), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_PERFORMANCE_DETAIL_KEY, STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP),
794 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_PHG_KEY), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
795 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
796 NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
797 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
798 EndContainer(),
799 NWidget(WWT_PANEL, COLOUR_BROWN, WID_PHG_BACKGROUND),
800 NWidget(NWID_HORIZONTAL),
801 NWidget(WWT_EMPTY, COLOUR_BROWN, WID_PHG_GRAPH), SetMinimalSize(576, 224), SetFill(1, 1), SetResize(1, 1),
802 NWidget(NWID_VERTICAL),
803 NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
804 NWidget(WWT_RESIZEBOX, COLOUR_BROWN, WID_PHG_RESIZE),
805 EndContainer(),
806 EndContainer(),
807 EndContainer(),
808 };
809
810 static WindowDesc _performance_history_desc(
811 WDP_AUTO, "graph_performance", 0, 0,
812 WC_PERFORMANCE_HISTORY, WC_NONE,
813 0,
814 _nested_performance_history_widgets, lengthof(_nested_performance_history_widgets)
815 );
816
817 void ShowPerformanceHistoryGraph()
818 {
819 AllocateWindowDescFront<PerformanceHistoryGraphWindow>(&_performance_history_desc, 0);
820 }
821
822 /*****************/
823 /* COMPANY VALUE */
824 /*****************/
825
826 struct CompanyValueGraphWindow : BaseGraphWindow {
827 CompanyValueGraphWindow(WindowDesc *desc, WindowNumber window_number) :
828 BaseGraphWindow(desc, WID_CV_GRAPH, STR_JUST_CURRENCY_SHORT)
829 {
830 this->InitializeWindow(window_number);
831 }
832
833 OverflowSafeInt64 GetGraphData(const Company *c, int j) override
834 {
835 return c->old_economy[j].company_value;
836 }
837 };
838
839 static const NWidgetPart _nested_company_value_graph_widgets[] = {
840 NWidget(NWID_HORIZONTAL),
841 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
842 NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_COMPANY_VALUES_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
843 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
844 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
845 NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
846 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
847 EndContainer(),
848 NWidget(WWT_PANEL, COLOUR_BROWN, WID_CV_BACKGROUND),
849 NWidget(NWID_HORIZONTAL),
850 NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CV_GRAPH), SetMinimalSize(576, 224), SetFill(1, 1), SetResize(1, 1),
851 NWidget(NWID_VERTICAL),
852 NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
853 NWidget(WWT_RESIZEBOX, COLOUR_BROWN, WID_CV_RESIZE),
854 EndContainer(),
855 EndContainer(),
856 EndContainer(),
857 };
858
859 static WindowDesc _company_value_graph_desc(
860 WDP_AUTO, "graph_company_value", 0, 0,
861 WC_COMPANY_VALUE, WC_NONE,
862 0,
863 _nested_company_value_graph_widgets, lengthof(_nested_company_value_graph_widgets)
864 );
865
866 void ShowCompanyValueGraph()
867 {
868 AllocateWindowDescFront<CompanyValueGraphWindow>(&_company_value_graph_desc, 0);
869 }
870
871 /*****************/
872 /* PAYMENT RATES */
873 /*****************/
874
875 struct PaymentRatesGraphWindow : BaseGraphWindow {
876 uint line_height;
877 Scrollbar *vscroll;
878 uint legend_width;
879
880 PaymentRatesGraphWindow(WindowDesc *desc, WindowNumber window_number) :
881 BaseGraphWindow(desc, WID_CPR_GRAPH, STR_JUST_CURRENCY_SHORT)
882 {
883 this->num_on_x_axis = 20;
884 this->num_vert_lines = 20;
885 this->month = 0xFF;
886 this->x_values_start = 10;
887 this->x_values_increment = 10;
888
889 this->CreateNestedTree();
890 this->vscroll = this->GetScrollbar(WID_CPR_MATRIX_SCROLLBAR);
891 this->vscroll->SetCount(static_cast<int>(_sorted_standard_cargo_specs.size()));
892
893 /* Initialise the dataset */
894 this->OnHundredthTick();
895
896 this->FinishInitNested(window_number);
897 }
898
899 void OnInit() override
900 {
901 /* Width of the legend blob. */
902 this->legend_width = (FONT_HEIGHT_SMALL - ScaleGUITrad(1)) * 8 / 5;
903 }
904
905 void UpdateExcludedData()
906 {
907 this->excluded_data = 0;
908
909 int i = 0;
910 for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
911 if (HasBit(_legend_excluded_cargo, cs->Index())) SetBit(this->excluded_data, i);
912 i++;
913 }
914 }
915
916 void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
917 {
918 if (widget != WID_CPR_MATRIX) {
919 BaseGraphWindow::UpdateWidgetSize(widget, size, padding, fill, resize);
920 return;
921 }
922
923 for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
924 SetDParam(0, cs->name);
925 Dimension d = GetStringBoundingBox(STR_GRAPH_CARGO_PAYMENT_CARGO);
926 d.width += this->legend_width + WidgetDimensions::scaled.hsep_normal; // colour field
927 d.width += WidgetDimensions::scaled.framerect.Horizontal();
928 d.height += WidgetDimensions::scaled.framerect.Vertical();
929 *size = maxdim(d, *size);
930 }
931
932 this->line_height = size->height;
933 size->height = this->line_height * 11; /* Default number of cargo types in most climates. */
934 resize->width = 0;
935 resize->height = this->line_height;
936 }
937
938 void DrawWidget(const Rect &r, int widget) const override
939 {
940 if (widget != WID_CPR_MATRIX) {
941 BaseGraphWindow::DrawWidget(r, widget);
942 return;
943 }
944
945 bool rtl = _current_text_dir == TD_RTL;
946
947 int pos = this->vscroll->GetPosition();
948 int max = pos + this->vscroll->GetCapacity();
949
950 Rect line = r.WithHeight(this->line_height);
951 for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
952 if (pos-- > 0) continue;
953 if (--max < 0) break;
954
955 bool lowered = !HasBit(_legend_excluded_cargo, cs->Index());
956
957 /* Redraw frame if lowered */
958 if (lowered) DrawFrameRect(line, COLOUR_BROWN, FR_LOWERED);
959
960 const Rect text = line.Shrink(WidgetDimensions::scaled.framerect).Translate(lowered ? WidgetDimensions::scaled.pressed : 0, lowered ? WidgetDimensions::scaled.pressed : 0);
961
962 /* Cargo-colour box with outline */
963 const Rect cargo = text.WithWidth(this->legend_width, rtl);
964 GfxFillRect(cargo, PC_BLACK);
965 GfxFillRect(cargo.Shrink(WidgetDimensions::scaled.bevel), cs->legend_colour);
966
967 /* Cargo name */
968 SetDParam(0, cs->name);
969 DrawString(text.Indent(this->legend_width + WidgetDimensions::scaled.hsep_normal, rtl), STR_GRAPH_CARGO_PAYMENT_CARGO);
970
971 line = line.Translate(0, this->line_height);
972 }
973 }
974
975 void OnClick(Point pt, int widget, int click_count) override
976 {
977 switch (widget) {
978 case WID_CPR_ENABLE_CARGOES:
979 /* Remove all cargoes from the excluded lists. */
980 _legend_excluded_cargo = 0;
981 this->excluded_data = 0;
982 this->SetDirty();
983 break;
984
985 case WID_CPR_DISABLE_CARGOES: {
986 /* Add all cargoes to the excluded lists. */
987 int i = 0;
988 for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
989 SetBit(_legend_excluded_cargo, cs->Index());
990 SetBit(this->excluded_data, i);
991 i++;
992 }
993 this->SetDirty();
994 break;
995 }
996
997 case WID_CPR_MATRIX: {
998 uint row = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_CPR_MATRIX);
999 if (row >= this->vscroll->GetCount()) return;
1000
1001 for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
1002 if (row-- > 0) continue;
1003
1004 ToggleBit(_legend_excluded_cargo, cs->Index());
1005 this->UpdateExcludedData();
1006 this->SetDirty();
1007 break;
1008 }
1009 break;
1010 }
1011 }
1012 }
1013
1014 void OnResize() override
1015 {
1016 this->vscroll->SetCapacityFromWidget(this, WID_CPR_MATRIX);
1017 }
1018
1019 void OnGameTick() override
1020 {
1021 /* Override default OnGameTick */
1022 }
1023
1029 void OnInvalidateData(int data = 0, bool gui_scope = true) override
1030 {
1031 if (!gui_scope) return;
1032 this->OnHundredthTick();
1033 }
1034
1035 void OnHundredthTick() override
1036 {
1037 this->UpdateExcludedData();
1038
1039 int i = 0;
1040 for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
1041 this->colours[i] = cs->legend_colour;
1042 for (uint j = 0; j != 20; j++) {
1043 this->cost[i][j] = GetTransportedGoodsIncome(10, 20, j * 4 + 4, cs->Index());
1044 }
1045 i++;
1046 }
1047 this->num_dataset = i;
1048 }
1049 };
1050
1051 static const NWidgetPart _nested_cargo_payment_rates_widgets[] = {
1052 NWidget(NWID_HORIZONTAL),
1053 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
1054 NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1055 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
1056 NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
1057 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
1058 EndContainer(),
1059 NWidget(WWT_PANEL, COLOUR_BROWN, WID_CPR_BACKGROUND), SetMinimalSize(568, 128),
1060 NWidget(NWID_HORIZONTAL),
1061 NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
1062 NWidget(WWT_TEXT, COLOUR_BROWN, WID_CPR_HEADER), SetMinimalSize(0, 6), SetPadding(2, 0, 2, 0), SetDataTip(STR_GRAPH_CARGO_PAYMENT_RATES_TITLE, STR_NULL),
1063 NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
1064 EndContainer(),
1065 NWidget(NWID_HORIZONTAL),
1066 NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CPR_GRAPH), SetMinimalSize(495, 0), SetFill(1, 1), SetResize(1, 1),
1067 NWidget(NWID_VERTICAL),
1068 NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 1),
1069 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CPR_ENABLE_CARGOES), SetDataTip(STR_GRAPH_CARGO_ENABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL), SetFill(1, 0),
1070 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CPR_DISABLE_CARGOES), SetDataTip(STR_GRAPH_CARGO_DISABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL), SetFill(1, 0),
1071 NWidget(NWID_SPACER), SetMinimalSize(0, 4),
1072 NWidget(NWID_HORIZONTAL),
1073 NWidget(WWT_MATRIX, COLOUR_BROWN, WID_CPR_MATRIX), SetResize(0, 2), SetMatrixDataTip(1, 0, STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO), SetScrollbar(WID_CPR_MATRIX_SCROLLBAR),
1074 NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_CPR_MATRIX_SCROLLBAR),
1075 EndContainer(),
1076 NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 1),
1077 EndContainer(),
1078 NWidget(NWID_SPACER), SetMinimalSize(5, 0), SetFill(0, 1), SetResize(0, 1),
1079 EndContainer(),
1080 NWidget(NWID_HORIZONTAL),
1081 NWidget(NWID_SPACER), SetMinimalSize(12, 0), SetFill(1, 0), SetResize(1, 0),
1082 NWidget(WWT_TEXT, COLOUR_BROWN, WID_CPR_FOOTER), SetMinimalSize(0, 6), SetPadding(2, 0, 2, 0), SetDataTip(STR_GRAPH_CARGO_PAYMENT_RATES_X_LABEL, STR_NULL),
1083 NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
1084 NWidget(WWT_RESIZEBOX, COLOUR_BROWN, WID_CPR_RESIZE),
1085 EndContainer(),
1086 EndContainer(),
1087 };
1088
1089 static WindowDesc _cargo_payment_rates_desc(
1090 WDP_AUTO, "graph_cargo_payment_rates", 0, 0,
1091 WC_PAYMENT_RATES, WC_NONE,
1092 0,
1093 _nested_cargo_payment_rates_widgets, lengthof(_nested_cargo_payment_rates_widgets)
1094 );
1095
1096
1097 void ShowCargoPaymentRates()
1098 {
1099 AllocateWindowDescFront<PaymentRatesGraphWindow>(&_cargo_payment_rates_desc, 0);
1100 }
1101
1102 /*****************************/
1103 /* PERFORMANCE RATING DETAIL */
1104 /*****************************/
1105
1106 struct PerformanceRatingDetailWindow : Window {
1107 static CompanyID company;
1108 int timeout;
1109
1110 PerformanceRatingDetailWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
1111 {
1112 this->UpdateCompanyStats();
1113
1114 this->InitNested(window_number);
1115 this->OnInvalidateData(INVALID_COMPANY);
1116 }
1117
1118 void UpdateCompanyStats()
1119 {
1120 /* Update all company stats with the current data
1121 * (this is because _score_info is not saved to a savegame) */
1122 for (Company *c : Company::Iterate()) {
1123 UpdateCompanyRatingAndValue(c, false);
1124 }
1125
1126 this->timeout = DAY_TICKS * 5;
1127 }
1128
1129 uint score_info_left;
1130 uint score_info_right;
1131 uint bar_left;
1132 uint bar_right;
1133 uint bar_width;
1134 uint bar_height;
1135 uint score_detail_left;
1136 uint score_detail_right;
1137
1138 void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
1139 {
1140 switch (widget) {
1141 case WID_PRD_SCORE_FIRST:
1142 this->bar_height = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.fullbevel.Vertical();
1143 size->height = this->bar_height + WidgetDimensions::scaled.matrix.Vertical();
1144
1145 uint score_info_width = 0;
1146 for (uint i = SCORE_BEGIN; i < SCORE_END; i++) {
1147 score_info_width = std::max(score_info_width, GetStringBoundingBox(STR_PERFORMANCE_DETAIL_VEHICLES + i).width);
1148 }
1149 SetDParamMaxValue(0, 1000);
1150 score_info_width += GetStringBoundingBox(STR_BLACK_COMMA).width + WidgetDimensions::scaled.hsep_wide;
1151
1152 SetDParamMaxValue(0, 100);
1153 this->bar_width = GetStringBoundingBox(STR_PERFORMANCE_DETAIL_PERCENT).width + WidgetDimensions::scaled.hsep_indent * 2; // Wide bars!
1154
1155 /* At this number we are roughly at the max; it can become wider,
1156 * but then you need at 1000 times more money. At that time you're
1157 * not that interested anymore in the last few digits anyway.
1158 * The 500 is because 999 999 500 to 999 999 999 are rounded to
1159 * 1 000 M, and not 999 999 k. Use negative numbers to account for
1160 * the negative income/amount of money etc. as well. */
1161 int max = -(999999999 - 500);
1162
1163 /* Scale max for the display currency. Prior to rendering the value
1164 * is converted into the display currency, which may cause it to
1165 * raise significantly. We need to compensate for that since {{CURRCOMPACT}}
1166 * is used, which can produce quite short renderings of very large
1167 * values. Otherwise the calculated width could be too narrow.
1168 * Note that it doesn't work if there was a currency with an exchange
1169 * rate greater than max.
1170 * When the currency rate is more than 1000, the 999 999 k becomes at
1171 * least 999 999 M which roughly is equally long. Furthermore if the
1172 * exchange rate is that high, 999 999 k is usually not enough anymore
1173 * to show the different currency numbers. */
1174 if (_currency->rate < 1000) max /= _currency->rate;
1175 SetDParam(0, max);
1176 SetDParam(1, max);
1177 uint score_detail_width = GetStringBoundingBox(STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY).width;
1178
1179 size->width = WidgetDimensions::scaled.frametext.Horizontal() + score_info_width + WidgetDimensions::scaled.hsep_wide + this->bar_width + WidgetDimensions::scaled.hsep_wide + score_detail_width;
1180 uint left = WidgetDimensions::scaled.frametext.left;
1181 uint right = size->width - WidgetDimensions::scaled.frametext.right;
1182
1183 bool rtl = _current_text_dir == TD_RTL;
1184 this->score_info_left = rtl ? right - score_info_width : left;
1185 this->score_info_right = rtl ? right : left + score_info_width;
1186
1187 this->score_detail_left = rtl ? left : right - score_detail_width;
1188 this->score_detail_right = rtl ? left + score_detail_width : right;
1189
1190 this->bar_left = left + (rtl ? score_detail_width : score_info_width) + WidgetDimensions::scaled.hsep_wide;
1191 this->bar_right = this->bar_left + this->bar_width - 1;
1192 break;
1193 }
1194 }
1195
1196 void DrawWidget(const Rect &r, int widget) const override
1197 {
1198 /* No need to draw when there's nothing to draw */
1199 if (this->company == INVALID_COMPANY) return;
1200
1201 if (IsInsideMM(widget, WID_PRD_COMPANY_FIRST, WID_PRD_COMPANY_LAST + 1)) {
1202 if (this->IsWidgetDisabled(widget)) return;
1203 CompanyID cid = (CompanyID)(widget - WID_PRD_COMPANY_FIRST);
1204 int offset = (cid == this->company) ? WidgetDimensions::scaled.pressed : 0;
1205 Dimension sprite_size = GetSpriteSize(SPR_COMPANY_ICON);
1206 DrawCompanyIcon(cid, CenterBounds(r.left, r.right, sprite_size.width) + offset, CenterBounds(r.top, r.bottom, sprite_size.height) + offset);
1207 return;
1208 }
1209
1210 if (!IsInsideMM(widget, WID_PRD_SCORE_FIRST, WID_PRD_SCORE_LAST + 1)) return;
1211
1212 ScoreID score_type = (ScoreID)(widget - WID_PRD_SCORE_FIRST);
1213
1214 /* The colours used to show how the progress is going */
1215 int colour_done = _colour_gradient[COLOUR_GREEN][4];
1216 int colour_notdone = _colour_gradient[COLOUR_RED][4];
1217
1218 /* Draw all the score parts */
1219 int64 val = _score_part[company][score_type];
1220 int64 needed = _score_info[score_type].needed;
1221 int score = _score_info[score_type].score;
1222
1223 /* SCORE_TOTAL has its own rules ;) */
1224 if (score_type == SCORE_TOTAL) {
1225 for (ScoreID i = SCORE_BEGIN; i < SCORE_END; i++) score += _score_info[i].score;
1226 needed = SCORE_MAX;
1227 }
1228
1229 uint bar_top = CenterBounds(r.top, r.bottom, this->bar_height);
1230 uint text_top = CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL);
1231
1232 DrawString(this->score_info_left, this->score_info_right, text_top, STR_PERFORMANCE_DETAIL_VEHICLES + score_type);
1233
1234 /* Draw the score */
1235 SetDParam(0, score);
1236 DrawString(this->score_info_left, this->score_info_right, text_top, STR_BLACK_COMMA, TC_FROMSTRING, SA_RIGHT);
1237
1238 /* Calculate the %-bar */
1239 uint x = Clamp<int64>(val, 0, needed) * this->bar_width / needed;
1240 bool rtl = _current_text_dir == TD_RTL;
1241 if (rtl) {
1242 x = this->bar_right - x;
1243 } else {
1244 x = this->bar_left + x;
1245 }
1246
1247 /* Draw the bar */
1248 if (x != this->bar_left) GfxFillRect(this->bar_left, bar_top, x, bar_top + this->bar_height - 1, rtl ? colour_notdone : colour_done);
1249 if (x != this->bar_right) GfxFillRect(x, bar_top, this->bar_right, bar_top + this->bar_height - 1, rtl ? colour_done : colour_notdone);
1250
1251 /* Draw it */
1252 SetDParam(0, Clamp<int64>(val, 0, needed) * 100 / needed);
1253 DrawString(this->bar_left, this->bar_right, text_top, STR_PERFORMANCE_DETAIL_PERCENT, TC_FROMSTRING, SA_HOR_CENTER);
1254
1255 /* SCORE_LOAN is inversed */
1256 if (score_type == SCORE_LOAN) val = needed - val;
1257
1258 /* Draw the amount we have against what is needed
1259 * For some of them it is in currency format */
1260 SetDParam(0, val);
1261 SetDParam(1, needed);
1262 switch (score_type) {
1263 case SCORE_MIN_PROFIT:
1264 case SCORE_MIN_INCOME:
1265 case SCORE_MAX_INCOME:
1266 case SCORE_MONEY:
1267 case SCORE_LOAN:
1268 DrawString(this->score_detail_left, this->score_detail_right, text_top, STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY);
1269 break;
1270 default:
1271 DrawString(this->score_detail_left, this->score_detail_right, text_top, STR_PERFORMANCE_DETAIL_AMOUNT_INT);
1272 }
1273 }
1274
1275 void OnClick(Point pt, int widget, int click_count) override
1276 {
1277 /* Check which button is clicked */
1278 if (IsInsideMM(widget, WID_PRD_COMPANY_FIRST, WID_PRD_COMPANY_LAST + 1)) {
1279 /* Is it no on disable? */
1280 if (!this->IsWidgetDisabled(widget)) {
1281 this->RaiseWidget(this->company + WID_PRD_COMPANY_FIRST);
1282 this->company = (CompanyID)(widget - WID_PRD_COMPANY_FIRST);
1283 this->LowerWidget(this->company + WID_PRD_COMPANY_FIRST);
1284 this->SetDirty();
1285 }
1286 }
1287 }
1288
1289 void OnGameTick() override
1290 {
1291 /* Update the company score every 5 days */
1292 if (--this->timeout == 0) {
1293 this->UpdateCompanyStats();
1294 this->SetDirty();
1295 }
1296 }
1297
1303 void OnInvalidateData(int data = 0, bool gui_scope = true) override
1304 {
1305 if (!gui_scope) return;
1306 /* Disable the companies who are not active */
1307 for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
1308 this->SetWidgetDisabledState(i + WID_PRD_COMPANY_FIRST, !Company::IsValidID(i));
1309 }
1310
1311 /* Check if the currently selected company is still active. */
1312 if (this->company != INVALID_COMPANY && !Company::IsValidID(this->company)) {
1313 /* Raise the widget for the previous selection. */
1314 this->RaiseWidget(this->company + WID_PRD_COMPANY_FIRST);
1315 this->company = INVALID_COMPANY;
1316 }
1317
1318 if (this->company == INVALID_COMPANY) {
1319 for (const Company *c : Company::Iterate()) {
1320 this->company = c->index;
1321 break;
1322 }
1323 }
1324
1325 /* Make sure the widget is lowered */
1326 this->LowerWidget(this->company + WID_PRD_COMPANY_FIRST);
1327 }
1328 };
1329
1330 CompanyID PerformanceRatingDetailWindow::company = INVALID_COMPANY;
1331
1338 static NWidgetBase *MakePerformanceDetailPanels(int *biggest_index)
1339 {
1340 const StringID performance_tips[] = {
1341 STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP,
1342 STR_PERFORMANCE_DETAIL_STATIONS_TOOLTIP,
1343 STR_PERFORMANCE_DETAIL_MIN_PROFIT_TOOLTIP,
1344 STR_PERFORMANCE_DETAIL_MIN_INCOME_TOOLTIP,
1345 STR_PERFORMANCE_DETAIL_MAX_INCOME_TOOLTIP,
1346 STR_PERFORMANCE_DETAIL_DELIVERED_TOOLTIP,
1347 STR_PERFORMANCE_DETAIL_CARGO_TOOLTIP,
1348 STR_PERFORMANCE_DETAIL_MONEY_TOOLTIP,
1349 STR_PERFORMANCE_DETAIL_LOAN_TOOLTIP,
1350 STR_PERFORMANCE_DETAIL_TOTAL_TOOLTIP,
1351 };
1352
1353 static_assert(lengthof(performance_tips) == SCORE_END - SCORE_BEGIN);
1354
1355 NWidgetVertical *vert = new NWidgetVertical(NC_EQUALSIZE);
1356 for (int widnum = WID_PRD_SCORE_FIRST; widnum <= WID_PRD_SCORE_LAST; widnum++) {
1357 NWidgetBackground *panel = new NWidgetBackground(WWT_PANEL, COLOUR_BROWN, widnum);
1358 panel->SetFill(1, 1);
1359 panel->SetDataTip(0x0, performance_tips[widnum - WID_PRD_SCORE_FIRST]);
1360 vert->Add(panel);
1361 }
1362 *biggest_index = WID_PRD_SCORE_LAST;
1363 return vert;
1364 }
1365
1367 NWidgetBase *MakeCompanyButtonRowsGraphGUI(int *biggest_index)
1368 {
1369 return MakeCompanyButtonRows(biggest_index, WID_PRD_COMPANY_FIRST, WID_PRD_COMPANY_LAST, COLOUR_BROWN, 8, STR_PERFORMANCE_DETAIL_SELECT_COMPANY_TOOLTIP);
1370 }
1371
1372 static const NWidgetPart _nested_performance_rating_detail_widgets[] = {
1373 NWidget(NWID_HORIZONTAL),
1374 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
1375 NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_PERFORMANCE_DETAIL, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1376 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
1377 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
1378 EndContainer(),
1379 NWidget(WWT_PANEL, COLOUR_BROWN),
1380 NWidgetFunction(MakeCompanyButtonRowsGraphGUI), SetPadding(2),
1381 EndContainer(),
1382 NWidgetFunction(MakePerformanceDetailPanels),
1383 };
1384
1385 static WindowDesc _performance_rating_detail_desc(
1386 WDP_AUTO, "league_details", 0, 0,
1387 WC_PERFORMANCE_DETAIL, WC_NONE,
1388 0,
1389 _nested_performance_rating_detail_widgets, lengthof(_nested_performance_rating_detail_widgets)
1390 );
1391
1392 void ShowPerformanceRatingDetail()
1393 {
1394 AllocateWindowDescFront<PerformanceRatingDetailWindow>(&_performance_rating_detail_desc, 0);
1395 }
1396
1397 void InitializeGraphGui()
1398 {
1399 _legend_excluded_companies = 0;
1400 _legend_excluded_cargo = 0;
1401 }
MakeCompanyButtonRows
NWidgetBase * MakeCompanyButtonRows(int *biggest_index, int widget_first, int widget_last, Colours button_colour, int max_length, StringID button_tooltip)
Make a number of rows with button-like graphics, for enabling/disabling each company.
Definition: widget.cpp:3323
PaymentRatesGraphWindow::UpdateWidgetSize
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
Update size and resize step of a widget in the window.
Definition: graph_gui.cpp:916
PaymentRatesGraphWindow::legend_width
uint legend_width
Width of legend 'blob'.
Definition: graph_gui.cpp:878
CargoArray::GetSum
const T GetSum() const
Get the sum of all cargo amounts.
Definition: cargo_type.h:122
InvalidateWindowData
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition: window.cpp:3254
IsInsideMM
static constexpr bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
Definition: math_func.hpp:230
PaymentRatesGraphWindow::DrawWidget
void DrawWidget(const Rect &r, int widget) const override
Draw the contents of a nested widget.
Definition: graph_gui.cpp:938
CompanyEconomyEntry::company_value
Money company_value
The value of the company.
Definition: company_base.h:28
NWidgetFunction
static NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
Obtain a nested widget (sub)tree from an external source.
Definition: widget_type.h:1261
WID_PHG_KEY
@ WID_PHG_KEY
Key button.
Definition: graph_widget.h:34
SetWindowDirty
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3156
GraphLegendWindow::DrawWidget
void DrawWidget(const Rect &r, int widget) const override
Draw the contents of a nested widget.
Definition: graph_gui.cpp:57
SetScrollbar
static NWidgetPart SetScrollbar(int index)
Attach a scrollbar to a widget.
Definition: widget_type.h:1210
WID_CV_KEY_BUTTON
@ WID_CV_KEY_BUTTON
Key button.
Definition: graph_widget.h:26
WID_CPR_RESIZE
@ WID_CPR_RESIZE
Resize button.
Definition: graph_widget.h:46
Dimension
Dimensions (a width and height) of a rectangle in 2D.
Definition: geometry_type.hpp:27
Scrollbar::GetCapacity
uint16 GetCapacity() const
Gets the number of visible elements of the scrollbar.
Definition: widget_type.h:669
WWT_STICKYBOX
@ WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition: widget_type.h:64
SetPadding
static NWidgetPart SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
Widget part function for setting additional space around a widget.
Definition: widget_type.h:1143
Pool::PoolItem<&_company_pool >::GetIfValid
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:348
Window::GetScrollbar
const Scrollbar * GetScrollbar(uint widnum) const
Return the Scrollbar to a widget index.
Definition: window.cpp:319
Rect::Shrink
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
Definition: geometry_type.hpp:92
FindLastBit
uint8 FindLastBit(uint64 x)
Search the last set bit in a 64 bit variable.
Definition: bitmath_func.cpp:66
SCORE_TOTAL
@ SCORE_TOTAL
This must always be the last entry.
Definition: economy_type.h:56
company_base.h
WidgetDimensions::unscaled
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition: window_gui.h:67
_cur_year
Year _cur_year
Current year, starting at 0.
Definition: date.cpp:26
NWidgetContainer::Add
void Add(NWidgetBase *wid)
Append widget wid to container.
Definition: widget.cpp:1261
GUISettings::graph_line_thickness
uint8 graph_line_thickness
the thickness of the lines in the various graph guis
Definition: settings_type.h:171
WWT_CAPTION
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition: widget_type.h:59
PerformanceRatingDetailWindow
Definition: graph_gui.cpp:1106
company_gui.h
currency.h
WWT_DEFSIZEBOX
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition: widget_type.h:63
NWidgetResizeBase::SetMinimalTextLines
void SetMinimalTextLines(uint8 min_lines, uint8 spacing, FontSize size)
Set minimal text lines for the widget.
Definition: widget.cpp:1106
Window::CreateNestedTree
void CreateNestedTree(bool fill_nested=true)
Perform the first part of the initialization of a nested widget tree.
Definition: window.cpp:1775
NWID_HORIZONTAL
@ NWID_HORIZONTAL
Horizontal container.
Definition: widget_type.h:73
WID_GL_FIRST_COMPANY
@ WID_GL_FIRST_COMPANY
First company in the legend.
Definition: graph_widget.h:20
maxdim
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Definition: geometry_func.cpp:22
WWT_MATRIX
@ WWT_MATRIX
Grid of rows and columns.
Definition: widget_type.h:57
WC_PERFORMANCE_HISTORY
@ WC_PERFORMANCE_HISTORY
Performance history graph; Window numbers:
Definition: window_type.h:539
HasBit
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Definition: bitmath_func.hpp:103
Scrollbar::SetCount
void SetCount(int num)
Sets the number of elements in the list.
Definition: widget_type.h:717
PerformanceHistoryGraphWindow::OnClick
void OnClick(Point pt, int widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition: graph_gui.cpp:782
WID_PHG_DETAILED_PERFORMANCE
@ WID_PHG_DETAILED_PERFORMANCE
Detailed performance.
Definition: graph_widget.h:35
Year
int32 Year
Type for the year, note: 0 based, i.e. starts at the year 0.
Definition: date_type.h:18
TextColour
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition: gfx_type.h:253
SetResize
static NWidgetPart SetResize(int16 dx, int16 dy)
Widget part function for setting the resize step.
Definition: widget_type.h:997
zoom_func.h
PerformanceRatingDetailWindow::DrawWidget
void DrawWidget(const Rect &r, int widget) const override
Draw the contents of a nested widget.
Definition: graph_gui.cpp:1196
MakeCompanyButtonRowsGraphGUI
NWidgetBase * MakeCompanyButtonRowsGraphGUI(int *biggest_index)
Make a number of rows with buttons for each company for the performance rating detail window.
Definition: graph_gui.cpp:1367
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:53
DrawString
int DrawString(int left, int right, int top, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition: gfx.cpp:644
CargoSpec
Specification of a cargo type.
Definition: cargotype.h:57
WWT_EMPTY
@ WWT_EMPTY
Empty widget, place holder to reserve space in widget array.
Definition: widget_type.h:46
WindowNumber
int32 WindowNumber
Number to differentiate different windows of the same class.
Definition: window_type.h:713
FR_LOWERED
@ FR_LOWERED
If set the frame is lowered and the background colour brighter (ie. buttons when pressed)
Definition: window_gui.h:34
economy_func.h
SA_RIGHT
@ SA_RIGHT
Right align the text (must be a single bit).
Definition: gfx_type.h:336
Scrollbar::GetScrolledRowFromWidget
int GetScrolledRowFromWidget(int clickpos, const Window *const w, int widget, int padding=0) const
Compute the row of a scrolled widget that a user clicked in.
Definition: widget.cpp:2353
ValuesInterval::highest
OverflowSafeInt64 highest
Highest value of this interval. Must be zero or greater.
Definition: graph_gui.cpp:156
NWidgetBase::SetPadding
void SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
Set additional space (padding) around the widget.
Definition: widget_type.h:150
Owner
Owner
Enum for all companies/owners.
Definition: company_type.h:18
Scrollbar
Scrollbar data structure.
Definition: widget_type.h:636
WID_CV_BACKGROUND
@ WID_CV_BACKGROUND
Background of the window.
Definition: graph_widget.h:27
_colour_gradient
byte _colour_gradient[COLOUR_END][8]
All 16 colour gradients 8 colours per gradient from darkest (0) to lightest (7)
Definition: gfx.cpp:55
Rect::WithHeight
Rect WithHeight(int height, bool end=false) const
Copy Rect and set its height.
Definition: geometry_type.hpp:205
Window::Window
Window(WindowDesc *desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
Definition: window.cpp:1814
SetDParam
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings_func.h:196
NWidgetPart
Partial widget specification to allow NWidgets to be written nested.
Definition: widget_type.h:975
SetDataTip
static NWidgetPart SetDataTip(uint32 data, StringID tip)
Widget part function for setting the data and tooltip.
Definition: widget_type.h:1111
GetStringBoundingBox
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition: gfx.cpp:890
BaseGraphWindow
Definition: graph_gui.cpp:164
WID_PHG_RESIZE
@ WID_PHG_RESIZE
Resize button.
Definition: graph_widget.h:38
DrawStringMultiLine
int DrawStringMultiLine(int left, int right, int top, int bottom, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly over multiple lines.
Definition: gfx.cpp:789
PaymentRatesGraphWindow::OnClick
void OnClick(Point pt, int widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition: graph_gui.cpp:975
PaymentRatesGraphWindow
Definition: graph_gui.cpp:875
WC_DELIVERED_CARGO
@ WC_DELIVERED_CARGO
Delivered cargo graph; Window numbers:
Definition: window_type.h:533
WID_CV_RESIZE
@ WID_CV_RESIZE
Resize button.
Definition: graph_widget.h:29
gfx_func.h
ScoreInfo::score
int score
How much score it will give.
Definition: economy_type.h:67
WindowDesc
High level window description.
Definition: window_gui.h:102
COMPANY_FIRST
@ COMPANY_FIRST
First company, same as owner.
Definition: company_type.h:22
WC_GRAPH_LEGEND
@ WC_GRAPH_LEGEND
Legend for graphs; Window numbers:
Definition: window_type.h:509
window_gui.h
WID_PHG_GRAPH
@ WID_PHG_GRAPH
Graph itself.
Definition: graph_widget.h:37
NC_EQUALSIZE
@ NC_EQUALSIZE
Value of the NCB_EQUALSIZE flag.
Definition: widget_type.h:469
MakePerformanceDetailPanels
static NWidgetBase * MakePerformanceDetailPanels(int *biggest_index)
Make a vertical list of panels for outputting score details.
Definition: graph_gui.cpp:1338
BaseGraphWindow::GetValuesInterval
ValuesInterval GetValuesInterval(int num_hori_lines) const
Get the interval that contains the graph's data.
Definition: graph_gui.cpp:205
WDP_AUTO
@ WDP_AUTO
Find a place automatically.
Definition: window_gui.h:90
WID_CPR_MATRIX_SCROLLBAR
@ WID_CPR_MATRIX_SCROLLBAR
Cargo list scrollbar.
Definition: graph_widget.h:51
CompanyProperties::colour
byte colour
Company colour.
Definition: company_base.h:71
Window::resize
ResizeInfo resize
Resize information.
Definition: window_gui.h:251
CompanyEconomyEntry::performance_history
int32 performance_history
Company score (scale 0-1000)
Definition: company_base.h:27
Scrollbar::GetCount
uint16 GetCount() const
Gets the number of elements in the list.
Definition: widget_type.h:660
WID_PRD_COMPANY_LAST
@ WID_PRD_COMPANY_LAST
Last company.
Definition: graph_widget.h:60
CompanyProperties::num_valid_stat_ent
byte num_valid_stat_ent
Number of valid statistical entries in old_economy.
Definition: company_base.h:101
WID_GL_BACKGROUND
@ WID_GL_BACKGROUND
Background of the window.
Definition: graph_widget.h:18
FS_NORMAL
@ FS_NORMAL
Index of the normal font in the font tables.
Definition: gfx_type.h:203
Rect::Translate
Rect Translate(int x, int y) const
Copy and translate Rect by x,y pixels.
Definition: geometry_type.hpp:168
WidgetDimensions::hsep_normal
int hsep_normal
Normal horizontal spacing.
Definition: window_gui.h:63
Window::InitNested
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition: window.cpp:1804
GraphLegendWindow
Definition: graph_gui.cpp:45
PaymentRatesGraphWindow::OnInit
void OnInit() override
Notification that the nested widget tree gets initialized.
Definition: graph_gui.cpp:899
SCORE_END
@ SCORE_END
How many scores are there..
Definition: economy_type.h:57
Window::height
int height
Height of the window (number of pixels down in y direction)
Definition: window_gui.h:249
PaymentRatesGraphWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition: graph_gui.cpp:1029
Window::SetDirty
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition: window.cpp:1008
WidgetDimensions::matrix
RectPadding matrix
Offsets within a matrix cell.
Definition: window_gui.h:49
FS_SMALL
@ FS_SMALL
Index of the small font in the font tables.
Definition: gfx_type.h:204
RectPadding::Horizontal
uint Horizontal() const
Get total horizontal padding of RectPadding.
Definition: geometry_type.hpp:59
BaseGraphWindow::GRAPH_AXIS_LABEL_COLOUR
static const TextColour GRAPH_AXIS_LABEL_COLOUR
colour of the graph axis label.
Definition: graph_gui.cpp:174
BaseGraphWindow::UpdateStatistics
void UpdateStatistics(bool initialize)
Update the statistics.
Definition: graph_gui.cpp:567
WWT_PUSHTXTBTN
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
Definition: widget_type.h:104
PaymentRatesGraphWindow::line_height
uint line_height
Pixel height of each cargo type row.
Definition: graph_gui.cpp:876
NWidgetBase
Baseclass for nested widgets.
Definition: widget_type.h:126
WidgetDimensions::hsep_wide
int hsep_wide
Wide horizontal spacing.
Definition: window_gui.h:64
SetMatrixDataTip
static NWidgetPart SetMatrixDataTip(uint8 cols, uint8 rows, StringID tip)
Widget part function for setting the data and tooltip of WWT_MATRIX widgets.
Definition: widget_type.h:1129
WID_CPR_ENABLE_CARGOES
@ WID_CPR_ENABLE_CARGOES
Enable cargoes button.
Definition: graph_widget.h:48
BaseGraphWindow::excluded_data
uint64 excluded_data
bitmask of the datasets that shouldn't be displayed.
Definition: graph_gui.cpp:179
WID_CPR_GRAPH
@ WID_CPR_GRAPH
Graph itself.
Definition: graph_widget.h:45
Window::SetWidgetDisabledState
void SetWidgetDisabledState(byte widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition: window_gui.h:321
WID_PRD_COMPANY_FIRST
@ WID_PRD_COMPANY_FIRST
First company.
Definition: graph_widget.h:59
MAX_COMPANIES
@ MAX_COMPANIES
Maximum number of companies.
Definition: company_type.h:23
BaseGraphWindow::OnClick
void OnClick(Point pt, int widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition: graph_gui.cpp:541
safeguards.h
WID_PRD_SCORE_LAST
@ WID_PRD_SCORE_LAST
Last entry in the score list.
Definition: graph_widget.h:57
Window::left
int left
x position of left edge of the window
Definition: window_gui.h:246
Rect::Indent
Rect Indent(int indent, bool end) const
Copy Rect and indent it from its position.
Definition: geometry_type.hpp:192
ValuesInterval::lowest
OverflowSafeInt64 lowest
Lowest value of this interval. Must be zero or less.
Definition: graph_gui.cpp:157
UpdateCompanyRatingAndValue
int UpdateCompanyRatingAndValue(Company *c, bool update)
if update is set to true, the economy is updated with this score (also the house is updated,...
Definition: economy.cpp:166
BaseGraphWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition: graph_gui.cpp:557
Rect::WithWidth
Rect WithWidth(int width, bool end) const
Copy Rect and set its width.
Definition: geometry_type.hpp:179
sprites.h
PaymentRatesGraphWindow::OnGameTick
void OnGameTick() override
Called once per (game) tick.
Definition: graph_gui.cpp:1019
Point
Coordinates of a point in 2D.
Definition: geometry_type.hpp:21
PerformanceHistoryGraphWindow
Definition: graph_gui.cpp:770
date_func.h
WC_INCOME_GRAPH
@ WC_INCOME_GRAPH
Income graph; Window numbers:
Definition: window_type.h:521
stdafx.h
PC_BLACK
static const uint8 PC_BLACK
Black palette colour.
Definition: gfx_func.h:242
Window::window_number
WindowNumber window_number
Window number within the window class.
Definition: window_gui.h:241
GfxFillRect
void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen.
Definition: gfx.cpp:116
RectPadding::Vertical
uint Vertical() const
Get total vertical padding of RectPadding.
Definition: geometry_type.hpp:65
SCORE_MAX
@ SCORE_MAX
The max score that can be in the performance history.
Definition: economy_type.h:59
WC_NONE
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition: window_type.h:38
SA_HOR_CENTER
@ SA_HOR_CENTER
Horizontally center the text.
Definition: gfx_type.h:335
NWID_VERTICAL
@ NWID_VERTICAL
Vertical container.
Definition: widget_type.h:75
NWidgetResizeBase::SetFill
void SetFill(uint fill_x, uint fill_y)
Set the filling of the widget from initial size.
Definition: widget.cpp:1119
WID_CPR_FOOTER
@ WID_CPR_FOOTER
Footer.
Definition: graph_widget.h:47
FONT_HEIGHT_SMALL
#define FONT_HEIGHT_SMALL
Height of characters in the small (FS_SMALL) font.
Definition: gfx_func.h:203
CompanyEconomyEntry::delivered_cargo
CargoArray delivered_cargo
The amount of delivered cargo.
Definition: company_base.h:26
DrawCompanyIcon
void DrawCompanyIcon(CompanyID c, int x, int y)
Draw the icon of a company.
Definition: company_cmd.cpp:147
BaseGraphWindow::UpdateWidgetSize
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
Update size and resize step of a widget in the window.
Definition: graph_gui.cpp:493
BaseGraphWindow::DrawGraph
void DrawGraph(Rect r) const
Actually draw the graph.
Definition: graph_gui.cpp:288
PerformanceRatingDetailWindow::UpdateWidgetSize
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
Update size and resize step of a widget in the window.
Definition: graph_gui.cpp:1138
WC_PAYMENT_RATES
@ WC_PAYMENT_RATES
Payment rates graph; Window numbers:
Definition: window_type.h:557
GetSpriteSize
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition: gfx.cpp:993
WWT_CLOSEBOX
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition: widget_type.h:67
WWT_RESIZEBOX
@ WWT_RESIZEBOX
Resize box (normally at bottom-right of a window)
Definition: widget_type.h:66
ValuesInterval
Contains the interval of a graph's data.
Definition: graph_gui.cpp:155
WC_COMPANY_VALUE
@ WC_COMPANY_VALUE
Company value graph; Window numbers:
Definition: window_type.h:545
CompanyEconomyEntry::expenses
Money expenses
The amount of expenses.
Definition: company_base.h:25
StringID
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
EndContainer
static NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
Definition: widget_type.h:1096
Pool::PoolItem<&_company_pool >::Iterate
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:386
strings_func.h
NWID_VSCROLLBAR
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition: widget_type.h:82
_sorted_standard_cargo_specs
span< const CargoSpec * > _sorted_standard_cargo_specs
Standard cargo specifications sorted alphabetically by name.
Definition: cargotype.cpp:154
graph_gui.h
NWidgetCore::SetDataTip
void SetDataTip(uint32 widget_data, StringID tool_tip)
Set data and tool tip of the nested widget.
Definition: widget.cpp:1176
WC_PERFORMANCE_DETAIL
@ WC_PERFORMANCE_DETAIL
Performance detail window; Window numbers:
Definition: window_type.h:563
WID_CPR_MATRIX
@ WID_CPR_MATRIX
Cargo list.
Definition: graph_widget.h:50
IncomeGraphWindow
Definition: graph_gui.cpp:672
WWT_TEXT
@ WWT_TEXT
Pure simple text.
Definition: widget_type.h:56
WidgetDimensions::hsep_indent
int hsep_indent
Width of identation for tree layouts.
Definition: window_gui.h:65
FONT_HEIGHT_NORMAL
#define FONT_HEIGHT_NORMAL
Height of characters in the normal (FS_NORMAL) font.
Definition: gfx_func.h:206
NWidget
static NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx=-1)
Widget part function for starting a new 'real' widget.
Definition: widget_type.h:1229
WidgetDimensions::fullbevel
RectPadding fullbevel
Always-scaled bevel border.
Definition: window_gui.h:46
geometry_func.hpp
WID_PRD_SCORE_FIRST
@ WID_PRD_SCORE_FIRST
First entry in the score list.
Definition: graph_widget.h:56
SetDParamMaxValue
void SetDParamMaxValue(uint n, uint64 max_value, uint min_count, FontSize size)
Set DParam n to some number that is suitable for string size computations.
Definition: strings.cpp:95
SetMinimalSize
static NWidgetPart SetMinimalSize(int16 x, int16 y)
Widget part function for setting the minimal size.
Definition: widget_type.h:1014
WWT_PANEL
@ WWT_PANEL
Simple depressed panel.
Definition: widget_type.h:48
BaseGraphWindow::MIN_GRID_PIXEL_SIZE
static const int MIN_GRID_PIXEL_SIZE
Minimum distance between graph lines.
Definition: graph_gui.cpp:177
WID_CPR_BACKGROUND
@ WID_CPR_BACKGROUND
Background of the window.
Definition: graph_widget.h:43
BaseGraphWindow::DrawWidget
void DrawWidget(const Rect &r, int widget) const override
Draw the contents of a nested widget.
Definition: graph_gui.cpp:529
NUM_CARGO
@ NUM_CARGO
Maximal number of cargo types in a game.
Definition: cargo_type.h:65
NWidgetVertical
Vertical container.
Definition: widget_type.h:523
Scrollbar::GetPosition
uint16 GetPosition() const
Gets the position of the first visible element in the list.
Definition: widget_type.h:678
cargotype.h
ScoreInfo::needed
int needed
How much you need to get the perfect score.
Definition: economy_type.h:66
GraphLegendWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition: graph_gui.cpp:96
WidgetDimensions::bevel
RectPadding bevel
Widths of bevel border.
Definition: window_gui.h:45
Window::FinishInitNested
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition: window.cpp:1791
BaseGraphWindow::GetYLabelWidth
uint GetYLabelWidth(ValuesInterval current_interval, int num_hori_lines) const
Get width for Y labels.
Definition: graph_gui.cpp:264
CompanyValueGraphWindow
Definition: graph_gui.cpp:826
NWID_SPACER
@ NWID_SPACER
Invisible widget that takes some space.
Definition: widget_type.h:77
PerformanceRatingDetailWindow::OnClick
void OnClick(Point pt, int widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition: graph_gui.cpp:1275
BaseGraphWindow::MIN_GRAPH_NUM_LINES_Y
static const int MIN_GRAPH_NUM_LINES_Y
Minimal number of horizontal lines to draw.
Definition: graph_gui.cpp:176
WID_GL_LAST_COMPANY
@ WID_GL_LAST_COMPANY
Last company in the legend.
Definition: graph_widget.h:21
abs
static T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition: math_func.hpp:21
WidgetDimensions::framerect
RectPadding framerect
Offsets within frame area.
Definition: window_gui.h:47
WID_CPR_HEADER
@ WID_CPR_HEADER
Header.
Definition: graph_widget.h:44
ScoreID
ScoreID
Score categories in the detailed performance rating.
Definition: economy_type.h:45
CompanyEconomyEntry::income
Money income
The amount of income.
Definition: company_base.h:24
BaseGraphWindow::cost
OverflowSafeInt64 cost[GRAPH_MAX_DATASETS][GRAPH_NUM_MONTHS]
Stored costs for the last GRAPH_NUM_MONTHS months.
Definition: graph_gui.cpp:197
SA_LEFT
@ SA_LEFT
Left align the text.
Definition: gfx_type.h:334
DrawFrameRect
void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags)
Draw frame rectangle.
Definition: widget.cpp:414
PaymentRatesGraphWindow::OnResize
void OnResize() override
Called after the window got resized.
Definition: graph_gui.cpp:1014
window_func.h
CenterBounds
static int CenterBounds(int min, int max, int size)
Determine where to draw a centred object inside a widget.
Definition: gfx_func.h:178
ToggleBit
static T ToggleBit(T &x, const uint8 y)
Toggles a bit in a variable.
Definition: bitmath_func.hpp:181
Window::ToggleWidgetLoweredState
void ToggleWidgetLoweredState(byte widget_index)
Invert the lowered/raised status of a widget.
Definition: window_gui.h:392
GetCharacterHeight
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition: fontcache.cpp:62
SetBit
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
Definition: bitmath_func.hpp:121
graph_widget.h
lengthof
#define lengthof(x)
Return the length of an fixed size array.
Definition: stdafx.h:386
Window::width
int width
width of the window (number of pixels to the right in x direction)
Definition: window_gui.h:248
Scrollbar::SetCapacityFromWidget
void SetCapacityFromWidget(Window *w, int widget, int padding=0)
Set capacity of visible elements from the size and resize properties of a widget.
Definition: widget.cpp:2427
OverflowSafeInt< int64 >
BaseGraphWindow::GRAPH_NUM_MONTHS
static const int GRAPH_NUM_MONTHS
Number of months displayed in the graph.
Definition: graph_gui.cpp:172
INVALID_COMPANY
@ INVALID_COMPANY
An invalid company.
Definition: company_type.h:30
SetFill
static NWidgetPart SetFill(uint fill_x, uint fill_y)
Widget part function for setting filling.
Definition: widget_type.h:1080
PaymentRatesGraphWindow::OnHundredthTick
void OnHundredthTick() override
Called once every 100 (game) ticks, or once every 3s, whichever comes last.
Definition: graph_gui.cpp:1035
DeliveredCargoGraphWindow
Definition: graph_gui.cpp:721
GREY_SCALE
#define GREY_SCALE(level)
Return the colour for a particular greyscale level.
Definition: gfx_func.h:240
PaymentRatesGraphWindow::vscroll
Scrollbar * vscroll
Cargo list scrollbar.
Definition: graph_gui.cpp:877
Window
Data structure for an opened window.
Definition: window_gui.h:213
WID_CV_GRAPH
@ WID_CV_GRAPH
Graph itself.
Definition: graph_widget.h:28
Pool::PoolItem<&_company_pool >::IsValidID
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition: pool_type.hpp:326
Window::RaiseWidget
void RaiseWidget(byte widget_index)
Marks a widget as raised.
Definition: window_gui.h:412
ZOOM_LVL_OUT_4X
@ ZOOM_LVL_OUT_4X
Zoomed 4 times out.
Definition: zoom_type.h:24
NWidgetBackground
Nested widget with a child.
Definition: widget_type.h:591
BaseGraphWindow::OnGameTick
void OnGameTick() override
Called once per (game) tick.
Definition: graph_gui.cpp:547
WidgetDimensions::frametext
RectPadding frametext
Offsets within a text frame area.
Definition: window_gui.h:48
PerformanceRatingDetailWindow::OnGameTick
void OnGameTick() override
Called once per (game) tick.
Definition: graph_gui.cpp:1289
WidgetDimensions::scaled
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition: window_gui.h:68
MakeNWidgetCompanyLines
static NWidgetBase * MakeNWidgetCompanyLines(int *biggest_index)
Construct a vertical list of buttons, one for each company.
Definition: graph_gui.cpp:112
WID_CPR_DISABLE_CARGOES
@ WID_CPR_DISABLE_CARGOES
Disable cargoes button.
Definition: graph_widget.h:49
WC_OPERATING_PROFIT
@ WC_OPERATING_PROFIT
Operating profit graph; Window numbers:
Definition: window_type.h:527
Window::IsWidgetDisabled
bool IsWidgetDisabled(byte widget_index) const
Gets the enabled/disabled status of a widget.
Definition: window_gui.h:350
Rect
Specification of a rectangle with absolute coordinates of all edges.
Definition: geometry_type.hpp:69
Window::LowerWidget
void LowerWidget(byte widget_index)
Marks a widget as lowered.
Definition: window_gui.h:403
Company
Definition: company_base.h:117
_cur_month
Month _cur_month
Current month (0..11)
Definition: date.cpp:27
CompanyProperties::old_economy
CompanyEconomyEntry old_economy[MAX_HISTORY_QUARTERS]
Economic data of the company of the last MAX_HISTORY_QUARTERS quarters.
Definition: company_base.h:100
PerformanceRatingDetailWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition: graph_gui.cpp:1303
NWidgetResizeBase::SetMinimalSize
void SetMinimalSize(uint min_x, uint min_y)
Set minimal size of the widget.
Definition: widget.cpp:1080
TD_RTL
@ TD_RTL
Text is written right-to-left by default.
Definition: strings_type.h:24
DAY_TICKS
static const int DAY_TICKS
1 day is 74 ticks; _date_fract used to be uint16 and incremented by 885.
Definition: date_type.h:28
_current_text_dir
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition: strings.cpp:49
OperatingProfitGraphWindow
Definition: graph_gui.cpp:621
ClientSettings::gui
GUISettings gui
settings related to the GUI
Definition: settings_type.h:604
WID_PHG_BACKGROUND
@ WID_PHG_BACKGROUND
Background of the window.
Definition: graph_widget.h:36
SetMinimalTextLines
static NWidgetPart SetMinimalTextLines(uint8 lines, uint8 spacing, FontSize size=FS_NORMAL)
Widget part function for setting the minimal text lines.
Definition: widget_type.h:1032
_score_info
const ScoreInfo _score_info[]
Score info, values used for computing the detailed performance rating.
Definition: economy.cpp:86
ScaleGUITrad
static RectPadding ScaleGUITrad(const RectPadding &r)
Scale a RectPadding to GUI zoom level.
Definition: widget.cpp:168
GraphLegendWindow::OnClick
void OnClick(Point pt, int widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition: graph_gui.cpp:77
WWT_SHADEBOX
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition: widget_type.h:62