OpenTTD Source  20241108-master-g80f628063a
news_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 "gui.h"
12 #include "viewport_func.h"
13 #include "strings_func.h"
14 #include "window_func.h"
15 #include "vehicle_base.h"
16 #include "vehicle_func.h"
17 #include "vehicle_gui.h"
18 #include "roadveh.h"
19 #include "station_base.h"
20 #include "industry.h"
21 #include "town.h"
22 #include "sound_func.h"
23 #include "string_func.h"
24 #include "statusbar_gui.h"
25 #include "company_manager_face.h"
26 #include "company_func.h"
27 #include "engine_base.h"
28 #include "engine_gui.h"
29 #include "core/geometry_func.hpp"
30 #include "command_func.h"
31 #include "company_base.h"
32 #include "settings_internal.h"
33 #include "group_gui.h"
34 #include "zoom_func.h"
35 #include "news_cmd.h"
36 #include "news_func.h"
37 #include "timer/timer.h"
38 #include "timer/timer_window.h"
40 
41 #include "widgets/news_widget.h"
42 
43 #include "table/strings.h"
44 
45 #include "safeguards.h"
46 
47 static const uint MIN_NEWS_AMOUNT = 30;
48 static const uint MAX_NEWS_AMOUNT = 1U << 10;
49 
51 
58 static NewsIterator _forced_news = std::end(_news);
59 
61 static NewsIterator _current_news = std::end(_news);
62 
64 static NewsIterator _statusbar_news = std::end(_news);
65 
71 {
72  return (_statusbar_news == std::end(_news)) ? nullptr : &*_statusbar_news;
73 }
74 
80 {
81  return _news;
82 }
83 
90 static TileIndex GetReferenceTile(NewsReferenceType reftype, uint32_t ref)
91 {
92  switch (reftype) {
93  case NR_TILE: return (TileIndex)ref;
94  case NR_STATION: return Station::Get((StationID)ref)->xy;
95  case NR_INDUSTRY: return Industry::Get((IndustryID)ref)->location.tile + TileDiffXY(1, 1);
96  case NR_TOWN: return Town::Get((TownID)ref)->xy;
97  default: return INVALID_TILE;
98  }
99 }
100 
101 /* Normal news items. */
102 static constexpr NWidgetPart _nested_normal_news_widgets[] = {
103  NWidget(WWT_PANEL, COLOUR_WHITE, WID_N_PANEL),
104  NWidget(NWID_HORIZONTAL), SetPadding(1, 1, 0, 1),
105  NWidget(WWT_CLOSEBOX, COLOUR_WHITE, WID_N_CLOSEBOX), SetPadding(0, 0, 0, 1),
106  NWidget(NWID_SPACER), SetFill(1, 0),
108  NWidget(WWT_LABEL, COLOUR_WHITE, WID_N_DATE), SetDataTip(STR_JUST_DATE_LONG, STR_NULL), SetTextStyle(TC_BLACK, FS_SMALL),
109  NWidget(NWID_SPACER), SetFill(0, 1),
110  EndContainer(),
111  EndContainer(),
112  NWidget(WWT_EMPTY, COLOUR_WHITE, WID_N_MESSAGE), SetMinimalSize(428, 154), SetPadding(0, 5, 1, 5),
113  EndContainer(),
114 };
115 
116 static WindowDesc _normal_news_desc(
117  WDP_MANUAL, nullptr, 0, 0,
119  0,
120  _nested_normal_news_widgets
121 );
122 
123 /* New vehicles news items. */
124 static constexpr NWidgetPart _nested_vehicle_news_widgets[] = {
125  NWidget(WWT_PANEL, COLOUR_WHITE, WID_N_PANEL),
126  NWidget(NWID_HORIZONTAL), SetPadding(1, 1, 0, 1),
128  NWidget(WWT_CLOSEBOX, COLOUR_WHITE, WID_N_CLOSEBOX), SetPadding(0, 0, 0, 1),
129  NWidget(NWID_SPACER), SetFill(0, 1),
130  EndContainer(),
131  NWidget(WWT_LABEL, COLOUR_WHITE, WID_N_VEH_TITLE), SetFill(1, 1), SetMinimalSize(419, 55), SetDataTip(STR_EMPTY, STR_NULL),
132  EndContainer(),
133  NWidget(WWT_PANEL, COLOUR_WHITE, WID_N_VEH_BKGND), SetPadding(0, 25, 1, 25),
135  NWidget(WWT_EMPTY, INVALID_COLOUR, WID_N_VEH_NAME), SetMinimalSize(369, 33), SetFill(1, 0),
136  NWidget(WWT_EMPTY, INVALID_COLOUR, WID_N_VEH_SPR), SetMinimalSize(369, 32), SetFill(1, 0),
137  NWidget(WWT_EMPTY, INVALID_COLOUR, WID_N_VEH_INFO), SetMinimalSize(369, 46), SetFill(1, 0),
138  EndContainer(),
139  EndContainer(),
140  EndContainer(),
141 };
142 
143 static WindowDesc _vehicle_news_desc(
144  WDP_MANUAL, nullptr, 0, 0,
146  0,
147  _nested_vehicle_news_widgets
148 );
149 
150 /* Company news items. */
151 static constexpr NWidgetPart _nested_company_news_widgets[] = {
152  NWidget(WWT_PANEL, COLOUR_WHITE, WID_N_PANEL),
153  NWidget(NWID_HORIZONTAL), SetPadding(1, 1, 0, 1),
155  NWidget(WWT_CLOSEBOX, COLOUR_WHITE, WID_N_CLOSEBOX), SetPadding(0, 0, 0, 1),
156  NWidget(NWID_SPACER), SetFill(0, 1),
157  EndContainer(),
158  NWidget(WWT_LABEL, COLOUR_WHITE, WID_N_TITLE), SetFill(1, 1), SetMinimalSize(410, 20), SetDataTip(STR_EMPTY, STR_NULL),
159  EndContainer(),
160  NWidget(NWID_HORIZONTAL), SetPadding(0, 1, 1, 1),
162  NWidget(WWT_EMPTY, COLOUR_WHITE, WID_N_MGR_FACE), SetMinimalSize(93, 119), SetPadding(2, 6, 2, 1),
163  NWidget(WWT_EMPTY, COLOUR_WHITE, WID_N_MGR_NAME), SetMinimalSize(93, 24), SetPadding(0, 0, 0, 1),
164  NWidget(NWID_SPACER), SetFill(0, 1),
165  EndContainer(),
166  NWidget(WWT_EMPTY, COLOUR_WHITE, WID_N_COMPANY_MSG), SetFill(1, 1), SetMinimalSize(328, 150),
167  EndContainer(),
168  EndContainer(),
169 };
170 
171 static WindowDesc _company_news_desc(
172  WDP_MANUAL, nullptr, 0, 0,
174  0,
175  _nested_company_news_widgets
176 );
177 
178 /* Thin news items. */
179 static constexpr NWidgetPart _nested_thin_news_widgets[] = {
180  NWidget(WWT_PANEL, COLOUR_WHITE, WID_N_PANEL),
181  NWidget(NWID_HORIZONTAL), SetPadding(1, 1, 0, 1),
182  NWidget(WWT_CLOSEBOX, COLOUR_WHITE, WID_N_CLOSEBOX), SetPadding(0, 0, 0, 1),
183  NWidget(NWID_SPACER), SetFill(1, 0),
185  NWidget(WWT_LABEL, COLOUR_WHITE, WID_N_DATE), SetDataTip(STR_JUST_DATE_LONG, STR_NULL), SetTextStyle(TC_BLACK, FS_SMALL),
186  NWidget(NWID_SPACER), SetFill(0, 1),
187  EndContainer(),
188  EndContainer(),
189  NWidget(WWT_EMPTY, COLOUR_WHITE, WID_N_MESSAGE), SetMinimalSize(428, 48), SetFill(1, 0), SetPadding(0, 5, 0, 5),
190  NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_N_VIEWPORT), SetMinimalSize(426, 70), SetPadding(1, 2, 2, 2),
191  EndContainer(),
192 };
193 
194 static WindowDesc _thin_news_desc(
195  WDP_MANUAL, nullptr, 0, 0,
197  0,
198  _nested_thin_news_widgets
199 );
200 
201 /* Small news items. */
202 static constexpr NWidgetPart _nested_small_news_widgets[] = {
203  /* Caption + close box. The caption is no WWT_CAPTION as the window shall not be moveable and so on. */
205  NWidget(WWT_CLOSEBOX, COLOUR_LIGHT_BLUE, WID_N_CLOSEBOX),
206  NWidget(WWT_EMPTY, COLOUR_LIGHT_BLUE, WID_N_CAPTION), SetFill(1, 0),
207  NWidget(WWT_TEXTBTN, COLOUR_LIGHT_BLUE, WID_N_SHOW_GROUP), SetAspect(WidgetDimensions::ASPECT_VEHICLE_ICON), SetResize(1, 0),
208  SetDataTip(STR_NULL /* filled in later */, STR_NEWS_SHOW_VEHICLE_GROUP_TOOLTIP),
209  EndContainer(),
210 
211  /* Main part */
212  NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE, WID_N_HEADLINE),
213  NWidget(WWT_INSET, COLOUR_LIGHT_BLUE, WID_N_INSET), SetPadding(2, 2, 2, 2),
214  NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_N_VIEWPORT), SetMinimalSize(274, 47), SetFill(1, 0),
215  EndContainer(),
216  NWidget(WWT_EMPTY, COLOUR_WHITE, WID_N_MESSAGE), SetMinimalSize(275, 20), SetFill(1, 0), SetPadding(0, 5, 0, 5),
217  EndContainer(),
218 };
219 
220 static WindowDesc _small_news_desc(
221  WDP_MANUAL, nullptr, 0, 0,
223  0,
224  _nested_small_news_widgets
225 );
226 
231  &_thin_news_desc,
232  &_small_news_desc,
233  &_normal_news_desc,
234  &_vehicle_news_desc,
235  &_company_news_desc,
236 };
237 
238 WindowDesc &GetNewsWindowLayout(NewsFlag flags)
239 {
240  uint layout = GB(flags, NFB_WINDOW_LAYOUT, NFB_WINDOW_LAYOUT_COUNT);
241  assert(layout < lengthof(_news_window_layout));
242  return *_news_window_layout[layout];
243 }
244 
249  /* name, age, sound, */
250  NewsTypeData("news_display.arrival_player", 60, SND_1D_APPLAUSE ),
251  NewsTypeData("news_display.arrival_other", 60, SND_1D_APPLAUSE ),
252  NewsTypeData("news_display.accident", 90, SND_BEGIN ),
253  NewsTypeData("news_display.accident_other", 90, SND_BEGIN ),
254  NewsTypeData("news_display.company_info", 60, SND_BEGIN ),
255  NewsTypeData("news_display.open", 90, SND_BEGIN ),
256  NewsTypeData("news_display.close", 90, SND_BEGIN ),
257  NewsTypeData("news_display.economy", 30, SND_BEGIN ),
258  NewsTypeData("news_display.production_player", 30, SND_BEGIN ),
259  NewsTypeData("news_display.production_other", 30, SND_BEGIN ),
260  NewsTypeData("news_display.production_nobody", 30, SND_BEGIN ),
261  NewsTypeData("news_display.advice", 150, SND_BEGIN ),
262  NewsTypeData("news_display.new_vehicles", 30, SND_1E_NEW_ENGINE),
263  NewsTypeData("news_display.acceptance", 90, SND_BEGIN ),
264  NewsTypeData("news_display.subsidies", 180, SND_BEGIN ),
265  NewsTypeData("news_display.general", 60, SND_BEGIN ),
266 };
267 
268 static_assert(lengthof(_news_type_data) == NT_END);
269 
275 {
276  const SettingDesc *sd = GetSettingFromName(this->name);
277  assert(sd != nullptr && sd->IsIntSetting());
278  return (NewsDisplay)sd->AsIntSetting()->Read(nullptr);
279 }
280 
282 struct NewsWindow : Window {
283  uint16_t chat_height;
284  uint16_t status_height;
285  const NewsItem *ni;
286  static int duration;
287 
288  NewsWindow(WindowDesc &desc, const NewsItem *ni) : Window(desc), ni(ni)
289  {
290  NewsWindow::duration = 16650;
292  this->chat_height = (w != nullptr) ? w->height : 0;
293  this->status_height = FindWindowById(WC_STATUS_BAR, 0)->height;
294 
295  this->flags |= WF_DISABLE_VP_SCROLL;
296 
297  this->CreateNestedTree();
298 
299  /* For company news with a face we have a separate headline in param[0] */
300  if (&desc == &_company_news_desc) this->GetWidget<NWidgetCore>(WID_N_TITLE)->widget_data = std::get<uint64_t>(this->ni->params[0]);
301 
302  NWidgetCore *nwid = this->GetWidget<NWidgetCore>(WID_N_SHOW_GROUP);
303  if (ni->reftype1 == NR_VEHICLE && nwid != nullptr) {
304  const Vehicle *v = Vehicle::Get(ni->ref1);
305  switch (v->type) {
306  case VEH_TRAIN:
307  nwid->widget_data = STR_TRAIN;
308  break;
309  case VEH_ROAD:
310  nwid->widget_data = RoadVehicle::From(v)->IsBus() ? STR_BUS : STR_LORRY;
311  break;
312  case VEH_SHIP:
313  nwid->widget_data = STR_SHIP;
314  break;
315  case VEH_AIRCRAFT:
316  nwid->widget_data = STR_PLANE;
317  break;
318  default:
319  break; // Do nothing
320  }
321  }
322 
323  this->FinishInitNested(0);
324 
325  /* Initialize viewport if it exists. */
326  NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_N_VIEWPORT);
327  if (nvp != nullptr) {
328  if (ni->reftype1 == NR_VEHICLE) {
329  nvp->InitializeViewport(this, static_cast<VehicleID>(ni->ref1), ScaleZoomGUI(ZOOM_LVL_NEWS));
330  } else {
332  }
333  if (this->ni->flags & NF_NO_TRANSPARENT) nvp->disp_flags |= ND_NO_TRANSPARENCY;
334  if ((this->ni->flags & NF_INCOLOUR) == 0) {
335  nvp->disp_flags |= ND_SHADE_GREY;
336  } else if (this->ni->flags & NF_SHADE) {
337  nvp->disp_flags |= ND_SHADE_DIMMED;
338  }
339  }
340 
341  PositionNewsMessage(this);
342  }
343 
344  void DrawNewsBorder(const Rect &r) const
345  {
346  Rect ir = r.Shrink(WidgetDimensions::scaled.bevel);
347  GfxFillRect(ir, PC_WHITE);
348 
349  ir = ir.Expand(1);
350  GfxFillRect( r.left, r.top, ir.left, r.bottom, PC_BLACK);
351  GfxFillRect(ir.right, r.top, r.right, r.bottom, PC_BLACK);
352  GfxFillRect( r.left, r.top, r.right, ir.top, PC_BLACK);
353  GfxFillRect( r.left, ir.bottom, r.right, r.bottom, PC_BLACK);
354  }
355 
356  Point OnInitialPosition([[maybe_unused]] int16_t sm_width, [[maybe_unused]] int16_t sm_height, [[maybe_unused]] int window_number) override
357  {
358  Point pt = { 0, _screen.height };
359  return pt;
360  }
361 
362  void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
363  {
364  StringID str = STR_NULL;
365  switch (widget) {
366  case WID_N_CAPTION: {
367  /* Caption is not a real caption (so that the window cannot be moved)
368  * thus it doesn't get the default sizing of a caption. */
369  Dimension d2 = GetStringBoundingBox(STR_NEWS_MESSAGE_CAPTION);
371  size = maxdim(size, d2);
372  return;
373  }
374 
375  case WID_N_MGR_FACE:
376  size = maxdim(size, GetScaledSpriteSize(SPR_GRADIENT));
377  break;
378 
379  case WID_N_MGR_NAME:
380  SetDParamStr(0, static_cast<const CompanyNewsInformation *>(this->ni->data.get())->president_name);
381  str = STR_JUST_RAW_STRING;
382  break;
383 
384  case WID_N_MESSAGE:
385  CopyInDParam(this->ni->params);
386  str = this->ni->string_id;
387  break;
388 
389  case WID_N_COMPANY_MSG:
390  str = this->GetCompanyMessageString();
391  break;
392 
393  case WID_N_VEH_NAME:
394  case WID_N_VEH_TITLE:
395  str = this->GetNewVehicleMessageString(widget);
396  break;
397 
398  case WID_N_VEH_INFO: {
399  assert(this->ni->reftype1 == NR_ENGINE);
400  EngineID engine = this->ni->ref1;
401  str = GetEngineInfoString(engine);
402  break;
403  }
404 
405  case WID_N_SHOW_GROUP:
406  if (this->ni->reftype1 == NR_VEHICLE) {
407  Dimension d2 = GetStringBoundingBox(this->GetWidget<NWidgetCore>(WID_N_SHOW_GROUP)->widget_data);
410  size = d2;
411  } else {
412  /* Hide 'Show group window' button if this news is not about a vehicle. */
413  size.width = 0;
414  size.height = 0;
415  resize.width = 0;
416  resize.height = 0;
417  fill.width = 0;
418  fill.height = 0;
419  }
420  return;
421 
422  default:
423  return; // Do nothing
424  }
425 
426  /* Update minimal size with length of the multi-line string. */
427  Dimension d = size;
428  d.width = (d.width >= padding.width) ? d.width - padding.width : 0;
429  d.height = (d.height >= padding.height) ? d.height - padding.height : 0;
430  d = GetStringMultiLineBoundingBox(str, d);
431  d.width += padding.width;
432  d.height += padding.height;
433  size = maxdim(size, d);
434  }
435 
436  void SetStringParameters(WidgetID widget) const override
437  {
438  if (widget == WID_N_DATE) SetDParam(0, this->ni->date);
439  }
440 
441  void DrawWidget(const Rect &r, WidgetID widget) const override
442  {
443  switch (widget) {
444  case WID_N_CAPTION:
445  DrawCaption(r, COLOUR_LIGHT_BLUE, this->owner, TC_FROMSTRING, STR_NEWS_MESSAGE_CAPTION, SA_CENTER, FS_NORMAL);
446  break;
447 
448  case WID_N_PANEL:
449  this->DrawNewsBorder(r);
450  break;
451 
452  case WID_N_MESSAGE:
453  CopyInDParam(this->ni->params);
454  DrawStringMultiLine(r.left, r.right, r.top, r.bottom, this->ni->string_id, TC_FROMSTRING, SA_CENTER);
455  break;
456 
457  case WID_N_MGR_FACE: {
458  const CompanyNewsInformation *cni = static_cast<const CompanyNewsInformation*>(this->ni->data.get());
459  DrawCompanyManagerFace(cni->face, cni->colour, r);
460  GfxFillRect(r.left, r.top, r.right, r.bottom, PALETTE_NEWSPAPER, FILLRECT_RECOLOUR);
461  break;
462  }
463  case WID_N_MGR_NAME: {
464  const CompanyNewsInformation *cni = static_cast<const CompanyNewsInformation*>(this->ni->data.get());
465  SetDParamStr(0, cni->president_name);
466  DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_JUST_RAW_STRING, TC_FROMSTRING, SA_CENTER);
467  break;
468  }
469  case WID_N_COMPANY_MSG:
470  DrawStringMultiLine(r.left, r.right, r.top, r.bottom, this->GetCompanyMessageString(), TC_FROMSTRING, SA_CENTER);
471  break;
472 
473  case WID_N_VEH_BKGND:
474  GfxFillRect(r.left, r.top, r.right, r.bottom, PC_GREY);
475  break;
476 
477  case WID_N_VEH_NAME:
478  case WID_N_VEH_TITLE:
479  DrawStringMultiLine(r.left, r.right, r.top, r.bottom, this->GetNewVehicleMessageString(widget), TC_FROMSTRING, SA_CENTER);
480  break;
481 
482  case WID_N_VEH_SPR: {
483  assert(this->ni->reftype1 == NR_ENGINE);
484  EngineID engine = this->ni->ref1;
485  DrawVehicleEngine(r.left, r.right, CenterBounds(r.left, r.right, 0), CenterBounds(r.top, r.bottom, 0), engine, GetEnginePalette(engine, _local_company), EIT_PREVIEW);
486  GfxFillRect(r.left, r.top, r.right, r.bottom, PALETTE_NEWSPAPER, FILLRECT_RECOLOUR);
487  break;
488  }
489  case WID_N_VEH_INFO: {
490  assert(this->ni->reftype1 == NR_ENGINE);
491  EngineID engine = this->ni->ref1;
492  DrawStringMultiLine(r.left, r.right, r.top, r.bottom, GetEngineInfoString(engine), TC_FROMSTRING, SA_CENTER);
493  break;
494  }
495  }
496  }
497 
498  void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
499  {
500  switch (widget) {
501  case WID_N_CLOSEBOX:
503  this->Close();
504  _forced_news = std::end(_news);
505  break;
506 
507  case WID_N_CAPTION:
508  if (this->ni->reftype1 == NR_VEHICLE) {
509  const Vehicle *v = Vehicle::Get(this->ni->ref1);
511  }
512  break;
513 
514  case WID_N_VIEWPORT:
515  break; // Ignore clicks
516 
517  case WID_N_SHOW_GROUP:
518  if (this->ni->reftype1 == NR_VEHICLE) {
519  const Vehicle *v = Vehicle::Get(this->ni->ref1);
521  }
522  break;
523  default:
524  if (this->ni->reftype1 == NR_VEHICLE) {
525  const Vehicle *v = Vehicle::Get(this->ni->ref1);
526  ScrollMainWindowTo(v->x_pos, v->y_pos, v->z_pos);
527  } else {
528  TileIndex tile1 = GetReferenceTile(this->ni->reftype1, this->ni->ref1);
529  TileIndex tile2 = GetReferenceTile(this->ni->reftype2, this->ni->ref2);
530  if (_ctrl_pressed) {
531  if (tile1 != INVALID_TILE) ShowExtraViewportWindow(tile1);
532  if (tile2 != INVALID_TILE) ShowExtraViewportWindow(tile2);
533  } else {
534  if ((tile1 == INVALID_TILE || !ScrollMainWindowToTile(tile1)) && tile2 != INVALID_TILE) {
535  ScrollMainWindowToTile(tile2);
536  }
537  }
538  }
539  break;
540  }
541  }
542 
543  void OnResize() override
544  {
545  if (this->viewport != nullptr) {
546  NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_N_VIEWPORT);
547  nvp->UpdateViewportCoordinates(this);
548 
549  if (ni->reftype1 != NR_VEHICLE) {
550  ScrollWindowToTile(GetReferenceTile(ni->reftype1, ni->ref1), this, true); // Re-center viewport.
551  }
552  }
553  }
554 
560  void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
561  {
562  if (!gui_scope) return;
563  /* The chatbar has notified us that is was either created or closed */
564  int newtop = this->top + this->chat_height - data;
565  this->chat_height = data;
566  this->SetWindowTop(newtop);
567  }
568 
569  void OnRealtimeTick([[maybe_unused]] uint delta_ms) override
570  {
571  /* Decrement the news timer. We don't need to action an elapsed event here,
572  * so no need to use TimerElapsed(). */
573  if (NewsWindow::duration > 0) NewsWindow::duration -= delta_ms;
574  }
575 
581  IntervalTimer<TimerWindow> scroll_interval = {std::chrono::milliseconds(210) / GetCharacterHeight(FS_NORMAL), [this](uint count) {
582  int newtop = std::max(this->top - 2 * static_cast<int>(count), _screen.height - this->height - this->status_height - this->chat_height);
583  this->SetWindowTop(newtop);
584  }};
585 
586 private:
591  void SetWindowTop(int newtop)
592  {
593  if (this->top == newtop) return;
594 
595  int mintop = std::min(newtop, this->top);
596  int maxtop = std::max(newtop, this->top);
597  if (this->viewport != nullptr) this->viewport->top += newtop - this->top;
598  this->top = newtop;
599 
600  AddDirtyBlock(this->left, mintop, this->left + this->width, maxtop + this->height);
601  }
602 
603  StringID GetCompanyMessageString() const
604  {
605  /* Company news with a face have a separate headline, so the normal message is shifted by two params */
606  CopyInDParam(std::span(this->ni->params.data() + 2, this->ni->params.size() - 2));
607  return std::get<uint64_t>(this->ni->params[1]);
608  }
609 
610  StringID GetNewVehicleMessageString(WidgetID widget) const
611  {
612  assert(this->ni->reftype1 == NR_ENGINE);
613  EngineID engine = this->ni->ref1;
614 
615  switch (widget) {
616  case WID_N_VEH_TITLE:
617  SetDParam(0, GetEngineCategoryName(engine));
618  return STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE;
619 
620  case WID_N_VEH_NAME:
622  return STR_NEWS_NEW_VEHICLE_TYPE;
623 
624  default:
625  NOT_REACHED();
626  }
627  }
628 };
629 
630 /* static */ int NewsWindow::duration = 0; // Instance creation.
631 
633 static void ShowNewspaper(const NewsItem *ni)
634 {
635  SoundFx sound = _news_type_data[ni->type].sound;
636  if (sound != 0 && _settings_client.sound.news_full) SndPlayFx(sound);
637 
638  new NewsWindow(GetNewsWindowLayout(ni->flags), ni);
639 }
640 
642 static void ShowTicker(NewsIterator ni)
643 {
645 
646  _statusbar_news = ni;
648 }
649 
652 {
653  _news.clear();
654  _forced_news = std::end(_news);
655  _current_news = std::end(_news);
656  _statusbar_news = std::end(_news);
658 }
659 
665 {
666  const NewsItem *ni = GetStatusbarNews();
667  if (ni == nullptr) return true;
668 
669  /* Ticker message
670  * Check if the status bar message is still being displayed? */
671  return !IsNewsTickerShown();
672 }
673 
678 static bool ReadyForNextNewsItem()
679 {
680  if (_forced_news == std::end(_news) && _current_news == std::end(_news)) return true;
681 
682  /* neither newsticker nor newspaper are running */
683  return (NewsWindow::duration <= 0 || FindWindowById(WC_NEWS_WINDOW, 0) == nullptr);
684 }
685 
687 static void MoveToNextTickerItem()
688 {
689  /* There is no status bar, so no reason to show news;
690  * especially important with the end game screen when
691  * there is no status bar but possible news. */
692  if (FindWindowById(WC_STATUS_BAR, 0) == nullptr) return;
693 
694  /* No news to move to. */
695  if (std::empty(_news)) return;
696 
697  /* if we're not at the latest item, then move on */
698  while (_statusbar_news != std::begin(_news)) {
699  --_statusbar_news;
700  const NewsType type = _statusbar_news->type;
701 
702  /* check the date, don't show too old items */
703  if (TimerGameEconomy::date - _news_type_data[type].age > _statusbar_news->economy_date) continue;
704 
705  switch (_news_type_data[type].GetDisplay()) {
706  default: NOT_REACHED();
707  case ND_OFF: // Off - show nothing only a small reminder in the status bar
709  return;
710 
711  case ND_SUMMARY: // Summary - show ticker
713  return;
714 
715  case ND_FULL: // Full - show newspaper, skipped here
716  break;;
717  }
718  }
719 }
720 
722 static void MoveToNextNewsItem()
723 {
724  /* There is no status bar, so no reason to show news;
725  * especially important with the end game screen when
726  * there is no status bar but possible news. */
727  if (FindWindowById(WC_STATUS_BAR, 0) == nullptr) return;
728 
729  CloseWindowById(WC_NEWS_WINDOW, 0); // close the newspapers window if shown
730  _forced_news = std::end(_news);
731 
732  /* No news to move to. */
733  if (std::empty(_news)) return;
734 
735  /* if we're not at the latest item, then move on */
736  while (_current_news != std::begin(_news)) {
737  --_current_news;
738  const NewsType type = _current_news->type;
739 
740  /* check the date, don't show too old items */
741  if (TimerGameEconomy::date - _news_type_data[type].age > _current_news->economy_date) continue;
742 
743  switch (_news_type_data[type].GetDisplay()) {
744  default: NOT_REACHED();
745  case ND_OFF: // Off - show nothing only a small reminder in the status bar, skipped here
746  break;
747 
748  case ND_SUMMARY: // Summary - show ticker, skipped here
749  break;;
750 
751  case ND_FULL: // Full - show newspaper
753  return;
754  }
755  }
756 }
757 
759 static std::list<NewsItem>::iterator DeleteNewsItem(std::list<NewsItem>::iterator ni)
760 {
761  bool updateCurrentNews = (_forced_news == ni || _current_news == ni);
762  bool updateStatusbarNews = (_statusbar_news == ni);
763 
764  if (updateCurrentNews) {
765  /* When we're the current news, go to the next older item first;
766  * we just possibly made that the last news item. */
767  if (_current_news == ni) ++_current_news;
768  if (_forced_news == ni) _forced_news = std::end(_news);
769  }
770 
771  if (updateStatusbarNews) {
772  /* When we're the current news, go to the next older item first;
773  * we just possibly made that the last news item. */
774  ++_statusbar_news;
775  }
776 
777  /* Delete the news from the news queue. */
778  ni = _news.erase(ni);
779 
780  if (updateCurrentNews) {
781  /* About to remove the currently forced item (shown as newspapers) ||
782  * about to remove the currently displayed item (newspapers) */
784  }
785 
786  if (updateStatusbarNews) {
787  /* About to remove the currently displayed item (ticker, or just a reminder) */
788  InvalidateWindowData(WC_STATUS_BAR, 0, SBI_NEWS_DELETED); // invalidate the statusbar
790  }
791 
792  return ni;
793 }
794 
808 NewsItem::NewsItem(StringID string_id, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, const NewsAllocatedData *data) :
809  string_id(string_id), date(TimerGameCalendar::date), economy_date(TimerGameEconomy::date), type(type), flags(flags), reftype1(reftype1), reftype2(reftype2), ref1(ref1), ref2(ref2), data(data)
810 {
811  /* show this news message in colour? */
813  CopyOutDParam(this->params, 10);
814 }
815 
829 void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, const NewsAllocatedData *data)
830 {
831  if (_game_mode == GM_MENU) return;
832 
833  /* Create new news item node */
834  _news.emplace_front(string, type, flags, reftype1, ref1, reftype2, ref2, data);
835 
836  /* Keep the number of stored news items to a managable number */
837  if (std::size(_news) > MAX_NEWS_AMOUNT) {
838  DeleteNewsItem(std::prev(std::end(_news)));
839  }
840 
842 }
843 
854 CommandCost CmdCustomNewsItem(DoCommandFlag flags, NewsType type, NewsReferenceType reftype1, CompanyID company, uint32_t reference, const std::string &text)
855 {
856  if (_current_company != OWNER_DEITY) return CMD_ERROR;
857 
858  if (company != INVALID_OWNER && !Company::IsValidID(company)) return CMD_ERROR;
859  if (type >= NT_END) return CMD_ERROR;
860  if (text.empty()) return CMD_ERROR;
861 
862  switch (reftype1) {
863  case NR_NONE: break;
864  case NR_TILE:
865  if (!IsValidTile(reference)) return CMD_ERROR;
866  break;
867 
868  case NR_VEHICLE:
869  if (!Vehicle::IsValidID(reference)) return CMD_ERROR;
870  break;
871 
872  case NR_STATION:
873  if (!Station::IsValidID(reference)) return CMD_ERROR;
874  break;
875 
876  case NR_INDUSTRY:
877  if (!Industry::IsValidID(reference)) return CMD_ERROR;
878  break;
879 
880  case NR_TOWN:
881  if (!Town::IsValidID(reference)) return CMD_ERROR;
882  break;
883 
884  case NR_ENGINE:
885  if (!Engine::IsValidID(reference)) return CMD_ERROR;
886  break;
887 
888  default: return CMD_ERROR;
889  }
890 
891  if (company != INVALID_OWNER && company != _local_company) return CommandCost();
892 
893  if (flags & DC_EXEC) {
894  SetDParamStr(0, text);
895  AddNewsItem(STR_NEWS_CUSTOM_ITEM, type, NF_NORMAL, reftype1, reference, NR_NONE, UINT32_MAX);
896  }
897 
898  return CommandCost();
899 }
900 
906 template <size_t Tmin = 0, class Tpredicate>
907 void DeleteNews(Tpredicate predicate)
908 {
909  bool dirty = false;
910  for (auto it = std::rbegin(_news); it != std::rend(_news); /* nothing */) {
911  if constexpr (Tmin > 0) {
912  if (std::size(_news) <= Tmin) break;
913  }
914  if (predicate(*it)) {
915  it = std::make_reverse_iterator(DeleteNewsItem(std::prev(it.base())));
916  dirty = true;
917  } else {
918  ++it;
919  }
920  }
922 }
923 
931 {
932  DeleteNews([&](const auto &ni) {
933  return ((ni.reftype1 == NR_VEHICLE && ni.ref1 == vid) || (ni.reftype2 == NR_VEHICLE && ni.ref2 == vid)) && (news == INVALID_STRING_ID || ni.string_id == news);
934  });
935 }
936 
942 void DeleteStationNews(StationID sid)
943 {
944  DeleteNews([&](const auto &ni) {
945  return (ni.reftype1 == NR_STATION && ni.ref1 == sid) || (ni.reftype2 == NR_STATION && ni.ref2 == sid);
946  });
947 }
948 
953 void DeleteIndustryNews(IndustryID iid)
954 {
955  DeleteNews([&](const auto &ni) {
956  return (ni.reftype1 == NR_INDUSTRY && ni.ref1 == iid) || (ni.reftype2 == NR_INDUSTRY && ni.ref2 == iid);
957  });
958 }
959 
964 {
965  DeleteNews([](const auto &ni) {
966  return (ni.reftype1 == NR_ENGINE && (!Engine::IsValidID(ni.ref1) || !Engine::Get(ni.ref1)->IsEnabled())) ||
967  (ni.reftype2 == NR_ENGINE && (!Engine::IsValidID(ni.ref2) || !Engine::Get(ni.ref2)->IsEnabled()));
968  });
969 }
970 
971 static void RemoveOldNewsItems()
972 {
973  DeleteNews<MIN_NEWS_AMOUNT>([](const auto &ni) {
975  });
976 }
977 
984 void ChangeVehicleNews(VehicleID from_index, VehicleID to_index)
985 {
986  for (auto &ni : _news) {
987  if (ni.reftype1 == NR_VEHICLE && ni.ref1 == from_index) ni.ref1 = to_index;
988  if (ni.reftype2 == NR_VEHICLE && ni.ref2 == from_index) ni.ref2 = to_index;
989  if (ni.flags & NF_VEHICLE_PARAM0 && std::get<uint64_t>(ni.params[0]) == from_index) ni.params[0] = to_index;
990  }
991 }
992 
993 void NewsLoop()
994 {
995  /* no news item yet */
996  if (std::empty(_news)) return;
997 
998  static TimerGameEconomy::Month _last_clean_month = 0;
999 
1000  if (_last_clean_month != TimerGameEconomy::month) {
1001  RemoveOldNewsItems();
1002  _last_clean_month = TimerGameEconomy::month;
1003  }
1004 
1007 }
1008 
1011 {
1012  assert(!std::empty(_news));
1013 
1014  /* Delete the news window */
1016 
1017  /* setup forced news item */
1018  _forced_news = ni;
1019 
1020  if (_forced_news != std::end(_news)) {
1022  ShowNewspaper(&*ni);
1023  }
1024 }
1025 
1031 {
1032  NewsWindow *w = dynamic_cast<NewsWindow *>(FindWindowById(WC_NEWS_WINDOW, 0));
1033  if (w == nullptr) return false;
1034  w->Close();
1035  return true;
1036 }
1037 
1040 {
1041  if (std::empty(_news)) return;
1042 
1043  NewsIterator ni;
1044  if (_forced_news == std::end(_news)) {
1045  /* Not forced any news yet, show the current one, unless a news window is
1046  * open (which can only be the current one), then show the previous item */
1047  if (_current_news == std::end(_news)) {
1048  /* No news were shown yet resp. the last shown one was already deleted.
1049  * Treat this as if _forced_news reached the oldest news; so, wrap around and start anew with the latest. */
1050  ni = std::begin(_news);
1051  } else {
1052  const Window *w = FindWindowById(WC_NEWS_WINDOW, 0);
1053  ni = (w == nullptr || (std::next(_current_news) == std::end(_news))) ? _current_news : std::next(_current_news);
1054  }
1055  } else if (std::next(_forced_news) == std::end(_news)) {
1056  /* We have reached the oldest news, start anew with the latest */
1057  ni = std::begin(_news);
1058  } else {
1059  /* 'Scrolling' through news history show each one in turn */
1060  ni = std::next(_forced_news);
1061  }
1062  bool wrap = false;
1063  for (;;) {
1064  if (_news_type_data[ni->type].GetDisplay() != ND_OFF) {
1065  ShowNewsMessage(ni);
1066  break;
1067  }
1068 
1069  ++ni;
1070  if (ni == std::end(_news)) {
1071  if (wrap) break;
1072  /* We have reached the oldest news, start anew with the latest */
1073  ni = std::begin(_news);
1074  wrap = true;
1075  }
1076  }
1077 }
1078 
1079 
1089 static void DrawNewsString(uint left, uint right, int y, TextColour colour, const NewsItem *ni)
1090 {
1091  CopyInDParam(ni->params);
1092 
1093  /* Get the string, replaces newlines with spaces and remove control codes from the string. */
1095 
1096  /* Truncate and show string; postfixed by '...' if necessary */
1097  DrawString(left, right, y, message, colour);
1098 }
1099 
1101  int line_height;
1103 
1105 
1106  MessageHistoryWindow(WindowDesc &desc) : Window(desc)
1107  {
1108  this->CreateNestedTree();
1109  this->vscroll = this->GetScrollbar(WID_MH_SCROLLBAR);
1110  this->FinishInitNested(); // Initializes 'this->line_height' and 'this->date_width'.
1111  this->OnInvalidateData(0);
1112  }
1113 
1114  void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
1115  {
1116  if (widget == WID_MH_BACKGROUND) {
1118  resize.height = this->line_height;
1119 
1120  /* Months are off-by-one, so it's actually 8. Not using
1121  * month 12 because the 1 is usually less wide. */
1123  this->date_width = GetStringBoundingBox(STR_JUST_DATE_TINY).width + WidgetDimensions::scaled.hsep_wide;
1124 
1125  size.height = 4 * resize.height + WidgetDimensions::scaled.framerect.Vertical(); // At least 4 lines are visible.
1126  size.width = std::max(200u, size.width); // At least 200 pixels wide.
1127  }
1128  }
1129 
1130  void DrawWidget(const Rect &r, WidgetID widget) const override
1131  {
1132  if (widget != WID_MH_BACKGROUND || std::empty(_news)) return;
1133 
1134  /* Fill the widget with news items. */
1135  bool rtl = _current_text_dir == TD_RTL;
1136  Rect news = r.Shrink(WidgetDimensions::scaled.framerect).Indent(this->date_width + WidgetDimensions::scaled.hsep_wide, rtl);
1137  Rect date = r.Shrink(WidgetDimensions::scaled.framerect).WithWidth(this->date_width, rtl);
1138  int y = news.top;
1139 
1140  auto [first, last] = this->vscroll->GetVisibleRangeIterators(_news);
1141  for (auto ni = first; ni != last; ++ni) {
1142  SetDParam(0, ni->date);
1143  DrawString(date.left, date.right, y, STR_JUST_DATE_TINY, TC_WHITE);
1144 
1145  DrawNewsString(news.left, news.right, y, TC_WHITE, &*ni);
1146  y += this->line_height;
1147  }
1148  }
1149 
1155  void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
1156  {
1157  if (!gui_scope) return;
1158  this->vscroll->SetCount(std::size(_news));
1159  }
1160 
1161  void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1162  {
1163  if (widget == WID_MH_BACKGROUND) {
1164  /* Scheduled window invalidations currently occur after the input loop, which means the scrollbar count
1165  * could be invalid, so ensure it's correct now. Potentially this means that item clicked on might be
1166  * different as well. */
1167  this->vscroll->SetCount(std::size(_news));
1168  auto ni = this->vscroll->GetScrolledItemFromWidget(_news, pt.y, this, widget, WidgetDimensions::scaled.framerect.top);
1169  if (ni == std::end(_news)) return;
1170 
1171  ShowNewsMessage(ni);
1172  }
1173  }
1174 
1175  void OnResize() override
1176  {
1177  this->vscroll->SetCapacityFromWidget(this, WID_MH_BACKGROUND, WidgetDimensions::scaled.framerect.Vertical());
1178  }
1179 };
1180 
1181 static constexpr NWidgetPart _nested_message_history[] = {
1183  NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
1184  NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_MESSAGE_HISTORY, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1185  NWidget(WWT_SHADEBOX, COLOUR_BROWN),
1186  NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
1187  NWidget(WWT_STICKYBOX, COLOUR_BROWN),
1188  EndContainer(),
1189 
1191  NWidget(WWT_PANEL, COLOUR_BROWN, WID_MH_BACKGROUND), SetMinimalSize(200, 125), SetDataTip(0x0, STR_MESSAGE_HISTORY_TOOLTIP), SetResize(1, 12), SetScrollbar(WID_MH_SCROLLBAR),
1192  EndContainer(),
1194  NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_MH_SCROLLBAR),
1195  NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
1196  EndContainer(),
1197  EndContainer(),
1198 };
1199 
1200 static WindowDesc _message_history_desc(
1201  WDP_AUTO, "list_news", 400, 140,
1203  0,
1204  _nested_message_history
1205 );
1206 
1209 {
1211  new MessageHistoryWindow(_message_history_desc);
1212 }
constexpr static debug_inline uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
Common return value for all commands.
Definition: command_type.h:23
Base class for a 'real' widget.
Definition: widget_type.h:370
NWidgetDisplay disp_flags
Flags that affect display and interaction with the widget.
Definition: widget_type.h:390
uint32_t widget_data
Data of the widget.
Definition: widget_type.h:393
Nested widget to display a viewport in a window.
Definition: widget_type.h:680
void UpdateViewportCoordinates(Window *w)
Update the position and size of the viewport (after eg a resize).
Definition: widget.cpp:2297
void InitializeViewport(Window *w, std::variant< TileIndex, VehicleID > focus, ZoomLevel zoom)
Initialize the viewport of the window.
Definition: widget.cpp:2288
Scrollbar data structure.
Definition: widget_type.h:694
void SetCount(size_t num)
Sets the number of elements in the list.
Definition: widget_type.h:780
auto GetScrolledItemFromWidget(Tcontainer &container, int clickpos, const Window *const w, WidgetID widget, int padding=0, int line_height=-1) const
Return an iterator pointing to the element of a scrolled widget that a user clicked in.
Definition: widget_type.h:879
void SetCapacityFromWidget(Window *w, WidgetID widget, int padding=0)
Set capacity of visible elements from the size and resize properties of a widget.
Definition: widget.cpp:2394
auto GetVisibleRangeIterators(Tcontainer &container) const
Get a pair of iterators for the range of visible elements in a container.
Definition: widget_type.h:860
Timer that is increased every 27ms, and counts towards ticks / days / months / years.
static Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
static Year year
Current year, starting at 0.
static constexpr TimerGame< struct Calendar >::Year ORIGINAL_MAX_YEAR
The maximum year of the original TTD.
Timer that is increased every 27ms, and counts towards economy time units, expressed in days / months...
static Date date
Current date in days (day counter).
static Month month
Current month (0..11).
uint8_t Month
Type for the month, note: 0 based, i.e.
RectPadding framerect
Standard padding inside many panels.
Definition: window_gui.h:42
RectPadding captiontext
Padding for text within caption widget.
Definition: window_gui.h:51
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition: window_gui.h:68
int vsep_normal
Normal vertical spacing.
Definition: window_gui.h:60
int hsep_wide
Wide horizontal spacing.
Definition: window_gui.h:64
Functions related to commands.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition: command_func.h:28
DoCommandFlag
List of flags for a command.
Definition: command_type.h:374
@ DC_EXEC
execute the given command
Definition: command_type.h:376
Definition of stuff that is very close to a company, like the company struct itself.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:52
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:53
Functions related to companies.
void DrawCompanyManagerFace(CompanyManagerFace cmf, Colours colour, const Rect &r)
Draws the face of a company manager's face.
Functionality related to the company manager's face.
Owner
Enum for all companies/owners.
Definition: company_type.h:18
@ INVALID_OWNER
An invalid owner.
Definition: company_type.h:29
@ OWNER_DEITY
The object is owned by a superuser / goal script.
Definition: company_type.h:27
Base class for engines.
StringID GetEngineCategoryName(EngineID engine)
Return the category of an engine.
Definition: engine_gui.cpp:40
StringID GetEngineInfoString(EngineID engine)
Get a multi-line string with some technical data, describing the engine.
Definition: engine_gui.cpp:273
void DrawVehicleEngine(int left, int right, int preferred_x, int y, EngineID engine, PaletteID pal, EngineImageType image_type)
Draw an engine.
Definition: engine_gui.cpp:303
Engine GUI functions, used by build_vehicle_gui and autoreplace_gui
uint16_t EngineID
Unique identification number of an engine.
Definition: engine_type.h:21
uint64_t PackEngineNameDParam(EngineID engine_id, EngineNameContext context, uint32_t extra_data=0)
Combine an engine ID and a name context to an engine name dparam.
Definition: engine_type.h:199
@ PreviewNews
Name is shown in exclusive preview or newspaper.
Definition: engine_type.h:194
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition: fontcache.cpp:77
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Geometry functions.
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition: gfx.cpp:851
int DrawString(int left, int right, int top, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition: gfx.cpp:657
bool _ctrl_pressed
Is Ctrl pressed?
Definition: gfx.cpp:38
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:114
Dimension GetStringMultiLineBoundingBox(StringID str, const Dimension &suggestion)
Calculate string bounding box for multi-line strings.
Definition: gfx.cpp:740
int DrawStringMultiLine(int left, int right, int top, int bottom, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly over multiple lines.
Definition: gfx.cpp:774
Dimension GetScaledSpriteSize(SpriteID sprid)
Scale sprite size for GUI.
Definition: widget.cpp:54
int CenterBounds(int min, int max, int size)
Determine where to draw a centred object inside a widget.
Definition: gfx_func.h:166
@ SA_CENTER
Center both horizontally and vertically.
Definition: gfx_type.h:353
@ FS_SMALL
Index of the small font in the font tables.
Definition: gfx_type.h:210
@ FS_NORMAL
Index of the normal font in the font tables.
Definition: gfx_type.h:209
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition: gfx_type.h:260
@ FILLRECT_RECOLOUR
Apply a recolour sprite to the screen content.
Definition: gfx_type.h:300
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
Definition: widget_type.h:1181
constexpr NWidgetPart SetScrollbar(WidgetID index)
Attach a scrollbar to a widget.
Definition: widget_type.h:1284
constexpr NWidgetPart SetPadding(uint8_t top, uint8_t right, uint8_t bottom, uint8_t left)
Widget part function for setting additional space around a widget.
Definition: widget_type.h:1228
constexpr NWidgetPart SetDataTip(uint32_t data, StringID tip)
Widget part function for setting the data and tooltip.
Definition: widget_type.h:1202
constexpr NWidgetPart SetTextStyle(TextColour colour, FontSize size=FS_NORMAL)
Widget part function for setting the text style.
Definition: widget_type.h:1160
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
Definition: widget_type.h:1137
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=-1)
Widget part function for starting a new 'real' widget.
Definition: widget_type.h:1309
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
Definition: widget_type.h:1191
constexpr NWidgetPart SetAspect(float ratio, AspectFlags flags=AspectFlags::ResizeX)
Widget part function for setting the aspect ratio.
Definition: widget_type.h:1295
constexpr NWidgetPart SetResize(int16_t dx, int16_t dy)
Widget part function for setting the resize step.
Definition: widget_type.h:1126
void AddDirtyBlock(int left, int top, int right, int bottom)
Extend the internal _invalid_rect rectangle to contain the rectangle defined by the given parameters.
Definition: gfx.cpp:1486
void ShowCompanyGroupForVehicle(const Vehicle *v)
Show the group window for the given vehicle.
Definition: group_gui.cpp:1194
Functions/definitions that have something to do with groups.
GUI functions that shouldn't be here.
void ShowExtraViewportWindow(TileIndex tile=INVALID_TILE)
Show a new Extra Viewport window.
Base of all industries.
TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition: map_func.h:389
Command definitions related to news messages.
Functions related to news.
void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, const NewsAllocatedData *data)
Add a new newsitem to be shown.
Definition: news_gui.cpp:829
static NewsContainer _news
List of news, with newest items at the start.
Definition: news_gui.cpp:50
static void DrawNewsString(uint left, uint right, int y, TextColour colour, const NewsItem *ni)
Draw an unformatted news message truncated to a maximum length.
Definition: news_gui.cpp:1089
static std::list< NewsItem >::iterator DeleteNewsItem(std::list< NewsItem >::iterator ni)
Delete a news item from the queue.
Definition: news_gui.cpp:759
static void MoveToNextNewsItem()
Move to the next news item.
Definition: news_gui.cpp:722
static void ShowTicker(NewsIterator ni)
Show news item in the ticker.
Definition: news_gui.cpp:642
void DeleteNews(Tpredicate predicate)
Delete news items by predicate, and invalidate the message history if necessary.
Definition: news_gui.cpp:907
void DeleteVehicleNews(VehicleID vid, StringID news)
Delete a news item type about a vehicle.
Definition: news_gui.cpp:930
static void ShowNewspaper(const NewsItem *ni)
Open up an own newspaper window for the news item.
Definition: news_gui.cpp:633
static const uint MIN_NEWS_AMOUNT
preferred minimum amount of news messages.
Definition: news_gui.cpp:47
static NewsTypeData _news_type_data[]
Per-NewsType data.
Definition: news_gui.cpp:248
static NewsIterator _forced_news
Forced news item.
Definition: news_gui.cpp:58
void DeleteIndustryNews(IndustryID iid)
Remove news regarding given industry.
Definition: news_gui.cpp:953
void DeleteStationNews(StationID sid)
Remove news regarding given station so there are no 'unknown station now accepts Mail' or 'First trai...
Definition: news_gui.cpp:942
void ShowLastNewsMessage()
Show previous news item.
Definition: news_gui.cpp:1039
static const uint MAX_NEWS_AMOUNT
Do not exceed this number of news messages.
Definition: news_gui.cpp:48
void DeleteInvalidEngineNews()
Remove engine announcements for invalid engines.
Definition: news_gui.cpp:963
static bool ReadyForNextNewsItem()
Are we ready to show another news item? Only if no newspaper is displayed.
Definition: news_gui.cpp:678
static TileIndex GetReferenceTile(NewsReferenceType reftype, uint32_t ref)
Get the position a news-reference is referencing.
Definition: news_gui.cpp:90
bool HideActiveNewsMessage()
Close active news message window.
Definition: news_gui.cpp:1030
void ShowMessageHistory()
Display window with news messages history.
Definition: news_gui.cpp:1208
void ChangeVehicleNews(VehicleID from_index, VehicleID to_index)
Report a change in vehicle IDs (due to autoreplace) to affected vehicle news.
Definition: news_gui.cpp:984
CommandCost CmdCustomNewsItem(DoCommandFlag flags, NewsType type, NewsReferenceType reftype1, CompanyID company, uint32_t reference, const std::string &text)
Create a new custom news item.
Definition: news_gui.cpp:854
void InitNewsItemStructs()
Initialize the news-items data structures.
Definition: news_gui.cpp:651
static void MoveToNextTickerItem()
Move to the next ticker item.
Definition: news_gui.cpp:687
const NewsItem * GetStatusbarNews()
Get pointer to the current status bar news item.
Definition: news_gui.cpp:70
static void ShowNewsMessage(NewsIterator ni)
Do a forced show of a specific message.
Definition: news_gui.cpp:1010
static NewsIterator _current_news
Current news item (last item shown regularly).
Definition: news_gui.cpp:61
const NewsContainer & GetNews()
Get read-only reference to all news items.
Definition: news_gui.cpp:79
static bool ReadyForNextTickerItem()
Are we ready to show another ticker item? Only if nothing is in the newsticker is displayed.
Definition: news_gui.cpp:664
static WindowDesc * _news_window_layout[]
Window layouts for news items.
Definition: news_gui.cpp:230
static NewsIterator _statusbar_news
Current status bar news item.
Definition: news_gui.cpp:64
NewsType
Type of news.
Definition: news_type.h:23
@ NT_END
end-of-array marker
Definition: news_type.h:40
NewsReferenceType
References to objects in news.
Definition: news_type.h:52
@ NR_TILE
Reference tile. Scroll to tile when clicking on the news.
Definition: news_type.h:54
@ NR_STATION
Reference station. Scroll to station when clicking on the news. Delete news when station is deleted.
Definition: news_type.h:56
@ NR_ENGINE
Reference engine.
Definition: news_type.h:59
@ NR_TOWN
Reference town. Scroll to town when clicking on the news.
Definition: news_type.h:58
@ NR_INDUSTRY
Reference industry. Scroll to industry when clicking on the news. Delete news when industry is delete...
Definition: news_type.h:57
@ NR_NONE
Empty reference.
Definition: news_type.h:53
@ NR_VEHICLE
Reference vehicle. Scroll to vehicle when clicking on the news. Delete news when vehicle is deleted.
Definition: news_type.h:55
NewsContainer::const_iterator NewsIterator
Iterator type for news items.
Definition: news_type.h:165
NewsDisplay
News display options.
Definition: news_type.h:91
@ ND_SUMMARY
Show ticker.
Definition: news_type.h:93
@ ND_OFF
Only show a reminder in the status bar.
Definition: news_type.h:92
@ ND_FULL
Show newspaper.
Definition: news_type.h:94
std::list< NewsItem > NewsContainer
Container type for storing news items.
Definition: news_type.h:164
NewsFlag
Various OR-able news-item flags.
Definition: news_type.h:66
@ NF_NO_TRANSPARENT
Bit value for disabling transparency.
Definition: news_type.h:75
@ NF_SHADE
Bit value for enabling shading.
Definition: news_type.h:76
@ NF_VEHICLE_PARAM0
Bit value for specifying that string param 0 contains a vehicle ID. (special autoreplace behaviour)
Definition: news_type.h:77
@ NFB_WINDOW_LAYOUT
First bit for window layout.
Definition: news_type.h:70
@ NF_NORMAL
Normal news item. (Newspaper with text only)
Definition: news_type.h:81
@ NF_INCOLOUR
Bit value for coloured news.
Definition: news_type.h:74
@ NFB_WINDOW_LAYOUT_COUNT
Number of bits for window layout.
Definition: news_type.h:71
Types related to the news widgets.
@ WID_N_DATE
Date of the news item.
Definition: news_widget.h:21
@ WID_N_PANEL
Panel of the window.
Definition: news_widget.h:17
@ WID_N_CLOSEBOX
Close the window.
Definition: news_widget.h:20
@ WID_N_SHOW_GROUP
Show vehicle's group.
Definition: news_widget.h:34
@ WID_N_CAPTION
Title bar of the window. Only used in small news items.
Definition: news_widget.h:22
@ WID_N_HEADLINE
The news headline.
Definition: news_widget.h:19
@ WID_N_INSET
Inset around the viewport in the window. Only used in small news items.
Definition: news_widget.h:23
@ WID_N_VEH_TITLE
Vehicle new title.
Definition: news_widget.h:29
@ WID_N_VEH_INFO
Some technical data of the new vehicle.
Definition: news_widget.h:33
@ WID_N_TITLE
Title of the company news.
Definition: news_widget.h:18
@ WID_N_VIEWPORT
Viewport in the window.
Definition: news_widget.h:24
@ WID_N_MGR_FACE
Face of the manager.
Definition: news_widget.h:27
@ WID_N_MESSAGE
Space for displaying the message. Only used in small news items.
Definition: news_widget.h:26
@ WID_N_VEH_BKGND
Dark background of new vehicle news.
Definition: news_widget.h:30
@ WID_N_VEH_SPR
Graphical display of the new vehicle.
Definition: news_widget.h:32
@ WID_N_VEH_NAME
Name of the new vehicle.
Definition: news_widget.h:31
@ WID_N_COMPANY_MSG
Message in company news items.
Definition: news_widget.h:25
@ WID_N_MGR_NAME
Name of the manager.
Definition: news_widget.h:28
@ WID_MH_SCROLLBAR
Scrollbar for the list.
Definition: news_widget.h:41
@ WID_MH_BACKGROUND
Background of the window.
Definition: news_widget.h:40
static const uint8_t PC_GREY
Grey palette colour.
Definition: palette_func.h:69
static const uint8_t PC_WHITE
White palette colour.
Definition: palette_func.h:70
static const uint8_t PC_BLACK
Black palette colour.
Definition: palette_func.h:67
Road vehicle states.
A number of safeguards to prevent using unsafe methods.
static const SettingDesc * GetSettingFromName(const std::string_view name, const SettingTable &settings)
Given a name of setting, return a setting description from the table.
Definition: settings.cpp:1616
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:56
Functions and types used internally for the settings configurations.
bool ScrollMainWindowTo(int x, int y, int z, bool instant)
Scrolls the main window to given coordinates.
Functions related to sound.
SoundFx
Sound effects from baseset.
Definition: sound_type.h:37
@ SND_1D_APPLAUSE
27 == 0x1B News: first vehicle at station
Definition: sound_type.h:66
@ SND_16_NEWS_TICKER
20 == 0x14 News ticker
Definition: sound_type.h:59
@ SND_1E_NEW_ENGINE
28 == 0x1C News: new engine available
Definition: sound_type.h:67
static const PaletteID PALETTE_NEWSPAPER
Recolour sprite for newspaper-greying.
Definition: sprites.h:1604
Base classes/functions for stations.
bool IsNewsTickerShown()
Checks whether the news ticker is currently being used.
Functions, definitions and such used only by the GUI.
@ SBI_SHOW_REMINDER
show a reminder (dot on the right side of the statusbar)
Definition: statusbar_gui.h:18
@ SBI_SHOW_TICKER
start scrolling news
Definition: statusbar_gui.h:17
@ SBI_NEWS_DELETED
abort current news display (active news were deleted)
Definition: statusbar_gui.h:19
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
Definition: stdafx.h:280
static void StrMakeValid(T &dst, const char *str, const char *last, StringValidationSettings settings)
Copies the valid (UTF-8) characters from str up to last to the dst.
Definition: string.cpp:107
Functions related to low-level strings.
@ SVS_REPLACE_TAB_CR_NL_WITH_SPACE
Replace tabs ('\t'), carriage returns ('\r') and newlines (' ') with spaces.
Definition: string_type.h:54
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings.cpp:104
std::string GetString(StringID string)
Resolve the given StringID into a std::string with all the associated DParam lookups and formatting.
Definition: strings.cpp:319
void CopyOutDParam(std::vector< StringParameterData > &backup, size_t num)
Copy num string parameters from the global string parameter array to the backup.
Definition: strings.cpp:171
void CopyInDParam(const std::span< const StringParameterData > backup)
Copy the parameters from the backup into the global string parameter array.
Definition: strings.cpp:159
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition: strings.cpp:56
void SetDParamStr(size_t n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition: strings.cpp:357
Functions related to OTTD's strings.
@ TD_RTL
Text is written right-to-left by default.
Definition: strings_type.h:24
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Definition: strings_type.h:17
TileIndex xy
Base tile of the station.
VehicleType type
Type of vehicle.
Definition: vehicle_type.h:51
SoundSettings sound
sound effect settings
GUISettings gui
settings related to the GUI
Data that needs to be stored for company news messages.
Definition: news_type.h:153
uint32_t face
The face of the president.
Definition: news_type.h:158
Colours colour
The colour related to the company.
Definition: news_type.h:159
std::string president_name
The name of the president.
Definition: news_type.h:155
Dimensions (a width and height) of a rectangle in 2D.
uint8_t news_message_timeout
how much longer than the news message "age" should we keep the message in the history
TimerGameCalendar::Year coloured_news_year
when does newspaper become coloured?
int32_t Read(const void *object) const
Read the integer from the the actual setting.
Definition: settings.cpp:561
int date_width
< Height of a single line in the news history window including spacing.
Definition: news_gui.cpp:1102
void OnInvalidateData([[maybe_unused]] int data=0, [[maybe_unused]] bool gui_scope=true) override
Some data on this window has become invalid.
Definition: news_gui.cpp:1155
void OnResize() override
Called after the window got resized.
Definition: news_gui.cpp:1175
Scrollbar * vscroll
< Width needed for the date part.
Definition: news_gui.cpp:1104
Partial widget specification to allow NWidgets to be written nested.
Definition: widget_type.h:1075
Container for any custom data that must be deleted after the news item has reached end-of-life.
Definition: news_type.h:122
Information about a single item of news.
Definition: news_type.h:128
TimerGameCalendar::Date date
Calendar date to show for the news.
Definition: news_type.h:130
std::vector< StringParameterData > params
Parameters for string resolving.
Definition: news_type.h:142
NewsType type
Type of the news.
Definition: news_type.h:132
uint32_t ref1
Reference 1 to some object: Used for a possible viewport, scrolling after clicking on the news,...
Definition: news_type.h:137
NewsReferenceType reftype1
Type of ref1.
Definition: news_type.h:135
TimerGameEconomy::Date economy_date
Economy date of the news item, never shown but used to calculate age.
Definition: news_type.h:131
std::unique_ptr< const NewsAllocatedData > data
Custom data for the news item that will be deallocated (deleted) when the news item has reached its e...
Definition: news_type.h:140
uint32_t ref2
Reference 2 to some object: Used for scrolling after clicking on the news, and for deleting the news ...
Definition: news_type.h:138
StringID string_id
Message text.
Definition: news_type.h:129
NewsItem(StringID string_id, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, const NewsAllocatedData *data)
Create a new newsitem to be shown.
Definition: news_gui.cpp:808
NewsFlag flags
NewsFlags bits.
Definition: news_type.h:133
NewsReferenceType reftype2
Type of ref2.
Definition: news_type.h:136
Per-NewsType data.
Definition: news_type.h:100
NewsDisplay GetDisplay() const
Return the news display option.
Definition: news_gui.cpp:274
const char *const name
Name.
Definition: news_type.h:101
const SoundFx sound
Sound.
Definition: news_type.h:103
const uint8_t age
Maximum age of news items (in days)
Definition: news_type.h:102
Window class displaying a news item.
Definition: news_gui.cpp:282
void OnRealtimeTick([[maybe_unused]] uint delta_ms) override
Called periodically.
Definition: news_gui.cpp:569
uint16_t chat_height
Height of the chat window.
Definition: news_gui.cpp:283
void OnResize() override
Called after the window got resized.
Definition: news_gui.cpp:543
static int duration
Remaining time for showing the current news message (may only be access while a news item is displaye...
Definition: news_gui.cpp:286
uint16_t status_height
Height of the status bar window.
Definition: news_gui.cpp:284
const NewsItem * ni
News item to display.
Definition: news_gui.cpp:285
void SetWindowTop(int newtop)
Moves the window to a new top coordinate.
Definition: news_gui.cpp:591
void OnInvalidateData([[maybe_unused]] int data=0, [[maybe_unused]] bool gui_scope=true) override
Some data on this window has become invalid.
Definition: news_gui.cpp:560
IntervalTimer< TimerWindow > scroll_interval
Scroll the news message slowly up from the bottom.
Definition: news_gui.cpp:581
Coordinates of a point in 2D.
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:339
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition: pool_type.hpp:328
constexpr uint Horizontal() const
Get total horizontal padding of RectPadding.
constexpr uint Vertical() const
Get total vertical padding of RectPadding.
Specification of a rectangle with absolute coordinates of all edges.
Rect WithWidth(int width, bool end) const
Copy Rect and set its width.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
Rect Indent(int indent, bool end) const
Copy Rect and indent it from its position.
Rect Expand(int s) const
Copy and expand Rect by s pixels.
Properties of config file settings.
virtual bool IsIntSetting() const
Check whether this setting is an integer type setting.
const struct IntSettingDesc * AsIntSetting() const
Get the setting description of this setting as an integer setting.
Definition: settings.cpp:910
bool news_ticker
Play a ticker sound when a news item is published.
bool news_full
Play sound effects associated to certain news types.
static Station * Get(size_t index)
Gets station with given index.
static bool IsValidID(size_t index)
Tests whether given index is a valid index for station of this type.
static T * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
Vehicle data structure.
Definition: vehicle_base.h:244
int32_t z_pos
z coordinate.
Definition: vehicle_base.h:306
int32_t y_pos
y coordinate.
Definition: vehicle_base.h:305
int32_t x_pos
x coordinate.
Definition: vehicle_base.h:304
int top
Screen coordinate top edge of the viewport.
Definition: viewport_type.h:24
High level window description.
Definition: window_gui.h:159
Data structure for an opened window.
Definition: window_gui.h:273
virtual void Close(int data=0)
Hide the window and all its child windows, and mark them for a later deletion.
Definition: window.cpp:1047
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition: window.cpp:1733
ResizeInfo resize
Resize information.
Definition: window_gui.h:314
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition: window.cpp:1723
ViewportData * viewport
Pointer to viewport data, if present.
Definition: window_gui.h:318
Owner owner
The owner of the content shown in this window. Company colour is acquired from this variable.
Definition: window_gui.h:316
int left
x position of left edge of the window
Definition: window_gui.h:309
int top
y position of top edge of the window
Definition: window_gui.h:310
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition: window.cpp:314
int height
Height of the window (number of pixels down in y direction)
Definition: window_gui.h:312
int width
width of the window (number of pixels to the right in x direction)
Definition: window_gui.h:311
WindowNumber window_number
Window number within the window class.
Definition: window_gui.h:302
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition: tile_map.h:161
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:95
Definition of Interval and OneShot timers.
Definition of the game-calendar-timer.
Definition of the Window system.
Base of the town class.
PaletteID GetEnginePalette(EngineID engine_type, CompanyID company)
Get the colour map for an engine.
Definition: vehicle.cpp:2142
Base class for all vehicles.
Functions related to vehicles.
void ShowVehicleViewWindow(const Vehicle *v)
Shows the vehicle view window of the given vehicle.
Functions related to the vehicle's GUIs.
@ EIT_PREVIEW
Vehicle drawn in preview window, news, ...
Definition: vehicle_type.h:84
@ VEH_ROAD
Road vehicle type.
Definition: vehicle_type.h:25
@ VEH_AIRCRAFT
Aircraft vehicle type.
Definition: vehicle_type.h:27
@ VEH_SHIP
Ship vehicle type.
Definition: vehicle_type.h:26
@ VEH_TRAIN
Train vehicle type.
Definition: vehicle_type.h:24
uint32_t VehicleID
The type all our vehicle IDs have.
Definition: vehicle_type.h:16
bool ScrollWindowToTile(TileIndex tile, Window *w, bool instant)
Scrolls the viewport in a window to a given location.
Definition: viewport.cpp:2504
bool ScrollMainWindowToTile(TileIndex tile, bool instant)
Scrolls the viewport of the main window to a given location.
Definition: viewport.cpp:2515
Functions related to (drawing on) viewports.
void DrawCaption(const Rect &r, Colours colour, Owner owner, TextColour text_colour, StringID str, StringAlignment align, FontSize fs)
Draw a caption bar.
Definition: widget.cpp:679
@ ND_SHADE_GREY
Bit value of the 'shade to grey' flag.
Definition: widget_type.h:356
@ ND_SHADE_DIMMED
Bit value of the 'dimmed colours' flag.
Definition: widget_type.h:357
@ ND_NO_TRANSPARENCY
Bit value of the 'no transparency' flag.
Definition: widget_type.h:355
@ WWT_INSET
Pressed (inset) panel, most commonly used as combo box text area.
Definition: widget_type.h:51
@ WWT_LABEL
Centered label.
Definition: widget_type.h:57
@ NWID_SPACER
Invisible widget that takes some space.
Definition: widget_type.h:79
@ NWID_HORIZONTAL
Horizontal container.
Definition: widget_type.h:75
@ WWT_TEXTBTN
(Toggle) Button with text
Definition: widget_type.h:55
@ WWT_PANEL
Simple depressed panel.
Definition: widget_type.h:50
@ WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition: widget_type.h:66
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition: widget_type.h:64
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition: widget_type.h:61
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition: widget_type.h:84
@ NWID_VERTICAL
Vertical container.
Definition: widget_type.h:77
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition: widget_type.h:69
@ WWT_EMPTY
Empty widget, place holder to reserve space in widget tree.
Definition: widget_type.h:48
@ WWT_RESIZEBOX
Resize box (normally at bottom-right of a window)
Definition: widget_type.h:68
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition: widget_type.h:65
@ NWID_VIEWPORT
Nested widget containing a viewport.
Definition: widget_type.h:81
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition: window.cpp:1140
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition: window.cpp:1098
Window * FindWindowByClass(WindowClass cls)
Find any window by its class.
Definition: window.cpp:1113
int PositionNewsMessage(Window *w)
(Re)position news message window at the screen.
Definition: window.cpp:3404
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:3211
Window functions not directly related to making/drawing windows.
@ WF_DISABLE_VP_SCROLL
Window does not do autoscroll,.
Definition: window_gui.h:235
@ WDP_AUTO
Find a place automatically.
Definition: window_gui.h:147
@ WDP_MANUAL
Manually align the window (so no automatic location finding)
Definition: window_gui.h:146
int WidgetID
Widget ID.
Definition: window_type.h:18
@ WC_NEWS_WINDOW
News window; Window numbers:
Definition: window_type.h:248
@ WC_STATUS_BAR
Statusbar (at the bottom of your screen); Window numbers:
Definition: window_type.h:64
@ WC_SEND_NETWORK_MSG
Chatbox; Window numbers:
Definition: window_type.h:509
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition: window_type.h:45
@ WC_MESSAGE_HISTORY
News history list; Window numbers:
Definition: window_type.h:272
Functions related to zooming.
ZoomLevel ScaleZoomGUI(ZoomLevel value)
Scale zoom level relative to GUI zoom.
Definition: zoom_func.h:87
@ ZOOM_LVL_NEWS
Default zoom level for the news messages.
Definition: zoom_type.h:29