OpenTTD
group_gui.cpp
Go to the documentation of this file.
1 /* $Id$ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #include "stdafx.h"
13 #include "textbuf_gui.h"
14 #include "command_func.h"
15 #include "vehicle_gui.h"
16 #include "vehicle_base.h"
17 #include "string_func.h"
18 #include "strings_func.h"
19 #include "window_func.h"
20 #include "vehicle_func.h"
21 #include "autoreplace_gui.h"
22 #include "company_func.h"
23 #include "widgets/dropdown_func.h"
24 #include "tilehighlight_func.h"
25 #include "vehicle_gui_base.h"
26 #include "core/geometry_func.hpp"
27 #include "company_base.h"
28 #include "company_gui.h"
29 
30 #include "widgets/group_widget.h"
31 
32 #include "table/sprites.h"
33 
34 #include "safeguards.h"
35 
36 static const int LEVEL_WIDTH = 10;
37 
39 
40 static const NWidgetPart _nested_group_widgets[] = {
41  NWidget(NWID_HORIZONTAL), // Window header
42  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
43  NWidget(WWT_CAPTION, COLOUR_GREY, WID_GL_CAPTION),
44  NWidget(WWT_SHADEBOX, COLOUR_GREY),
45  NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
46  NWidget(WWT_STICKYBOX, COLOUR_GREY),
47  EndContainer(),
49  /* left part */
52  NWidget(WWT_PANEL, COLOUR_GREY, WID_GL_ALL_VEHICLES), SetFill(1, 0), EndContainer(),
55  NWidget(WWT_MATRIX, COLOUR_GREY, WID_GL_LIST_GROUP), SetMatrixDataTip(1, 0, STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP),
58  EndContainer(),
59  NWidget(WWT_PANEL, COLOUR_GREY, WID_GL_INFO), SetFill(1, 0), EndContainer(),
61  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_GL_CREATE_GROUP), SetFill(0, 1),
62  SetDataTip(SPR_GROUP_CREATE_TRAIN, STR_GROUP_CREATE_TOOLTIP),
63  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_GL_DELETE_GROUP), SetFill(0, 1),
64  SetDataTip(SPR_GROUP_DELETE_TRAIN, STR_GROUP_DELETE_TOOLTIP),
65  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_GL_RENAME_GROUP), SetFill(0, 1),
66  SetDataTip(SPR_GROUP_RENAME_TRAIN, STR_GROUP_RENAME_TOOLTIP),
67  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_GL_LIVERY_GROUP), SetFill(0, 1),
68  SetDataTip(SPR_GROUP_LIVERY_TRAIN, STR_GROUP_LIVERY_TOOLTIP),
69  NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), EndContainer(),
71  SetDataTip(SPR_GROUP_REPLACE_OFF_TRAIN, STR_GROUP_REPLACE_PROTECTION_TOOLTIP),
72  EndContainer(),
73  EndContainer(),
74  /* right part */
77  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GL_SORT_BY_ORDER), SetMinimalSize(81, 12), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
78  NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GL_SORT_BY_DROPDOWN), SetMinimalSize(167, 12), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA),
79  NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(12, 12), SetResize(1, 0), EndContainer(),
80  EndContainer(),
84  EndContainer(),
85  NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(1, 0), SetFill(1, 1), SetResize(1, 0), EndContainer(),
88  SetDataTip(STR_BLACK_STRING, STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP),
89  NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 1), SetResize(1, 0), EndContainer(),
91  SetDataTip(STR_VEHICLE_LIST_MANAGE_LIST, STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP),
92  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_GL_STOP_ALL), SetMinimalSize(12, 12), SetFill(0, 1),
93  SetDataTip(SPR_FLAG_VEH_STOPPED, STR_VEHICLE_LIST_MASS_STOP_LIST_TOOLTIP),
94  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_GL_START_ALL), SetMinimalSize(12, 12), SetFill(0, 1),
95  SetDataTip(SPR_FLAG_VEH_RUNNING, STR_VEHICLE_LIST_MASS_START_LIST_TOOLTIP),
96  NWidget(WWT_RESIZEBOX, COLOUR_GREY),
97  EndContainer(),
98  EndContainer(),
99  EndContainer(),
100 };
101 
103 private:
104  /* Columns in the group list */
105  enum ListColumns {
111 
112  VGC_END
113  };
114 
122  Scrollbar *group_sb;
123 
125 
127 
128  void AddChildren(GUIGroupList *source, GroupID parent, int indent)
129  {
130  for (const Group **g = source->Begin(); g != source->End(); g++) {
131  if ((*g)->parent != parent) continue;
132  *this->groups.Append() = *g;
133  *this->indents.Append() = indent;
134  AddChildren(source, (*g)->index, indent + 1);
135  }
136  }
137 
139  static int CDECL GroupNameSorter(const Group * const *a, const Group * const *b)
140  {
141  static const Group *last_group[2] = { NULL, NULL };
142  static char last_name[2][64] = { "", "" };
143 
144  if (*a != last_group[0]) {
145  last_group[0] = *a;
146  SetDParam(0, (*a)->index);
147  GetString(last_name[0], STR_GROUP_NAME, lastof(last_name[0]));
148  }
149 
150  if (*b != last_group[1]) {
151  last_group[1] = *b;
152  SetDParam(0, (*b)->index);
153  GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1]));
154  }
155 
156  int r = strnatcmp(last_name[0], last_name[1]); // Sort by name (natural sorting).
157  if (r == 0) return (*a)->index - (*b)->index;
158  return r;
159  }
160 
167  {
168  if (!this->groups.NeedRebuild()) return;
169 
170  this->groups.Clear();
171  this->indents.Clear();
172 
173  GUIGroupList list;
174 
175  const Group *g;
176  FOR_ALL_GROUPS(g) {
177  if (g->owner == owner && g->vehicle_type == this->vli.vtype) {
178  *list.Append() = g;
179  }
180  }
181 
182  list.ForceResort();
183  list.Sort(&GroupNameSorter);
184 
185  AddChildren(&list, INVALID_GROUP, 0);
186 
187  this->groups.Compact();
188  this->groups.RebuildDone();
189  }
190 
196  {
197  this->column_size[VGC_NAME] = maxdim(GetStringBoundingBox(STR_GROUP_DEFAULT_TRAINS + this->vli.vtype), GetStringBoundingBox(STR_GROUP_ALL_TRAINS + this->vli.vtype));
198  this->column_size[VGC_NAME].width = max(170u, this->column_size[VGC_NAME].width);
199  this->tiny_step_height = this->column_size[VGC_NAME].height;
200 
201  this->column_size[VGC_PROTECT] = GetSpriteSize(SPR_GROUP_REPLACE_PROTECT);
202  this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_PROTECT].height);
203 
204  this->column_size[VGC_AUTOREPLACE] = GetSpriteSize(SPR_GROUP_REPLACE_ACTIVE);
205  this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_AUTOREPLACE].height);
206 
207  this->column_size[VGC_PROFIT].width = 0;
208  this->column_size[VGC_PROFIT].height = 0;
209  static const SpriteID profit_sprites[] = {SPR_PROFIT_NA, SPR_PROFIT_NEGATIVE, SPR_PROFIT_SOME, SPR_PROFIT_LOT};
210  for (uint i = 0; i < lengthof(profit_sprites); i++) {
211  Dimension d = GetSpriteSize(profit_sprites[i]);
212  this->column_size[VGC_PROFIT] = maxdim(this->column_size[VGC_PROFIT], d);
213  }
214  this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_PROFIT].height);
215 
217  this->column_size[VGC_NUMBER] = GetStringBoundingBox(STR_TINY_COMMA);
218  this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_NUMBER].height);
219 
220  this->tiny_step_height += WD_MATRIX_TOP;
221 
222  return WD_FRAMERECT_LEFT + 8 +
223  this->column_size[VGC_NAME].width + 8 +
224  this->column_size[VGC_PROTECT].width + 2 +
225  this->column_size[VGC_AUTOREPLACE].width + 2 +
226  this->column_size[VGC_PROFIT].width + 2 +
227  this->column_size[VGC_NUMBER].width + 2 +
229  }
230 
240  void DrawGroupInfo(int y, int left, int right, GroupID g_id, int indent = 0, bool protection = false) const
241  {
242  /* Highlight the group if a vehicle is dragged over it */
243  if (g_id == this->group_over) {
244  GfxFillRect(left + WD_FRAMERECT_LEFT, y + WD_FRAMERECT_TOP, right - WD_FRAMERECT_RIGHT, y + this->tiny_step_height - WD_FRAMERECT_BOTTOM - WD_MATRIX_TOP, _colour_gradient[COLOUR_GREY][7]);
245  }
246 
247  if (g_id == NEW_GROUP) return;
248 
249  /* draw the selected group in white, else we draw it in black */
250  TextColour colour = g_id == this->vli.index ? TC_WHITE : TC_BLACK;
251  const GroupStatistics &stats = GroupStatistics::Get(this->vli.company, g_id, this->vli.vtype);
252  bool rtl = _current_text_dir == TD_RTL;
253 
254  /* draw group name */
255  StringID str;
256  if (IsAllGroupID(g_id)) {
257  str = STR_GROUP_ALL_TRAINS + this->vli.vtype;
258  } else if (IsDefaultGroupID(g_id)) {
259  str = STR_GROUP_DEFAULT_TRAINS + this->vli.vtype;
260  } else {
261  SetDParam(0, g_id);
262  str = STR_GROUP_NAME;
263  }
264  int x = rtl ? right - WD_FRAMERECT_RIGHT - 8 - this->column_size[VGC_NAME].width + 1 : left + WD_FRAMERECT_LEFT + 8;
265  DrawString(x + (rtl ? 0 : indent), x + this->column_size[VGC_NAME].width - 1 - (rtl ? indent : 0), y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour);
266 
267  /* draw autoreplace protection */
268  x = rtl ? x - 8 - this->column_size[VGC_PROTECT].width : x + 8 + this->column_size[VGC_NAME].width;
269  if (protection) DrawSprite(SPR_GROUP_REPLACE_PROTECT, PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_PROTECT].height) / 2);
270 
271  /* draw autoreplace status */
272  x = rtl ? x - 2 - this->column_size[VGC_AUTOREPLACE].width : x + 2 + this->column_size[VGC_PROTECT].width;
273  if (stats.autoreplace_defined) DrawSprite(SPR_GROUP_REPLACE_ACTIVE, stats.autoreplace_finished ? PALETTE_CRASH : PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_AUTOREPLACE].height) / 2);
274 
275  /* draw the profit icon */
276  x = rtl ? x - 2 - this->column_size[VGC_PROFIT].width : x + 2 + this->column_size[VGC_AUTOREPLACE].width;
277  SpriteID spr;
278  if (stats.num_profit_vehicle == 0) {
279  spr = SPR_PROFIT_NA;
280  } else if (stats.profit_last_year < 0) {
281  spr = SPR_PROFIT_NEGATIVE;
282  } else if (stats.profit_last_year < 10000 * stats.num_profit_vehicle) { // TODO magic number
283  spr = SPR_PROFIT_SOME;
284  } else {
285  spr = SPR_PROFIT_LOT;
286  }
287  DrawSprite(spr, PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_PROFIT].height) / 2);
288 
289  /* draw the number of vehicles of the group */
290  x = rtl ? x - 2 - this->column_size[VGC_NUMBER].width : x + 2 + this->column_size[VGC_PROFIT].width;
291  SetDParam(0, stats.num_vehicle);
292  DrawString(x, x + this->column_size[VGC_NUMBER].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NUMBER].height) / 2, STR_TINY_COMMA, colour, SA_RIGHT | SA_FORCE);
293  }
294 
299  {
300  if (this->group_over == INVALID_GROUP) return;
301 
302  if (IsAllGroupID(this->group_over)) {
304  } else if (IsDefaultGroupID(this->group_over)) {
306  } else {
308  }
309  }
310 
311 public:
313  {
314  this->CreateNestedTree();
315 
316  this->vscroll = this->GetScrollbar(WID_GL_LIST_VEHICLE_SCROLLBAR);
317  this->group_sb = this->GetScrollbar(WID_GL_LIST_GROUP_SCROLLBAR);
318 
319  switch (this->vli.vtype) {
320  default: NOT_REACHED();
321  case VEH_TRAIN: this->sorting = &_sorting.train; break;
322  case VEH_ROAD: this->sorting = &_sorting.roadveh; break;
323  case VEH_SHIP: this->sorting = &_sorting.ship; break;
324  case VEH_AIRCRAFT: this->sorting = &_sorting.aircraft; break;
325  }
326 
327  this->vli.index = ALL_GROUP;
328  this->vehicle_sel = INVALID_VEHICLE;
329  this->group_sel = INVALID_GROUP;
330  this->group_rename = INVALID_GROUP;
331  this->group_over = INVALID_GROUP;
332 
333  this->vehicles.SetListing(*this->sorting);
334  this->vehicles.ForceRebuild();
335  this->vehicles.NeedResort();
336 
337  this->BuildVehicleList();
338  this->SortVehicleList();
339 
340  this->groups.ForceRebuild();
341  this->groups.NeedResort();
342  this->BuildGroupList(vli.company);
343 
344  this->GetWidget<NWidgetCore>(WID_GL_CAPTION)->widget_data = STR_VEHICLE_LIST_TRAIN_CAPTION + this->vli.vtype;
345  this->GetWidget<NWidgetCore>(WID_GL_LIST_VEHICLE)->tool_tip = STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP + this->vli.vtype;
346 
347  this->GetWidget<NWidgetCore>(WID_GL_CREATE_GROUP)->widget_data += this->vli.vtype;
348  this->GetWidget<NWidgetCore>(WID_GL_RENAME_GROUP)->widget_data += this->vli.vtype;
349  this->GetWidget<NWidgetCore>(WID_GL_DELETE_GROUP)->widget_data += this->vli.vtype;
350  this->GetWidget<NWidgetCore>(WID_GL_LIVERY_GROUP)->widget_data += this->vli.vtype;
351  this->GetWidget<NWidgetCore>(WID_GL_REPLACE_PROTECTION)->widget_data += this->vli.vtype;
352 
353  this->FinishInitNested(window_number);
354  this->owner = vli.company;
355  }
356 
358  {
359  *this->sorting = this->vehicles.GetListing();
360  }
361 
362  virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
363  {
364  switch (widget) {
365  case WID_GL_LIST_GROUP: {
366  size->width = this->ComputeGroupInfoSize();
367  resize->height = this->tiny_step_height;
368 
369  /* Minimum height is the height of the list widget minus all and default vehicles... */
370  size->height = 4 * GetVehicleListHeight(this->vli.vtype, this->tiny_step_height) - 2 * this->tiny_step_height;
371 
372  /* ... minus the buttons at the bottom ... */
373  uint max_icon_height = GetSpriteSize(this->GetWidget<NWidgetCore>(WID_GL_CREATE_GROUP)->widget_data).height;
374  max_icon_height = max(max_icon_height, GetSpriteSize(this->GetWidget<NWidgetCore>(WID_GL_RENAME_GROUP)->widget_data).height);
375  max_icon_height = max(max_icon_height, GetSpriteSize(this->GetWidget<NWidgetCore>(WID_GL_DELETE_GROUP)->widget_data).height);
376  max_icon_height = max(max_icon_height, GetSpriteSize(this->GetWidget<NWidgetCore>(WID_GL_REPLACE_PROTECTION)->widget_data).height);
377 
378  /* ... minus the height of the group info ... */
379  max_icon_height += (FONT_HEIGHT_NORMAL * 3) + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
380 
381  /* Get a multiple of tiny_step_height of that amount */
382  size->height = Ceil(size->height - max_icon_height, tiny_step_height);
383  break;
384  }
385 
386  case WID_GL_ALL_VEHICLES:
388  size->width = this->ComputeGroupInfoSize();
389  size->height = this->tiny_step_height;
390  break;
391 
392  case WID_GL_SORT_BY_ORDER: {
393  Dimension d = GetStringBoundingBox(this->GetWidget<NWidgetCore>(widget)->widget_data);
394  d.width += padding.width + Window::SortButtonWidth() * 2; // Doubled since the string is centred and it also looks better.
395  d.height += padding.height;
396  *size = maxdim(*size, d);
397  break;
398  }
399 
400  case WID_GL_LIST_VEHICLE:
401  this->ComputeGroupInfoSize();
402  resize->height = GetVehicleListHeight(this->vli.vtype, this->tiny_step_height);
403  size->height = 4 * resize->height;
404  break;
405 
407  Dimension d = this->GetActionDropdownSize(true, true);
408  d.height += padding.height;
409  d.width += padding.width;
410  *size = maxdim(*size, d);
411  break;
412  }
413 
414  case WID_GL_INFO: {
416  break;
417  }
418  }
419  }
420 
426  virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
427  {
428  if (data == 0) {
429  /* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */
430  this->vehicles.ForceRebuild();
431  this->groups.ForceRebuild();
432  } else {
433  this->vehicles.ForceResort();
434  this->groups.ForceResort();
435  }
436 
437  /* Process ID-invalidation in command-scope as well */
438  if (this->group_rename != INVALID_GROUP && !Group::IsValidID(this->group_rename)) {
440  this->group_rename = INVALID_GROUP;
441  }
442 
443  if (!(IsAllGroupID(this->vli.index) || IsDefaultGroupID(this->vli.index) || Group::IsValidID(this->vli.index))) {
444  this->vli.index = ALL_GROUP;
445  HideDropDownMenu(this);
446  }
447  this->SetDirty();
448  }
449 
450  virtual void SetStringParameters(int widget) const
451  {
452  switch (widget) {
454  SetDParam(0, STR_VEHICLE_LIST_AVAILABLE_TRAINS + this->vli.vtype);
455  break;
456 
457  case WID_GL_CAPTION:
458  /* If selected_group == DEFAULT_GROUP || ALL_GROUP, draw the standard caption
459  * We list all vehicles or ungrouped vehicles */
460  if (IsDefaultGroupID(this->vli.index) || IsAllGroupID(this->vli.index)) {
461  SetDParam(0, STR_COMPANY_NAME);
462  SetDParam(1, this->vli.company);
463  SetDParam(2, this->vehicles.Length());
464  SetDParam(3, this->vehicles.Length());
465  } else {
466  const Group *g = Group::Get(this->vli.index);
467 
468  SetDParam(0, STR_GROUP_NAME);
469  SetDParam(1, g->index);
472  }
473  break;
474  }
475  }
476 
477  virtual void OnPaint()
478  {
479  /* If we select the all vehicles, this->list will contain all vehicles of the owner
480  * else this->list will contain all vehicles which belong to the selected group */
481  this->BuildVehicleList();
482  this->SortVehicleList();
483 
484  this->BuildGroupList(this->owner);
485 
486  this->group_sb->SetCount(this->groups.Length());
487  this->vscroll->SetCount(this->vehicles.Length());
488 
489  /* The drop down menu is out, *but* it may not be used, retract it. */
490  if (this->vehicles.Length() == 0 && this->IsWidgetLowered(WID_GL_MANAGE_VEHICLES_DROPDOWN)) {
492  HideDropDownMenu(this);
493  }
494 
495  /* Disable all lists management button when the list is empty */
496  this->SetWidgetsDisabledState(this->vehicles.Length() == 0 || _local_company != this->vli.company,
501 
502  /* Disable the group specific function when we select the default group or all vehicles */
503  this->SetWidgetsDisabledState(IsDefaultGroupID(this->vli.index) || IsAllGroupID(this->vli.index) || _local_company != this->vli.company,
509 
510  /* Disable remaining buttons for non-local companies
511  * Needed while changing _local_company, eg. by cheats
512  * All procedures (eg. move vehicle to another group)
513  * verify, whether you are the owner of the vehicle,
514  * so it doesn't have to be disabled
515  */
520 
521  /* If not a default group and the group has replace protection, show an enabled replace sprite. */
522  uint16 protect_sprite = SPR_GROUP_REPLACE_OFF_TRAIN;
523  if (!IsDefaultGroupID(this->vli.index) && !IsAllGroupID(this->vli.index) && Group::Get(this->vli.index)->replace_protection) protect_sprite = SPR_GROUP_REPLACE_ON_TRAIN;
524  this->GetWidget<NWidgetCore>(WID_GL_REPLACE_PROTECTION)->widget_data = protect_sprite + this->vli.vtype;
525 
526  /* Set text of sort by dropdown */
527  this->GetWidget<NWidgetCore>(WID_GL_SORT_BY_DROPDOWN)->widget_data = this->vehicle_sorter_names[this->vehicles.SortType()];
528 
529  this->DrawWidgets();
530  }
531 
532  virtual void DrawWidget(const Rect &r, int widget) const
533  {
534  switch (widget) {
535  case WID_GL_ALL_VEHICLES:
536  DrawGroupInfo(r.top + WD_FRAMERECT_TOP, r.left, r.right, ALL_GROUP);
537  break;
538 
540  DrawGroupInfo(r.top + WD_FRAMERECT_TOP, r.left, r.right, DEFAULT_GROUP);
541  break;
542 
543  case WID_GL_INFO: {
544  Money this_year = 0;
545  Money last_year = 0;
546  uint32 occupancy = 0;
547  uint32 vehicle_count = this->vehicles.Length();
548 
549  for (uint i = 0; i < vehicle_count; i++) {
550  const Vehicle *v = this->vehicles[i];
551  assert(v->owner == this->owner);
552 
553  this_year += v->GetDisplayProfitThisYear();
554  last_year += v->GetDisplayProfitLastYear();
555  occupancy += v->trip_occupancy;
556  }
557 
558  const int left = r.left + WD_FRAMERECT_LEFT + 8;
559  const int right = r.right - WD_FRAMERECT_RIGHT - 8;
560 
561  int y = r.top + WD_FRAMERECT_TOP;
562  DrawString(left, right, y, STR_GROUP_PROFIT_THIS_YEAR, TC_BLACK);
563  SetDParam(0, this_year);
564  DrawString(left, right, y, STR_JUST_CURRENCY_LONG, TC_BLACK, SA_RIGHT);
565 
566  y += FONT_HEIGHT_NORMAL;
567  DrawString(left, right, y, STR_GROUP_PROFIT_LAST_YEAR, TC_BLACK);
568  SetDParam(0, last_year);
569  DrawString(left, right, y, STR_JUST_CURRENCY_LONG, TC_BLACK, SA_RIGHT);
570 
571  y += FONT_HEIGHT_NORMAL;
572  DrawString(left, right, y, STR_GROUP_OCCUPANCY, TC_BLACK);
573  if (vehicle_count > 0) {
574  SetDParam(0, occupancy / vehicle_count);
575  DrawString(left, right, y, STR_GROUP_OCCUPANCY_VALUE, TC_BLACK, SA_RIGHT);
576  }
577 
578  break;
579  }
580 
581  case WID_GL_LIST_GROUP: {
582  int y1 = r.top + WD_FRAMERECT_TOP;
583  int max = min(this->group_sb->GetPosition() + this->group_sb->GetCapacity(), this->groups.Length());
584  for (int i = this->group_sb->GetPosition(); i < max; ++i) {
585  const Group *g = this->groups[i];
586 
587  assert(g->owner == this->owner);
588 
589  DrawGroupInfo(y1, r.left, r.right, g->index, this->indents[i] * LEVEL_WIDTH, g->replace_protection);
590 
591  y1 += this->tiny_step_height;
592  }
593  if ((uint)this->group_sb->GetPosition() + this->group_sb->GetCapacity() > this->groups.Length()) {
594  DrawGroupInfo(y1, r.left, r.right, NEW_GROUP);
595  }
596  break;
597  }
598 
601  break;
602 
603  case WID_GL_LIST_VEHICLE:
604  if (this->vli.index != ALL_GROUP) {
605  /* Mark vehicles which are in sub-groups */
606  int y = r.top;
607  uint max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehicles.Length());
608  for (uint i = this->vscroll->GetPosition(); i < max; ++i) {
609  const Vehicle *v = this->vehicles[i];
610  if (v->group_id != this->vli.index) {
611  GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->resize.step_height - 2, _colour_gradient[COLOUR_GREY][3], FILLRECT_CHECKER);
612  }
613  y += this->resize.step_height;
614  }
615  }
616 
617  this->DrawVehicleListItems(this->vehicle_sel, this->resize.step_height, r);
618  break;
619  }
620  }
621 
622  static void DeleteGroupCallback(Window *win, bool confirmed)
623  {
624  if (confirmed) {
626  w->vli.index = ALL_GROUP;
627  DoCommandP(0, w->group_confirm, 0, CMD_DELETE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_DELETE));
628  }
629  }
630 
631  virtual void OnClick(Point pt, int widget, int click_count)
632  {
633  switch (widget) {
634  case WID_GL_SORT_BY_ORDER: // Flip sorting method ascending/descending
635  this->vehicles.ToggleSortOrder();
636  this->SetDirty();
637  break;
638 
639  case WID_GL_SORT_BY_DROPDOWN: // Select sorting criteria dropdown menu
640  ShowDropDownMenu(this, this->vehicle_sorter_names, this->vehicles.SortType(), WID_GL_SORT_BY_DROPDOWN, 0, (this->vli.vtype == VEH_TRAIN || this->vli.vtype == VEH_ROAD) ? 0 : (1 << 10));
641  return;
642 
643  case WID_GL_ALL_VEHICLES: // All vehicles button
644  if (!IsAllGroupID(this->vli.index)) {
645  this->vli.index = ALL_GROUP;
646  this->vehicles.ForceRebuild();
647  this->SetDirty();
648  }
649  break;
650 
651  case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles button
652  if (!IsDefaultGroupID(this->vli.index)) {
653  this->vli.index = DEFAULT_GROUP;
654  this->vehicles.ForceRebuild();
655  this->SetDirty();
656  }
657  break;
658 
659  case WID_GL_LIST_GROUP: { // Matrix Group
660  uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP, 0, this->tiny_step_height);
661  if (id_g >= this->groups.Length()) return;
662 
663  this->group_sel = this->vli.index = this->groups[id_g]->index;
664 
665  SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
666 
667  this->vehicles.ForceRebuild();
668  this->SetDirty();
669  break;
670  }
671 
672  case WID_GL_LIST_VEHICLE: { // Matrix Vehicle
673  uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_VEHICLE);
674  if (id_v >= this->vehicles.Length()) return; // click out of list bound
675 
676  const Vehicle *v = this->vehicles[id_v];
677  if (VehicleClicked(v)) break;
678 
679  this->vehicle_sel = v->index;
680 
681  SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
683  _cursor.vehchain = true;
684 
685  this->SetDirty();
686  break;
687  }
688 
689  case WID_GL_CREATE_GROUP: { // Create a new group
690  DoCommandP(0, this->vli.vtype, this->vli.index, CMD_CREATE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_CREATE), CcCreateGroup);
691  break;
692  }
693 
694  case WID_GL_DELETE_GROUP: { // Delete the selected group
695  this->group_confirm = this->vli.index;
696  ShowQuery(STR_QUERY_GROUP_DELETE_CAPTION, STR_GROUP_DELETE_QUERY_TEXT, this, DeleteGroupCallback);
697  break;
698  }
699 
700  case WID_GL_RENAME_GROUP: // Rename the selected roup
701  this->ShowRenameGroupWindow(this->vli.index, false);
702  break;
703 
704  case WID_GL_LIVERY_GROUP: // Set group livery
705  ShowCompanyLiveryWindow(this->owner, this->vli.index);
706  break;
707 
709  ShowBuildVehicleWindow(INVALID_TILE, this->vli.vtype);
710  break;
711 
713  DropDownList *list = this->BuildActionDropdownList(true, Group::IsValidID(this->vli.index));
715  break;
716  }
717 
718  case WID_GL_START_ALL:
719  case WID_GL_STOP_ALL: { // Start/stop all vehicles of the list
720  DoCommandP(0, (1 << 1) | (widget == WID_GL_START_ALL ? (1 << 0) : 0), this->vli.Pack(), CMD_MASS_START_STOP);
721  break;
722  }
723 
725  const Group *g = Group::GetIfValid(this->vli.index);
726  if (g != NULL) {
728  }
729  break;
730  }
731  }
732  }
733 
734  void OnDragDrop_Group(Point pt, int widget)
735  {
736  const Group *g = Group::Get(this->group_sel);
737 
738  switch (widget) {
739  case WID_GL_ALL_VEHICLES: // All vehicles
740  case WID_GL_DEFAULT_VEHICLES: // Ungroupd vehicles
741  if (g->parent != INVALID_GROUP) {
742  DoCommandP(0, this->group_sel | (1 << 16), INVALID_GROUP, CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_SET_PARENT));
743  }
744 
745  this->group_sel = INVALID_GROUP;
746  this->group_over = INVALID_GROUP;
747  this->SetDirty();
748  break;
749 
750  case WID_GL_LIST_GROUP: { // Matrix group
751  uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP, 0, this->tiny_step_height);
752  GroupID new_g = id_g >= this->groups.Length() ? INVALID_GROUP : this->groups[id_g]->index;
753 
754  if (this->group_sel != new_g && g->parent != new_g) {
755  DoCommandP(0, this->group_sel | (1 << 16), new_g, CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_SET_PARENT));
756  }
757 
758  this->group_sel = INVALID_GROUP;
759  this->group_over = INVALID_GROUP;
760  this->SetDirty();
761  break;
762  }
763  }
764  }
765 
766  void OnDragDrop_Vehicle(Point pt, int widget)
767  {
768  switch (widget) {
769  case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles
770  DoCommandP(0, DEFAULT_GROUP, this->vehicle_sel | (_ctrl_pressed ? 1 << 31 : 0), CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE));
771 
772  this->vehicle_sel = INVALID_VEHICLE;
773  this->group_over = INVALID_GROUP;
774 
775  this->SetDirty();
776  break;
777 
778  case WID_GL_LIST_GROUP: { // Matrix group
779  const VehicleID vindex = this->vehicle_sel;
780  this->vehicle_sel = INVALID_VEHICLE;
781  this->group_over = INVALID_GROUP;
782  this->SetDirty();
783 
784  uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP, 0, this->tiny_step_height);
785  GroupID new_g = id_g >= this->groups.Length() ? NEW_GROUP : this->groups[id_g]->index;
786 
787  DoCommandP(0, new_g, vindex | (_ctrl_pressed ? 1 << 31 : 0), CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE), new_g == NEW_GROUP ? CcAddVehicleNewGroup : NULL);
788  break;
789  }
790 
791  case WID_GL_LIST_VEHICLE: { // Matrix vehicle
792  const VehicleID vindex = this->vehicle_sel;
793  this->vehicle_sel = INVALID_VEHICLE;
794  this->group_over = INVALID_GROUP;
795  this->SetDirty();
796 
797  uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_VEHICLE);
798  if (id_v >= this->vehicles.Length()) return; // click out of list bound
799 
800  const Vehicle *v = this->vehicles[id_v];
801  if (!VehicleClicked(v) && vindex == v->index) {
803  }
804  break;
805  }
806  }
807  }
808 
809  virtual void OnDragDrop(Point pt, int widget)
810  {
811  if (this->vehicle_sel != INVALID_VEHICLE) OnDragDrop_Vehicle(pt, widget);
812  if (this->group_sel != INVALID_GROUP) OnDragDrop_Group(pt, widget);
813 
814  _cursor.vehchain = false;
815  }
816 
817  virtual void OnQueryTextFinished(char *str)
818  {
819  if (str != NULL) DoCommandP(0, this->group_rename, 0, CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_RENAME), NULL, str);
820  this->group_rename = INVALID_GROUP;
821  }
822 
823  virtual void OnResize()
824  {
825  this->group_sb->SetCapacityFromWidget(this, WID_GL_LIST_GROUP);
826  this->vscroll->SetCapacityFromWidget(this, WID_GL_LIST_VEHICLE);
827  }
828 
829  virtual void OnDropdownSelect(int widget, int index)
830  {
831  switch (widget) {
833  this->vehicles.SetSortType(index);
834  break;
835 
837  assert(this->vehicles.Length() != 0);
838 
839  switch (index) {
840  case ADI_REPLACE: // Replace window
841  ShowReplaceGroupVehicleWindow(this->vli.index, this->vli.vtype);
842  break;
843  case ADI_SERVICE: // Send for servicing
844  case ADI_DEPOT: { // Send to Depots
845  DoCommandP(0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : 0U), this->vli.Pack(), GetCmdSendToDepot(this->vli.vtype));
846  break;
847  }
848 
849  case ADI_ADD_SHARED: // Add shared Vehicles
850  assert(Group::IsValidID(this->vli.index));
851 
852  DoCommandP(0, this->vli.index, this->vli.vtype, CMD_ADD_SHARED_VEHICLE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE));
853  break;
854  case ADI_REMOVE_ALL: // Remove all Vehicles from the selected group
855  assert(Group::IsValidID(this->vli.index));
856 
857  DoCommandP(0, this->vli.index, 0, CMD_REMOVE_ALL_VEHICLES_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES));
858  break;
859  default: NOT_REACHED();
860  }
861  break;
862 
863  default: NOT_REACHED();
864  }
865 
866  this->SetDirty();
867  }
868 
869  virtual void OnGameTick()
870  {
871  if (this->groups.NeedResort() || this->vehicles.NeedResort()) {
872  this->SetDirty();
873  }
874  }
875 
876  virtual void OnPlaceObjectAbort()
877  {
878  /* abort drag & drop */
879  this->vehicle_sel = INVALID_VEHICLE;
881  this->group_over = INVALID_GROUP;
883  }
884 
885  virtual void OnMouseDrag(Point pt, int widget)
886  {
887  if (this->vehicle_sel == INVALID_VEHICLE && this->group_sel == INVALID_GROUP) return;
888 
889  /* A vehicle is dragged over... */
890  GroupID new_group_over = INVALID_GROUP;
891  switch (widget) {
892  case WID_GL_DEFAULT_VEHICLES: // ... the 'default' group.
893  new_group_over = DEFAULT_GROUP;
894  break;
895 
896  case WID_GL_LIST_GROUP: { // ... the list of custom groups.
897  uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP, 0, this->tiny_step_height);
898  new_group_over = id_g >= this->groups.Length() ? NEW_GROUP : this->groups[id_g]->index;
899  break;
900  }
901  }
902 
903  /* Do not highlight when dragging over the current group */
904  if (this->vehicle_sel != INVALID_VEHICLE) {
905  if (Vehicle::Get(vehicle_sel)->group_id == new_group_over) new_group_over = INVALID_GROUP;
906  } else if (this->group_sel != INVALID_GROUP) {
907  if (this->group_sel == new_group_over || Group::Get(this->group_sel)->parent == new_group_over) new_group_over = INVALID_GROUP;
908  }
909 
910  /* Mark widgets as dirty if the group changed. */
911  if (new_group_over != this->group_over) {
913  this->group_over = new_group_over;
915  }
916  }
917 
918  void ShowRenameGroupWindow(GroupID group, bool empty)
919  {
920  assert(Group::IsValidID(group));
921  this->group_rename = group;
922  /* Show empty query for new groups */
923  StringID str = STR_EMPTY;
924  if (!empty) {
925  SetDParam(0, group);
926  str = STR_GROUP_NAME;
927  }
929  }
930 
937  {
938  if (this->vehicle_sel == vehicle) ResetObjectToPlace();
939  }
940 };
941 
942 
943 static WindowDesc _other_group_desc(
944  WDP_AUTO, "list_groups", 460, 246,
946  0,
947  _nested_group_widgets, lengthof(_nested_group_widgets)
948 );
949 
950 static WindowDesc _train_group_desc(
951  WDP_AUTO, "list_groups_train", 525, 246,
953  0,
954  _nested_group_widgets, lengthof(_nested_group_widgets)
955 );
956 
962 void ShowCompanyGroup(CompanyID company, VehicleType vehicle_type)
963 {
964  if (!Company::IsValidID(company)) return;
965 
966  WindowNumber num = VehicleListIdentifier(VL_GROUP_LIST, vehicle_type, company).Pack();
967  if (vehicle_type == VEH_TRAIN) {
968  AllocateWindowDescFront<VehicleGroupWindow>(&_train_group_desc, num);
969  } else {
970  _other_group_desc.cls = GetWindowClassForVehicleType(vehicle_type);
971  AllocateWindowDescFront<VehicleGroupWindow>(&_other_group_desc, num);
972  }
973 }
974 
982 {
983  return (VehicleGroupWindow *)FindWindowById(GetWindowClassForVehicleType(vt), VehicleListIdentifier(VL_GROUP_LIST, vt, owner).Pack());
984 }
985 
995 void CcCreateGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd)
996 {
997  if (result.Failed()) return;
998  assert(p1 <= VEH_AIRCRAFT);
999 
1001  if (w != NULL) w->ShowRenameGroupWindow(_new_group_id, true);
1002 }
1003 
1012 void CcAddVehicleNewGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd)
1013 {
1014  if (result.Failed()) return;
1015  assert(Vehicle::IsValidID(GB(p2, 0, 20)));
1016 
1017  CcCreateGroup(result, 0, Vehicle::Get(GB(p2, 0, 20))->type, 0, cmd);
1018 }
1019 
1025 {
1026  /* If we haven't got any vehicles on the mouse pointer, we haven't got any highlighted in any group windows either
1027  * If that is the case, we can skip looping though the windows and save time
1028  */
1029  if (_special_mouse_mode != WSM_DRAGDROP) return;
1030 
1032  if (w != NULL) w->UnselectVehicle(v->index);
1033 }
Functions related to OTTD&#39;s strings.
void DirtyHighlightedGroupWidget()
Mark the widget containing the currently highlighted group as dirty.
Definition: group_gui.cpp:298
void UnselectVehicle(VehicleID vehicle)
Tests whether a given vehicle is selected in the window, and unselects it if necessary.
Definition: group_gui.cpp:936
Normal push-button (no toggle button) with image caption.
Definition: widget_type.h:105
void RebuildDone()
Notify the sortlist that the rebuild is done.
virtual void OnClick(Point pt, int widget, int click_count)
A click with the left mouse button has been made on the window.
Definition: group_gui.cpp:631
DropDownList * BuildActionDropdownList(bool show_autoreplace, bool show_group)
Display the Action dropdown window.
Definition of stuff that is very close to a company, like the company struct itself.
virtual void DrawWidget(const Rect &r, int widget) const
Draw the contents of a nested widget.
Definition: group_gui.cpp:532
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:257
Manage vehicles dropdown list.
Definition: group_widget.h:23
uint32 widget_data
Data of the widget.
Definition: widget_type.h:305
bool replace_protection
If set to true, the global autoreplace have no effect on the group.
Definition: group.h:72
CompanyID company
The company associated with this list.
Definition: vehiclelist.h:34
The information about a vehicle list.
Definition: vehiclelist.h:31
ResizeInfo resize
Resize information.
Definition: window_gui.h:324
static NWidgetPart SetResize(int16 dx, int16 dy)
Widget part function for setting the resize step.
Definition: widget_type.h:930
GroupStatistics statistics
NOSAVE: Statistics and caches on the vehicles in the group.
Definition: group.h:74
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:113
virtual void OnDragDrop(Point pt, int widget)
A dragged &#39;object&#39; has been released.
Definition: group_gui.cpp:809
Money GetDisplayProfitThisYear() const
Gets the profit vehicle had this year.
Definition: vehicle_base.h:566
Window * parent
Parent window.
Definition: window_gui.h:339
Group livery button.
Definition: group_widget.h:34
High level window description.
Definition: window_gui.h:168
virtual void OnGameTick()
Called once per (game) tick.
Definition: group_gui.cpp:869
Functions related to the autoreplace GUIs.
StringID tool_tip
Tooltip of the widget.
Definition: widget_type.h:306
int left
x position of left edge of the window
Definition: window_gui.h:319
bool vehchain
vehicle chain is dragged
Definition: gfx_type.h:146
SpecialMouseMode _special_mouse_mode
Mode of the mouse.
Definition: window.cpp:82
bool VehicleClicked(const Vehicle *v)
Dispatch a "vehicle selected" event if any window waits for it.
void DrawWidgets() const
Paint all widgets of a window.
Definition: widget.cpp:604
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:246
virtual void OnMouseDrag(Point pt, int widget)
An &#39;object&#39; is being dragged at the provided position, highlight the target if possible.
Definition: group_gui.cpp:885
Scrollbar data structure.
Definition: widget_type.h:589
void SetWidgetDirty(byte widget_index) const
Invalidate a widget, i.e.
Definition: window.cpp:581
Offset at top to draw the frame rectangular area.
Definition: window_gui.h:64
List of the groups.
Definition: group_widget.h:29
Dragging an object.
Definition: window_gui.h:911
Horizontal container.
Definition: widget_type.h:75
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition: window.cpp:1114
byte _colour_gradient[COLOUR_END][8]
All 16 colour gradients 8 colours per gradient from darkest (0) to lightest (7)
Definition: gfx.cpp:53
void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets,...)
Sets the enabled/disabled status of a list of widgets.
Definition: window.cpp:520
void ShowQueryString(StringID str, StringID caption, uint maxsize, Window *parent, CharSetFilter afilter, QueryStringFlags flags)
Show a query popup window with a textbox in it.
Definition: misc_gui.cpp:1064
GUIVehicleList vehicles
The list of vehicles.
Functions related to vehicles.
Types related to the group widgets.
Resize box (normally at bottom-right of a window)
Definition: widget_type.h:68
Vehicle data structure.
Definition: vehicle_base.h:212
void Clear()
Remove all items from the list.
void Compact()
Compact the list down to the smallest block size boundary.
const T * Begin() const
Get the pointer to the first item (const)
virtual void OnDropdownSelect(int widget, int index)
A dropdown option associated to this window has been selected.
Definition: group_gui.cpp:829
Tindex index
Index of this pool item.
Definition: pool_type.hpp:147
static int CDECL GroupNameSorter(const Group *const *a, const Group *const *b)
Sort the groups by their name.
Definition: group_gui.cpp:139
Money profit_last_year
Sum of profits for all vehicles.
Definition: group.h:34
Close box (at top-left of a window)
Definition: widget_type.h:69
Offset at top of a matrix cell.
Definition: window_gui.h:80
Delete group button.
Definition: group_widget.h:32
bool NeedResort()
Check if a resort is needed next loop If used the resort timer will decrease every call till 0...
List of the vehicles.
Definition: group_widget.h:20
static NWidgetPart SetMinimalTextLines(uint8 lines, uint8 spacing, FontSize size=FS_NORMAL)
Widget part function for setting the minimal text lines.
Definition: widget_type.h:965
#define lastof(x)
Get the last element of an fixed size array.
Definition: depend.cpp:50
bool autoreplace_finished
Have all autoreplacement finished?
Definition: group.h:31
uint16 num_profit_vehicle
Number of vehicles considered for profit statistics;.
Definition: group.h:33
Stuff related to the text buffer GUI.
Invalid window.
Definition: window_type.h:696
Common return value for all commands.
Definition: command_type.h:25
All vehicles entry.
Definition: group_widget.h:27
static const VehicleID INVALID_VEHICLE
Constant representing a non-existing vehicle.
Definition: vehicle_type.h:59
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
Update size and resize step of a widget in the window.
Definition: group_gui.cpp:362
static T max(const T a, const T b)
Returns the maximum of two values.
Definition: math_func.hpp:26
VehicleID vehicle_sel
Selected vehicle.
Definition: group_gui.cpp:115
void RaiseWidget(byte widget_index)
Marks a widget as raised.
Definition: window_gui.h:485
WindowClass cls
Class of the window,.
Definition: window_gui.h:177
void CcCreateGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd)
Opens a &#39;Rename group&#39; window for newly created group.
Definition: group_gui.cpp:995
uint ComputeGroupInfoSize()
Compute tiny_step_height and column_size.
Definition: group_gui.cpp:195
const T * End() const
Get the pointer behind the last valid item (const)
void CreateNestedTree(bool fill_nested=true)
Perform the first part of the initialization of a nested widget tree.
Definition: window.cpp:1812
Functions related to the vehicle&#39;s GUIs.
void SetListing(Listing l)
Import sort conditions.
GroupID group_rename
Group being renamed, INVALID_GROUP if none.
Definition: group_gui.cpp:117
bool NeedRebuild() const
Check if a rebuild is needed.
delete a group
Definition: command_type.h:319
T * Append(uint to_add=1)
Append an item and return it.
void SetCount(int num)
Sets the number of elements in the list.
Definition: widget_type.h:670
CompanyByte _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:46
Force the alignment, i.e. don&#39;t swap for RTL languages.
Definition: gfx_func.h:110
Partial widget specification to allow NWidgets to be written nested.
Definition: widget_type.h:910
void ForceRebuild()
Force that a rebuild is needed.
Data structure for an opened window.
Definition: window_gui.h:278
alter a group
Definition: command_type.h:320
bool _ctrl_pressed
Is Ctrl pressed?
Definition: gfx.cpp:36
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:1032
static const GroupID NEW_GROUP
Sentinel for a to-be-created group.
Definition: group_type.h:17
dragging items in the depot windows
virtual void SetStringParameters(int widget) const
Initialize string parameters for a widget.
Definition: group_gui.cpp:450
enable the &#39;Default&#39; button ("\0" is returned)
Definition: textbuf_gui.h:23
static bool IsAllGroupID(GroupID id_g)
Checks if a GroupID stands for all vehicles of a company.
Definition: group.h:93
Aircraft vehicle type.
Definition: vehicle_type.h:29
add all other shared vehicles to a group which are missing
Definition: command_type.h:322
static const uint MAX_LENGTH_GROUP_NAME_CHARS
The maximum length of a group name in characters including &#39;\0&#39;.
Definition: group_type.h:22
Functions related to low-level strings.
Stop all button.
Definition: group_widget.h:24
static const int LEVEL_WIDTH
Indenting width of a sub-group in pixels.
Definition: group_gui.cpp:36
remove all vehicles from a group
Definition: command_type.h:323
void DrawVehicleListItems(VehicleID selected_vehicle, int line_height, const Rect &r) const
Draw all the vehicle list items.
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX) ...
Definition: widget_type.h:65
uint Length() const
Get the number of items in the list.
int GetScrolledRowFromWidget(int clickpos, const Window *const w, int widget, int padding=0, int line_height=-1) const
Compute the row of a scrolled widget that a user clicked in.
Definition: widget.cpp:1959
bool IsWidgetLowered(byte widget_index) const
Gets the lowered state of a widget.
Definition: window_gui.h:495
Statistics and caches on the vehicles in a group.
Definition: group.h:26
Listing GetListing() const
Export current sort conditions.
virtual void OnResize()
Called after the window got resized.
Definition: group_gui.cpp:823
void ShowQuery(StringID caption, StringID message, Window *parent, QueryCallbackProc *callback)
Show a modal confirmation window with standard &#39;yes&#39; and &#39;no&#39; buttons The window is aligned to the ce...
Definition: misc_gui.cpp:1205
VehicleType
Available vehicle types.
Definition: vehicle_type.h:23
Dimension column_size[VGC_END]
Size of the columns in the group list.
Definition: group_gui.cpp:126
uint32 index
A vehicle list type specific index.
Definition: vehiclelist.h:35
Sort descending.
Definition: window_gui.h:227
uint32 VehicleID
The type all our vehicle IDs have.
Definition: vehicle_type.h:18
Autoreplace active icon.
Definition: group_gui.cpp:108
#define FONT_HEIGHT_NORMAL
Height of characters in the normal (FS_NORMAL) font.
Definition: gfx_func.h:180
static NWidgetPart SetDataTip(uint32 data, StringID tip)
Widget part function for setting the data and tooltip.
Definition: widget_type.h:1014
Simple vector template class, with automatic delete.
static NWidgetPart SetMinimalSize(int16 x, int16 y)
Widget part function for setting the minimal size.
Definition: widget_type.h:947
Definition of base types and functions in a cross-platform compatible way.
Tells that it&#39;s a mass send to depot command (type in VLW flag)
Definition: vehicle_type.h:71
the length of the string is counted in characters
Definition: textbuf_gui.h:24
virtual void OnQueryTextFinished(char *str)
The query window opened from this window has closed.
Definition: group_gui.cpp:817
void ShowCompanyGroup(CompanyID company, VehicleType vehicle_type)
Show the group window for the given company and vehicle type.
Definition: group_gui.cpp:962
A number of safeguards to prevent using unsafe methods.
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition: gfx_type.h:247
Group info.
Definition: group_widget.h:36
Normal push-button (no toggle button) with text caption.
Definition: widget_type.h:104
Geometry functions.
Simple depressed panel.
Definition: widget_type.h:50
void CcAddVehicleNewGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd)
Open rename window after adding a vehicle to a new group via drag and drop.
Definition: group_gui.cpp:1012
uint16 GroupID
Type for all group identifiers.
Definition: group_type.h:15
virtual void OnPlaceObjectAbort()
The user cancelled a tile highlight mode that has been set.
Definition: group_gui.cpp:876
void DrawSortButtonState(int widget, SortButtonState state) const
Draw a sort button&#39;s up or down arrow symbol.
Definition: widget.cpp:638
uint step_height
Step-size of height resize changes.
Definition: window_gui.h:220
const Scrollbar * GetScrollbar(uint widnum) const
Return the Scrollbar to a widget index.
Definition: window.cpp:311
GUI Functions related to companies.
VehicleTypeByte vehicle_type
Vehicle type of the group.
Definition: group.h:70
static GroupStatistics & Get(CompanyID company, GroupID id_g, VehicleType type)
Returns the GroupStatistics for a specific group.
Definition: group_cmd.cpp:65
static NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx=-1)
Widget part function for starting a new &#39;real&#39; widget.
Definition: widget_type.h:1114
Offset at bottom to draw the frame rectangular area.
Definition: window_gui.h:65
static const GroupID INVALID_GROUP
Sentinel for invalid groups.
Definition: group_type.h:20
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:500
void ShowVehicleViewWindow(const Vehicle *v)
Shows the vehicle view window of the given vehicle.
uint16 num_vehicle
Number of vehicles.
Definition: group.h:27
bool DoCommandP(const CommandContainer *container, bool my_cmd)
Shortcut for the long DoCommandP when having a container with the data.
Definition: command.cpp:531
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
Road vehicle type.
Definition: vehicle_type.h:27
Grid of rows and columns.
Definition: widget_type.h:59
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:42
Create group button.
Definition: group_widget.h:31
Number of vehicles in the group.
Definition: group_gui.cpp:110
void SetSortType(uint8 n_type)
Set the sorttype of the list.
bool Sort(SortFunction *compare)
Sort the list.
static int SortButtonWidth()
Get width of up/down arrow of sort button state.
Definition: widget.cpp:658
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:18
bool Failed() const
Did this command fail?
Definition: command_type.h:161
void DeleteWindowByClass(WindowClass cls)
Delete all windows of a given class.
Definition: window.cpp:1159
virtual void OnPaint()
The window must be repainted.
Definition: group_gui.cpp:477
static const int WIDGET_LIST_END
indicate the end of widgets&#39; list for vararg functions
Definition: widget_type.h:22
Ship vehicle type.
Definition: vehicle_type.h:28
Functions/classes shared between the different vehicle list GUIs.
Caption of the window.
Definition: group_widget.h:17
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition: window.cpp:968
void BuildGroupList(Owner owner)
(Re)Build the group list.
Definition: group_gui.cpp:166
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition: gfx.cpp:700
void ForceResort()
Force a resort next Sort call Reset the resort timer if used too.
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Draw only every second pixel, used for greying-out.
Definition: gfx_type.h:284
No window, redirects to WC_MAIN_WINDOW.
Definition: window_type.h:40
int8 trip_occupancy
NOSAVE: Occupancy of vehicle of the current trip (updated after leaving a station).
Definition: vehicle_base.h:311
static const GroupID DEFAULT_GROUP
Ungrouped vehicles are in this group.
Definition: group_type.h:19
The vehicle will leave the depot right after arrival (serivce only)
Definition: vehicle_type.h:70
Functions related to companies.
Vehicle drawn in vehicle list, group list, ...
Definition: vehicle_type.h:93
void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Window *w)
Change the cursor and mouse click/drag handling to a mode for performing special operations like tile...
Definition: viewport.cpp:3025
add a vehicle to a group
Definition: command_type.h:321
Scrollbar for the list.
Definition: group_widget.h:21
Both numeric and alphabetic and spaces and stuff.
Definition: string_type.h:27
void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type)
Set the mouse cursor to look like a vehicle.
GroupID parent
Parent group.
Definition: group.h:76
Sort by dropdown list.
Definition: group_widget.h:19
Window caption (window title between closebox and stickybox)
Definition: widget_type.h:61
int strnatcmp(const char *s1, const char *s2, bool ignore_garbage_at_front)
Compares two strings using case insensitive natural sort.
Definition: string.cpp:580
Autoreplace protect icon.
Definition: group_gui.cpp:107
Base class for all vehicles.
static VehicleGroupWindow * FindVehicleGroupWindow(VehicleType vt, Owner owner)
Finds a group list window determined by vehicle type and owner.
Definition: group_gui.cpp:981
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:19
CompanyByte _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:80
virtual void OnInvalidateData(int data=0, bool gui_scope=true)
Some data on this window has become invalid.
Definition: group_gui.cpp:426
static const PaletteID PALETTE_CRASH
Recolour sprite greying of crashed vehicles.
Definition: sprites.h:1580
void DrawGroupInfo(int y, int left, int right, GroupID g_id, int indent=0, bool protection=false) const
Draw a row in the group list.
Definition: group_gui.cpp:240
uint32 Pack() const
Pack a VehicleListIdentifier in a single uint32.
Definition: vehiclelist.cpp:23
void DeleteGroupHighlightOfVehicle(const Vehicle *v)
Removes the highlight of a vehicle in a group window.
Definition: group_gui.cpp:1024
bool autoreplace_defined
Are any autoreplace rules set?
Definition: group.h:30
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition: strings.cpp:52
void ToggleSortOrder()
Toggle the sort order Since that is the worst condition for the sort function reverse the list here...
Sort ascending.
Definition: window_gui.h:226
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:108
void ShowReplaceGroupVehicleWindow(GroupID id_g, VehicleType vehicletype)
Show the autoreplace configuration window for a particular group.
Vertical container.
Definition: widget_type.h:77
OwnerByte owner
Which company owns the vehicle?
Definition: vehicle_base.h:273
static NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME, WWT_INSET, or WWT_PANEL).
Definition: widget_type.h:999
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
Trains list; Window numbers:
Definition: window_type.h:303
GroupID group_sel
Selected group (for drag/drop)
Definition: group_gui.cpp:116
Group data.
Definition: group.h:67
create a new group
Definition: command_type.h:318
VehicleListIdentifier vli
Identifier of the vehicle list we want to currently show.
Bottom offset of the dropdown widget string.
Definition: window_gui.h:137
Functions related to commands.
Coordinates of a point in 2D.
set the autoreplace-protection for a group
Definition: command_type.h:324
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition: gfx.cpp:769
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-NULL) Titem.
Definition: pool_type.hpp:235
Drop down list.
Definition: widget_type.h:70
uint16 GetCapacity() const
Gets the number of visible elements of the scrollbar.
Definition: widget_type.h:622
Index of the small font in the font tables.
Definition: gfx_type.h:205
static WindowClass GetWindowClassForVehicleType(VehicleType vt)
Get WindowClass for vehicle list of given vehicle type.
Definition: vehicle_gui.h:85
start/stop all vehicles (in a depot)
Definition: command_type.h:313
Start all button.
Definition: group_widget.h:25
Owner owner
The owner of the content shown in this window. Company colour is acquired from this variable...
Definition: window_gui.h:326
Offset at right to draw the frame rectangular area.
Definition: window_gui.h:63
OwnerByte owner
Group Owner.
Definition: group.h:69
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition: widget_type.h:66
int width
width of the window (number of pixels to the right in x direction)
Definition: window_gui.h:321
uint GetVehicleListHeight(VehicleType type, uint divisor)
Get the height of a vehicle in the vehicle list GUIs.
static NWidgetPart SetFill(uint fill_x, uint fill_y)
Widget part function for setting filling.
Definition: widget_type.h:983
Replace protection button.
Definition: group_widget.h:35
static const TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:85
GUIGroupList groups
List of groups.
Definition: group_gui.cpp:120
bool IsDescSortOrder() const
Check if the sort order is descending.
#define CMD_MSG(x)
Used to combine a StringID with the command.
Definition: command_type.h:369
int32 WindowNumber
Number to differentiate different windows of the same class.
Definition: window_type.h:707
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:1973
void ResetObjectToPlace()
Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows)...
Definition: viewport.cpp:3088
Specification of a rectangle with absolute coordinates of all edges.
Vertical scrollbar.
Definition: widget_type.h:84
Text is written right-to-left by default.
Definition: strings_type.h:26
Right align the text (must be a single bit).
Definition: gfx_func.h:100
WindowNumber window_number
Window number within the window class.
Definition: window_gui.h:314
Functions related to tile highlights.
Owner
Enum for all companies/owners.
Definition: company_type.h:20
Window functions not directly related to making/drawing windows.
static uint Ceil(uint a, uint b)
Computes ceil(a / b) * b for non-negative a and b.
Definition: math_func.hpp:327
Find a place automatically.
Definition: window_gui.h:156
uint tiny_step_height
Step height for the group list.
Definition: group_gui.cpp:121
Dimension GetActionDropdownSize(bool show_autoreplace, bool show_group)
Compute the size for the Action dropdown.
Listing * sorting
Pointer to the vehicle type related sorting.
static const CursorID SPR_CURSOR_MOUSE
Cursor sprite numbers.
Definition: sprites.h:1360
GroupID group_over
Group over which a vehicle is dragged, INVALID_GROUP if none.
Definition: group_gui.cpp:118
SmallVector< int, 16 > indents
Indentation levels.
Definition: group_gui.cpp:124
GroupID group_confirm
Group awaiting delete confirmation.
Definition: group_gui.cpp:119
VehicleType vtype
The vehicle type associated with this list.
Definition: vehiclelist.h:33
Rename group button.
Definition: group_widget.h:33
static NWidgetPart SetScrollbar(int index)
Attach a scrollbar to a widget.
Definition: widget_type.h:1095
Default vehicles entry.
Definition: group_widget.h:28
VehicleTypeByte type
Type of vehicle.
Definition: vehicle_type.h:56
Dimensions (a width and height) of a rectangle in 2D.
Query string window; Window numbers:
Definition: window_type.h:118
Offset at left to draw the frame rectangular area.
Definition: window_gui.h:62
This file contains all sprite-related enums and defines.
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition: widget_type.h:64
Money GetDisplayProfitLastYear() const
Gets the profit vehicle had last year.
Definition: vehicle_base.h:572
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition: gfx.cpp:834
Top offset of the dropdown widget string.
Definition: window_gui.h:136
GroupID group_id
Index of group Pool array.
Definition: vehicle_base.h:326
int height
Height of the window (number of pixels down in y direction)
Definition: window_gui.h:322
Scrollbar for the list.
Definition: group_widget.h:30
Available vehicles.
Definition: group_widget.h:22
uint16 GetPosition() const
Gets the position of the first visible element in the list.
Definition: widget_type.h:631
Train vehicle type.
Definition: vehicle_type.h:26
uint8 SortType() const
Get the sorttype of the list.
Definition: sortlist_type.h:97
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:201
Base class for a &#39;real&#39; widget.
Definition: widget_type.h:284
static const GroupID ALL_GROUP
All vehicles are in this group.
Definition: group_type.h:18