OpenTTD Source  20241108-master-g80f628063a
misc_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 "debug.h"
12 #include "landscape.h"
13 #include "error.h"
14 #include "gui.h"
15 #include "gfx_layout.h"
16 #include "command_func.h"
17 #include "company_func.h"
18 #include "town.h"
19 #include "string_func.h"
20 #include "company_base.h"
21 #include "texteff.hpp"
22 #include "strings_func.h"
23 #include "window_func.h"
24 #include "querystring_gui.h"
25 #include "core/geometry_func.hpp"
26 #include "newgrf_debug.h"
27 #include "zoom_func.h"
28 #include "viewport_func.h"
29 #include "landscape_cmd.h"
30 #include "rev.h"
31 #include "timer/timer.h"
32 #include "timer/timer_window.h"
34 
35 #include "widgets/misc_widget.h"
36 
37 #include "table/strings.h"
38 
39 #include <sstream>
40 #include <iomanip>
41 
42 #include "safeguards.h"
43 
50 };
51 
52 
53 static constexpr NWidgetPart _nested_land_info_widgets[] = {
55  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
56  NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_LAND_AREA_INFORMATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
57  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_LI_LOCATION), SetAspect(WidgetDimensions::ASPECT_LOCATION), SetDataTip(SPR_GOTO_LOCATION, STR_LAND_AREA_INFORMATION_LOCATION_TOOLTIP),
58  NWidget(WWT_DEBUGBOX, COLOUR_GREY),
59  EndContainer(),
61 };
62 
63 static WindowDesc _land_info_desc(
64  WDP_AUTO, nullptr, 0, 0,
66  0,
67  _nested_land_info_widgets
68 );
69 
70 class LandInfoWindow : public Window {
72  std::string cargo_acceptance;
73 
74 public:
75  TileIndex tile;
76 
77  void DrawWidget(const Rect &r, WidgetID widget) const override
78  {
79  if (widget != WID_LI_BACKGROUND) return;
80 
81  Rect ir = r.Shrink(WidgetDimensions::scaled.frametext);
82  for (size_t i = 0; i < this->landinfo_data.size(); i++) {
83  DrawString(ir, this->landinfo_data[i], i == 0 ? TC_LIGHT_BLUE : TC_FROMSTRING, SA_HOR_CENTER);
85  }
86 
87  if (!this->cargo_acceptance.empty()) {
88  SetDParamStr(0, this->cargo_acceptance);
89  DrawStringMultiLine(ir, STR_JUST_RAW_STRING, TC_FROMSTRING, SA_CENTER);
90  }
91  }
92 
93  void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
94  {
95  if (widget != WID_LI_BACKGROUND) return;
96 
98  for (size_t i = 0; i < this->landinfo_data.size(); i++) {
99  uint width = GetStringBoundingBox(this->landinfo_data[i]).width + WidgetDimensions::scaled.frametext.Horizontal();
100  size.width = std::max(size.width, width);
101 
103  }
104 
105  if (!this->cargo_acceptance.empty()) {
106  uint width = GetStringBoundingBox(this->cargo_acceptance).width + WidgetDimensions::scaled.frametext.Horizontal();
107  size.width = std::max(size.width, std::min(static_cast<uint>(ScaleGUITrad(300)), width));
109  size.height += GetStringHeight(STR_JUST_RAW_STRING, size.width - WidgetDimensions::scaled.frametext.Horizontal());
110  }
111  }
112 
113  LandInfoWindow(Tile tile) : Window(_land_info_desc), tile(tile)
114  {
115  this->InitNested();
116 
117 #if defined(_DEBUG)
118 # define LANDINFOD_LEVEL 0
119 #else
120 # define LANDINFOD_LEVEL 1
121 #endif
122  Debug(misc, LANDINFOD_LEVEL, "TILE: {0} (0x{0:x}) ({1},{2})", (TileIndex)tile, TileX(tile), TileY(tile));
123  Debug(misc, LANDINFOD_LEVEL, "type = 0x{:x}", tile.type());
124  Debug(misc, LANDINFOD_LEVEL, "height = 0x{:x}", tile.height());
125  Debug(misc, LANDINFOD_LEVEL, "m1 = 0x{:x}", tile.m1());
126  Debug(misc, LANDINFOD_LEVEL, "m2 = 0x{:x}", tile.m2());
127  Debug(misc, LANDINFOD_LEVEL, "m3 = 0x{:x}", tile.m3());
128  Debug(misc, LANDINFOD_LEVEL, "m4 = 0x{:x}", tile.m4());
129  Debug(misc, LANDINFOD_LEVEL, "m5 = 0x{:x}", tile.m5());
130  Debug(misc, LANDINFOD_LEVEL, "m6 = 0x{:x}", tile.m6());
131  Debug(misc, LANDINFOD_LEVEL, "m7 = 0x{:x}", tile.m7());
132  Debug(misc, LANDINFOD_LEVEL, "m8 = 0x{:x}", tile.m8());
133 
134  PrintWaterRegionDebugInfo(tile);
135 #undef LANDINFOD_LEVEL
136  }
137 
138  void OnInit() override
139  {
141 
142  /* Because build_date is not set yet in every TileDesc, we make sure it is empty */
143  TileDesc td;
144 
146 
147  /* Most tiles have only one owner, but
148  * - drivethrough roadstops can be build on town owned roads (up to 2 owners) and
149  * - roads can have up to four owners (railroad, road, tram, 3rd-roadtype "highway").
150  */
151  td.owner_type[0] = STR_LAND_AREA_INFORMATION_OWNER; // At least one owner is displayed, though it might be "N/A".
152  td.owner_type[1] = STR_NULL; // STR_NULL results in skipping the owner
153  td.owner_type[2] = STR_NULL;
154  td.owner_type[3] = STR_NULL;
155  td.owner[0] = OWNER_NONE;
156  td.owner[1] = OWNER_NONE;
157  td.owner[2] = OWNER_NONE;
158  td.owner[3] = OWNER_NONE;
159 
160  td.station_class = STR_NULL;
161  td.station_name = STR_NULL;
162  td.airport_class = STR_NULL;
163  td.airport_name = STR_NULL;
164  td.airport_tile_name = STR_NULL;
165  td.railtype = STR_NULL;
166  td.rail_speed = 0;
167  td.roadtype = STR_NULL;
168  td.road_speed = 0;
169  td.tramtype = STR_NULL;
170  td.tram_speed = 0;
171 
172  td.grf = nullptr;
173 
174  CargoArray acceptance{};
175  AddAcceptedCargo(tile, acceptance, nullptr);
176  GetTileDesc(tile, &td);
177 
178  this->landinfo_data.clear();
179 
180  /* Tiletype */
181  SetDParam(0, td.dparam);
182  this->landinfo_data.push_back(GetString(td.str));
183 
184  /* Up to four owners */
185  for (uint i = 0; i < 4; i++) {
186  if (td.owner_type[i] == STR_NULL) continue;
187 
188  SetDParam(0, STR_LAND_AREA_INFORMATION_OWNER_N_A);
189  if (td.owner[i] != OWNER_NONE && td.owner[i] != OWNER_WATER) SetDParamsForOwnedBy(td.owner[i], tile);
190  this->landinfo_data.push_back(GetString(td.owner_type[i]));
191  }
192 
193  /* Cost to clear/revenue when cleared */
194  StringID str = STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A;
196  if (c != nullptr) {
197  assert(_current_company == _local_company);
199  if (costclear.Succeeded()) {
200  Money cost = costclear.GetCost();
201  if (cost < 0) {
202  cost = -cost; // Negate negative cost to a positive revenue
203  str = STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED;
204  } else {
205  str = STR_LAND_AREA_INFORMATION_COST_TO_CLEAR;
206  }
207  SetDParam(0, cost);
208  }
209  }
210  this->landinfo_data.push_back(GetString(str));
211 
212  /* Location */
213  SetDParam(0, TileX(tile));
214  SetDParam(1, TileY(tile));
215  SetDParam(2, GetTileZ(tile));
216  this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_LANDINFO_COORDS));
217 
218  /* Tile index */
219  SetDParam(0, tile);
220  SetDParam(1, tile);
221  this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_LANDINFO_INDEX));
222 
223  /* Local authority */
224  SetDParam(0, STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE);
225  if (t != nullptr) {
226  SetDParam(0, STR_TOWN_NAME);
227  SetDParam(1, t->index);
228  }
229  this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY));
230 
231  /* Build date */
233  SetDParam(0, td.build_date);
234  this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_BUILD_DATE));
235  }
236 
237  /* Station class */
238  if (td.station_class != STR_NULL) {
239  SetDParam(0, td.station_class);
240  this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_STATION_CLASS));
241  }
242 
243  /* Station type name */
244  if (td.station_name != STR_NULL) {
245  SetDParam(0, td.station_name);
246  this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_STATION_TYPE));
247  }
248 
249  /* Airport class */
250  if (td.airport_class != STR_NULL) {
251  SetDParam(0, td.airport_class);
252  this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_AIRPORT_CLASS));
253  }
254 
255  /* Airport name */
256  if (td.airport_name != STR_NULL) {
257  SetDParam(0, td.airport_name);
258  this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_AIRPORT_NAME));
259  }
260 
261  /* Airport tile name */
262  if (td.airport_tile_name != STR_NULL) {
264  this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME));
265  }
266 
267  /* Rail type name */
268  if (td.railtype != STR_NULL) {
269  SetDParam(0, td.railtype);
270  this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_RAIL_TYPE));
271  }
272 
273  /* Rail speed limit */
274  if (td.rail_speed != 0) {
276  this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT));
277  }
278 
279  /* Road type name */
280  if (td.roadtype != STR_NULL) {
281  SetDParam(0, td.roadtype);
282  this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_ROAD_TYPE));
283  }
284 
285  /* Road speed limit */
286  if (td.road_speed != 0) {
288  this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT));
289  }
290 
291  /* Tram type name */
292  if (td.tramtype != STR_NULL) {
293  SetDParam(0, td.tramtype);
294  this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_TRAM_TYPE));
295  }
296 
297  /* Tram speed limit */
298  if (td.tram_speed != 0) {
300  this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT));
301  }
302 
303  /* NewGRF name */
304  if (td.grf != nullptr) {
305  SetDParamStr(0, td.grf);
306  this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_NEWGRF_NAME));
307  }
308 
309  /* Cargo acceptance is displayed in a extra multiline */
310  std::stringstream line;
311  line << GetString(STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED);
312 
313  bool found = false;
314  for (const CargoSpec *cs : _sorted_cargo_specs) {
315  CargoID cid = cs->Index();
316  if (acceptance[cid] > 0) {
317  /* Add a comma between each item. */
318  if (found) line << ", ";
319  found = true;
320 
321  /* If the accepted value is less than 8, show it in 1/8:ths */
322  if (acceptance[cid] < 8) {
323  SetDParam(0, acceptance[cid]);
324  SetDParam(1, cs->name);
325  line << GetString(STR_LAND_AREA_INFORMATION_CARGO_EIGHTS);
326  } else {
327  line << GetString(cs->name);
328  }
329  }
330  }
331  if (found) {
332  this->cargo_acceptance = line.str();
333  } else {
334  this->cargo_acceptance.clear();
335  }
336  }
337 
338  bool IsNewGRFInspectable() const override
339  {
340  return ::IsNewGRFInspectable(GetGrfSpecFeature(this->tile), this->tile.base());
341  }
342 
343  void ShowNewGRFInspectWindow() const override
344  {
345  ::ShowNewGRFInspectWindow(GetGrfSpecFeature(this->tile), this->tile.base());
346  }
347 
348  void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
349  {
350  switch (widget) {
351  case WID_LI_LOCATION:
352  if (_ctrl_pressed) {
353  ShowExtraViewportWindow(this->tile);
354  } else {
355  ScrollMainWindowToTile(this->tile);
356  }
357  break;
358  }
359  }
360 
366  void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
367  {
368  if (!gui_scope) return;
369 
370  /* ReInit, "debug" sprite might have changed */
371  if (data == 1) this->ReInit();
372  }
373 };
374 
380 {
382  new LandInfoWindow(tile);
383 }
384 
385 static constexpr NWidgetPart _nested_about_widgets[] = {
387  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
388  NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_ABOUT_OPENTTD, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
389  EndContainer(),
390  NWidget(WWT_PANEL, COLOUR_GREY), SetPIP(4, 2, 4),
391  NWidget(WWT_LABEL, COLOUR_GREY), SetDataTip(STR_ABOUT_ORIGINAL_COPYRIGHT, STR_NULL),
392  NWidget(WWT_LABEL, COLOUR_GREY), SetDataTip(STR_ABOUT_VERSION, STR_NULL),
393  NWidget(WWT_FRAME, COLOUR_GREY), SetPadding(0, 5, 1, 5),
394  NWidget(WWT_EMPTY, INVALID_COLOUR, WID_A_SCROLLING_TEXT),
395  EndContainer(),
396  NWidget(WWT_LABEL, COLOUR_GREY, WID_A_WEBSITE), SetDataTip(STR_JUST_RAW_STRING, STR_NULL),
397  NWidget(WWT_LABEL, COLOUR_GREY, WID_A_COPYRIGHT), SetDataTip(STR_ABOUT_COPYRIGHT_OPENTTD, STR_NULL),
398  EndContainer(),
399 };
400 
401 static WindowDesc _about_desc(
402  WDP_CENTER, nullptr, 0, 0,
404  0,
405  _nested_about_widgets
406 );
407 
408 static const std::initializer_list<const std::string_view> _credits = {
409  "Original design by Chris Sawyer",
410  "Original graphics by Simon Foster",
411  "",
412  "The OpenTTD team (in alphabetical order):",
413  " Matthijs Kooijman (blathijs) - Pathfinder-guru, Debian port (since 0.3)",
414  " Christoph Elsenhans (frosch) - General coding (since 0.6)",
415  " Lo\u00efc Guilloux (glx) - General / Windows Expert (since 0.4.5)",
416  " Koen Bussemaker (Kuhnovic) - General / Ship pathfinder (since 14)",
417  " Charles Pigott (LordAro) - General / Correctness police (since 1.9)",
418  " Michael Lutz (michi_cc) - Path based signals (since 0.7)",
419  " Niels Martin Hansen (nielsm) - Music system, general coding (since 1.9)",
420  " Owen Rudge (orudge) - Forum host, OS/2 port (since 0.1)",
421  " Peter Nelson (peter1138) - Spiritual descendant from NewGRF gods (since 0.4.5)",
422  " Remko Bijker (Rubidium) - Coder and way more (since 0.4.5)",
423  " Patric Stout (TrueBrain) - NoProgrammer (since 0.3), sys op",
424  " Tyler Trahan (2TallTyler) - General / Time Lord (since 13)",
425  "",
426  "Inactive Developers:",
427  " Grzegorz Duczy\u0144ski (adf88) - General coding (1.7 - 1.8)",
428  " Albert Hofkamp (Alberth) - GUI expert (0.7 - 1.9)",
429  " Jean-Fran\u00e7ois Claeys (Belugas) - GUI, NewGRF and more (0.4.5 - 1.0)",
430  " Bjarni Corfitzen (Bjarni) - MacOSX port, coder and vehicles (0.3 - 0.7)",
431  " Victor Fischer (Celestar) - Programming everywhere you need him to (0.3 - 0.6)",
432  " Ulf Hermann (fonsinchen) - Cargo Distribution (1.3 - 1.6)",
433  " Jaroslav Mazanec (KUDr) - YAPG (Yet Another Pathfinder God) ;) (0.4.5 - 0.6)",
434  " Jonathan Coome (Maedhros) - High priest of the NewGRF Temple (0.5 - 0.6)",
435  " Attila B\u00e1n (MiHaMiX) - Developer WebTranslator 1 and 2 (0.3 - 0.5)",
436  " Ingo von Borstel (planetmaker) - General coding, Support (1.1 - 1.9)",
437  " Zden\u011bk Sojka (SmatZ) - Bug finder and fixer (0.6 - 1.3)",
438  " Jos\u00e9 Soler (Terkhen) - General coding (1.0 - 1.4)",
439  " Christoph Mallon (Tron) - Programmer, code correctness police (0.3 - 0.5)",
440  " Thijs Marinussen (Yexo) - AI Framework, General (0.6 - 1.3)",
441  " Leif Linse (Zuu) - AI/Game Script (1.2 - 1.6)",
442  "",
443  "Retired Developers:",
444  " Tam\u00e1s Farag\u00f3 (Darkvater) - Ex-Lead coder (0.3 - 0.5)",
445  " Dominik Scherer (dominik81) - Lead programmer, GUI expert (0.3 - 0.3)",
446  " Emil Djupfeld (egladil) - MacOSX (0.4.5 - 0.6)",
447  " Simon Sasburg (HackyKid) - Many bugfixes (0.4 - 0.4.5)",
448  " Ludvig Strigeus (ludde) - Original author of OpenTTD, main coder (0.1 - 0.3)",
449  " Cian Duffy (MYOB) - BeOS port / manual writing (0.1 - 0.3)",
450  " Petr Baudi\u0161 (pasky) - Many patches, NewGRF support (0.3 - 0.3)",
451  " Benedikt Br\u00fcggemeier (skidd13) - Bug fixer and code reworker (0.6 - 0.7)",
452  " Serge Paquet (vurlix) - 2nd contributor after ludde (0.1 - 0.3)",
453  "",
454  "Special thanks go out to:",
455  " Josef Drexler - For his great work on TTDPatch",
456  " Marcin Grzegorczyk - Track foundations and for describing TTD internals",
457  " Stefan Mei\u00dfner (sign_de) - For his work on the console",
458  " Mike Ragsdale - OpenTTD installer",
459  " Christian Rosentreter (tokai) - MorphOS / AmigaOS port",
460  " Richard Kempton (richK) - additional airports, initial TGP implementation",
461  " Alberto Demichelis - Squirrel scripting language \u00a9 2003-2008",
462  " L. Peter Deutsch - MD5 implementation \u00a9 1999, 2000, 2002",
463  " Michael Blunck - Pre-signals and semaphores \u00a9 2003",
464  " George - Canal/Lock graphics \u00a9 2003-2004",
465  " Andrew Parkhouse (andythenorth) - River graphics",
466  " David Dallaston (Pikka) - Tram tracks",
467  " All Translators - Who made OpenTTD a truly international game",
468  " Bug Reporters - Without whom OpenTTD would still be full of bugs!",
469  "",
470  "",
471  "And last but not least:",
472  " Chris Sawyer - For an amazing game!"
473 };
474 
475 struct AboutWindow : public Window {
478  static const int num_visible_lines = 19;
479 
480  AboutWindow() : Window(_about_desc)
481  {
483 
484  this->text_position = this->GetWidget<NWidgetBase>(WID_A_SCROLLING_TEXT)->pos_y + this->GetWidget<NWidgetBase>(WID_A_SCROLLING_TEXT)->current_y;
485  }
486 
487  void SetStringParameters(WidgetID widget) const override
488  {
489  if (widget == WID_A_WEBSITE) SetDParamStr(0, "Website: https://www.openttd.org");
490  if (widget == WID_A_COPYRIGHT) SetDParamStr(0, _openttd_revision_year);
491  }
492 
493  void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
494  {
495  if (widget != WID_A_SCROLLING_TEXT) return;
496 
497  this->line_height = GetCharacterHeight(FS_NORMAL);
498 
499  Dimension d;
500  d.height = this->line_height * num_visible_lines;
501 
502  d.width = 0;
503  for (const auto &str : _credits) {
504  d.width = std::max(d.width, GetStringBoundingBox(str).width);
505  }
506  size = maxdim(size, d);
507  }
508 
509  void DrawWidget(const Rect &r, WidgetID widget) const override
510  {
511  if (widget != WID_A_SCROLLING_TEXT) return;
512 
513  int y = this->text_position;
514 
515  /* Show all scrolling _credits */
516  for (const auto &str : _credits) {
517  if (y >= r.top + 7 && y < r.bottom - this->line_height) {
518  DrawString(r.left, r.right, y, str, TC_BLACK, SA_LEFT | SA_FORCE);
519  }
520  y += this->line_height;
521  }
522  }
523 
529  IntervalTimer<TimerWindow> scroll_interval = {std::chrono::milliseconds(2100) / GetCharacterHeight(FS_NORMAL), [this](uint count) {
530  this->text_position -= count;
531  /* If the last text has scrolled start a new from the start */
532  if (this->text_position < (int)(this->GetWidget<NWidgetBase>(WID_A_SCROLLING_TEXT)->pos_y - std::size(_credits) * this->line_height)) {
533  this->text_position = this->GetWidget<NWidgetBase>(WID_A_SCROLLING_TEXT)->pos_y + this->GetWidget<NWidgetBase>(WID_A_SCROLLING_TEXT)->current_y;
534  }
536  }};
537 };
538 
539 void ShowAboutWindow()
540 {
542  new AboutWindow();
543 }
544 
551 void ShowEstimatedCostOrIncome(Money cost, int x, int y)
552 {
553  StringID msg = STR_MESSAGE_ESTIMATED_COST;
554 
555  if (cost < 0) {
556  cost = -cost;
557  msg = STR_MESSAGE_ESTIMATED_INCOME;
558  }
559  SetDParam(0, cost);
561 }
562 
570 void ShowCostOrIncomeAnimation(int x, int y, int z, Money cost)
571 {
572  if (cost == 0) {
573  return;
574  }
575  Point pt = RemapCoords(x, y, z);
576  StringID msg = STR_INCOME_FLOAT_COST;
577 
578  if (cost < 0) {
579  cost = -cost;
580  msg = STR_INCOME_FLOAT_INCOME;
581  }
582  SetDParam(0, cost);
583  AddTextEffect(msg, pt.x, pt.y, Ticks::DAY_TICKS, TE_RISING);
584 }
585 
594 void ShowFeederIncomeAnimation(int x, int y, int z, Money transfer, Money income)
595 {
596  Point pt = RemapCoords(x, y, z);
597 
598  SetDParam(0, transfer);
599  if (income == 0) {
600  AddTextEffect(STR_FEEDER, pt.x, pt.y, Ticks::DAY_TICKS, TE_RISING);
601  } else {
602  StringID msg = STR_FEEDER_COST;
603  if (income < 0) {
604  income = -income;
605  msg = STR_FEEDER_INCOME;
606  }
607  SetDParam(1, income);
608  AddTextEffect(msg, pt.x, pt.y, Ticks::DAY_TICKS, TE_RISING);
609  }
610 }
611 
621 TextEffectID ShowFillingPercent(int x, int y, int z, uint8_t percent, StringID string)
622 {
623  Point pt = RemapCoords(x, y, z);
624 
625  assert(string != STR_NULL);
626 
627  SetDParam(0, percent);
628  return AddTextEffect(string, pt.x, pt.y, 0, TE_STATIC);
629 }
630 
636 void UpdateFillingPercent(TextEffectID te_id, uint8_t percent, StringID string)
637 {
638  assert(string != STR_NULL);
639 
640  SetDParam(0, percent);
641  UpdateTextEffect(te_id, string);
642 }
643 
648 void HideFillingPercent(TextEffectID *te_id)
649 {
650  if (*te_id == INVALID_TE_ID) return;
651 
652  RemoveTextEffect(*te_id);
653  *te_id = INVALID_TE_ID;
654 }
655 
656 static constexpr NWidgetPart _nested_tooltips_widgets[] = {
657  NWidget(WWT_EMPTY, INVALID_COLOUR, WID_TT_BACKGROUND),
658 };
659 
660 static WindowDesc _tool_tips_desc(
661  WDP_MANUAL, nullptr, 0, 0, // Coordinates and sizes are not used,
664  _nested_tooltips_widgets
665 );
666 
668 struct TooltipsWindow : public Window
669 {
671  std::vector<StringParameterData> params;
672  TooltipCloseCondition close_cond;
673 
674  TooltipsWindow(Window *parent, StringID str, uint paramcount, TooltipCloseCondition close_tooltip) : Window(_tool_tips_desc)
675  {
676  this->parent = parent;
677  this->string_id = str;
678  CopyOutDParam(this->params, paramcount);
679  this->close_cond = close_tooltip;
680 
681  this->InitNested();
682 
683  CLRBITS(this->flags, WF_WHITE_BORDER);
684  }
685 
686  Point OnInitialPosition([[maybe_unused]] int16_t sm_width, [[maybe_unused]] int16_t sm_height, [[maybe_unused]] int window_number) override
687  {
688  /* Find the free screen space between the main toolbar at the top, and the statusbar at the bottom.
689  * Add a fixed distance 2 so the tooltip floats free from both bars.
690  */
691  int scr_top = GetMainViewTop() + 2;
692  int scr_bot = GetMainViewBottom() - 2;
693 
694  Point pt;
695 
696  /* Correctly position the tooltip position, watch out for window and cursor size
697  * Clamp value to below main toolbar and above statusbar. If tooltip would
698  * go below window, flip it so it is shown above the cursor */
699  pt.y = SoftClamp(_cursor.pos.y + _cursor.total_size.y + _cursor.total_offs.y + 5, scr_top, scr_bot);
700  if (pt.y + sm_height > scr_bot) pt.y = std::min(_cursor.pos.y + _cursor.total_offs.y - 5, scr_bot) - sm_height;
701  pt.x = sm_width >= _screen.width ? 0 : SoftClamp(_cursor.pos.x - (sm_width >> 1), 0, _screen.width - sm_width);
702 
703  return pt;
704  }
705 
706  void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
707  {
708  if (widget != WID_TT_BACKGROUND) return;
709  CopyInDParam(this->params);
710 
711  size.width = std::min<uint>(GetStringBoundingBox(this->string_id).width, ScaleGUITrad(194));
712  size.height = GetStringHeight(this->string_id, size.width);
713 
714  /* Increase slightly to have some space around the box. */
717  }
718 
719  void DrawWidget(const Rect &r, WidgetID widget) const override
720  {
721  if (widget != WID_TT_BACKGROUND) return;
722  GfxFillRect(r, PC_BLACK);
724 
725  CopyInDParam(this->params);
727  }
728 
729  void OnMouseLoop() override
730  {
731  /* Always close tooltips when the cursor is not in our window. */
732  if (!_cursor.in_window) {
733  this->Close();
734  return;
735  }
736 
737  /* We can show tooltips while dragging tools. These are shown as long as
738  * we are dragging the tool. Normal tooltips work with hover or rmb. */
739  switch (this->close_cond) {
740  case TCC_RIGHT_CLICK: if (!_right_button_down) this->Close(); break;
741  case TCC_HOVER: if (!_mouse_hovering) this->Close(); break;
742  case TCC_NONE: break;
743 
744  case TCC_EXIT_VIEWPORT: {
745  Window *w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y);
746  if (w == nullptr || IsPtInWindowViewport(w, _cursor.pos.x, _cursor.pos.y) == nullptr) this->Close();
747  break;
748  }
749  }
750  }
751 };
752 
760 void GuiShowTooltips(Window *parent, StringID str, TooltipCloseCondition close_tooltip, uint paramcount)
761 {
763 
764  if (str == STR_NULL || !_cursor.in_window) return;
765 
766  new TooltipsWindow(parent, str, paramcount, close_tooltip);
767 }
768 
769 void QueryString::HandleEditBox(Window *w, WidgetID wid)
770 {
771  if (w->IsWidgetGloballyFocused(wid) && this->text.HandleCaret()) {
772  w->SetWidgetDirty(wid);
773 
774  /* For the OSK also invalidate the parent window */
775  if (w->window_class == WC_OSK) w->InvalidateData();
776  }
777 }
778 
779 static int GetCaretWidth()
780 {
781  return GetCharacterWidth(FS_NORMAL, '_');
782 }
783 
791 {
792  const int linewidth = tb.pixels + GetCaretWidth();
793  const int boxwidth = r.Width();
794  if (linewidth <= boxwidth) return r;
795 
796  /* Extend to cover whole string. This is left-aligned, adjusted by caret position. */
797  r = r.WithWidth(linewidth, false);
798 
799  /* Slide so that the caret is at the centre unless limited by bounds of the line, i.e. near either end. */
800  return r.Translate(-std::clamp(tb.caretxoffs - (boxwidth / 2), 0, linewidth - boxwidth), 0);
801 }
802 
803 void QueryString::DrawEditBox(const Window *w, WidgetID wid) const
804 {
805  const NWidgetLeaf *wi = w->GetWidget<NWidgetLeaf>(wid);
806 
807  assert((wi->type & WWT_MASK) == WWT_EDITBOX);
808 
809  bool rtl = _current_text_dir == TD_RTL;
810  Dimension sprite_size = GetScaledSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT);
811  int clearbtn_width = sprite_size.width + WidgetDimensions::scaled.imgbtn.Horizontal();
812 
813  Rect r = wi->GetCurrentRect();
814  Rect cr = r.WithWidth(clearbtn_width, !rtl);
815  Rect fr = r.Indent(clearbtn_width, !rtl);
816 
817  DrawFrameRect(cr, wi->colour, wi->IsLowered() ? FR_LOWERED : FR_NONE);
818  DrawSpriteIgnorePadding(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT, PAL_NONE, cr, SA_CENTER);
819  if (this->text.bytes == 1) GfxFillRect(cr.Shrink(WidgetDimensions::scaled.bevel), GetColourGradient(wi->colour, SHADE_DARKER), FILLRECT_CHECKER);
820 
823 
824  fr = fr.Shrink(WidgetDimensions::scaled.framerect);
825  /* Limit the drawing of the string inside the widget boundaries */
826  DrawPixelInfo dpi;
827  if (!FillDrawPixelInfo(&dpi, fr)) return;
828  /* Keep coordinates relative to the window. */
829  dpi.left += fr.left;
830  dpi.top += fr.top;
831 
832  AutoRestoreBackup dpi_backup(_cur_dpi, &dpi);
833 
834  /* We will take the current widget length as maximum width, with a small
835  * space reserved at the end for the caret to show */
836  const Textbuf *tb = &this->text;
837  fr = ScrollEditBoxTextRect(fr, *tb);
838 
839  /* If we have a marked area, draw a background highlight. */
840  if (tb->marklength != 0) GfxFillRect(fr.left + tb->markxoffs, fr.top, fr.left + tb->markxoffs + tb->marklength - 1, fr.bottom, PC_GREY);
841 
842  DrawString(fr.left, fr.right, CenterBounds(fr.top, fr.bottom, GetCharacterHeight(FS_NORMAL)), tb->buf, TC_YELLOW);
843  bool focussed = w->IsWidgetGloballyFocused(wid) || IsOSKOpenedFor(w, wid);
844  if (focussed && tb->caret) {
845  int caret_width = GetCaretWidth();
846  if (rtl) {
847  DrawString(fr.right - tb->pixels + tb->caretxoffs - caret_width, fr.right - tb->pixels + tb->caretxoffs, CenterBounds(fr.top, fr.bottom, GetCharacterHeight(FS_NORMAL)), "_", TC_WHITE);
848  } else {
849  DrawString(fr.left + tb->caretxoffs, fr.left + tb->caretxoffs + caret_width, CenterBounds(fr.top, fr.bottom, GetCharacterHeight(FS_NORMAL)), "_", TC_WHITE);
850  }
851  }
852 }
853 
861 {
862  const NWidgetLeaf *wi = w->GetWidget<NWidgetLeaf>(wid);
863 
864  assert((wi->type & WWT_MASK) == WWT_EDITBOX);
865 
866  bool rtl = _current_text_dir == TD_RTL;
867  Dimension sprite_size = GetScaledSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT);
868  int clearbtn_width = sprite_size.width + WidgetDimensions::scaled.imgbtn.Horizontal();
869 
870  Rect r = wi->GetCurrentRect().Indent(clearbtn_width, !rtl).Shrink(WidgetDimensions::scaled.framerect);
871 
872  /* Clamp caret position to be inside out current width. */
873  const Textbuf *tb = &this->text;
874  r = ScrollEditBoxTextRect(r, *tb);
875 
876  Point pt = {r.left + tb->caretxoffs, r.top};
877  return pt;
878 }
879 
888 Rect QueryString::GetBoundingRect(const Window *w, WidgetID wid, const char *from, const char *to) const
889 {
890  const NWidgetLeaf *wi = w->GetWidget<NWidgetLeaf>(wid);
891 
892  assert((wi->type & WWT_MASK) == WWT_EDITBOX);
893 
894  bool rtl = _current_text_dir == TD_RTL;
895  Dimension sprite_size = GetScaledSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT);
896  int clearbtn_width = sprite_size.width + WidgetDimensions::scaled.imgbtn.Horizontal();
897 
898  Rect r = wi->GetCurrentRect().Indent(clearbtn_width, !rtl).Shrink(WidgetDimensions::scaled.framerect);
899 
900  /* Clamp caret position to be inside our current width. */
901  const Textbuf *tb = &this->text;
902  r = ScrollEditBoxTextRect(r, *tb);
903 
904  /* Get location of first and last character. */
905  const auto p1 = GetCharPosInString(tb->buf, from, FS_NORMAL);
906  const auto p2 = from != to ? GetCharPosInString(tb->buf, to, FS_NORMAL) : p1;
907 
908  return { Clamp(r.left + p1.left, r.left, r.right), r.top, Clamp(r.left + p2.right, r.left, r.right), r.bottom };
909 }
910 
918 ptrdiff_t QueryString::GetCharAtPosition(const Window *w, WidgetID wid, const Point &pt) const
919 {
920  const NWidgetLeaf *wi = w->GetWidget<NWidgetLeaf>(wid);
921 
922  assert((wi->type & WWT_MASK) == WWT_EDITBOX);
923 
924  bool rtl = _current_text_dir == TD_RTL;
925  Dimension sprite_size = GetScaledSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT);
926  int clearbtn_width = sprite_size.width + WidgetDimensions::scaled.imgbtn.Horizontal();
927 
928  Rect r = wi->GetCurrentRect().Indent(clearbtn_width, !rtl).Shrink(WidgetDimensions::scaled.framerect);
929 
930  if (!IsInsideMM(pt.y, r.top, r.bottom)) return -1;
931 
932  /* Clamp caret position to be inside our current width. */
933  const Textbuf *tb = &this->text;
934  r = ScrollEditBoxTextRect(r, *tb);
935 
936  return ::GetCharAtPosition(tb->buf, pt.x - r.left);
937 }
938 
939 void QueryString::ClickEditBox(Window *w, Point pt, WidgetID wid, int click_count, bool focus_changed)
940 {
941  const NWidgetLeaf *wi = w->GetWidget<NWidgetLeaf>(wid);
942 
943  assert((wi->type & WWT_MASK) == WWT_EDITBOX);
944 
945  bool rtl = _current_text_dir == TD_RTL;
946  Dimension sprite_size = GetScaledSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT);
947  int clearbtn_width = sprite_size.width + WidgetDimensions::scaled.imgbtn.Horizontal();
948 
949  Rect cr = wi->GetCurrentRect().WithWidth(clearbtn_width, !rtl);
950 
951  if (IsInsideMM(pt.x, cr.left, cr.right)) {
952  if (this->text.bytes > 1) {
953  this->text.DeleteAll();
954  w->HandleButtonClick(wid);
955  w->OnEditboxChanged(wid);
956  }
957  return;
958  }
959 
961  (!focus_changed || _settings_client.gui.osk_activation == OSKA_IMMEDIATELY) &&
962  (click_count == 2 || _settings_client.gui.osk_activation != OSKA_DOUBLE_CLICK)) {
963  /* Open the OSK window */
964  ShowOnScreenKeyboard(w, wid);
965  }
966 }
967 
969 struct QueryStringWindow : public Window
970 {
973 
974  QueryStringWindow(StringID str, StringID caption, uint max_bytes, uint max_chars, WindowDesc &desc, Window *parent, CharSetFilter afilter, QueryStringFlags flags) :
975  Window(desc), editbox(max_bytes, max_chars)
976  {
977  this->editbox.text.Assign(str);
978 
979  if ((flags & QSF_ACCEPT_UNCHANGED) == 0) this->editbox.orig = this->editbox.text.buf;
980 
981  this->querystrings[WID_QS_TEXT] = &this->editbox;
982  this->editbox.caption = caption;
983  this->editbox.cancel_button = WID_QS_CANCEL;
984  this->editbox.ok_button = WID_QS_OK;
985  this->editbox.text.afilter = afilter;
986  this->flags = flags;
987 
989 
990  this->parent = parent;
991 
993  }
994 
995  void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
996  {
997  if (widget == WID_QS_DEFAULT && (this->flags & QSF_ENABLE_DEFAULT) == 0) {
998  /* We don't want this widget to show! */
999  fill.width = 0;
1000  resize.width = 0;
1001  size.width = 0;
1002  }
1003  }
1004 
1005  void SetStringParameters(WidgetID widget) const override
1006  {
1007  if (widget == WID_QS_CAPTION) SetDParam(0, this->editbox.caption);
1008  }
1009 
1010  void OnOk()
1011  {
1012  if (!this->editbox.orig.has_value() || this->editbox.text.buf != this->editbox.orig) {
1013  assert(this->parent != nullptr);
1014 
1015  this->parent->OnQueryTextFinished(this->editbox.text.buf);
1016  this->editbox.handled = true;
1017  }
1018  }
1019 
1020  void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1021  {
1022  switch (widget) {
1023  case WID_QS_DEFAULT:
1024  this->editbox.text.DeleteAll();
1025  [[fallthrough]];
1026 
1027  case WID_QS_OK:
1028  this->OnOk();
1029  [[fallthrough]];
1030 
1031  case WID_QS_CANCEL:
1032  this->Close();
1033  break;
1034  }
1035  }
1036 
1037  void Close([[maybe_unused]] int data = 0) override
1038  {
1039  if (!this->editbox.handled && this->parent != nullptr) {
1040  Window *parent = this->parent;
1041  this->parent = nullptr; // so parent doesn't try to close us again
1042  parent->OnQueryTextFinished(std::nullopt);
1043  }
1044  this->Window::Close();
1045  }
1046 };
1047 
1048 static constexpr NWidgetPart _nested_query_string_widgets[] = {
1050  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1051  NWidget(WWT_CAPTION, COLOUR_GREY, WID_QS_CAPTION), SetDataTip(STR_JUST_STRING, STR_NULL), SetTextStyle(TC_WHITE),
1052  EndContainer(),
1053  NWidget(WWT_PANEL, COLOUR_GREY),
1054  NWidget(WWT_EDITBOX, COLOUR_GREY, WID_QS_TEXT), SetMinimalSize(256, 0), SetFill(1, 0), SetPadding(2, 2, 2, 2),
1055  EndContainer(),
1057  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_QS_DEFAULT), SetMinimalSize(87, 12), SetFill(1, 1), SetDataTip(STR_BUTTON_DEFAULT, STR_NULL),
1058  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_QS_CANCEL), SetMinimalSize(86, 12), SetFill(1, 1), SetDataTip(STR_BUTTON_CANCEL, STR_NULL),
1059  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_QS_OK), SetMinimalSize(87, 12), SetFill(1, 1), SetDataTip(STR_BUTTON_OK, STR_NULL),
1060  EndContainer(),
1061 };
1062 
1063 static WindowDesc _query_string_desc(
1064  WDP_CENTER, nullptr, 0, 0,
1066  0,
1067  _nested_query_string_widgets
1068 );
1069 
1079 void ShowQueryString(StringID str, StringID caption, uint maxsize, Window *parent, CharSetFilter afilter, QueryStringFlags flags)
1080 {
1081  assert(parent != nullptr);
1082 
1084  new QueryStringWindow(str, caption, ((flags & QSF_LEN_IN_CHARS) ? MAX_CHAR_LENGTH : 1) * maxsize, maxsize, _query_string_desc, parent, afilter, flags);
1085 }
1086 
1090 struct QueryWindow : public Window {
1092  std::vector<StringParameterData> params;
1094 
1095  QueryWindow(WindowDesc &desc, StringID caption, StringID message, Window *parent, QueryCallbackProc *callback) : Window(desc)
1096  {
1097  /* Create a backup of the variadic arguments to strings because it will be
1098  * overridden pretty often. We will copy these back for drawing */
1099  CopyOutDParam(this->params, 10);
1100  this->message = message;
1101  this->proc = callback;
1102  this->parent = parent;
1103 
1104  this->CreateNestedTree();
1105  this->GetWidget<NWidgetCore>(WID_Q_CAPTION)->SetDataTip(caption, STR_NULL);
1107  }
1108 
1109  void Close([[maybe_unused]] int data = 0) override
1110  {
1111  if (this->proc != nullptr) this->proc(this->parent, false);
1112  this->Window::Close();
1113  }
1114 
1115  void FindWindowPlacementAndResize([[maybe_unused]] int def_width, [[maybe_unused]] int def_height) override
1116  {
1117  /* Position query window over the calling window, ensuring it's within screen bounds. */
1118  this->left = SoftClamp(parent->left + (parent->width / 2) - (this->width / 2), 0, _screen.width - this->width);
1119  this->top = SoftClamp(parent->top + (parent->height / 2) - (this->height / 2), 0, _screen.height - this->height);
1120  this->SetDirty();
1121  }
1122 
1123  void SetStringParameters(WidgetID widget) const override
1124  {
1125  switch (widget) {
1126  case WID_Q_CAPTION:
1127  case WID_Q_TEXT:
1128  CopyInDParam(this->params);
1129  break;
1130  }
1131  }
1132 
1133  void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
1134  {
1135  if (widget != WID_Q_TEXT) return;
1136 
1137  size = GetStringMultiLineBoundingBox(this->message, size);
1138  }
1139 
1140  void DrawWidget(const Rect &r, WidgetID widget) const override
1141  {
1142  if (widget != WID_Q_TEXT) return;
1143 
1144  DrawStringMultiLine(r, this->message, TC_FROMSTRING, SA_CENTER);
1145  }
1146 
1147  void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1148  {
1149  switch (widget) {
1150  case WID_Q_YES: {
1151  /* in the Generate New World window, clicking 'Yes' causes
1152  * CloseNonVitalWindows() to be called - we shouldn't be in a window then */
1153  QueryCallbackProc *proc = this->proc;
1154  Window *parent = this->parent;
1155  /* Prevent the destructor calling the callback function */
1156  this->proc = nullptr;
1157  this->Close();
1158  if (proc != nullptr) {
1159  proc(parent, true);
1160  proc = nullptr;
1161  }
1162  break;
1163  }
1164  case WID_Q_NO:
1165  this->Close();
1166  break;
1167  }
1168  }
1169 
1170  EventState OnKeyPress([[maybe_unused]] char32_t key, uint16_t keycode) override
1171  {
1172  /* ESC closes the window, Enter confirms the action */
1173  switch (keycode) {
1174  case WKC_RETURN:
1175  case WKC_NUM_ENTER:
1176  if (this->proc != nullptr) {
1177  this->proc(this->parent, true);
1178  this->proc = nullptr;
1179  }
1180  [[fallthrough]];
1181 
1182  case WKC_ESC:
1183  this->Close();
1184  return ES_HANDLED;
1185  }
1186  return ES_NOT_HANDLED;
1187  }
1188 };
1189 
1190 static constexpr NWidgetPart _nested_query_widgets[] = {
1192  NWidget(WWT_CLOSEBOX, COLOUR_RED),
1193  NWidget(WWT_CAPTION, COLOUR_RED, WID_Q_CAPTION), // The caption's string is set in the constructor
1194  EndContainer(),
1195  NWidget(WWT_PANEL, COLOUR_RED),
1197  NWidget(WWT_TEXT, COLOUR_RED, WID_Q_TEXT), SetMinimalSize(200, 12),
1199  NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_Q_NO), SetMinimalSize(71, 12), SetFill(1, 1), SetDataTip(STR_QUIT_NO, STR_NULL),
1200  NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_Q_YES), SetMinimalSize(71, 12), SetFill(1, 1), SetDataTip(STR_QUIT_YES, STR_NULL),
1201  EndContainer(),
1202  EndContainer(),
1203  EndContainer(),
1204 };
1205 
1206 static WindowDesc _query_desc(
1207  WDP_CENTER, nullptr, 0, 0,
1209  WDF_MODAL,
1210  _nested_query_widgets
1211 );
1212 
1223 void ShowQuery(StringID caption, StringID message, Window *parent, QueryCallbackProc *callback, bool focus)
1224 {
1225  if (parent == nullptr) parent = GetMainWindow();
1226 
1227  for (Window *w : Window::Iterate()) {
1228  if (w->window_class != WC_CONFIRM_POPUP_QUERY) continue;
1229 
1230  QueryWindow *qw = dynamic_cast<QueryWindow *>(w);
1231  if (qw->parent != parent || qw->proc != callback) continue;
1232 
1233  qw->Close();
1234  break;
1235  }
1236 
1237  QueryWindow *q = new QueryWindow(_query_desc, caption, message, parent, callback);
1238  if (focus) SetFocusedWindow(q);
1239 }
#define CLRBITS(x, y)
Clears several bits in a variable.
uint8_t CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:22
std::vector< const CargoSpec * > _sorted_cargo_specs
Cargo specifications sorted alphabetically by name.
Definition: cargotype.cpp:180
Common return value for all commands.
Definition: command_type.h:23
bool Succeeded() const
Did this command succeed?
Definition: command_type.h:162
Money GetCost() const
The costs as made up to this moment.
Definition: command_type.h:83
StringList landinfo_data
Info lines to show.
Definition: misc_gui.cpp:71
std::string cargo_acceptance
Centered multi-line string for cargo acceptance.
Definition: misc_gui.cpp:72
bool IsNewGRFInspectable() const override
Is the data related to this window NewGRF inspectable?
Definition: misc_gui.cpp:338
void OnInvalidateData([[maybe_unused]] int data=0, [[maybe_unused]] bool gui_scope=true) override
Some data on this window has become invalid.
Definition: misc_gui.cpp:366
void OnInit() override
Notification that the nested widget tree gets initialized.
Definition: misc_gui.cpp:138
void ShowNewGRFInspectWindow() const override
Show the NewGRF inspection window.
Definition: misc_gui.cpp:343
WidgetType type
Type of the widget / nested widget.
Definition: widget_type.h:232
Colours colour
Colour of this widget.
Definition: widget_type.h:391
bool IsLowered() const
Return whether the widget is lowered.
Definition: widget_type.h:434
Leaf widget.
Definition: widget_type.h:916
static constexpr TimerGameTick::Ticks DAY_TICKS
1 day is 74 ticks; TimerGameCalendar::date_fract used to be uint16_t and incremented by 885.
Wrapper class to abstract away the way the tiles are stored.
Definition: map_func.h:25
static constexpr TimerGame< struct Calendar >::Date INVALID_DATE
Representation of an invalid date.
RectPadding framerect
Standard padding inside many panels.
Definition: window_gui.h:42
RectPadding frametext
Padding inside frame with text.
Definition: window_gui.h:43
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition: window_gui.h:68
RectPadding imgbtn
Padding around image button image.
Definition: window_gui.h:36
int vsep_normal
Normal vertical spacing.
Definition: window_gui.h:60
int vsep_wide
Wide vertical spacing.
Definition: window_gui.h:62
RectPadding fullbevel
Always-scaled bevel thickness.
Definition: window_gui.h:41
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition: window_gui.h:67
RectPadding bevel
Bevel thickness, affected by "scaled bevels" game option.
Definition: window_gui.h:40
Functions related to commands.
@ DC_QUERY_COST
query cost only, don't build.
Definition: command_type.h:378
Definition of stuff that is very close to a company, like the company struct itself.
void SetDParamsForOwnedBy(Owner owner, TileIndex tile)
Set the right DParams for STR_ERROR_OWNED_BY.
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.
@ OWNER_NONE
The tile has no ownership.
Definition: company_type.h:25
@ OWNER_WATER
The tile/execution is done by "water".
Definition: company_type.h:26
Functions related to debugging.
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition: debug.h:37
Functions related to errors.
void ShowErrorMessage(StringID summary_msg, int x, int y, CommandCost cc)
Display an error message in a window.
Definition: error_gui.cpp:367
@ WL_INFO
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
Definition: error.h:24
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.
int GetStringHeight(std::string_view str, int maxw, FontSize fontsize)
Calculates height of string (in pixels).
Definition: gfx.cpp:704
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
uint8_t GetCharacterWidth(FontSize size, char32_t key)
Return width of character glyph.
Definition: gfx.cpp:1227
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
bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int height)
Set up a clipping area for only drawing into a certain area.
Definition: gfx.cpp:1548
bool _right_button_down
Is right mouse button pressed?
Definition: gfx.cpp:43
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
ptrdiff_t GetCharAtPosition(std::string_view str, int x, FontSize start_fontsize)
Get the character from a string that is drawn at a specific position.
Definition: gfx_layout.cpp:438
ParagraphLayouter::Position GetCharPosInString(std::string_view str, const char *ch, FontSize start_fontsize)
Get the leading corner of a character in a single-line string relative to the start of the string.
Definition: gfx_layout.cpp:421
Functions related to laying out the texts.
@ SA_LEFT
Left align the text.
Definition: gfx_type.h:343
@ SA_HOR_CENTER
Horizontally center the text.
Definition: gfx_type.h:344
@ SA_FORCE
Force the alignment, i.e. don't swap for RTL languages.
Definition: gfx_type.h:355
@ SA_CENTER
Center both horizontally and vertically.
Definition: gfx_type.h:353
@ FS_NORMAL
Index of the normal font in the font tables.
Definition: gfx_type.h:209
@ FILLRECT_CHECKER
Draw only every second pixel, used for greying-out.
Definition: gfx_type.h:299
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
Definition: widget_type.h:1181
constexpr NWidgetPart SetPIP(uint8_t pre, uint8_t inter, uint8_t post)
Widget part function for setting a pre/inter/post spaces.
Definition: widget_type.h:1260
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
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition: window.cpp:940
GUI functions that shouldn't be here.
void ShowExtraViewportWindow(TileIndex tile=INVALID_TILE)
Show a new Extra Viewport window.
Functions related to OTTD's landscape.
Point RemapCoords(int x, int y, int z)
Map 3D world or tile coordinate to equivalent 2D coordinate as used in the viewports and smallmap.
Definition: landscape.h:79
Command definitions related to landscape (slopes etc.).
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:425
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:415
constexpr T SoftClamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:102
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:79
constexpr bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
Definition: math_func.hpp:268
void HideFillingPercent(TextEffectID *te_id)
Hide vehicle loading indicators.
Definition: misc_gui.cpp:648
OskActivation
Method to open the OSK.
Definition: misc_gui.cpp:45
@ OSKA_SINGLE_CLICK
Single click after focus click opens OSK.
Definition: misc_gui.cpp:48
@ OSKA_IMMEDIATELY
Focusing click already opens OSK.
Definition: misc_gui.cpp:49
@ OSKA_DISABLED
The OSK shall not be activated at all.
Definition: misc_gui.cpp:46
@ OSKA_DOUBLE_CLICK
Double click on the edit box opens OSK.
Definition: misc_gui.cpp:47
void ShowCostOrIncomeAnimation(int x, int y, int z, Money cost)
Display animated income or costs on the map.
Definition: misc_gui.cpp:570
void GuiShowTooltips(Window *parent, StringID str, TooltipCloseCondition close_tooltip, uint paramcount)
Shows a tooltip.
Definition: misc_gui.cpp:760
void ShowEstimatedCostOrIncome(Money cost, int x, int y)
Display estimated costs.
Definition: misc_gui.cpp:551
void ShowLandInfo(TileIndex tile)
Show land information window.
Definition: misc_gui.cpp:379
void ShowFeederIncomeAnimation(int x, int y, int z, Money transfer, Money income)
Display animated feeder income.
Definition: misc_gui.cpp:594
void UpdateFillingPercent(TextEffectID te_id, uint8_t percent, StringID string)
Update vehicle loading indicators.
Definition: misc_gui.cpp:636
TextEffectID ShowFillingPercent(int x, int y, int z, uint8_t percent, StringID string)
Display vehicle loading indicators.
Definition: misc_gui.cpp:621
void ShowQuery(StringID caption, StringID message, Window *parent, QueryCallbackProc *callback, bool focus)
Show a confirmation window with standard 'yes' and 'no' buttons The window is aligned to the centre o...
Definition: misc_gui.cpp:1223
static Rect ScrollEditBoxTextRect(Rect r, const Textbuf &tb)
Reposition edit text box rect based on textbuf length can caret position.
Definition: misc_gui.cpp:790
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:1079
Types related to the misc widgets.
@ WID_TT_BACKGROUND
Background of the window.
Definition: misc_widget.h:21
@ WID_QS_DEFAULT
Default button.
Definition: misc_widget.h:35
@ WID_QS_CAPTION
Caption of the window.
Definition: misc_widget.h:33
@ WID_QS_TEXT
Text of the query.
Definition: misc_widget.h:34
@ WID_QS_CANCEL
Cancel button.
Definition: misc_widget.h:36
@ WID_QS_OK
OK button.
Definition: misc_widget.h:37
@ WID_A_WEBSITE
URL of OpenTTD website.
Definition: misc_widget.h:27
@ WID_A_COPYRIGHT
Copyright string.
Definition: misc_widget.h:28
@ WID_A_SCROLLING_TEXT
The actually scrolling text.
Definition: misc_widget.h:26
@ WID_Q_NO
Yes button.
Definition: misc_widget.h:44
@ WID_Q_YES
No button.
Definition: misc_widget.h:45
@ WID_Q_CAPTION
Caption of the window.
Definition: misc_widget.h:42
@ WID_Q_TEXT
Text of the query.
Definition: misc_widget.h:43
@ WID_LI_BACKGROUND
Background of the window.
Definition: misc_widget.h:16
@ WID_LI_LOCATION
Scroll to location.
Definition: misc_widget.h:15
Functions/types related to NewGRF debugging.
GrfSpecFeature GetGrfSpecFeature(TileIndex tile)
Get the GrfSpecFeature associated with the tile.
bool IsNewGRFInspectable(GrfSpecFeature feature, uint index)
Can we inspect the data given a certain feature and index.
void ShowOnScreenKeyboard(Window *parent, WidgetID button)
Show the on-screen keyboard (osk) associated with a given textbox.
Definition: osk_gui.cpp:395
bool IsOSKOpenedFor(const Window *w, WidgetID button)
Check whether the OSK is opened for a specific editbox.
Definition: osk_gui.cpp:426
uint8_t GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
Definition: palette.cpp:314
static const uint8_t PC_LIGHT_YELLOW
Light yellow palette colour.
Definition: palette_func.h:81
static const uint8_t PC_GREY
Grey palette colour.
Definition: palette_func.h:69
static const uint8_t PC_BLACK
Black palette colour.
Definition: palette_func.h:67
Base for the GUIs that have an edit box in them.
declaration of OTTD revision dependent variables
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:57
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:56
Definition of base types and functions in a cross-platform compatible way.
Functions related to low-level strings.
CharSetFilter
Valid filter types for IsValidChar.
Definition: string_type.h:24
std::vector< std::string > StringList
Type for a list of strings.
Definition: string_type.h:60
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.
int64_t PackVelocity(uint speed, VehicleType type)
Pack velocity and vehicle type for use with SCC_VELOCITY string parameter.
Definition: strings_func.h:75
@ 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
static const int MAX_CHAR_LENGTH
Max. length of UTF-8 encoded unicode character.
Definition: strings_type.h:18
IntervalTimer< TimerWindow > scroll_interval
Scroll the text in the about window slow.
Definition: misc_gui.cpp:529
int text_position
The top of the scrolling text.
Definition: misc_gui.cpp:476
static const int num_visible_lines
The number of lines visible simultaneously.
Definition: misc_gui.cpp:478
int line_height
The height of a single line.
Definition: misc_gui.cpp:477
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
Class for storing amounts of cargo.
Definition: cargo_type.h:114
Specification of a cargo type.
Definition: cargotype.h:71
GUISettings gui
settings related to the GUI
Point pos
logical mouse position
Definition: gfx_type.h:125
bool in_window
mouse inside this window, determines drawing logic
Definition: gfx_type.h:147
Point total_size
union of sprite properties
Definition: gfx_type.h:137
Dimensions (a width and height) of a rectangle in 2D.
Data about how and where to blit pixels.
Definition: gfx_type.h:157
uint8_t dist_local_authority
distance for town local authority, default 20
uint8_t osk_activation
Mouse gesture to trigger the OSK.
EconomySettings economy
settings to change the economy
Partial widget specification to allow NWidgets to be written nested.
Definition: widget_type.h:1075
Coordinates of a point in 2D.
Tindex index
Index of this pool item.
Definition: pool_type.hpp:238
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:350
Class for the string query window.
Definition: misc_gui.cpp:970
QueryString editbox
Editbox.
Definition: misc_gui.cpp:971
QueryStringFlags flags
Flags controlling behaviour of the window.
Definition: misc_gui.cpp:972
Data stored about a string that can be modified in the GUI.
int ok_button
Widget button of parent window to simulate when pressing OK in OSK.
int cancel_button
Widget button of parent window to simulate when pressing CANCEL in OSK.
ptrdiff_t GetCharAtPosition(const Window *w, WidgetID wid, const Point &pt) const
Get the character that is rendered at a position.
Definition: misc_gui.cpp:918
Rect GetBoundingRect(const Window *w, WidgetID wid, const char *from, const char *to) const
Get the bounding rectangle for a range of the query string.
Definition: misc_gui.cpp:888
Point GetCaretPosition(const Window *w, WidgetID wid) const
Get the current caret position.
Definition: misc_gui.cpp:860
Window used for asking the user a YES/NO question.
Definition: misc_gui.cpp:1090
QueryCallbackProc * proc
callback function executed on closing of popup. Window* points to parent, bool is true if 'yes' click...
Definition: misc_gui.cpp:1091
StringID message
message shown for query window
Definition: misc_gui.cpp:1093
std::vector< StringParameterData > params
local copy of #_global_string_params
Definition: misc_gui.cpp:1092
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.
int Width() const
Get width of Rect.
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 Translate(int x, int y) const
Copy and translate Rect by x,y pixels.
Helper/buffer for input fields.
Definition: textbuf_type.h:30
uint16_t pixels
the current size of the string in pixels
Definition: textbuf_type.h:37
uint16_t markxoffs
the start position of the marked area in pixels
Definition: textbuf_type.h:43
void DeleteAll()
Delete every character in the textbuffer.
Definition: textbuf.cpp:114
void Assign(StringID string)
Render a string into the textbuffer.
Definition: textbuf.cpp:431
uint16_t bytes
the current size of the string in bytes (including terminating '\0')
Definition: textbuf_type.h:35
uint16_t caretxoffs
the current position of the caret in pixels
Definition: textbuf_type.h:40
uint16_t marklength
the length of the marked area in pixels
Definition: textbuf_type.h:44
bool caret
is the caret ("_") visible or not
Definition: textbuf_type.h:38
CharSetFilter afilter
Allowed characters.
Definition: textbuf_type.h:31
char *const buf
buffer in which text is saved
Definition: textbuf_type.h:32
Tile description for the 'land area information' tool.
Definition: tile_cmd.h:52
uint16_t rail_speed
Speed limit of rail (bridges and track)
Definition: tile_cmd.h:65
StringID station_name
Type of station within the class.
Definition: tile_cmd.h:59
StringID str
Description of the tile.
Definition: tile_cmd.h:53
TimerGameCalendar::Date build_date
Date of construction of tile contents.
Definition: tile_cmd.h:57
uint64_t dparam
Parameter of the str string.
Definition: tile_cmd.h:54
StringID airport_class
Name of the airport class.
Definition: tile_cmd.h:60
StringID airport_name
Name of the airport.
Definition: tile_cmd.h:61
uint16_t tram_speed
Speed limit of tram (bridges and track)
Definition: tile_cmd.h:69
StringID roadtype
Type of road on the tile.
Definition: tile_cmd.h:66
StringID tramtype
Type of tram on the tile.
Definition: tile_cmd.h:68
StringID railtype
Type of rail on the tile.
Definition: tile_cmd.h:64
uint16_t road_speed
Speed limit of road (bridges and track)
Definition: tile_cmd.h:67
const char * grf
newGRF used for the tile contents
Definition: tile_cmd.h:63
StringID airport_tile_name
Name of the airport tile.
Definition: tile_cmd.h:62
Owner owner[4]
Name of the owner(s)
Definition: tile_cmd.h:55
StringID owner_type[4]
Type of each owner.
Definition: tile_cmd.h:56
StringID station_class
Class of station.
Definition: tile_cmd.h:58
Window for displaying a tooltip.
Definition: misc_gui.cpp:669
TooltipCloseCondition close_cond
Condition for closing the window.
Definition: misc_gui.cpp:672
std::vector< StringParameterData > params
The string parameters.
Definition: misc_gui.cpp:671
StringID string_id
String to display as tooltip.
Definition: misc_gui.cpp:670
void OnMouseLoop() override
Called for every mouse loop run, which is at least once per (game) tick.
Definition: misc_gui.cpp:729
Town data structure.
Definition: town.h:54
High level window description.
Definition: window_gui.h:159
Iterable ensemble of all valid Windows.
Definition: window_gui.h:913
Data structure for an opened window.
Definition: window_gui.h:273
void ReInit(int rx=0, int ry=0, bool reposition=false)
Re-initialize a window, and optionally change its size.
Definition: window.cpp:952
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
bool IsWidgetGloballyFocused(WidgetID widget_index) const
Check if given widget has user input focus.
Definition: window_gui.h:437
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition: window.cpp:1733
std::map< WidgetID, QueryString * > querystrings
QueryString associated to WWT_EDITBOX widgets.
Definition: window_gui.h:320
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing)
Definition: window.cpp:3151
Window * parent
Parent window.
Definition: window_gui.h:328
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition: window.cpp:551
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
WindowClass window_class
Window class.
Definition: window_gui.h:301
bool SetFocusedWidget(WidgetID widget_index)
Set focus within this window to the given widget.
Definition: window.cpp:486
virtual void OnQueryTextFinished([[maybe_unused]] std::optional< std::string > str)
The query window opened from this window has closed.
Definition: window_gui.h:779
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 NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition: window_gui.h:977
virtual void OnEditboxChanged([[maybe_unused]] WidgetID widget)
The text in an editbox has been edited.
Definition: window_gui.h:771
void HandleButtonClick(WidgetID widget)
Do all things to make a button look clicked and mark it to be unclicked in a few ticks.
Definition: window.cpp:590
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition: window.cpp:1746
WindowFlags flags
Window flags.
Definition: window_gui.h:300
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
void QueryCallbackProc(Window *, bool)
Callback procedure for the ShowQuery method.
Definition: textbuf_gui.h:28
QueryStringFlags
Flags used in ShowQueryString() call.
Definition: textbuf_gui.h:18
@ QSF_ENABLE_DEFAULT
enable the 'Default' button ("\0" is returned)
Definition: textbuf_gui.h:21
@ QSF_ACCEPT_UNCHANGED
return success even when the text didn't change
Definition: textbuf_gui.h:20
@ QSF_LEN_IN_CHARS
the length of the string is counted in characters
Definition: textbuf_gui.h:22
Functions related to text effects.
@ TE_STATIC
Keep the text effect static.
Definition: texteff.hpp:22
@ TE_RISING
Make the text effect slowly go upwards.
Definition: texteff.hpp:21
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition: tile_map.cpp:116
Definition of Interval and OneShot timers.
Definition of the Window system.
Base of the town class.
Town * ClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest (in distance or ownership) to a given tile, within a given threshold.
Definition: town_cmd.cpp:3870
@ VEH_ROAD
Road vehicle type.
Definition: vehicle_type.h:25
@ VEH_TRAIN
Train vehicle type.
Definition: vehicle_type.h:24
bool ScrollMainWindowToTile(TileIndex tile, bool instant)
Scrolls the viewport of the main window to a given location.
Definition: viewport.cpp:2515
Viewport * IsPtInWindowViewport(const Window *w, int x, int y)
Is a xy position inside the viewport of the window?
Definition: viewport.cpp:411
Functions related to (drawing on) viewports.
Handles dividing the water in the map into regions to assist pathfinding.
void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags)
Draw frame rectangle.
Definition: widget.cpp:281
@ NC_EQUALSIZE
Value of the NCB_EQUALSIZE flag.
Definition: widget_type.h:524
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
Definition: widget_type.h:112
@ WWT_PUSHIMGBTN
Normal push-button (no toggle button) with image caption.
Definition: widget_type.h:113
@ WWT_LABEL
Centered label.
Definition: widget_type.h:57
@ WWT_EDITBOX
a textbox for typing
Definition: widget_type.h:71
@ 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_CAPTION
Window caption (window title between closebox and stickybox)
Definition: widget_type.h:61
@ 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_FRAME
Frame.
Definition: widget_type.h:60
@ WWT_EMPTY
Empty widget, place holder to reserve space in widget tree.
Definition: widget_type.h:48
@ WWT_TEXT
Pure simple text.
Definition: widget_type.h:58
@ WWT_DEBUGBOX
NewGRF debug box (at top-right of a window, between WWT_CAPTION and WWT_SHADEBOX)
Definition: widget_type.h:63
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
void SetFocusedWindow(Window *w)
Set the window that has the focus.
Definition: window.cpp:422
int GetMainViewTop()
Return the top of the main view available for general use.
Definition: window.cpp:2062
void CloseWindowByClass(WindowClass cls, int data)
Close all windows of a given class.
Definition: window.cpp:1152
Window * GetMainWindow()
Get the main window, i.e.
Definition: window.cpp:1127
int GetMainViewBottom()
Return the bottom of the main view available for general use.
Definition: window.cpp:2073
bool _mouse_hovering
The mouse is hovering over the same point.
Definition: window.cpp:91
Window * FindWindowFromPt(int x, int y)
Do a search for a window at specific coordinates.
Definition: window.cpp:1768
Window functions not directly related to making/drawing windows.
@ WF_WHITE_BORDER
Window white border counter bit mask.
Definition: window_gui.h:236
@ FR_DARKENED
If set the background is darker, allows for lowered frames with normal background colour when used wi...
Definition: window_gui.h:29
@ FR_LOWERED
If set the frame is lowered and the background colour brighter (ie. buttons when pressed)
Definition: window_gui.h:28
@ WDF_NO_CLOSE
This window can't be interactively closed.
Definition: window_gui.h:206
@ WDF_MODAL
The window is a modal child of some other window, meaning the parent is 'inactive'.
Definition: window_gui.h:204
@ WDF_NO_FOCUS
This window won't get focus/make any other window lose focus when click.
Definition: window_gui.h:205
@ WDP_CENTER
Center the window.
Definition: window_gui.h:148
@ 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
@ WN_QUERY_STRING
Query string.
Definition: window_type.h:29
@ WN_GAME_OPTIONS_ABOUT
About window.
Definition: window_type.h:24
@ WN_CONFIRM_POPUP_QUERY
Query popup confirm.
Definition: window_type.h:32
EventState
State of handling an event.
Definition: window_type.h:743
@ ES_HANDLED
The passed event is handled.
Definition: window_type.h:744
@ ES_NOT_HANDLED
The passed event is not handled.
Definition: window_type.h:745
@ WC_LAND_INFO
Land info window; Window numbers:
Definition: window_type.h:150
@ WC_OSK
On Screen Keyboard; Window numbers:
Definition: window_type.h:162
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition: window_type.h:45
@ WC_CONFIRM_POPUP_QUERY
Popup with confirm question; Window numbers:
Definition: window_type.h:130
@ WC_GAME_OPTIONS
Game options window; Window numbers:
Definition: window_type.h:624
@ WC_QUERY_STRING
Query string window; Window numbers:
Definition: window_type.h:123
@ WC_TOOLTIPS
Tooltip window; Window numbers:
Definition: window_type.h:116
Functions related to zooming.
int ScaleGUITrad(int value)
Scale traditional pixel dimensions to GUI zoom level.
Definition: zoom_func.h:117