38#include "table/strings.h"
44static std::vector<PickerCallbacks *> &GetPickerCallbacks()
46 static std::vector<PickerCallbacks *> callbacks;
50PickerCallbacks::PickerCallbacks(
const std::string &ini_group) : ini_group(ini_group)
52 GetPickerCallbacks().push_back(
this);
55PickerCallbacks::~PickerCallbacks()
57 auto &callbacks = GetPickerCallbacks();
58 callbacks.erase(std::ranges::find(callbacks,
this));
68 callbacks.
saved.clear();
72 auto pos = group.
name.find(
'-');
73 if (pos == std::string_view::npos && group.
name != callbacks.
ini_group)
continue;
74 std::string collection = (pos == std::string_view::npos) ?
"" : group.
name.substr(pos + 1);
76 if (group.
items.empty() && pos != std::string_view::npos) {
77 callbacks.
saved[collection];
82 std::array<uint8_t, 4> grfid_buf;
84 std::string_view str = item.
name;
87 auto grfid_pos = str.find(
'|');
88 if (grfid_pos == std::string_view::npos)
continue;
90 std::string_view grfid_str = str.substr(0, grfid_pos);
93 str = str.substr(grfid_pos + 1);
94 uint32_t grfid = grfid_buf[0] | (grfid_buf[1] << 8) | (grfid_buf[2] << 16) | (grfid_buf[3] << 24);
96 auto [ptr, err] = std::from_chars(str.data(), str.data() + str.size(), localid);
98 if (err == std::errc{} && ptr == str.data() + str.size()) {
99 callbacks.
saved[collection].emplace(grfid, localid, 0, 0);
113 for (
const std::string &rm_collection : callbacks.
rm_collections) {
117 for (
const auto &collection : callbacks.
saved) {
120 for (
const PickerItem &item : collection.second) {
121 std::string key = fmt::format(
"{:08X}|{}",
std::byteswap(item.grfid), item.local_id);
162 int r = a.class_index - b.class_index;
163 if (r == 0) r = a.index - b.index;
171 if (filter.bdf.has_value() && !filter.bdf->Filter(badges))
return false;
172 if (filter.btf.has_value() && filter.btf->Filter(badges))
return true;
190 if (a ==
GetString(STR_PICKER_DEFAULT_COLLECTION) || b ==
GetString(STR_PICKER_DEFAULT_COLLECTION))
return a ==
GetString(STR_PICKER_DEFAULT_COLLECTION);
206 this->window_number = window_number;
212void PickerWindow::ConstructWindow()
217 bool is_active = this->callbacks.IsActive();
234 bool is_vertical = (nwid->parent->parent->type ==
NWID_VERTICAL);
240 this->class_string_filter.SetFilterTerm(this->
class_editbox.text.GetText());
241 this->class_string_filter.callbacks = &this->callbacks;
243 this->
classes.SetListing(this->callbacks.class_last_sorting);
244 this->
classes.SetFiltering(this->callbacks.class_last_filtering);
250 this->callbacks.saved = this->callbacks.UpdateSavedItems(this->callbacks.saved);
251 this->
inactive = this->callbacks.InitializeInactiveCollections(this->callbacks.saved);
255 this->callbacks.used.clear();
259 this->callbacks.FillUsedItems(this->callbacks.used);
272 bool is_vertical = (nwid->parent->parent->type ==
NWID_VERTICAL);
278 this->type_string_filter.SetFilterTerm(this->
type_editbox.text.GetText());
279 this->type_string_filter.callbacks = &this->callbacks;
281 this->
types.SetListing(this->callbacks.type_last_sorting);
282 this->
types.SetFiltering(this->callbacks.type_last_filtering);
290 this->
collections.SetListing(this->callbacks.collection_last_sorting);
295 this->InvalidateData(PICKER_INVALIDATION_ALL);
309 this->callbacks.Close(data);
319 size.height = 5 *
resize.height;
325 size.width +=
resize.width;
326 fill.width =
resize.width;
341 if (this->badge_classes.GetClasses().empty()) size = {0, 0};
350 return this->callbacks.sel_collection ==
"" ?
GetString(STR_PICKER_DEFAULT_COLLECTION) : this->callbacks.sel_collection;
353 if (
IsInsideMM(widget, this->badge_filters.first, this->badge_filters.second)) {
366 list.push_back(MakeDropDownListStringItem(
GetString(collection ==
"" ? STR_PICKER_DEFAULT_COLLECTION : STR_JUST_RAW_STRING, collection), i,
false, this->
inactive.contains(collection)));
378 const int selected = this->callbacks.GetSelectedClass();
381 auto [first, last] = vscroll->GetVisibleRangeIterators(this->
classes);
382 for (
auto it = first; it != last; ++it) {
383 DrawString(ir, this->callbacks.GetClassName(*it), *it == selected ? TC_WHITE : TC_BLACK);
391 assert(this->
GetWidget<NWidgetBase>(widget)->GetParentWidget<NWidgetMatrix>()->GetCurrentElement() <
static_cast<int>(this->
types.size()));
401 this->callbacks.DrawType(x, y, item.class_index, item.index);
408 DrawBadgeColumn({0, by, ir.
Width() - 1, ir.
Height() - 1}, 0, this->badge_classes, this->callbacks.GetTypeBadges(item.class_index, item.index), feature, std::nullopt, palette);
410 if (this->callbacks.saved.contains(this->callbacks.sel_collection)) {
411 if (this->callbacks.saved.at(this->callbacks.sel_collection).contains(item)) {
412 DrawSprite(SPR_BLOT, PALETTE_TO_YELLOW, 0, 0);
415 if (this->callbacks.used.contains(item)) {
420 if (!this->callbacks.IsTypeAvailable(item.class_index, item.index)) {
427 StringID str = this->callbacks.GetTypeName(this->callbacks.GetSelectedClass(), this->callbacks.GetSelectedType());
441void PickerWindow::DeletePickerCollectionCallback(
Window *win,
bool confirmed)
463 if (it == this->
classes.end())
return;
465 if (this->callbacks.GetSelectedClass() != *it ||
HasBit(this->callbacks.mode,
PFM_ALL)) {
467 this->callbacks.SetSelectedClass(*it);
489 this->InvalidateData({});
495 this->InvalidateData({});
502 assert(sel < (
int)this->
types.size());
503 const auto &item = this->
types[sel];
506 if (this->callbacks.saved.find(this->callbacks.sel_collection) == this->callbacks.saved.end()) {
507 this->callbacks.saved[
""].emplace(item);
513 auto it = this->callbacks.saved.at(this->callbacks.sel_collection).find(item);
514 if (it == std::end(this->callbacks.saved.at(this->callbacks.sel_collection))) {
515 this->callbacks.saved.at(this->callbacks.sel_collection).emplace(item);
517 this->callbacks.saved.at(this->callbacks.sel_collection).erase(it);
523 if (this->callbacks.IsTypeAvailable(item.class_index, item.index)) {
524 this->callbacks.SetSelectedClass(item.class_index);
525 this->callbacks.SetSelectedType(item.index);
540 this->callbacks.rename_collection =
false;
545 if (this->callbacks.saved.contains(this->callbacks.sel_collection)) {
547 this->callbacks.edit_collection = this->callbacks.sel_collection;
548 this->callbacks.rename_collection =
true;
554 if (this->callbacks.saved.contains(this->callbacks.sel_collection)) {
556 this->callbacks.edit_collection = this->callbacks.sel_collection;
558 this->
inactive.contains(this->callbacks.sel_collection) ?
565 if (this->badge_classes.GetClasses().empty())
break;
570 if (
IsInsideMM(widget, this->badge_filters.first, this->badge_filters.second)) {
581 if (!str.has_value())
return;
583 if (!this->callbacks.saved.contains(*str)) {
584 if (this->callbacks.saved.contains(this->callbacks.edit_collection) && this->callbacks.rename_collection) {
585 auto rename_collection = this->callbacks.saved.extract(this->callbacks.edit_collection);
586 rename_collection.key() = *str;
587 this->callbacks.saved.insert(std::move(rename_collection));
589 if (this->
inactive.contains(this->callbacks.edit_collection)) {
590 this->
inactive.erase(this->callbacks.edit_collection);
594 this->callbacks.rm_collections.emplace(this->callbacks.edit_collection);
595 this->callbacks.edit_collection.clear();
598 this->callbacks.saved.insert({*str, {}});
602 this->callbacks.sel_collection = *str;
615 auto it = this->collections.begin() + index;
616 if (this->callbacks.sel_collection != *it) {
617 this->callbacks.sel_collection = *it;
633 ReplaceDropDownList(
this, BuildBadgeClassConfigurationList(this->badge_classes, 1, {}, COLOUR_DARK_GREEN), -1);
644 if (
IsInsideMM(widget, this->badge_filters.first, this->badge_filters.second)) {
658 if (!gui_scope)
return;
660 PickerInvalidations pi(data);
663 if (this->badge_filter_choices.empty()) {
664 this->type_string_filter.bdf.reset();
666 this->type_string_filter.bdf.emplace(this->badge_filter_choices);
668 this->
types.SetFilterState(!type_string_filter.IsEmpty() || type_string_filter.bdf.has_value());
717 this->class_string_filter.SetFilterTerm(this->
class_editbox.text.GetText());
718 this->
classes.SetFilterState(!class_string_filter.IsEmpty());
723 this->type_string_filter.SetFilterTerm(this->
type_editbox.text.GetText());
724 if (!type_string_filter.IsEmpty()) {
725 this->type_string_filter.btf.emplace(this->type_string_filter, this->callbacks.GetFeature());
727 this->type_string_filter.btf.reset();
740 if (!this->
classes.NeedRebuild())
return;
742 int count = this->callbacks.GetClassCount();
749 for (
int i = 0; i < count; i++) {
751 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;
752 if (filter_saved && this->callbacks.saved.find(this->callbacks.sel_collection) == this->callbacks.saved.end())
continue;
753 if (filter_saved && std::none_of(std::begin(this->callbacks.saved.at(this->callbacks.sel_collection)), std::end(this->callbacks.saved.at(this->callbacks.sel_collection)), [i](
const PickerItem &item) { return item.class_index == i; }))
continue;
757 this->
classes.Filter(this->class_string_filter);
765void PickerWindow::EnsureSelectedClassIsValid()
768 if (std::binary_search(std::begin(this->
classes), std::end(this->
classes), class_index))
return;
771 class_index = this->
classes.front();
774 int count = this->callbacks.GetClassCount();
775 for (
int i = 0; i < count; i++) {
782 this->callbacks.SetSelectedClass(class_index);
783 this->
types.ForceRebuild();
786void PickerWindow::EnsureSelectedClassIsVisible()
789 if (this->
classes.empty())
return;
791 auto it = std::ranges::find(this->
classes, this->callbacks.GetSelectedClass());
792 if (it == std::end(this->
classes))
return;
794 int pos =
static_cast<int>(std::distance(std::begin(this->
classes), it));
798void PickerWindow::RefreshUsedTypeList()
802 this->callbacks.used.clear();
803 this->callbacks.FillUsedItems(this->callbacks.used);
810 if (!this->
types.NeedRebuild())
return;
817 int cls_id = this->callbacks.GetSelectedClass();
821 this->
types.reserve(this->callbacks.used.size());
822 for (
const PickerItem &item : this->callbacks.used) {
823 if (!show_all && item.class_index != cls_id)
continue;
824 if (this->callbacks.GetTypeName(item.class_index, item.index) ==
INVALID_STRING_ID)
continue;
825 this->
types.emplace_back(item);
827 }
else if (filter_saved && this->callbacks.saved.contains(this->callbacks.sel_collection)) {
829 this->
types.reserve(std::size(this->callbacks.saved.at(this->callbacks.sel_collection)));
830 for (
const PickerItem &item : this->callbacks.saved.at(this->callbacks.sel_collection)) {
832 if (item.class_index == -1)
continue;
833 if (!show_all && item.class_index != cls_id)
continue;
834 if (this->callbacks.GetTypeName(item.class_index, item.index) ==
INVALID_STRING_ID)
continue;
835 this->
types.emplace_back(item);
837 }
else if (show_all) {
840 for (
int class_index : this->
classes) total += this->callbacks.GetTypeCount(class_index);
841 this->
types.reserve(total);
843 for (
int class_index : this->classes) {
844 int count = this->callbacks.GetTypeCount(class_index);
845 for (
int i = 0; i < count; i++) {
847 this->
types.emplace_back(this->callbacks.GetPickerItem(class_index, i));
852 if (cls_id >= 0 && cls_id < this->callbacks.GetClassCount()) {
853 int count = this->callbacks.GetTypeCount(cls_id);
854 this->
types.reserve(count);
855 for (
int i = 0; i < count; i++) {
857 this->
types.emplace_back(this->callbacks.GetPickerItem(cls_id, i));
862 this->
types.Filter(this->type_string_filter);
863 this->
types.RebuildDone();
870void PickerWindow::EnsureSelectedTypeIsValid()
874 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;
876 if (!this->
types.empty()) {
877 class_index = this->
types.front().class_index;
878 index = this->
types.front().index;
881 int count = this->callbacks.GetTypeCount(class_index);
882 for (
int i = 0; i < count; i++) {
888 this->callbacks.SetSelectedClass(class_index);
889 this->callbacks.SetSelectedType(index);
892void PickerWindow::EnsureSelectedTypeIsVisible()
895 if (this->
types.empty()) {
900 int class_index = this->callbacks.GetSelectedClass();
901 int index = this->callbacks.GetSelectedType();
903 auto it = std::ranges::find_if(this->
types, [class_index, index](
const auto &item) {
return item.class_index == class_index && item.index == index; });
905 if (it != std::end(this->
types)) {
906 pos =
static_cast<int>(std::distance(std::begin(this->
types), it));
915 if (!this->collections.NeedRebuild())
return;
917 int count = std::max(
static_cast<int>(this->callbacks.saved.size()), 1);
919 this->collections.clear();
920 this->collections.reserve(count);
922 if (this->callbacks.saved.find(
"") == this->callbacks.saved.end()) {
923 this->collections.emplace_back(
"");
926 for (
auto it = this->callbacks.saved.begin(); it != this->callbacks.saved.end(); it++) {
927 this->collections.emplace_back(it->first);
930 this->collections.RebuildDone();
931 this->collections.Sort();
939 static constexpr std::initializer_list<NWidgetPart> picker_class_widgets = {
943 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),
952 NWidget(
WWT_DROPDOWN, COLOUR_DARK_GREEN,
WID_PW_COLEC_LIST),
SetMinimalSize(144, 12),
SetFill(0, 1),
SetResize(1, 0),
SetToolTip(STR_PICKER_SELECT_COLLECTION_TOOLTIP),
974 static constexpr std::initializer_list<NWidgetPart> picker_type_widgets = {
979 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),
981 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),
1003 NWidget(
WWT_EMPTY, INVALID_COLOUR,
WID_PW_TYPE_NAME),
SetPadding(
WidgetDimensions::unscaled.framerect),
SetResize(1, 0),
SetFill(1, 0),
SetMinimalTextLines(1, 0),
1014void InvalidateAllPickerWindows()
Class for backupping variables and making sure they are restored later.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr enable_if_t< is_integral_v< T >, T > byteswap(T x) noexcept
Custom implementation of std::byteswap; remove once we build with C++23.
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.
Class for PickerClassWindow to collect information and retain state.
virtual int GetSelectedClass() const =0
Get the index of the selected class.
std::string edit_collection
Collection to rename or delete.
const std::string ini_group
Ini Group for saving favourites.
std::string sel_collection
Currently selected collection of saved items.
virtual StringID GetTypeName(int cls_id, int id) const =0
Get the item of a type.
virtual StringID GetClassName(int id) const =0
Get the name of a class.
virtual std::span< const BadgeID > GetTypeBadges(int cls_id, int id) const =0
Get the item of a type.
std::set< std::string > rm_collections
Set of removed or renamed collections for updating ini file.
std::map< std::string, std::set< PickerItem > > saved
Set of saved collections of items.
virtual int GetSelectedType() const =0
Get the selected type.
Base class for windows opened from a toolbar.
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
static constexpr int MAX_PREVIEW_HEIGHT
Maximum height of each preview button.
static constexpr int PREVIEW_WIDTH
Width of each preview button.
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.
bool has_class_picker
Set if this window has a class picker 'component'.
static constexpr int PREVIEW_HEIGHT
Height of each preview button.
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.
@ Collection
Refresh the collection list.
@ Filter
Update filter state.
bool has_collection_picker
Set if this window has a collection picker 'component'.
static constexpr int PREVIEW_LEFT
Offset from left edge to draw preview.
PickerTypeList types
List of types.
std::set< std::string > inactive
Set of collections with inactive items.
QueryString class_editbox
Filter editbox.
bool has_type_picker
Set if this window has a type picker 'component'.
void BuildPickerClassList()
Builds the filter list of classes.
@ PFM_USED
Show used types.
@ PFM_ALL
Show all classes.
@ PFM_SAVED
Show saved types.
void BuildPickerCollectionList()
Builds the filter list of collections.
void OnEditboxChanged(WidgetID wid) override
The text in an editbox has been edited.
void OnQueryTextFinished(std::optional< std::string > str) override
The query window opened from this window has closed.
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.
@ PCWHK_FOCUS_FILTER_BOX
Focus the edit box for editing the filter string.
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
PickerCollectionList collections
List of collections.
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.
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.
static constexpr int STEP_PREVIEW_HEIGHT
Step for decreasing or increase preview button height.
PaletteID GetCompanyPalette(CompanyID company)
Get the palette for recolouring with a company colour.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Functions related to companies.
void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width, DropDownOptions options)
Show a drop down list.
Functions related to the drop down widget.
std::vector< std::unique_ptr< const DropDownListItem > > DropDownList
A drop down list is a collection of drop down list items.
@ Persist
Set if this dropdown should stay open after an option is selected.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
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.
bool _ctrl_pressed
Is Ctrl pressed?
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
void GfxFillRect(int left, int top, int right, int bottom, const std::variant< PixelColour, PaletteID > &colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen.
bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int height)
Set up a clipping area for only drawing into a certain area.
@ FS_NORMAL
Index of the normal font in the font tables.
@ SA_CENTER
Center both horizontally and vertically.
uint32_t PaletteID
The number of the palette.
@ FILLRECT_CHECKER
Draw only every second pixel, used for greying-out.
void SetDirty() const
Mark entire window as dirty (in need of re-paint).
static const uint MAX_LENGTH_GROUP_NAME_CHARS
The maximum length of a group name in characters including '\0'.
GUI functions that shouldn't be here.
Hotkey related functions.
Types related to reading/writing '*.ini' files.
#define Point
Macro that prevents name conflicts between included headers.
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
void ShowQuery(EncodedString &&caption, EncodedString &&message, Window *parent, QueryCallbackProc *callback, bool focus)
Show a confirmation window with standard 'yes' and 'no' buttons The window is aligned to the centre o...
void ShowQueryString(std::string_view str, StringID caption, uint maxsize, Window *parent, CharSetFilter afilter, QueryStringFlags flags)
Show a query popup window with a textbox in it.
Functions related to NewGRF badges.
Functions related to NewGRF badge configuration.
void DrawBadgeColumn(Rect r, int column_group, const GUIBadgeClasses &gui_classes, std::span< const BadgeID > badges, GrfSpecFeature feature, std::optional< TimerGameCalendar::Date > introduction_date, PaletteID remap)
Draw a badge column group.
std::pair< WidgetID, WidgetID > AddBadgeDropdownFilters(Window *window, WidgetID container_id, WidgetID widget, Colours colour, GrfSpecFeature feature)
Add badge drop down filter widgets.
bool HandleBadgeConfigurationDropDownClick(GrfSpecFeature feature, uint columns, int result, int click_result, BadgeFilterChoices &choices)
Handle the badge configuration drop down selection.
void SetBadgeFilter(BadgeFilterChoices &choices, BadgeID badge_index)
Set badge filter choice for a class.
void ResetBadgeFilter(BadgeFilterChoices &choices, BadgeClassID badge_class_index)
Reset badge filter choice for a class.
GUI functions related to NewGRF badges.
PixelColour GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
PickerWindow * picker_window
Allow the collection sorter to test if the collection has inactive items.
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 const std::initializer_list< PickerCollectionList::SortFunction *const > _collection_sorter_funcs
Sort functions of the PickerCollectionList.
static bool CollectionIDSorter(std::string const &a, std::string const &b)
Sort collections by id.
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.
Base for the GUIs that have an edit box in them.
A number of safeguards to prevent using unsafe methods.
Types related to global configuration settings.
Base types for having sorted lists in GUIs.
void SndClickBeep()
Play a beep sound for a click event if enabled in settings.
Functions related to sound.
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.
int StrNaturalCompare(std::string_view s1, std::string_view s2, bool ignore_garbage_at_front)
Compares two strings using case insensitive natural sort.
Functions related to low-level strings.
@ CS_ALPHANUMERAL
Both numeric and alphabetic and spaces and stuff.
Searching and filtering using a stringterm.
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
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...
Dimensions (a width and height) of a rectangle in 2D.
Data about how and where to blit pixels.
Ini file that supports both loading and saving.
A group within an ini file.
void Clear()
Clear all items in the group.
std::string name
name of group
IniItem & CreateItem(std::string_view name)
Create an item with the given name.
std::list< IniItem > items
all items in the group
A single "line" in an ini file.
std::string name
The name of this item.
std::list< IniGroup > groups
all groups in the ini
void RemoveGroup(std::string_view name)
Remove the group with the given name.
IniGroup & GetOrCreateGroup(std::string_view name)
Get the group with the given name, and if it doesn't exist create a new group.
const PickerCallbacks * callbacks
Callbacks for filter functions to access to callbacks.
static const int ACTION_CLEAR
Clear editbox.
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.
void ResetState()
Reset the matching state to process a new item.
bool GetState() const
Get the matching state of the current item.
High level window description.
Data structure for an opened window.
void ReInit(int rx=0, int ry=0, bool reposition=false)
Re-initialize a window, and optionally change its size.
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
std::map< WidgetID, QueryString * > querystrings
QueryString associated to WWT_EDITBOX widgets.
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
void CloseChildWindows(WindowClass wc=WC_INVALID) const
Close all children a window might have in a head-recursive manner.
ResizeInfo resize
Resize information.
void SetWidgetsDisabledState(bool disab_stat, Args... widgets)
Sets the enabled/disabled status of a list of widgets.
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
bool SetFocusedWidget(WidgetID widget_index)
Set focus within this window to the given widget.
bool IsWidgetLowered(WidgetID widget_index) const
Gets the lowered state of a widget.
bool IsWidgetDisabled(WidgetID widget_index) const
Gets the enabled/disabled status of a widget.
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
const NWidgetCore * nested_focus
Currently focused nested widget, or nullptr if no nested widget has focus.
WidgetLookup widget_lookup
Indexed access to the nested widget tree. Do not access directly, use Window::GetWidget() instead.
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
std::unique_ptr< NWidgetBase > nested_root
Root of the nested tree.
int width
width of the window (number of pixels to the right in x direction)
WindowNumber window_number
Window number within the window class.
@ LengthIsInChars
the length of the string is counted in characters
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
void SetFocusedWindow(Window *w)
Set the window that has the focus.
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...
Window functions not directly related to making/drawing windows.
Functions, definitions and such used only by the GUI.
Types related to windows.
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_CONFIRM_POPUP_QUERY
Popup with confirm question; 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_QUERY_STRING
Query string window; 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.