OpenTTD Source  20241120-master-g6d3adc6169
signs_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 "company_gui.h"
12 #include "company_func.h"
13 #include "signs_base.h"
14 #include "signs_func.h"
15 #include "debug.h"
16 #include "command_func.h"
17 #include "strings_func.h"
18 #include "window_func.h"
19 #include "map_func.h"
20 #include "viewport_func.h"
21 #include "querystring_gui.h"
22 #include "sortlist_type.h"
23 #include "stringfilter_type.h"
24 #include "string_func.h"
25 #include "core/geometry_func.hpp"
26 #include "hotkeys.h"
27 #include "transparency.h"
28 #include "gui.h"
29 #include "signs_cmd.h"
30 #include "timer/timer.h"
31 #include "timer/timer_window.h"
32 
33 #include "widgets/sign_widget.h"
34 
35 #include "table/strings.h"
36 #include "table/sprites.h"
37 
38 #include "safeguards.h"
39 
40 struct SignList {
45 
46  GUISignList signs;
47 
49  static bool match_case;
50  static std::string default_name;
51 
56  {
57  }
58 
59  void BuildSignsList()
60  {
61  if (!this->signs.NeedRebuild()) return;
62 
63  Debug(misc, 3, "Building sign list");
64 
65  this->signs.clear();
66  this->signs.reserve(Sign::GetNumItems());
67 
68  for (const Sign *si : Sign::Iterate()) this->signs.push_back(si);
69 
70  this->signs.SetFilterState(true);
71  this->FilterSignList();
72  this->signs.RebuildDone();
73  }
74 
76  static bool SignNameSorter(const Sign * const &a, const Sign * const &b)
77  {
78  /* Signs are very very rarely using the default text, but there can also be
79  * a lot of them. Therefore a worthwhile performance gain can be made by
80  * directly comparing Sign::name instead of going through the string
81  * system for each comparison. */
82  const std::string &a_name = a->name.empty() ? SignList::default_name : a->name;
83  const std::string &b_name = b->name.empty() ? SignList::default_name : b->name;
84 
85  int r = StrNaturalCompare(a_name, b_name); // Sort by name (natural sorting).
86 
87  return r != 0 ? r < 0 : (a->index < b->index);
88  }
89 
90  void SortSignsList()
91  {
92  if (!this->signs.Sort(&SignNameSorter)) return;
93  }
94 
96  static bool SignNameFilter(const Sign * const *a, StringFilter &filter)
97  {
98  /* Same performance benefit as above for sorting. */
99  const std::string &a_name = (*a)->name.empty() ? SignList::default_name : (*a)->name;
100 
101  filter.ResetState();
102  filter.AddLine(a_name);
103  return filter.GetState();
104  }
105 
107  static bool OwnerDeityFilter(const Sign * const *a, StringFilter &)
108  {
109  /* You should never be able to edit signs of owner DEITY */
110  return (*a)->owner != OWNER_DEITY;
111  }
112 
114  static bool OwnerVisibilityFilter(const Sign * const *a, StringFilter &)
115  {
117  /* Hide sign if non-own signs are hidden in the viewport */
118  return (*a)->owner == _local_company || (*a)->owner == OWNER_DEITY;
119  }
120 
123  {
124  this->signs.Filter(&SignNameFilter, this->string_filter);
125  if (_game_mode != GM_EDITOR) this->signs.Filter(&OwnerDeityFilter, this->string_filter);
127  this->signs.Filter(&OwnerVisibilityFilter, this->string_filter);
128  }
129  }
130 };
131 
132 bool SignList::match_case = false;
133 std::string SignList::default_name;
134 
138 };
139 
143  Scrollbar *vscroll;
144 
146  {
147  this->CreateNestedTree();
148  this->vscroll = this->GetScrollbar(WID_SIL_SCROLLBAR);
149  this->FinishInitNested(window_number);
150  this->SetWidgetLoweredState(WID_SIL_FILTER_MATCH_CASE_BTN, SignList::match_case);
151 
152  /* Initialize the text edit widget */
154  this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
155 
156  /* Initialize the filtering variables */
157  this->SetFilterString("");
158 
159  /* Create initial list. */
160  this->signs.ForceRebuild();
161  this->signs.ForceResort();
162  this->BuildSortSignList();
163  }
164 
165  void OnInit() override
166  {
167  /* Default sign name, used if Sign::name is nullptr. */
168  SignList::default_name = GetString(STR_DEFAULT_SIGN_NAME);
169  this->signs.ForceResort();
170  this->SortSignsList();
171  this->SetDirty();
172  }
173 
180  void SetFilterString(const char *new_filter_string)
181  {
182  /* check if there is a new filter string */
183  this->string_filter.SetFilterTerm(new_filter_string);
184 
185  /* Rebuild the list of signs */
186  this->InvalidateData();
187  }
188 
189  void OnPaint() override
190  {
191  if (!this->IsShaded() && this->signs.NeedRebuild()) this->BuildSortSignList();
192  this->DrawWidgets();
193  }
194 
195  void DrawWidget(const Rect &r, WidgetID widget) const override
196  {
197  switch (widget) {
198  case WID_SIL_LIST: {
199  Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
200  uint text_offset_y = (this->resize.step_height - GetCharacterHeight(FS_NORMAL) + 1) / 2;
201  /* No signs? */
202  if (this->vscroll->GetCount() == 0) {
203  DrawString(tr.left, tr.right, tr.top + text_offset_y, STR_STATION_LIST_NONE);
204  return;
205  }
206 
207  Dimension d = GetSpriteSize(SPR_COMPANY_ICON);
208  bool rtl = _current_text_dir == TD_RTL;
209  int sprite_offset_y = (this->resize.step_height - d.height + 1) / 2;
210  uint icon_left = rtl ? tr.right - this->text_offset : tr.left;
211  tr = tr.Indent(this->text_offset, rtl);
212 
213  /* At least one sign available. */
214  auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->signs);
215  for (auto it = first; it != last; ++it) {
216  const Sign *si = *it;
217 
218  if (si->owner != OWNER_NONE) DrawCompanyIcon(si->owner, icon_left, tr.top + sprite_offset_y);
219 
220  SetDParam(0, si->index);
221  DrawString(tr.left, tr.right, tr.top + text_offset_y, STR_SIGN_NAME, TC_YELLOW);
222  tr.top += this->resize.step_height;
223  }
224  break;
225  }
226  }
227  }
228 
229  void SetStringParameters(WidgetID widget) const override
230  {
231  if (widget == WID_SIL_CAPTION) SetDParam(0, this->vscroll->GetCount());
232  }
233 
234  void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
235  {
236  switch (widget) {
237  case WID_SIL_LIST: {
238  auto it = this->vscroll->GetScrolledItemFromWidget(this->signs, pt.y, this, WID_SIL_LIST, WidgetDimensions::scaled.framerect.top);
239  if (it == this->signs.end()) return;
240 
241  const Sign *si = *it;
242  ScrollMainWindowToTile(TileVirtXY(si->x, si->y));
243  break;
244  }
245 
247  SignList::match_case = !SignList::match_case; // Toggle match case
248  this->SetWidgetLoweredState(WID_SIL_FILTER_MATCH_CASE_BTN, SignList::match_case); // Toggle button pushed state
249  this->InvalidateData(); // Rebuild the list of signs
250  break;
251  }
252  }
253 
254  void OnResize() override
255  {
256  this->vscroll->SetCapacityFromWidget(this, WID_SIL_LIST, WidgetDimensions::scaled.framerect.Vertical());
257  }
258 
259  void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
260  {
261  switch (widget) {
262  case WID_SIL_LIST: {
263  Dimension spr_dim = GetSpriteSize(SPR_COMPANY_ICON);
264  this->text_offset = WidgetDimensions::scaled.frametext.left + spr_dim.width + 2; // 2 pixels space between icon and the sign text.
265  resize.height = std::max<uint>(GetCharacterHeight(FS_NORMAL), spr_dim.height + 2);
266  Dimension d = {(uint)(this->text_offset + WidgetDimensions::scaled.frametext.right), padding.height + 5 * resize.height};
267  size = maxdim(size, d);
268  break;
269  }
270 
271  case WID_SIL_CAPTION:
273  size = GetStringBoundingBox(STR_SIGN_LIST_CAPTION);
274  size.height += padding.height;
275  size.width += padding.width;
276  break;
277  }
278  }
279 
280  EventState OnHotkey(int hotkey) override
281  {
282  switch (hotkey) {
285  SetFocusedWindow(this); // The user has asked to give focus to the text box, so make sure this window is focused.
286  break;
287 
288  default:
289  return ES_NOT_HANDLED;
290  }
291 
292  return ES_HANDLED;
293  }
294 
295  void OnEditboxChanged(WidgetID widget) override
296  {
297  if (widget == WID_SIL_FILTER_TEXT) this->SetFilterString(this->filter_editbox.text.buf);
298  }
299 
300  void BuildSortSignList()
301  {
302  if (this->signs.NeedRebuild()) {
303  this->BuildSignsList();
304  this->vscroll->SetCount(this->signs.size());
306  }
307  this->SortSignsList();
308  }
309 
311  IntervalTimer<TimerWindow> rebuild_interval = {std::chrono::seconds(3), [this](auto) {
312  this->BuildSortSignList();
313  this->SetDirty();
314  }};
315 
321  void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
322  {
323  /* When there is a filter string, we always need to rebuild the list even if
324  * the amount of signs in total is unchanged, as the subset of signs that is
325  * accepted by the filter might has changed. */
326  if (data == 0 || data == -1 || !this->string_filter.IsEmpty()) { // New or deleted sign, changed visibility setting or there is a filter string
327  /* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */
328  this->signs.ForceRebuild();
329  } else { // Change of sign contents while there is no filter string
330  this->signs.ForceResort();
331  }
332  }
333 
340  {
341  if (_game_mode == GM_MENU) return ES_NOT_HANDLED;
342  Window *w = ShowSignList();
343  if (w == nullptr) return ES_NOT_HANDLED;
344  return w->OnHotkey(hotkey);
345  }
346 
347  static inline HotkeyList hotkeys{"signlist", {
348  Hotkey('F', "focus_filter_box", SLHK_FOCUS_FILTER_BOX),
350 };
351 
352 static constexpr NWidgetPart _nested_sign_list_widgets[] = {
354  NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
355  NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SIL_CAPTION), SetDataTip(STR_SIGN_LIST_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
356  NWidget(WWT_SHADEBOX, COLOUR_BROWN),
357  NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
358  NWidget(WWT_STICKYBOX, COLOUR_BROWN),
359  EndContainer(),
362  NWidget(WWT_PANEL, COLOUR_BROWN, WID_SIL_LIST), SetMinimalSize(WidgetDimensions::unscaled.frametext.Horizontal() + 16 + 255, 0),
365  NWidget(WWT_PANEL, COLOUR_BROWN), SetFill(1, 1),
366  NWidget(WWT_EDITBOX, COLOUR_BROWN, WID_SIL_FILTER_TEXT), SetMinimalSize(80, 0), SetResize(1, 0), SetFill(1, 0), SetPadding(2, 2, 2, 2),
367  SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
368  EndContainer(),
369  NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_SIL_FILTER_MATCH_CASE_BTN), SetDataTip(STR_SIGN_LIST_MATCH_CASE, STR_SIGN_LIST_MATCH_CASE_TOOLTIP),
370  EndContainer(),
371  EndContainer(),
373  NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_SIL_SCROLLBAR),
374  NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
375  EndContainer(),
376  EndContainer(),
377 };
378 
379 static WindowDesc _sign_list_desc(
380  WDP_AUTO, "list_signs", 358, 138,
382  0,
383  _nested_sign_list_widgets,
384  &SignListWindow::hotkeys
385 );
386 
393 {
394  return AllocateWindowDescFront<SignListWindow>(_sign_list_desc, 0);
395 }
396 
403 static bool RenameSign(SignID index, const char *text)
404 {
405  bool remove = StrEmpty(text);
406  Command<CMD_RENAME_SIGN>::Post(StrEmpty(text) ? STR_ERROR_CAN_T_DELETE_SIGN : STR_ERROR_CAN_T_CHANGE_SIGN_NAME, index, text);
407  return remove;
408 }
409 
411  QueryString name_editbox;
412  SignID cur_sign;
413 
415  {
416  this->querystrings[WID_QES_TEXT] = &this->name_editbox;
417  this->name_editbox.caption = STR_EDIT_SIGN_CAPTION;
418  this->name_editbox.cancel_button = WID_QES_CANCEL;
419  this->name_editbox.ok_button = WID_QES_OK;
420 
422 
423  UpdateSignEditWindow(si);
425  }
426 
427  void UpdateSignEditWindow(const Sign *si)
428  {
429  /* Display an empty string when the sign hasn't been edited yet */
430  if (!si->name.empty()) {
431  SetDParam(0, si->index);
432  this->name_editbox.text.Assign(STR_SIGN_NAME);
433  } else {
434  this->name_editbox.text.DeleteAll();
435  }
436 
437  this->cur_sign = si->index;
438 
441  }
442 
448  const Sign *PrevNextSign(bool next)
449  {
450  /* Rebuild the sign list */
451  this->signs.ForceRebuild();
452  this->signs.NeedResort();
453  this->BuildSignsList();
454  this->SortSignsList();
455 
456  /* Search through the list for the current sign, excluding
457  * - the first sign if we want the previous sign or
458  * - the last sign if we want the next sign */
459  size_t end = this->signs.size() - (next ? 1 : 0);
460  for (uint i = next ? 0 : 1; i < end; i++) {
461  if (this->cur_sign == this->signs[i]->index) {
462  /* We've found the current sign, so return the sign before/after it */
463  return this->signs[i + (next ? 1 : -1)];
464  }
465  }
466  /* If we haven't found the current sign by now, return the last/first sign */
467  return next ? this->signs.front() : this->signs.back();
468  }
469 
470  void SetStringParameters(WidgetID widget) const override
471  {
472  switch (widget) {
473  case WID_QES_CAPTION:
474  SetDParam(0, this->name_editbox.caption);
475  break;
476  }
477  }
478 
479  void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
480  {
481  switch (widget) {
482  case WID_QES_LOCATION: {
483  const Sign *si = Sign::Get(this->cur_sign);
484  TileIndex tile = TileVirtXY(si->x, si->y);
485  if (_ctrl_pressed) {
487  } else {
489  }
490  break;
491  }
492 
493  case WID_QES_PREVIOUS:
494  case WID_QES_NEXT: {
495  const Sign *si = this->PrevNextSign(widget == WID_QES_NEXT);
496 
497  /* Rebuild the sign list */
498  this->signs.ForceRebuild();
499  this->signs.NeedResort();
500  this->BuildSignsList();
501  this->SortSignsList();
502 
503  /* Scroll to sign and reopen window */
504  ScrollMainWindowToTile(TileVirtXY(si->x, si->y));
505  UpdateSignEditWindow(si);
506  break;
507  }
508 
509  case WID_QES_DELETE:
510  /* Only need to set the buffer to null, the rest is handled as the OK button */
511  RenameSign(this->cur_sign, "");
512  /* don't delete this, we are deleted in Sign::~Sign() -> DeleteRenameSignWindow() */
513  break;
514 
515  case WID_QES_OK:
516  if (RenameSign(this->cur_sign, this->name_editbox.text.buf)) break;
517  [[fallthrough]];
518 
519  case WID_QES_CANCEL:
520  this->Close();
521  break;
522  }
523  }
524 };
525 
526 static constexpr NWidgetPart _nested_query_sign_edit_widgets[] = {
528  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
529  NWidget(WWT_CAPTION, COLOUR_GREY, WID_QES_CAPTION), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), SetTextStyle(TC_WHITE),
530  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_QES_LOCATION), SetAspect(WidgetDimensions::ASPECT_LOCATION), SetDataTip(SPR_GOTO_LOCATION, STR_EDIT_SIGN_LOCATION_TOOLTIP),
531  EndContainer(),
532  NWidget(WWT_PANEL, COLOUR_GREY),
533  NWidget(WWT_EDITBOX, COLOUR_GREY, WID_QES_TEXT), SetMinimalSize(256, 0), SetDataTip(STR_EDIT_SIGN_SIGN_OSKTITLE, STR_NULL), SetPadding(2, 2, 2, 2),
534  EndContainer(),
536  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_QES_OK), SetMinimalSize(61, 12), SetDataTip(STR_BUTTON_OK, STR_NULL),
537  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_QES_CANCEL), SetMinimalSize(60, 12), SetDataTip(STR_BUTTON_CANCEL, STR_NULL),
538  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_QES_DELETE), SetMinimalSize(60, 12), SetDataTip(STR_TOWN_VIEW_DELETE_BUTTON, STR_NULL),
539  NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), EndContainer(),
540  NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_QES_PREVIOUS), SetMinimalSize(11, 12), SetDataTip(AWV_DECREASE, STR_EDIT_SIGN_PREVIOUS_SIGN_TOOLTIP),
541  NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_QES_NEXT), SetMinimalSize(11, 12), SetDataTip(AWV_INCREASE, STR_EDIT_SIGN_NEXT_SIGN_TOOLTIP),
542  EndContainer(),
543 };
544 
545 static WindowDesc _query_sign_edit_desc(
546  WDP_CENTER, nullptr, 0, 0,
549  _nested_query_sign_edit_widgets
550 );
551 
556 void HandleClickOnSign(const Sign *si)
557 {
558  /* If we can't rename the sign, don't even open the rename GUI. */
559  if (!CompanyCanRenameSign(si)) return;
560 
561  if (_ctrl_pressed && (si->owner == _local_company || (si->owner == OWNER_DEITY && _game_mode == GM_EDITOR))) {
562  RenameSign(si->index, "");
563  return;
564  }
565 
567 }
568 
573 void ShowRenameSignWindow(const Sign *si)
574 {
575  /* Delete all other edit windows */
577 
578  new SignWindow(_query_sign_edit_desc, si);
579 }
580 
586 {
588 
589  if (w != nullptr && w->cur_sign == sign) w->Close();
590 }
constexpr debug_inline bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
bool Filter(FilterFunction *decide, F filter_data)
Filter the list.
void RebuildDone()
Notify the sortlist that the rebuild is done.
void SetFilterState(bool state)
Enable or disable the filter.
bool NeedRebuild() const
Check if a rebuild is needed.
void ForceRebuild()
Force that a rebuild is needed.
bool Sort(Comp compare)
Sort the list.
void ForceResort()
Force a resort next Sort call Reset the resort timer if used too.
bool NeedResort()
Check if a resort is needed next loop If used the resort timer will decrease every call till 0.
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
size_type GetCount() const
Gets the number of elements in the list.
Definition: widget_type.h:722
auto GetVisibleRangeIterators(Tcontainer &container) const
Get a pair of iterators for the range of visible elements in a container.
Definition: widget_type.h:860
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
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition: window_gui.h:67
Functions related to commands.
void DrawCompanyIcon(CompanyID c, int x, int y)
Draw the icon of a company.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:52
Functions related to companies.
GUI Functions related to companies.
@ OWNER_DEITY
The object is owned by a superuser / goal script.
Definition: company_type.h:27
@ OWNER_NONE
The tile has no ownership.
Definition: company_type.h:25
Functions related to debugging.
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition: debug.h:37
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 GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition: gfx.cpp:922
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
@ FS_NORMAL
Index of the normal font in the font tables.
Definition: gfx_type.h:209
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 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.
Hotkey related functions.
Functions related to maps.
static debug_inline TileIndex TileVirtXY(uint x, uint y)
Get a tile from the virtual XY-coordinate.
Definition: map_func.h:404
@ DO_SHOW_COMPETITOR_SIGNS
Display signs, station names and waypoint names of opponent companies. Buoys and oilrig-stations are ...
Definition: openttd.h:52
Base for the GUIs that have an edit box in them.
A number of safeguards to prevent using unsafe methods.
Types related to the sign widgets.
@ WID_QES_PREVIOUS
Previous button.
Definition: sign_widget.h:31
@ WID_QES_LOCATION
Scroll to sign location.
Definition: sign_widget.h:26
@ WID_QES_CANCEL
Cancel button.
Definition: sign_widget.h:29
@ WID_QES_OK
OK button.
Definition: sign_widget.h:28
@ WID_QES_NEXT
Next button.
Definition: sign_widget.h:32
@ WID_QES_DELETE
Delete button.
Definition: sign_widget.h:30
@ WID_QES_TEXT
Text of the query.
Definition: sign_widget.h:27
@ WID_QES_CAPTION
Caption of the window.
Definition: sign_widget.h:25
@ WID_SIL_SCROLLBAR
Scrollbar of list.
Definition: sign_widget.h:18
@ WID_SIL_FILTER_MATCH_CASE_BTN
Button to toggle if case sensitive filtering should be used.
Definition: sign_widget.h:20
@ WID_SIL_FILTER_TEXT
Text box for typing a filter string.
Definition: sign_widget.h:19
@ WID_SIL_CAPTION
Caption of the window.
Definition: sign_widget.h:16
@ WID_SIL_LIST
List of signs.
Definition: sign_widget.h:17
bool CompanyCanRenameSign(const Sign *si)
Check if the current company can rename a given sign.
Definition: signs.cpp:71
Base class for signs.
Command definitions related to signs.
Functions related to signs.
Window * ShowSignList()
Open the sign list window.
Definition: signs_gui.cpp:392
void HandleClickOnSign(const Sign *si)
Handle clicking on a sign.
Definition: signs_gui.cpp:556
void DeleteRenameSignWindow(SignID sign)
Close the sign window associated with the given sign.
Definition: signs_gui.cpp:585
SignListHotkeys
Enum referring to the Hotkeys in the sign list window.
Definition: signs_gui.cpp:136
@ SLHK_FOCUS_FILTER_BOX
Focus the edit box for editing the filter string.
Definition: signs_gui.cpp:137
static bool RenameSign(SignID index, const char *text)
Actually rename the sign.
Definition: signs_gui.cpp:403
void ShowRenameSignWindow(const Sign *si)
Show the window to change the text of a sign.
Definition: signs_gui.cpp:573
uint16_t SignID
The type of the IDs of signs.
Definition: signs_type.h:14
static const uint MAX_LENGTH_SIGN_NAME_CHARS
The maximum length of a sign name in characters including '\0'.
Definition: signs_type.h:19
Base types for having sorted lists in GUIs.
This file contains all sprite-related enums and defines.
Definition of base types and functions in a cross-platform compatible way.
int StrNaturalCompare(std::string_view s1, std::string_view s2, bool ignore_garbage_at_front)
Compares two strings using case insensitive natural sort.
Definition: string.cpp:589
Functions related to low-level strings.
bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:57
Searching and filtering using a stringterm.
void SetDParamMaxValue(size_t n, uint64_t max_value, uint min_count, FontSize size)
Set DParam n to some number that is suitable for string size computations.
Definition: strings.cpp:127
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
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition: strings.cpp:56
Functions related to OTTD's strings.
@ TD_RTL
Text is written right-to-left by default.
Definition: strings_type.h:24
static const int MAX_CHAR_LENGTH
Max. length of UTF-8 encoded unicode character.
Definition: strings_type.h:18
Dimensions (a width and height) of a rectangle in 2D.
List of hotkeys for a window.
Definition: hotkeys.h:37
All data for a single hotkey.
Definition: hotkeys.h:21
Partial widget specification to allow NWidgets to be written nested.
Definition: widget_type.h:1075
Coordinates of a point in 2D.
static size_t GetPoolSize()
Returns first unused index.
Definition: pool_type.hpp:360
Tindex index
Index of this pool item.
Definition: pool_type.hpp:238
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:339
static size_t GetNumItems()
Returns number of valid items in the pool.
Definition: pool_type.hpp:369
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:388
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.
static const int ACTION_CLEAR
Clear editbox.
Specification of a rectangle with absolute coordinates of all edges.
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.
uint step_height
Step-size of height resize changes.
Definition: window_gui.h:214
IntervalTimer< TimerWindow > rebuild_interval
Resort the sign listing on a regular interval.
Definition: signs_gui.cpp:311
void SetFilterString(const char *new_filter_string)
This function sets the filter string of the sign list.
Definition: signs_gui.cpp:180
EventState OnHotkey(int hotkey) override
A hotkey has been pressed.
Definition: signs_gui.cpp:280
int text_offset
Offset of the sign text relative to the left edge of the WID_SIL_LIST widget.
Definition: signs_gui.cpp:142
void OnInvalidateData([[maybe_unused]] int data=0, [[maybe_unused]] bool gui_scope=true) override
Some data on this window has become invalid.
Definition: signs_gui.cpp:321
QueryString filter_editbox
Filter editbox;.
Definition: signs_gui.cpp:141
void OnPaint() override
The window must be repainted.
Definition: signs_gui.cpp:189
void OnInit() override
Notification that the nested widget tree gets initialized.
Definition: signs_gui.cpp:165
static EventState SignListGlobalHotkeys(int hotkey)
Handler for global hotkeys of the SignListWindow.
Definition: signs_gui.cpp:339
void OnResize() override
Called after the window got resized.
Definition: signs_gui.cpp:254
static bool OwnerDeityFilter(const Sign *const *a, StringFilter &)
Filter sign list excluding OWNER_DEITY.
Definition: signs_gui.cpp:107
GUIList< const Sign *, std::nullptr_t, StringFilter & > GUISignList
A GUIList contains signs and uses a StringFilter for filtering.
Definition: signs_gui.cpp:44
static bool OwnerVisibilityFilter(const Sign *const *a, StringFilter &)
Filter sign list by owner.
Definition: signs_gui.cpp:114
static bool SignNameSorter(const Sign *const &a, const Sign *const &b)
Sort signs by their name.
Definition: signs_gui.cpp:76
SignList()
Creates a SignList with filtering disabled by default.
Definition: signs_gui.cpp:55
void FilterSignList()
Filter out signs from the sign list that does not match the name filter.
Definition: signs_gui.cpp:122
static bool match_case
Should case sensitive matching be used?
Definition: signs_gui.cpp:49
static std::string default_name
Default sign name, used if Sign::name is nullptr.
Definition: signs_gui.cpp:50
static bool SignNameFilter(const Sign *const *a, StringFilter &filter)
Filter sign list by sign name.
Definition: signs_gui.cpp:96
StringFilter string_filter
The match string to be used when the GUIList is (re)-sorted.
Definition: signs_gui.cpp:48
const Sign * PrevNextSign(bool next)
Returns a pointer to the (alphabetically) previous or next sign of the current sign.
Definition: signs_gui.cpp:448
String filter and state.
bool IsEmpty() const
Check whether any filter words were entered.
void SetFilterTerm(const char *str)
Set the term to filter on.
void ResetState()
Reset the matching state to process a new item.
void AddLine(const char *str)
Pass another text line from the current item to the filter.
bool GetState() const
Get the matching state of the current item.
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
char *const buf
buffer in which text is saved
Definition: textbuf_type.h:32
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
std::map< WidgetID, QueryString * > querystrings
QueryString associated to WWT_EDITBOX widgets.
Definition: window_gui.h:320
void DrawWidgets() const
Paint all widgets of a window.
Definition: widget.cpp:731
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
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
bool SetFocusedWidget(WidgetID widget_index)
Set focus within this window to the given widget.
Definition: window.cpp:486
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition: window_gui.h:447
bool IsShaded() const
Is window shaded currently?
Definition: window_gui.h:563
Window(WindowDesc &desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
Definition: window.cpp:1756
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition: window.cpp:1746
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition: window.cpp:314
virtual EventState OnHotkey(int hotkey)
A hotkey has been pressed.
Definition: window.cpp:565
WindowNumber window_number
Window number within the window class.
Definition: window_gui.h:302
Definition of Interval and OneShot timers.
Definition of the Window system.
Functions related to transparency.
uint8_t _display_opt
What do we want to draw/do?
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.
@ AWV_DECREASE
Arrow to the left or in case of RTL to the right.
Definition: widget_type.h:31
@ AWV_INCREASE
Arrow to the right or in case of RTL to the left.
Definition: widget_type.h:32
@ 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_PUSHARROWBTN
Normal push-button (no toggle button) with arrow caption.
Definition: widget_type.h:114
@ 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_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_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
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition: window.cpp:1098
void SetFocusedWindow(Window *w)
Set the window that has the focus.
Definition: window.cpp:422
void CloseWindowByClass(WindowClass cls, int data)
Close all windows of a given class.
Definition: window.cpp:1152
Window functions not directly related to making/drawing windows.
@ WDF_CONSTRUCTION
This window is used for construction; close it whenever changing company.
Definition: window_gui.h:203
@ WDP_CENTER
Center the window.
Definition: window_gui.h:148
@ WDP_AUTO
Find a place automatically.
Definition: window_gui.h:147
int WidgetID
Widget ID.
Definition: window_type.h:18
@ WN_QUERY_STRING_SIGN
Query string for signs.
Definition: window_type.h:30
int32_t WindowNumber
Number to differentiate different windows of the same class.
Definition: window_type.h:737
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_SIGN_LIST
Sign list; Window numbers:
Definition: window_type.h:278
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition: window_type.h:45
@ WC_QUERY_STRING
Query string window; Window numbers:
Definition: window_type.h:123