OpenTTD Source 20250716-master-g6b6caa6fa8
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 <http://www.gnu.org/licenses/>.
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;
69
71 virtual int GetSelectedType() const = 0;
73 virtual void SetSelectedType(int id) const = 0;
75 virtual PickerItem GetPickerItem(int cls_id, int id) const = 0;
77 virtual StringID GetTypeName(int cls_id, int id) const = 0;
79 virtual std::span<const BadgeID> GetTypeBadges(int cls_id, int id) const = 0;
81 virtual bool IsTypeAvailable(int cls_id, int id) const = 0;
83 virtual void DrawType(int x, int y, int cls_id, int id) const = 0;
84
86 virtual void FillUsedItems(std::set<PickerItem> &items) = 0;
88 virtual std::set<PickerItem> UpdateSavedItems(const std::set<PickerItem> &src) = 0;
89
90 Listing class_last_sorting = { false, 0 };
92
93 Listing type_last_sorting = { false, 0 };
95
96 const std::string ini_group;
97 uint8_t mode = 0;
98
100
101 std::set<PickerItem> used;
102 std::set<PickerItem> saved;
103};
104
106template <typename T>
108public:
109 explicit PickerCallbacksNewGRFClass(const std::string &ini_group) : PickerCallbacks(ini_group) {}
110
111 inline typename T::index_type GetClassIndex(int cls_id) const { return static_cast<typename T::index_type>(cls_id); }
112 inline const T *GetClass(int cls_id) const { return T::Get(this->GetClassIndex(cls_id)); }
113 inline const typename T::spec_type *GetSpec(int cls_id, int id) const { return this->GetClass(cls_id)->GetSpec(id); }
114
115 bool HasClassChoice() const override { return T::GetUIClassCount() > 1; }
116
117 int GetClassCount() const override { return T::GetClassCount(); }
118 int GetTypeCount(int cls_id) const override { return this->GetClass(cls_id)->GetSpecCount(); }
119
120 PickerItem GetPickerItem(const typename T::spec_type *spec, int cls_id = -1, int id = -1) const
121 {
122 if (spec == nullptr) return {0, 0, cls_id, id};
123 return {spec->grf_prop.grfid, spec->grf_prop.local_id, spec->class_index, spec->index};
124 }
125
126 PickerItem GetPickerItem(int cls_id, int id) const override
127 {
128 return GetPickerItem(GetClass(cls_id)->GetSpec(id), cls_id, id);
129 }
130
131 std::set<PickerItem> UpdateSavedItems(const std::set<PickerItem> &src) override
132 {
133 if (src.empty()) return {};
134
135 std::set<PickerItem> dst;
136 for (const auto &item : src) {
137 const auto *spec = T::GetByGrf(item.grfid, item.local_id);
138 if (spec == nullptr) {
139 dst.insert({item.grfid, item.local_id, -1, -1});
140 } else {
141 dst.insert(GetPickerItem(spec));
142 }
143 }
144 return dst;
145 }
146};
147
150 std::optional<BadgeTextFilter> btf;
151 std::optional<BadgeDropdownFilter> bdf;
152};
153
156
158public:
159 enum PickerFilterModes : uint8_t {
163 };
164
165 enum class PickerInvalidation : uint8_t {
166 Class,
167 Type,
168 Position,
169 Validate,
170 Filter,
171 };
172 using PickerInvalidations = EnumBitSet<PickerInvalidation, uint8_t>;
173
174 static constexpr PickerInvalidations PICKER_INVALIDATION_ALL{PickerInvalidation::Class, PickerInvalidation::Type, PickerInvalidation::Position, PickerInvalidation::Validate};
175
176 static constexpr int PREVIEW_WIDTH = 64;
177 static constexpr int PREVIEW_HEIGHT = 48;
178 static constexpr int PREVIEW_LEFT = 31;
179 static constexpr int PREVIEW_BOTTOM = 31;
180
181 static constexpr int STEP_PREVIEW_HEIGHT = 16;
182 static constexpr int MAX_PREVIEW_HEIGHT = PREVIEW_HEIGHT * 3;
183
184 static constexpr uint EDITBOX_MAX_SIZE = 16;
185
186 bool has_class_picker = false;
187 bool has_type_picker = false;
189
191 void OnInit() override;
192 void Close(int data = 0) override;
193 void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override;
194 std::string GetWidgetString(WidgetID widget, StringID stringid) const override;
195 void DrawWidget(const Rect &r, WidgetID widget) const override;
196 void OnDropdownSelect(WidgetID widget, int index, int click_result) override;
197 void OnResize() override;
198 void OnClick(Point pt, WidgetID widget, int click_count) override;
199 void OnInvalidateData(int data = 0, bool gui_scope = true) override;
200 EventState OnHotkey(int hotkey) override;
201 void OnEditboxChanged(WidgetID wid) override;
202
207
208 void InvalidateData(PickerInvalidations data) { this->Window::InvalidateData(data.base()); }
209
210protected:
211 void ConstructWindow();
212
213 PickerCallbacks &callbacks;
214
215private:
217 PickerFilterData class_string_filter;
219
221 void EnsureSelectedClassIsValid();
222 void EnsureSelectedClassIsVisible();
223
225 PickerFilterData type_string_filter;
227
228 void RefreshUsedTypeList();
229 void BuildPickerTypeList();
230 void EnsureSelectedTypeIsValid();
231 void EnsureSelectedTypeIsVisible();
232
233 GUIBadgeClasses badge_classes;
234 std::pair<WidgetID, WidgetID> badge_filters{};
235 BadgeFilterChoices badge_filter_choices{};
236
237 const IntervalTimer<TimerGameCalendar> yearly_interval = {{TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [this](auto) {
238 this->SetDirty();
239 }};
240
241 const IntervalTimer<TimerWindow> refresh_interval = {std::chrono::seconds(3), [this](auto) {
242 RefreshUsedTypeList();
243 }};
244};
245
246class NWidgetBase;
247std::unique_ptr<NWidgetBase> MakePickerClassWidgets();
248std::unique_ptr<NWidgetBase> MakePickerTypeWidgets();
249
250#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:107
PickerItem GetPickerItem(int cls_id, int id) const override
Get data about an item.
Definition picker_gui.h:126
int GetClassCount() const override
Get the number of classes.
Definition picker_gui.h:117
std::set< PickerItem > UpdateSavedItems(const std::set< PickerItem > &src) override
Update link between grfid/localidx and class_index/index in saved items.
Definition picker_gui.h:131
int GetTypeCount(int cls_id) const override
Get the number of types in a class.
Definition picker_gui.h:118
bool HasClassChoice() const override
Are there multiple classes to chose from?
Definition picker_gui.h:115
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
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
static constexpr uint EDITBOX_MAX_SIZE
The maximum number of characters for the filter edit box.
Definition picker_gui.h:184
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
PickerClassWindowHotkeys
Enum referring to the Hotkeys in the picker window.
Definition picker_gui.h:204
@ 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 SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition window.cpp:955
GrfSpecFeature
Definition newgrf.h:69
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.
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:149
Coordinates of a point in 2D.
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:167
Data structure for an opened window.
Definition window_gui.h:273
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing)
Definition window.cpp:3205
Window * parent
Parent window.
Definition window_gui.h:328
ResizeInfo resize
Resize information.
Definition window_gui.h:314
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:302
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.