OpenTTD Source 20250703-master-gbf07751ee7
picker_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 "core/backup_type.hpp"
12#include "company_func.h"
13#include "gui.h"
14#include "hotkeys.h"
15#include "ini_type.h"
16#include "newgrf_badge.h"
17#include "newgrf_badge_config.h"
18#include "newgrf_badge_gui.h"
19#include "picker_gui.h"
20#include "querystring_gui.h"
21#include "settings_type.h"
22#include "sortlist_type.h"
23#include "sound_func.h"
24#include "sound_type.h"
25#include "string_func.h"
26#include "stringfilter_type.h"
27#include "strings_func.h"
28#include "widget_type.h"
29#include "window_func.h"
30#include "window_gui.h"
31#include "window_type.h"
32#include "zoom_func.h"
33
35
36#include "table/sprites.h"
37#include "table/strings.h"
38
39#include <charconv>
40
41#include "safeguards.h"
42
43static std::vector<PickerCallbacks *> &GetPickerCallbacks()
44{
45 static std::vector<PickerCallbacks *> callbacks;
46 return callbacks;
47}
48
49PickerCallbacks::PickerCallbacks(const std::string &ini_group) : ini_group(ini_group)
50{
51 GetPickerCallbacks().push_back(this);
52}
53
54PickerCallbacks::~PickerCallbacks()
55{
56 auto &callbacks = GetPickerCallbacks();
57 callbacks.erase(std::ranges::find(callbacks, this));
58}
59
65static void PickerLoadConfig(const IniFile &ini, PickerCallbacks &callbacks)
66{
67 const IniGroup *group = ini.GetGroup(callbacks.ini_group);
68 if (group == nullptr) return;
69
70 callbacks.saved.clear();
71 for (const IniItem &item : group->items) {
72 std::array<uint8_t, 4> grfid_buf;
73
74 std::string_view str = item.name;
75
76 /* Try reading "<grfid>|<localid>" */
77 auto grfid_pos = str.find('|');
78 if (grfid_pos == std::string_view::npos) continue;
79
80 std::string_view grfid_str = str.substr(0, grfid_pos);
81 if (!ConvertHexToBytes(grfid_str, grfid_buf)) continue;
82
83 str = str.substr(grfid_pos + 1);
84 uint32_t grfid = grfid_buf[0] | (grfid_buf[1] << 8) | (grfid_buf[2] << 16) | (grfid_buf[3] << 24);
85 uint16_t localid;
86 auto [ptr, err] = std::from_chars(str.data(), str.data() + str.size(), localid);
87
88 if (err == std::errc{} && ptr == str.data() + str.size()) {
89 callbacks.saved.insert({grfid, localid, 0, 0});
90 }
91 }
92}
93
99static void PickerSaveConfig(IniFile &ini, const PickerCallbacks &callbacks)
100{
101 IniGroup &group = ini.GetOrCreateGroup(callbacks.ini_group);
102 group.Clear();
103
104 for (const PickerItem &item : callbacks.saved) {
105 std::string key = fmt::format("{:08X}|{}", std::byteswap(item.grfid), item.local_id);
106 group.CreateItem(key);
107 }
108}
109
114void PickerLoadConfig(const IniFile &ini)
115{
116 for (auto *cb : GetPickerCallbacks()) PickerLoadConfig(ini, *cb);
117}
118
124{
125 for (const auto *cb : GetPickerCallbacks()) PickerSaveConfig(ini, *cb);
126}
127
129static bool ClassIDSorter(int const &a, int const &b)
130{
131 return a < b;
132}
133
135static bool ClassTagNameFilter(int const *item, PickerFilterData &filter)
136{
137 filter.ResetState();
138 filter.AddLine(GetString(filter.callbacks->GetClassName(*item)));
139 return filter.GetState();
140}
141
143static bool TypeIDSorter(PickerItem const &a, PickerItem const &b)
144{
145 int r = a.class_index - b.class_index;
146 if (r == 0) r = a.index - b.index;
147 return r < 0;
148}
149
151static bool TypeTagNameFilter(PickerItem const *item, PickerFilterData &filter)
152{
153 auto badges = filter.callbacks->GetTypeBadges(item->class_index, item->index);
154 if (filter.bdf.has_value() && !filter.bdf->Filter(badges)) return false;
155 if (filter.btf.has_value() && filter.btf->Filter(badges)) return true;
156
157 filter.ResetState();
158 filter.AddLine(GetString(filter.callbacks->GetTypeName(item->class_index, item->index)));
159 return filter.GetState();
160}
161
162static const std::initializer_list<PickerClassList::SortFunction * const> _class_sorter_funcs = { &ClassIDSorter };
163static const std::initializer_list<PickerClassList::FilterFunction * const> _class_filter_funcs = { &ClassTagNameFilter };
164static const std::initializer_list<PickerTypeList::SortFunction * const> _type_sorter_funcs = { TypeIDSorter };
165static const std::initializer_list<PickerTypeList::FilterFunction * const> _type_filter_funcs = { TypeTagNameFilter };
166
167PickerWindow::PickerWindow(WindowDesc &desc, Window *parent, int window_number, PickerCallbacks &callbacks) : PickerWindowBase(desc, parent), callbacks(callbacks),
168 class_editbox(EDITBOX_MAX_SIZE * MAX_CHAR_LENGTH, EDITBOX_MAX_SIZE),
169 type_editbox(EDITBOX_MAX_SIZE * MAX_CHAR_LENGTH, EDITBOX_MAX_SIZE)
170{
171 this->window_number = window_number;
172
173 /* Init of nested tree is deferred.
174 * PickerWindow::ConstructWindow must be called by the inheriting window. */
175}
176
177void PickerWindow::ConstructWindow()
178{
179 this->CreateNestedTree();
180
181 /* Test if pickers should be active.*/
182 bool is_active = this->callbacks.IsActive();
183
184 this->preview_height = std::max(this->callbacks.preview_height, PREVIEW_HEIGHT);
185
186 /* Functionality depends on widgets being present, not window class. */
187 this->has_class_picker = is_active && this->GetWidget<NWidgetBase>(WID_PW_CLASS_LIST) != nullptr && this->callbacks.HasClassChoice();
188 this->has_type_picker = is_active && this->GetWidget<NWidgetBase>(WID_PW_TYPE_MATRIX) != nullptr;
189
190 if (this->has_class_picker) {
191 this->GetWidget<NWidgetCore>(WID_PW_CLASS_LIST)->SetToolTip(this->callbacks.GetClassTooltip());
192
194 } else {
195 if (auto *nwid = this->GetWidget<NWidgetStacked>(WID_PW_CLASS_SEL); nwid != nullptr) {
196 /* Check the container orientation. MakeNWidgets adds an additional NWID_VERTICAL container so we check the grand-parent. */
197 bool is_vertical = (nwid->parent->parent->type == NWID_VERTICAL);
198 nwid->SetDisplayedPlane(is_vertical ? SZSP_HORIZONTAL : SZSP_VERTICAL);
199 }
200 }
201
203 this->class_string_filter.SetFilterTerm(this->class_editbox.text.GetText());
204 this->class_string_filter.callbacks = &this->callbacks;
205
206 this->classes.SetListing(this->callbacks.class_last_sorting);
207 this->classes.SetFiltering(this->callbacks.class_last_filtering);
208 this->classes.SetSortFuncs(_class_sorter_funcs);
209 this->classes.SetFilterFuncs(_class_filter_funcs);
210
211 /* Update saved type information. */
212 this->callbacks.saved = this->callbacks.UpdateSavedItems(this->callbacks.saved);
213
214 /* Clear used type information. */
215 this->callbacks.used.clear();
216
217 if (this->has_type_picker) {
218 /* Populate used type information. */
219 this->callbacks.FillUsedItems(this->callbacks.used);
220
222
223 this->GetWidget<NWidgetCore>(WID_PW_TYPE_ITEM)->SetToolTip(this->callbacks.GetTypeTooltip());
224
225 auto *matrix = this->GetWidget<NWidgetMatrix>(WID_PW_TYPE_MATRIX);
226 matrix->SetScrollbar(this->GetScrollbar(WID_PW_TYPE_SCROLL));
227
229 } else {
230 if (auto *nwid = this->GetWidget<NWidgetStacked>(WID_PW_TYPE_SEL); nwid != nullptr) {
231 /* Check the container orientation. MakeNWidgets adds an additional NWID_VERTICAL container so we check the grand-parent. */
232 bool is_vertical = (nwid->parent->parent->type == NWID_VERTICAL);
233 nwid->SetDisplayedPlane(is_vertical ? SZSP_HORIZONTAL : SZSP_VERTICAL);
234 }
235 }
236
238 this->type_string_filter.SetFilterTerm(this->type_editbox.text.GetText());
239 this->type_string_filter.callbacks = &this->callbacks;
240
241 this->types.SetListing(this->callbacks.type_last_sorting);
242 this->types.SetFiltering(this->callbacks.type_last_filtering);
243 this->types.SetSortFuncs(_type_sorter_funcs);
244 this->types.SetFilterFuncs(_type_filter_funcs);
245
246 this->FinishInitNested(this->window_number);
247
248 this->InvalidateData(PICKER_INVALIDATION_ALL);
249}
250
252{
253 this->badge_classes = GUIBadgeClasses(this->callbacks.GetFeature());
254
255 auto container = this->GetWidget<NWidgetContainer>(WID_PW_BADGE_FILTER);
256 this->badge_filters = AddBadgeDropdownFilters(*container, WID_PW_BADGE_FILTER, COLOUR_DARK_GREEN, this->callbacks.GetFeature());
257
258 this->widget_lookup.clear();
259 this->nested_root->FillWidgetLookup(this->widget_lookup);
260}
261
263{
264 this->callbacks.Close(data);
265 this->PickerWindowBase::Close(data);
266}
267
268void PickerWindow::UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize)
269{
270 switch (widget) {
271 /* Class picker */
273 fill.height = resize.height = GetCharacterHeight(FS_NORMAL) + padding.height;
274 size.height = 5 * resize.height;
275 break;
276
277 /* Type picker */
279 /* At least two items wide. */
280 size.width += resize.width;
281 fill.width = resize.width;
282 fill.height = 1;
283
284 /* Resizing in X direction only at blob size, but at pixel level in Y. */
285 resize.height = 1;
286 break;
287
288 /* Type picker */
289 case WID_PW_TYPE_ITEM:
292 break;
293
295 /* Hide the configuration button if no configurable badges are present. */
296 if (this->badge_classes.GetClasses().empty()) size = {0, 0};
297 break;
298 }
299}
300
301std::string PickerWindow::GetWidgetString(WidgetID widget, StringID stringid) const
302{
303 if (IsInsideMM(widget, this->badge_filters.first, this->badge_filters.second)) {
304 return this->GetWidget<NWidgetBadgeFilter>(widget)->GetStringParameter(this->badge_filter_choices);
305 }
306
307 return this->Window::GetWidgetString(widget, stringid);
308}
309
310void PickerWindow::DrawWidget(const Rect &r, WidgetID widget) const
311{
312 switch (widget) {
313 /* Class picker */
314 case WID_PW_CLASS_LIST: {
315 Rect ir = r.Shrink(WidgetDimensions::scaled.matrix);
316 const int selected = this->callbacks.GetSelectedClass();
317 const auto vscroll = this->GetScrollbar(WID_PW_CLASS_SCROLL);
318 const int y_step = this->GetWidget<NWidgetResizeBase>(widget)->resize_y;
319 auto [first, last] = vscroll->GetVisibleRangeIterators(this->classes);
320 for (auto it = first; it != last; ++it) {
321 DrawString(ir, this->callbacks.GetClassName(*it), *it == selected ? TC_WHITE : TC_BLACK);
322 ir.top += y_step;
323 }
324 break;
325 }
326
327 /* Type picker */
328 case WID_PW_TYPE_ITEM: {
329 assert(this->GetWidget<NWidgetBase>(widget)->GetParentWidget<NWidgetMatrix>()->GetCurrentElement() < static_cast<int>(this->types.size()));
330 const auto &item = this->types[this->GetWidget<NWidgetBase>(widget)->GetParentWidget<NWidgetMatrix>()->GetCurrentElement()];
331
332 DrawPixelInfo tmp_dpi;
334 if (FillDrawPixelInfo(&tmp_dpi, ir)) {
335 AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
338
339 this->callbacks.DrawType(x, y, item.class_index, item.index);
340
341 int by = ir.Height() - ScaleGUITrad(12);
342
343 GrfSpecFeature feature = this->callbacks.GetFeature();
344 DrawBadgeColumn({0, by, ir.Width() - 1, ir.Height() - 1}, 0, this->badge_classes, this->callbacks.GetTypeBadges(item.class_index, item.index), feature, std::nullopt, PAL_NONE);
345
346 if (this->callbacks.saved.contains(item)) {
347 DrawSprite(SPR_BLOT, PALETTE_TO_YELLOW, 0, 0);
348 }
349 if (this->callbacks.used.contains(item)) {
350 DrawSprite(SPR_BLOT, PALETTE_TO_GREEN, ir.Width() - GetSpriteSize(SPR_BLOT).width, 0);
351 }
352 }
353
354 if (!this->callbacks.IsTypeAvailable(item.class_index, item.index)) {
355 GfxFillRect(ir, GetColourGradient(COLOUR_GREY, SHADE_DARKER), FILLRECT_CHECKER);
356 }
357 break;
358 }
359
360 case WID_PW_TYPE_NAME:
361 DrawString(r, this->callbacks.GetTypeName(this->callbacks.GetSelectedClass(), this->callbacks.GetSelectedType()), TC_ORANGE, SA_CENTER);
362 break;
363 }
364}
365
372
374{
375 switch (widget) {
376 /* Class Picker */
377 case WID_PW_CLASS_LIST: {
378 const auto vscroll = this->GetWidget<NWidgetScrollbar>(WID_PW_CLASS_SCROLL);
379 auto it = vscroll->GetScrolledItemFromWidget(this->classes, pt.y, this, WID_PW_CLASS_LIST);
380 if (it == this->classes.end()) return;
381
382 if (this->callbacks.GetSelectedClass() != *it || HasBit(this->callbacks.mode, PFM_ALL)) {
383 ClrBit(this->callbacks.mode, PFM_ALL); // Disable showing all.
384 this->callbacks.SetSelectedClass(*it);
386 }
389 break;
390 }
391
392 case WID_PW_MODE_ALL:
393 case WID_PW_MODE_USED:
395 ToggleBit(this->callbacks.mode, widget - WID_PW_MODE_ALL);
396 if (!this->IsWidgetDisabled(WID_PW_MODE_ALL) && HasBit(this->callbacks.mode, widget - WID_PW_MODE_ALL)) {
397 /* Enabling used or saved filters automatically enables all. */
398 SetBit(this->callbacks.mode, PFM_ALL);
399 }
401 break;
402
403 case WID_PW_SHRINK:
405 this->InvalidateData({});
406 this->ReInit();
407 break;
408
409 case WID_PW_EXPAND:
411 this->InvalidateData({});
412 this->ReInit();
413 break;
414
415 /* Type Picker */
416 case WID_PW_TYPE_ITEM: {
417 int sel = this->GetWidget<NWidgetBase>(widget)->GetParentWidget<NWidgetMatrix>()->GetCurrentElement();
418 assert(sel < (int)this->types.size());
419 const auto &item = this->types[sel];
420
421 if (_ctrl_pressed) {
422 auto it = this->callbacks.saved.find(item);
423 if (it == std::end(this->callbacks.saved)) {
424 this->callbacks.saved.insert(item);
425 } else {
426 this->callbacks.saved.erase(it);
427 }
428 this->InvalidateData(PickerInvalidation::Type);
429 break;
430 }
431
432 if (this->callbacks.IsTypeAvailable(item.class_index, item.index)) {
433 this->callbacks.SetSelectedClass(item.class_index);
434 this->callbacks.SetSelectedType(item.index);
435 this->InvalidateData(PickerInvalidation::Position);
436 }
439 break;
440 }
441
443 if (this->badge_classes.GetClasses().empty()) break;
444 ShowDropDownList(this, BuildBadgeClassConfigurationList(this->badge_classes, 1, {}), -1, widget, 0, false, true);
445 break;
446
447 default:
448 if (IsInsideMM(widget, this->badge_filters.first, this->badge_filters.second)) {
449 ShowDropDownList(this, this->GetWidget<NWidgetBadgeFilter>(widget)->GetDropDownList(), -1, widget, 0, false);
450 }
451 break;
452 }
453}
454
455void PickerWindow::OnDropdownSelect(WidgetID widget, int index, int click_result)
456{
457 switch (widget) {
459 bool reopen = HandleBadgeConfigurationDropDownClick(this->callbacks.GetFeature(), 1, index, click_result, this->badge_filter_choices);
460
461 this->ReInit();
462
463 if (reopen) {
464 ReplaceDropDownList(this, BuildBadgeClassConfigurationList(this->badge_classes, 1, {}), -1);
465 } else {
467 }
468
469 /* We need to refresh if a filter is removed. */
471 break;
472 }
473
474 default:
475 if (IsInsideMM(widget, this->badge_filters.first, this->badge_filters.second)) {
476 if (index < 0) {
477 ResetBadgeFilter(this->badge_filter_choices, this->GetWidget<NWidgetBadgeFilter>(widget)->GetBadgeClassID());
478 } else {
479 SetBadgeFilter(this->badge_filter_choices, BadgeID(index));
480 }
482 }
483 break;
484 }
485}
486
487void PickerWindow::OnInvalidateData(int data, bool gui_scope)
488{
489 if (!gui_scope) return;
490
491 PickerInvalidations pi(data);
492
494 if (this->badge_filter_choices.empty()) {
495 this->type_string_filter.bdf.reset();
496 } else {
497 this->type_string_filter.bdf.emplace(this->badge_filter_choices);
498 }
499 this->types.SetFilterState(!type_string_filter.IsEmpty() || type_string_filter.bdf.has_value());
500 }
501
504
505 this->BuildPickerClassList();
506 if (pi.Test(PickerInvalidation::Validate)) this->EnsureSelectedClassIsValid();
507 if (pi.Test(PickerInvalidation::Position)) this->EnsureSelectedClassIsVisible();
508
509 this->BuildPickerTypeList();
510 if (pi.Test(PickerInvalidation::Validate)) this->EnsureSelectedTypeIsValid();
511 if (pi.Test(PickerInvalidation::Position)) this->EnsureSelectedTypeIsVisible();
512
513 if (this->has_type_picker) {
517 }
518
521}
522
524{
525 switch (hotkey) {
527 /* Cycle between the two edit boxes. */
528 if (this->has_type_picker && (this->nested_focus == nullptr || this->nested_focus->GetIndex() != WID_PW_TYPE_FILTER)) {
530 } else if (this->has_class_picker && (this->nested_focus == nullptr || this->nested_focus->GetIndex() != WID_PW_CLASS_FILTER)) {
532 }
533 SetFocusedWindow(this);
534 return ES_HANDLED;
535
536 default:
537 return ES_NOT_HANDLED;
538 }
539}
540
542{
543 switch (wid) {
545 this->class_string_filter.SetFilterTerm(this->class_editbox.text.GetText());
546 this->classes.SetFilterState(!class_string_filter.IsEmpty());
547 this->InvalidateData(PickerInvalidation::Class);
548 break;
549
551 this->type_string_filter.SetFilterTerm(this->type_editbox.text.GetText());
552 if (!type_string_filter.IsEmpty()) {
553 this->type_string_filter.btf.emplace(this->type_string_filter, this->callbacks.GetFeature());
554 } else {
555 this->type_string_filter.btf.reset();
556 }
558 break;
559
560 default:
561 break;
562 }
563}
564
567{
568 if (!this->classes.NeedRebuild()) return;
569
570 int count = this->callbacks.GetClassCount();
571
572 this->classes.clear();
573 this->classes.reserve(count);
574
575 bool filter_used = HasBit(this->callbacks.mode, PFM_USED);
576 bool filter_saved = HasBit(this->callbacks.mode, PFM_SAVED);
577 for (int i = 0; i < count; i++) {
578 if (this->callbacks.GetClassName(i) == INVALID_STRING_ID) continue;
579 if (filter_used && std::none_of(std::begin(this->callbacks.used), std::end(this->callbacks.used), [i](const PickerItem &item) { return item.class_index == i; })) continue;
580 if (filter_saved && std::none_of(std::begin(this->callbacks.saved), std::end(this->callbacks.saved), [i](const PickerItem &item) { return item.class_index == i; })) continue;
581 this->classes.emplace_back(i);
582 }
583
584 this->classes.Filter(this->class_string_filter);
585 this->classes.RebuildDone();
586 this->classes.Sort();
587
588 if (!this->has_class_picker) return;
589 this->GetScrollbar(WID_PW_CLASS_SCROLL)->SetCount(this->classes.size());
590}
591
592void PickerWindow::EnsureSelectedClassIsValid()
593{
594 int class_index = this->callbacks.GetSelectedClass();
595 if (std::binary_search(std::begin(this->classes), std::end(this->classes), class_index)) return;
596
597 if (!this->classes.empty()) {
598 class_index = this->classes.front();
599 } else {
600 /* Classes can be empty if filters are enabled, find the first usable class. */
601 int count = this->callbacks.GetClassCount();
602 for (int i = 0; i < count; i++) {
603 if (this->callbacks.GetClassName(i) == INVALID_STRING_ID) continue;
604 class_index = i;
605 break;
606 }
607 }
608
609 this->callbacks.SetSelectedClass(class_index);
610 this->types.ForceRebuild();
611}
612
613void PickerWindow::EnsureSelectedClassIsVisible()
614{
615 if (!this->has_class_picker) return;
616 if (this->classes.empty()) return;
617
618 auto it = std::ranges::find(this->classes, this->callbacks.GetSelectedClass());
619 if (it == std::end(this->classes)) return;
620
621 int pos = static_cast<int>(std::distance(std::begin(this->classes), it));
623}
624
625void PickerWindow::RefreshUsedTypeList()
626{
627 if (!this->has_type_picker) return;
628
629 this->callbacks.used.clear();
630 this->callbacks.FillUsedItems(this->callbacks.used);
631 this->InvalidateData(PickerInvalidation::Type);
632}
633
636{
637 if (!this->types.NeedRebuild()) return;
638
639 this->types.clear();
640
641 bool show_all = HasBit(this->callbacks.mode, PFM_ALL);
642 bool filter_used = HasBit(this->callbacks.mode, PFM_USED);
643 bool filter_saved = HasBit(this->callbacks.mode, PFM_SAVED);
644 int cls_id = this->callbacks.GetSelectedClass();
645
646 if (filter_used) {
647 /* Showing used items. May also be filtered by saved items. */
648 this->types.reserve(this->callbacks.used.size());
649 for (const PickerItem &item : this->callbacks.used) {
650 if (!show_all && item.class_index != cls_id) continue;
651 if (this->callbacks.GetTypeName(item.class_index, item.index) == INVALID_STRING_ID) continue;
652 this->types.emplace_back(item);
653 }
654 } else if (filter_saved) {
655 /* Showing only saved items. */
656 this->types.reserve(this->callbacks.saved.size());
657 for (const PickerItem &item : this->callbacks.saved) {
658 /* The used list may contain items that aren't currently loaded, skip these. */
659 if (item.class_index == -1) continue;
660 if (!show_all && item.class_index != cls_id) continue;
661 if (this->callbacks.GetTypeName(item.class_index, item.index) == INVALID_STRING_ID) continue;
662 this->types.emplace_back(item);
663 }
664 } else if (show_all) {
665 /* Reserve enough space for everything. */
666 int total = 0;
667 for (int class_index : this->classes) total += this->callbacks.GetTypeCount(class_index);
668 this->types.reserve(total);
669 /* Add types in all classes. */
670 for (int class_index : this->classes) {
671 int count = this->callbacks.GetTypeCount(class_index);
672 for (int i = 0; i < count; i++) {
673 if (this->callbacks.GetTypeName(class_index, i) == INVALID_STRING_ID) continue;
674 this->types.emplace_back(this->callbacks.GetPickerItem(class_index, i));
675 }
676 }
677 } else {
678 /* Add types in only the selected class. */
679 if (cls_id >= 0 && cls_id < this->callbacks.GetClassCount()) {
680 int count = this->callbacks.GetTypeCount(cls_id);
681 this->types.reserve(count);
682 for (int i = 0; i < count; i++) {
683 if (this->callbacks.GetTypeName(cls_id, i) == INVALID_STRING_ID) continue;
684 this->types.emplace_back(this->callbacks.GetPickerItem(cls_id, i));
685 }
686 }
687 }
688
689 this->types.Filter(this->type_string_filter);
690 this->types.RebuildDone();
691 this->types.Sort();
692
693 if (!this->has_type_picker) return;
694 this->GetWidget<NWidgetMatrix>(WID_PW_TYPE_MATRIX)->SetCount(static_cast<int>(this->types.size()));
695}
696
697void PickerWindow::EnsureSelectedTypeIsValid()
698{
699 int class_index = this->callbacks.GetSelectedClass();
700 int index = this->callbacks.GetSelectedType();
701 if (std::any_of(std::begin(this->types), std::end(this->types), [class_index, index](const auto &item) { return item.class_index == class_index && item.index == index; })) return;
702
703 if (!this->types.empty()) {
704 class_index = this->types.front().class_index;
705 index = this->types.front().index;
706 } else {
707 /* Types can be empty if filters are enabled, find the first usable type. */
708 int count = this->callbacks.GetTypeCount(class_index);
709 for (int i = 0; i < count; i++) {
710 if (this->callbacks.GetTypeName(class_index, i) == INVALID_STRING_ID) continue;
711 index = i;
712 break;
713 }
714 }
715 this->callbacks.SetSelectedClass(class_index);
716 this->callbacks.SetSelectedType(index);
717}
718
719void PickerWindow::EnsureSelectedTypeIsVisible()
720{
721 if (!this->has_type_picker) return;
722 if (this->types.empty()) {
723 this->GetWidget<NWidgetMatrix>(WID_PW_TYPE_MATRIX)->SetClicked(-1);
724 return;
725 }
726
727 int class_index = this->callbacks.GetSelectedClass();
728 int index = this->callbacks.GetSelectedType();
729
730 auto it = std::ranges::find_if(this->types, [class_index, index](const auto &item) { return item.class_index == class_index && item.index == index; });
731 if (it == std::end(this->types)) return;
732
733 int pos = static_cast<int>(std::distance(std::begin(this->types), it));
734 this->GetWidget<NWidgetMatrix>(WID_PW_TYPE_MATRIX)->SetClicked(pos);
735}
736
738std::unique_ptr<NWidgetBase> MakePickerClassWidgets()
739{
740 static constexpr NWidgetPart picker_class_widgets[] = {
741 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_PW_CLASS_SEL),
743 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
744 NWidget(WWT_EDITBOX, COLOUR_DARK_GREEN, WID_PW_CLASS_FILTER), SetMinimalSize(144, 0), SetPadding(2), SetFill(1, 0), SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
745 EndContainer(),
747 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
750 EndContainer(),
751 NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, WID_PW_CLASS_SCROLL),
752 EndContainer(),
753 EndContainer(),
754 EndContainer(),
755 };
756
757 return MakeNWidgets(picker_class_widgets, nullptr);
758}
759
761std::unique_ptr<NWidgetBase> MakePickerTypeWidgets()
762{
763 static constexpr NWidgetPart picker_type_widgets[] = {
764 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_PW_TYPE_SEL),
767 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
768 NWidget(WWT_EDITBOX, COLOUR_DARK_GREEN, WID_PW_TYPE_FILTER), SetPadding(2), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
769 EndContainer(),
770 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_PW_CONFIGURE_BADGES), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON), SetResize(0, 0), SetFill(0, 1), SetSpriteTip(SPR_EXTRA_MENU, STR_BADGE_CONFIG_MENU_TOOLTIP),
771 EndContainer(),
773 EndContainer(),
775 NWidget(WWT_TEXTBTN, COLOUR_DARK_GREEN, WID_PW_MODE_ALL), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_PICKER_MODE_ALL, STR_PICKER_MODE_ALL_TOOLTIP),
776 NWidget(WWT_TEXTBTN, COLOUR_DARK_GREEN, WID_PW_MODE_USED), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_PICKER_MODE_USED, STR_PICKER_MODE_USED_TOOLTIP),
777 NWidget(WWT_TEXTBTN, COLOUR_DARK_GREEN, WID_PW_MODE_SAVED), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_PICKER_MODE_SAVED, STR_PICKER_MODE_SAVED_TOOLTIP),
778 NWidget(WWT_PUSHTXTBTN, COLOUR_DARK_GREEN, WID_PW_SHRINK), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON), SetStringTip(STR_PICKER_PREVIEW_SHRINK, STR_PICKER_PREVIEW_SHRINK_TOOLTIP),
779 NWidget(WWT_PUSHTXTBTN, COLOUR_DARK_GREEN, WID_PW_EXPAND), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON), SetStringTip(STR_PICKER_PREVIEW_EXPAND, STR_PICKER_PREVIEW_EXPAND_TOOLTIP),
780 EndContainer(),
782 NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetScrollbar(WID_PW_TYPE_SCROLL),
785 EndContainer(),
786 EndContainer(),
787 EndContainer(),
788 NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, WID_PW_TYPE_SCROLL),
789 EndContainer(),
791 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
793 EndContainer(),
794 NWidget(WWT_RESIZEBOX, COLOUR_DARK_GREEN, WID_PW_TYPE_RESIZE),
795 EndContainer(),
796 EndContainer(),
797 EndContainer(),
798 };
799
800 return MakeNWidgets(picker_type_widgets, nullptr);
801}
802
803void InvalidateAllPickerWindows()
804{
805 InvalidateWindowClassesData(WC_BUS_STATION, PickerWindow::PICKER_INVALIDATION_ALL);
806 InvalidateWindowClassesData(WC_TRUCK_STATION, PickerWindow::PICKER_INVALIDATION_ALL);
807 InvalidateWindowClassesData(WC_SELECT_STATION, PickerWindow::PICKER_INVALIDATION_ALL);
808 InvalidateWindowClassesData(WC_BUILD_WAYPOINT, PickerWindow::PICKER_INVALIDATION_ALL);
809 InvalidateWindowClassesData(WC_BUILD_OBJECT, PickerWindow::PICKER_INVALIDATION_ALL);
810 InvalidateWindowClassesData(WC_BUILD_HOUSE, PickerWindow::PICKER_INVALIDATION_ALL);
811}
Class for backupping variables and making sure they are restored later.
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
constexpr T ToggleBit(T &x, const uint8_t y)
Toggles a bit in a variable.
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Enum-as-bit-set wrapper.
bool Filter(FilterFunction *decide, F filter_data)
Filter the list.
void RebuildDone()
Notify the sortlist that the rebuild is done.
void SetFiltering(Filtering f)
Import filter conditions.
void SetListing(Listing l)
Import sort conditions.
void SetFilterState(bool state)
Enable or disable the filter.
void SetFilterFuncs(std::span< FilterFunction *const > n_funcs)
Hand the filter function pointers to the GUIList.
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 SetSortFuncs(std::span< SortFunction *const > n_funcs)
Hand the sort function pointers to the GUIList.
Matrix container with implicitly equal sized (virtual) sub-widgets.
Class for PickerClassWindow to collect information and retain state.
Definition picker_gui.h:39
virtual int GetSelectedClass() const =0
Get the index of the selected class.
Filtering type_last_filtering
Default filtering of PickerTypeList.
Definition picker_gui.h:94
virtual PickerItem GetPickerItem(int cls_id, int id) const =0
Get data about an item.
const std::string ini_group
Ini Group for saving favourites.
Definition picker_gui.h:96
virtual void SetSelectedClass(int id) const =0
Set the selected class.
virtual bool IsActive() const =0
Should picker class/type selection be enabled?
virtual StringID GetTypeName(int cls_id, int id) const =0
Get the item of a type.
virtual bool IsTypeAvailable(int cls_id, int id) const =0
Test if an item is currently buildable.
virtual void FillUsedItems(std::set< PickerItem > &items)=0
Fill a set with all items that are used by the current player.
virtual StringID GetTypeTooltip() const =0
Get the tooltip string for the type grid.
virtual bool HasClassChoice() const =0
Are there multiple classes to chose from?
Listing type_last_sorting
Default sorting of PickerTypeList.
Definition picker_gui.h:93
std::set< PickerItem > used
Set of items used in the current game by the current company.
Definition picker_gui.h:101
virtual StringID GetClassTooltip() const =0
Get the tooltip string for the class list.
virtual int GetTypeCount(int cls_id) const =0
Get the number of types in a class.
virtual int GetClassCount() const =0
Get the number of classes.
virtual void SetSelectedType(int id) const =0
Set the selected type.
virtual StringID GetClassName(int id) const =0
Get the name of a class.
int preview_height
Previously adjusted height.
Definition picker_gui.h:99
virtual std::set< PickerItem > UpdateSavedItems(const std::set< PickerItem > &src)=0
Update link between grfid/localidx and class_index/index in saved items.
virtual void DrawType(int x, int y, int cls_id, int id) const =0
Draw preview image of an item.
virtual std::span< const BadgeID > GetTypeBadges(int cls_id, int id) const =0
Get the item of a type.
Filtering class_last_filtering
Default filtering of PickerClassList.
Definition picker_gui.h:91
virtual int GetSelectedType() const =0
Get the selected type.
uint8_t mode
Bitmask of PickerFilterModes.
Definition picker_gui.h:97
std::set< PickerItem > saved
Set of saved favourite items.
Definition picker_gui.h:102
Listing class_last_sorting
Default sorting of PickerClassList.
Definition picker_gui.h:90
Base class for windows opened from a toolbar.
Definition window_gui.h:991
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
Definition window.cpp:3570
static constexpr int MAX_PREVIEW_HEIGHT
Maximum height of each preview button.
Definition picker_gui.h:182
static constexpr int PREVIEW_WIDTH
Width of each preview button.
Definition picker_gui.h:176
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
int preview_height
Height of preview images.
Definition picker_gui.h:188
bool has_class_picker
Set if this window has a class picker 'component'.
Definition picker_gui.h:186
static constexpr int PREVIEW_HEIGHT
Height of each preview button.
Definition picker_gui.h:177
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
@ Position
Update scroll positions.
@ Class
Refresh the class list.
@ Type
Refresh the type list.
@ Validate
Validate selected item.
@ Filter
Update filter state.
static constexpr int PREVIEW_LEFT
Offset from left edge to draw preview.
Definition picker_gui.h:178
PickerTypeList types
List of types.
Definition picker_gui.h:224
QueryString class_editbox
Filter editbox.
Definition picker_gui.h:218
bool has_type_picker
Set if this window has a type picker 'component'.
Definition picker_gui.h:187
void BuildPickerClassList()
Builds the filter list of classes.
@ PFM_USED
Show used types.
Definition picker_gui.h:161
@ PFM_ALL
Show all classes.
Definition picker_gui.h:160
@ PFM_SAVED
Show saved types.
Definition picker_gui.h:162
void OnEditboxChanged(WidgetID wid) override
The text in an editbox has been edited.
void BuildPickerTypeList()
Builds the filter list of types.
void OnDropdownSelect(WidgetID widget, int index, int click_result) override
A dropdown option associated to this window has been selected.
void OnResize() override
Called after the window got resized.
static constexpr int PREVIEW_BOTTOM
Offset from bottom edge to draw preview.
Definition picker_gui.h:179
@ PCWHK_FOCUS_FILTER_BOX
Focus the edit box for editing the filter string.
Definition picker_gui.h:205
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
QueryString type_editbox
Filter editbox.
Definition picker_gui.h:226
EventState OnHotkey(int hotkey) override
A hotkey has been pressed.
void OnInit() override
Notification that the nested widget tree gets initialized.
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.
PickerClassList classes
List of classes.
Definition picker_gui.h:216
static constexpr int STEP_PREVIEW_HEIGHT
Step for decreasing or increase preivew button height.
Definition picker_gui.h:181
void SetCount(size_t num)
Sets the number of elements in the list.
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:2510
void ScrollTowards(size_type position)
Scroll towards the given position; if the item is visible nothing happens, otherwise it will be shown...
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:30
RectPadding fullbevel
Always-scaled bevel thickness.
Definition window_gui.h:39
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition window_gui.h:93
Functions related to companies.
void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width, bool instant_close, bool persist)
Show a drop down list.
Definition dropdown.cpp:414
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:77
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition gfx.cpp:961
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:661
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:115
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition gfx.cpp:1027
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:1557
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:251
@ SA_CENTER
Center both horizontally and vertically.
Definition gfx_type.h:393
@ FILLRECT_CHECKER
Draw only every second pixel, used for greying-out.
Definition gfx_type.h:341
constexpr NWidgetPart SetMatrixDataTip(uint32_t cols, uint32_t rows, StringID tip={})
Widget part function for setting the data and tooltip of WWT_MATRIX widgets.
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
constexpr NWidgetPart SetSpriteTip(SpriteID sprite, StringID tip={})
Widget part function for setting the sprite and tooltip.
constexpr NWidgetPart SetPIP(uint8_t pre, uint8_t inter, uint8_t post)
Widget part function for setting a pre/inter/post spaces.
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 SetStringTip(StringID string, StringID tip={})
Widget part function for setting the string and tooltip.
constexpr NWidgetPart SetAspect(float ratio, AspectFlags flags=AspectFlag::ResizeX)
Widget part function for setting the aspect ratio.
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
std::unique_ptr< NWidgetBase > MakeNWidgets(std::span< const NWidgetPart > nwid_parts, std::unique_ptr< NWidgetBase > &&container)
Construct a nested widget tree from an array of parts.
Definition widget.cpp:3385
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 SetMinimalTextLines(uint8_t lines, uint8_t spacing, FontSize size=FS_NORMAL)
Widget part function for setting the minimal text lines.
constexpr NWidgetPart SetResize(int16_t dx, int16_t dy)
Widget part function for setting the resize step.
GUI functions that shouldn't be here.
Hotkey related functions.
Types related to reading/writing '*.ini' files.
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
GrfSpecFeature
Definition newgrf.h:69
Functions related to NewGRF badges.
Functions related to NewGRF badge configuration.
uint8_t GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
Definition palette.cpp:388
static const std::initializer_list< PickerClassList::FilterFunction *const > _class_filter_funcs
Filter functions of the PickerClassList.
static bool TypeIDSorter(PickerItem const &a, PickerItem const &b)
Sort types by id.
static void PickerLoadConfig(const IniFile &ini, PickerCallbacks &callbacks)
Load favourites of a picker from config.
static const std::initializer_list< PickerTypeList::SortFunction *const > _type_sorter_funcs
Sort functions of the PickerTypeList.
static bool ClassIDSorter(int const &a, int const &b)
Sort classes by id.
static const std::initializer_list< PickerClassList::SortFunction *const > _class_sorter_funcs
Sort functions of the PickerClassList.
std::unique_ptr< NWidgetBase > MakePickerClassWidgets()
Create nested widgets for the class picker widgets.
static bool TypeTagNameFilter(PickerItem const *item, PickerFilterData &filter)
Filter types by class name.
static const std::initializer_list< PickerTypeList::FilterFunction *const > _type_filter_funcs
Filter functions of the PickerTypeList.
static void PickerSaveConfig(IniFile &ini, const PickerCallbacks &callbacks)
Save favourites of a picker to config.
std::unique_ptr< NWidgetBase > MakePickerTypeWidgets()
Create nested widgets for the type picker widgets.
static bool ClassTagNameFilter(int const *item, PickerFilterData &filter)
Filter classes by class name.
Functions/types etc.
Types related to the picker widgets.
@ WID_PW_MODE_SAVED
Toggle showing only saved types.
@ WID_PW_CLASS_FILTER
Editbox filter.
@ WID_PW_TYPE_SCROLL
Scrollbar for the matrix.
@ WID_PW_EXPAND
Button to increase preview image height.
@ WID_PW_CONFIGURE_BADGES
Button to configure badges.
@ WID_PW_TYPE_ITEM
A single item.
@ WID_PW_CLASS_LIST
List of classes.
@ WID_PW_TYPE_FILTER
Text filter.
@ WID_PW_MODE_USED
Toggle showing only used types.
@ WID_PW_BADGE_FILTER
Container for dropdown badge filters.
@ WID_PW_TYPE_MATRIX
Matrix with items.
@ WID_PW_CLASS_SEL
Stack to hide the class picker.
@ WID_PW_MODE_ALL
Toggle "Show all" filter mode.
@ WID_PW_CLASS_SCROLL
Scrollbar for list of classes.
@ WID_PW_SHRINK
Button to reduce preview image height.
@ WID_PW_TYPE_SEL
Stack to hide the type picker.
@ WID_PW_TYPE_NAME
Name of selected item.
@ WID_PW_TYPE_RESIZE
Type resize handle.
Base for the GUIs that have an edit box in them.
A number of safeguards to prevent using unsafe methods.
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
Types related to global configuration settings.
Base types for having sorted lists in GUIs.
Functions related to sound.
Types related to sounds.
@ SND_15_BEEP
19 == 0x13 GUI button click
Definition sound_type.h:66
This file contains all sprite-related enums and defines.
Definition of base types and functions in a cross-platform compatible way.
bool ConvertHexToBytes(std::string_view hex, std::span< uint8_t > bytes)
Convert a hex-string to a byte-array, while validating it was actually hex.
Definition string.cpp:570
Functions related to low-level strings.
Searching and filtering using a stringterm.
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:415
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
static const int MAX_CHAR_LENGTH
Max. length of UTF-8 encoded unicode character.
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
SoundSettings sound
sound effect settings
Dimensions (a width and height) of a rectangle in 2D.
Data about how and where to blit pixels.
Definition gfx_type.h:158
Ini file that supports both loading and saving.
Definition ini_type.h:86
A group within an ini file.
Definition ini_type.h:34
void Clear()
Clear all items in the group.
Definition ini_load.cpp:97
IniItem & CreateItem(std::string_view name)
Create an item with the given name.
Definition ini_load.cpp:80
std::list< IniItem > items
all items in the group
Definition ini_type.h:35
A single "line" in an ini file.
Definition ini_type.h:23
const IniGroup * GetGroup(std::string_view name) const
Get the group with the given name.
Definition ini_load.cpp:118
IniGroup & GetOrCreateGroup(std::string_view name)
Get the group with the given name, and if it doesn't exist create a new group.
Definition ini_load.cpp:146
Partial widget specification to allow NWidgets to be written nested.
const PickerCallbacks * callbacks
Callbacks for filter functions to access to callbacks.
Definition picker_gui.h:149
Coordinates of a point in 2D.
int cancel_button
Widget button of parent window to simulate when pressing CANCEL in OSK.
static const int ACTION_CLEAR
Clear editbox.
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.
int Width() const
Get width of Rect.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
int Height() const
Get height of Rect.
bool click_beep
Beep on a random selection of buttons.
bool IsEmpty() const
Check whether any filter words were entered.
void SetFilterTerm(std::string_view str)
Set the term to filter on.
void ResetState()
Reset the matching state to process a new item.
bool GetState() const
Get the matching state of the current item.
std::string_view GetText() const
Get the current text.
Definition textbuf.cpp:284
High level window description.
Definition window_gui.h:167
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:967
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1778
std::map< WidgetID, QueryString * > querystrings
QueryString associated to WWT_EDITBOX widgets.
Definition window_gui.h:320
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
Definition window.cpp:503
void CloseChildWindows(WindowClass wc=WC_INVALID) const
Close all children a window might have in a head-recursive manner.
Definition window.cpp:1064
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:1768
bool SetFocusedWidget(WidgetID widget_index)
Set focus within this window to the given widget.
Definition window.cpp:484
bool IsWidgetDisabled(WidgetID widget_index) const
Gets the enabled/disabled status of a widget.
Definition window_gui.h:410
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition window_gui.h:441
const NWidgetCore * nested_focus
Currently focused nested widget, or nullptr if no nested widget has focus.
Definition window_gui.h:319
WidgetLookup widget_lookup
Indexed access to the nested widget tree. Do not access directly, use Window::GetWidget() instead.
Definition window_gui.h:322
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition window.cpp:312
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:381
std::unique_ptr< NWidgetBase > nested_root
Root of the nested tree.
Definition window_gui.h:321
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
static RectPadding ScaleGUITrad(const RectPadding &r)
Scale a RectPadding to GUI zoom level.
Definition widget.cpp:49
Definitions about widgets.
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
@ WWT_IMGBTN
(Toggle) Button with image
Definition widget_type.h:42
@ WWT_EDITBOX
a textbox for typing
Definition widget_type.h:63
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:67
@ WWT_TEXTBTN
(Toggle) Button with text
Definition widget_type.h:45
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:40
@ WWT_MATRIX
Grid of rows and columns.
Definition widget_type.h:51
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition widget_type.h:77
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:69
@ WWT_EMPTY
Empty widget, place holder to reserve space in widget tree.
Definition widget_type.h:38
@ WWT_RESIZEBOX
Resize box (normally at bottom-right of a window)
Definition widget_type.h:60
@ NWID_MATRIX
Matrix container.
Definition widget_type.h:70
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:72
@ SZSP_HORIZONTAL
Display plane with zero size vertically, and filling and resizing horizontally.
@ SZSP_VERTICAL
Display plane with zero size horizontally, and filling and resizing vertically.
NWidContainerFlag
Nested widget container flags,.
@ EqualSize
Containers should keep all their (resizing) children equally large.
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:1182
void SetFocusedWindow(Window *w)
Set the window that has the focus.
Definition window.cpp:420
void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope)
Mark window data of all windows of a given class as invalid (in need of re-computing) Note that by de...
Definition window.cpp:3282
Window functions not directly related to making/drawing windows.
Functions, definitions and such used only by the GUI.
Types related to windows.
int WidgetID
Widget ID.
Definition window_type.h:20
EventState
State of handling an event.
@ ES_HANDLED
The passed event is handled.
@ ES_NOT_HANDLED
The passed event is not handled.
@ WC_BUILD_OBJECT
Build object; Window numbers:
@ WC_BUILD_HOUSE
Build house; Window numbers:
@ WC_SELECT_STATION
Select station (when joining stations); Window numbers:
@ WC_TRUCK_STATION
Build truck station; Window numbers:
@ WC_DROPDOWN_MENU
Drop down menu; Window numbers:
@ WC_BUS_STATION
Build bus station; Window numbers:
@ WC_BUILD_WAYPOINT
Build waypoint; Window numbers:
Functions related to zooming.
int ScaleSpriteTrad(int value)
Scale traditional pixel dimensions to GUI zoom level, for drawing sprites.
Definition zoom_func.h:107