OpenTTD Source 20260129-master-g2bb01bd0e4
picker_gui.h
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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#ifndef PICKER_GUI_H
11#define PICKER_GUI_H
12
13#include "newgrf_badge.h"
14#include "newgrf_badge_gui.h"
15#include "querystring_gui.h"
16#include "sortlist_type.h"
17#include "stringfilter_type.h"
18#include "strings_type.h"
19#include "timer/timer.h"
21#include "timer/timer_window.h"
22#include "window_gui.h"
23#include "window_type.h"
24
25struct PickerItem {
26 uint32_t grfid;
27 uint16_t local_id;
28 int class_index;
29 int index;
30
31 inline auto operator<=>(const PickerItem &other) const
32 {
33 if (auto cmp = this->grfid <=> other.grfid; cmp != 0) return cmp;
34 return this->local_id <=> other.local_id;
35 }
36};
37
40public:
41 explicit PickerCallbacks(const std::string &ini_group);
42 virtual ~PickerCallbacks();
43
44 virtual void Close(int) { }
45
46 virtual GrfSpecFeature GetFeature() const = 0;
48 virtual bool IsActive() const = 0;
50 virtual bool HasClassChoice() const = 0;
51
52 /* Class callbacks */
54 virtual StringID GetClassTooltip() const = 0;
56 virtual int GetClassCount() const = 0;
58 virtual int GetSelectedClass() const = 0;
60 virtual void SetSelectedClass(int id) const = 0;
62 virtual StringID GetClassName(int id) const = 0;
63
64 /* Type callbacks */
66 virtual StringID GetTypeTooltip() const = 0;
68 virtual int GetTypeCount(int cls_id) const = 0;
70 virtual int GetSelectedType() const = 0;
72 virtual void SetSelectedType(int id) const = 0;
74 virtual PickerItem GetPickerItem(int cls_id, int id) const = 0;
76 virtual StringID GetTypeName(int cls_id, int id) const = 0;
78 virtual std::span<const BadgeID> GetTypeBadges(int cls_id, int id) const = 0;
80 virtual bool IsTypeAvailable(int cls_id, int id) const = 0;
82 virtual void DrawType(int x, int y, int cls_id, int id) const = 0;
83
84 /* Collection Callbacks */
86 virtual StringID GetCollectionTooltip() const = 0;
87
89 virtual void FillUsedItems(std::set<PickerItem> &items) = 0;
91 virtual std::map<std::string, std::set<PickerItem>> UpdateSavedItems(const std::map<std::string, std::set<PickerItem>> &src) = 0;
97 inline std::set<std::string> InitializeInactiveCollections(const std::map<std::string, std::set<PickerItem>> collections)
98 {
99 std::set<std::string> inactive;
100
101 for (const auto &collection : collections) {
102 if ((collection.second.size() == 1 && collection.second.contains({})) || collection.first == "") continue;
103 for (const PickerItem &item : collection.second) {
104 if (item.class_index == -1 || item.index == -1) {
105 inactive.emplace(collection.first);
106 break;
107 }
108 if (GetTypeName(item.class_index, item.index) == INVALID_STRING_ID) {
109 inactive.emplace(collection.first);
110 break;
111 }
112 }
113 }
114 return inactive;
115 }
116
119
120 Listing type_last_sorting = { false, 0 };
122
124
125 const std::string ini_group;
126 uint8_t mode = 0;
127 bool rename_collection = false;
128 std::string sel_collection;
129 std::string edit_collection;
130 std::set<std::string> rm_collections;
131
133
134 std::set<PickerItem> used;
135 std::map<std::string, std::set<PickerItem>> saved;
136};
137
139template <typename T>
141public:
142 explicit PickerCallbacksNewGRFClass(const std::string &ini_group) : PickerCallbacks(ini_group) {}
143
144 inline typename T::index_type GetClassIndex(int cls_id) const { return static_cast<typename T::index_type>(cls_id); }
145 inline const T *GetClass(int cls_id) const { return T::Get(this->GetClassIndex(cls_id)); }
146 inline const typename T::spec_type *GetSpec(int cls_id, int id) const { return this->GetClass(cls_id)->GetSpec(id); }
147
148 bool HasClassChoice() const override { return T::GetUIClassCount() > 1; }
149
150 int GetClassCount() const override { return T::GetClassCount(); }
151 int GetTypeCount(int cls_id) const override { return this->GetClass(cls_id)->GetSpecCount(); }
152
153 PickerItem GetPickerItem(const typename T::spec_type *spec, int cls_id = -1, int id = -1) const
154 {
155 if (spec == nullptr) return {0, 0, cls_id, id};
156 return {spec->grf_prop.grfid, spec->grf_prop.local_id, spec->class_index, spec->index};
157 }
158
159 PickerItem GetPickerItem(int cls_id, int id) const override
160 {
161 return GetPickerItem(GetClass(cls_id)->GetSpec(id), cls_id, id);
162 }
163
164 std::map<std::string, std::set<PickerItem>> UpdateSavedItems(const std::map<std::string, std::set<PickerItem>> &src) override
165 {
166 if (src.empty()) return {};
167
168 std::map<std::string, std::set<PickerItem>> dst;
169 for (auto it = src.begin(); it != src.end(); it++) {
170 if (it->second.empty() || (it->second.size() == 1 && it->second.contains({}))) {
171 dst[it->first];
172 continue;
173 }
174
175 for (const auto &item : it->second) {
176 const auto *spec = T::GetByGrf(item.grfid, item.local_id);
177 if (spec == nullptr) {
178 dst[it->first].emplace(item.grfid, item.local_id, -1, -1);
179 } else {
180 dst[it->first].emplace(GetPickerItem(spec));
181 }
182 }
183 }
184 return dst;
185 }
186};
187
190 std::optional<BadgeTextFilter> btf;
191 std::optional<BadgeDropdownFilter> bdf;
192};
193
197
199public:
200 enum PickerFilterModes : uint8_t {
204 };
205
207 enum class PickerInvalidation : uint8_t {
208 Class,
209 Type,
210 Collection,
211 Position,
212 Validate,
213 Filter,
214 };
215 using PickerInvalidations = EnumBitSet<PickerInvalidation, uint8_t>;
216
217 static constexpr PickerInvalidations PICKER_INVALIDATION_ALL{PickerInvalidation::Class, PickerInvalidation::Type, PickerInvalidation::Position, PickerInvalidation::Validate};
218
219 static constexpr int PREVIEW_WIDTH = 64;
220 static constexpr int PREVIEW_HEIGHT = 48;
221 static constexpr int PREVIEW_LEFT = 31;
222 static constexpr int PREVIEW_BOTTOM = 31;
223
224 static constexpr int STEP_PREVIEW_HEIGHT = 16;
225 static constexpr int MAX_PREVIEW_HEIGHT = PREVIEW_HEIGHT * 3;
226
227 static constexpr uint EDITBOX_MAX_SIZE = 16;
228
229 bool has_class_picker = false;
230 bool has_type_picker = false;
233 std::set<std::string> inactive;
234
236 void OnInit() override;
237 void Close(int data = 0) override;
238 void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override;
239 std::string GetWidgetString(WidgetID widget, StringID stringid) const override;
240 DropDownList BuildCollectionDropDownList();
241 void DrawWidget(const Rect &r, WidgetID widget) const override;
242 void OnDropdownSelect(WidgetID widget, int index, int click_result) override;
243 void OnResize() override;
244 void static DeletePickerCollectionCallback(Window *win, bool confirmed);
245 void OnClick(Point pt, WidgetID widget, int click_count) override;
246 void OnQueryTextFinished(std::optional<std::string> str) override;
247 void OnInvalidateData(int data = 0, bool gui_scope = true) override;
248 EventState OnHotkey(int hotkey) override;
249 void OnEditboxChanged(WidgetID wid) override;
250
255
256 void InvalidateData(PickerInvalidations data) { this->Window::InvalidateData(data.base()); }
257
258protected:
259 void ConstructWindow();
260
261 PickerCallbacks &callbacks;
262
263private:
265 PickerFilterData class_string_filter;
267
269 void EnsureSelectedClassIsValid();
270 void EnsureSelectedClassIsVisible();
271
273 PickerFilterData type_string_filter;
275
276 void RefreshUsedTypeList();
277 void BuildPickerTypeList();
278 void EnsureSelectedTypeIsValid();
279 void EnsureSelectedTypeIsVisible();
280
282
284
285 GUIBadgeClasses badge_classes;
286 std::pair<WidgetID, WidgetID> badge_filters{};
287 BadgeFilterChoices badge_filter_choices{};
288
289 const IntervalTimer<TimerGameCalendar> yearly_interval = {{TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [this](auto) {
290 this->SetDirty();
291 }};
292
293 const IntervalTimer<TimerWindow> refresh_interval = {std::chrono::seconds(3), [this](auto) {
294 RefreshUsedTypeList();
295 }};
296};
297
298class NWidgetBase;
299std::unique_ptr<NWidgetBase> MakePickerClassWidgets();
300std::unique_ptr<NWidgetBase> MakePickerTypeWidgets();
301
302#endif /* PICKER_GUI_H */
Enum-as-bit-set wrapper.
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
Baseclass for nested widgets.
Helper for PickerCallbacks when the class system is based on NewGRFClass.
Definition picker_gui.h:140
std::map< std::string, std::set< PickerItem > > UpdateSavedItems(const std::map< std::string, std::set< PickerItem > > &src) override
Update link between grfid/localidx and class_index/index in saved items.
Definition picker_gui.h:164
PickerItem GetPickerItem(int cls_id, int id) const override
Get data about an item.
Definition picker_gui.h:159
int GetClassCount() const override
Get the number of classes.
Definition picker_gui.h:150
int GetTypeCount(int cls_id) const override
Get the number of types in a class.
Definition picker_gui.h:151
bool HasClassChoice() const override
Are there multiple classes to chose from?
Definition picker_gui.h:148
Class for PickerClassWindow to collect information and retain state.
Definition picker_gui.h:39
std::set< std::string > InitializeInactiveCollections(const std::map< std::string, std::set< PickerItem > > collections)
Initialize the list of active collections for sorting purposes.
Definition picker_gui.h:97
virtual int GetSelectedClass() const =0
Get the index of the selected class.
std::string edit_collection
Collection to rename or delete.
Definition picker_gui.h:129
Filtering type_last_filtering
Default filtering of PickerTypeList.
Definition picker_gui.h:121
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:125
bool rename_collection
Are we renaming a collection?
Definition picker_gui.h:127
Listing collection_last_sorting
Default sorting of PickerCollectionList.
Definition picker_gui.h:123
virtual void SetSelectedClass(int id) const =0
Set the selected class.
std::string sel_collection
Currently selected collection of saved items.
Definition picker_gui.h:128
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:120
virtual StringID GetCollectionTooltip() const =0
Get the tooltip string for the collection list.
std::set< PickerItem > used
Set of items used in the current game by the current company.
Definition picker_gui.h:134
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:132
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.
virtual std::map< std::string, std::set< PickerItem > > UpdateSavedItems(const std::map< std::string, std::set< PickerItem > > &src)=0
Update link between grfid/localidx and class_index/index in saved items.
Filtering class_last_filtering
Default filtering of PickerClassList.
Definition picker_gui.h:118
std::set< std::string > rm_collections
Set of removed or renamed collections for updating ini file.
Definition picker_gui.h:130
std::map< std::string, std::set< PickerItem > > saved
Set of saved collections of items.
Definition picker_gui.h:135
virtual int GetSelectedType() const =0
Get the selected type.
uint8_t mode
Bitmask of PickerFilterModes.
Definition picker_gui.h:126
Listing class_last_sorting
Default sorting of PickerClassList.
Definition picker_gui.h:117
Base class for windows opened from a toolbar.
Definition window_gui.h:993
static constexpr int MAX_PREVIEW_HEIGHT
Maximum height of each preview button.
Definition picker_gui.h:225
static constexpr int PREVIEW_WIDTH
Width of each preview button.
Definition picker_gui.h:219
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:232
bool has_class_picker
Set if this window has a class picker 'component'.
Definition picker_gui.h:229
static constexpr int PREVIEW_HEIGHT
Height of each preview button.
Definition picker_gui.h:220
static constexpr uint EDITBOX_MAX_SIZE
The maximum number of characters for the filter edit box.
Definition picker_gui.h:227
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
PickerInvalidation
The things of a picker that can be invalidated.
Definition picker_gui.h:207
@ 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'.
Definition picker_gui.h:231
static constexpr int PREVIEW_LEFT
Offset from left edge to draw preview.
Definition picker_gui.h:221
PickerTypeList types
List of types.
Definition picker_gui.h:272
std::set< std::string > inactive
Set of collections with inactive items.
Definition picker_gui.h:233
QueryString class_editbox
Filter editbox.
Definition picker_gui.h:266
bool has_type_picker
Set if this window has a type picker 'component'.
Definition picker_gui.h:230
void BuildPickerClassList()
Builds the filter list of classes.
@ PFM_USED
Show used types.
Definition picker_gui.h:202
@ PFM_ALL
Show all classes.
Definition picker_gui.h:201
@ PFM_SAVED
Show saved types.
Definition picker_gui.h:203
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.
Definition picker_gui.h:222
PickerClassWindowHotkeys
Enum referring to the Hotkeys in the picker window.
Definition picker_gui.h:252
@ PCWHK_FOCUS_FILTER_BOX
Focus the edit box for editing the filter string.
Definition picker_gui.h:253
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
PickerCollectionList collections
List of collections.
Definition picker_gui.h:281
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:274
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:264
static constexpr int STEP_PREVIEW_HEIGHT
Step for decreasing or increase preview button height.
Definition picker_gui.h:224
std::vector< std::unique_ptr< const DropDownListItem > > DropDownList
A drop down list is a collection of drop down list items.
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition window.cpp:968
GrfSpecFeature
Definition newgrf.h:69
Functions related to NewGRF badges.
GUI functions related to NewGRF badges.
std::unique_ptr< NWidgetBase > MakePickerClassWidgets()
Create nested widgets for the class picker widgets.
std::unique_ptr< NWidgetBase > MakePickerTypeWidgets()
Create nested widgets for the type picker widgets.
Base for the GUIs that have an edit box in them.
Base types for having sorted lists in GUIs.
Searching and filtering using a stringterm.
Types related to 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)
Dimensions (a width and height) of a rectangle in 2D.
Data structure describing what to show in the list (filter criteria).
Data structure describing how to show the list (what sort direction and criteria).
const PickerCallbacks * callbacks
Callbacks for filter functions to access to callbacks.
Definition picker_gui.h:189
Data stored about a string that can be modified in the GUI.
Specification of a rectangle with absolute coordinates of all edges.
String filter and state.
High level window description.
Definition window_gui.h:168
Data structure for an opened window.
Definition window_gui.h:274
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing)
Definition window.cpp:3240
Window * parent
Parent window.
Definition window_gui.h:329
ResizeInfo resize
Resize information.
Definition window_gui.h:315
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:303
Definition of Interval and OneShot timers.
Definition of the game-calendar-timer.
Definition of the Window system.
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.