OpenTTD Source 20241224-master-gf74b0cf984
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"
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
40struct SignList {
45
46 GUISignList signs;
47
49 static bool match_case;
50 static std::string default_name;
51
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
132bool SignList::match_case = false;
133std::string SignList::default_name;
134
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. */
169 this->signs.ForceResort();
170 this->SortSignsList();
171 this->SetDirty();
172 }
173
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);
201 /* No signs? */
202 if (this->vscroll->GetCount() == 0) {
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;
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
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:
274 size.height += padding.height;
275 size.width += padding.width;
276 break;
277 }
278 }
279
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
352static 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(),
374 NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
375 EndContainer(),
376 EndContainer(),
377};
378
379static 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
403static 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 */
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
526static 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
545static WindowDesc _query_sign_edit_desc(
546 WDP_CENTER, nullptr, 0, 0,
549 _nested_query_sign_edit_widgets
550);
551
556void 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
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}
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
List template of 'things' T to sort in a GUI.
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.
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
Scrollbar data structure.
void SetCount(size_t num)
Sets the number of elements in the list.
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.
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:2451
size_type GetCount() const
Gets the number of elements in the list.
auto GetVisibleRangeIterators(Tcontainer &container) const
Get a pair of iterators for the range of visible elements in a container.
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:28
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition window_gui.h:96
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.
Functions related to companies.
GUI Functions related to companies.
@ OWNER_DEITY
The object is owned by a superuser / goal script.
@ OWNER_NONE
The tile has no ownership.
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.
constexpr NWidgetPart SetScrollbar(WidgetID index)
Attach a scrollbar to a widget.
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.
constexpr NWidgetPart SetDataTip(uint32_t data, StringID tip)
Widget part function for setting the data and tooltip.
constexpr NWidgetPart SetTextStyle(TextColour colour, FontSize size=FS_NORMAL)
Widget part function for setting the text style.
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=-1)
Widget part function for starting a new 'real' widget.
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
constexpr NWidgetPart SetAspect(float ratio, AspectFlags flags=AspectFlags::ResizeX)
Widget part function for setting the aspect ratio.
constexpr NWidgetPart SetResize(int16_t dx, int16_t dy)
Widget part function for setting the resize step.
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.
void HandleClickOnSign(const Sign *si)
Handle clicking on a sign.
void DeleteRenameSignWindow(SignID sign)
Close the sign window associated with the given sign.
SignListHotkeys
Enum referring to the Hotkeys in the sign list window.
@ SLHK_FOCUS_FILTER_BOX
Focus the edit box for editing the filter string.
static bool RenameSign(SignID index, const char *text)
Actually rename the sign.
void ShowRenameSignWindow(const Sign *si)
Show the window to change the text of a sign.
Window * ShowSignList()
Open the sign list window.
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:333
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.
static const int MAX_CHAR_LENGTH
Max. length of UTF-8 encoded unicode character.
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.
Coordinates of a point in 2D.
static size_t GetPoolSize()
Returns first unused index.
Tindex index
Index of this pool item.
static size_t GetNumItems()
Returns number of valid items in the pool.
static Titem * Get(size_t index)
Returns Titem with given index.
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.
uint step_height
Step-size of height resize changes.
Definition window_gui.h:214
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
void SetStringParameters(WidgetID widget) const override
Initialize string parameters for a widget.
void OnEditboxChanged(WidgetID widget) override
The text in an editbox has been edited.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
IntervalTimer< TimerWindow > rebuild_interval
Resort the sign listing on a regular interval.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
void SetFilterString(const char *new_filter_string)
This function sets the filter string of the sign list.
EventState OnHotkey(int hotkey) override
A hotkey has been pressed.
int text_offset
Offset of the sign text relative to the left edge of the WID_SIL_LIST widget.
QueryString filter_editbox
Filter editbox;.
void OnPaint() override
The window must be repainted.
void OnInit() override
Notification that the nested widget tree gets initialized.
static EventState SignListGlobalHotkeys(int hotkey)
Handler for global hotkeys of the SignListWindow.
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
void OnResize() override
Called after the window got resized.
static bool OwnerDeityFilter(const Sign *const *a, StringFilter &)
Filter sign list excluding OWNER_DEITY.
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.
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.
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
void SetStringParameters(WidgetID widget) const override
Initialize string parameters for a widget.
const Sign * PrevNextSign(bool next)
Returns a pointer to the (alphabetically) previous or next sign of the current sign.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
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
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:732
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing)
Definition window.cpp:3159
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
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:977
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.
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.
@ WWT_PUSHIMGBTN
Normal push-button (no toggle button) with image caption.
@ WWT_PUSHARROWBTN
Normal push-button (no toggle button) with arrow caption.
@ 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:85
@ 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
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 * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition window.cpp:1098
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.
EventState
State of handling an event.
@ ES_HANDLED
The passed event is handled.
@ ES_NOT_HANDLED
The passed event is not handled.
@ WC_SIGN_LIST
Sign list; Window numbers:
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:45
@ WC_QUERY_STRING
Query string window; Window numbers: