OpenTTD Source  20241108-master-g80f628063a
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 "querystring_gui.h"
14 #include "sortlist_type.h"
15 #include "stringfilter_type.h"
16 #include "strings_type.h"
17 #include "timer/timer.h"
19 #include "timer/timer_window.h"
20 #include "window_gui.h"
21 #include "window_type.h"
22 
23 struct PickerItem {
24  uint32_t grfid;
25  uint16_t local_id;
26  int class_index;
27  int index;
28 
29  inline auto operator<=>(const PickerItem &other) const
30  {
31  if (auto cmp = this->grfid <=> other.grfid; cmp != 0) return cmp;
32  return this->local_id <=> other.local_id;
33  }
34 };
35 
38 public:
39  explicit PickerCallbacks(const std::string &ini_group);
40  virtual ~PickerCallbacks();
41 
42  virtual void Close(int) { }
43 
45  virtual bool IsActive() const = 0;
47  virtual bool HasClassChoice() const = 0;
48 
49  /* Class callbacks */
51  virtual StringID GetClassTooltip() const = 0;
53  virtual int GetClassCount() const = 0;
55  virtual int GetSelectedClass() const = 0;
57  virtual void SetSelectedClass(int id) const = 0;
59  virtual StringID GetClassName(int id) const = 0;
60 
61  /* Type callbacks */
63  virtual StringID GetTypeTooltip() const = 0;
65  virtual int GetTypeCount(int cls_id) const = 0;
66 
68  virtual int GetSelectedType() const = 0;
70  virtual void SetSelectedType(int id) const = 0;
72  virtual PickerItem GetPickerItem(int cls_id, int id) const = 0;
74  virtual StringID GetTypeName(int cls_id, int id) const = 0;
76  virtual bool IsTypeAvailable(int cls_id, int id) const = 0;
78  virtual void DrawType(int x, int y, int cls_id, int id) const = 0;
79 
81  virtual void FillUsedItems(std::set<PickerItem> &items) = 0;
83  virtual std::set<PickerItem> UpdateSavedItems(const std::set<PickerItem> &src) = 0;
84 
85  Listing class_last_sorting = { false, 0 };
87 
88  Listing type_last_sorting = { false, 0 };
89  Filtering type_last_filtering = { false, 0 };
90 
91  const std::string ini_group;
92  uint8_t mode = 0;
93 
94  std::set<PickerItem> used;
95  std::set<PickerItem> saved;
96 };
97 
99 template <typename T>
101 public:
102  explicit PickerCallbacksNewGRFClass(const std::string &ini_group) : PickerCallbacks(ini_group) {}
103 
104  inline typename T::index_type GetClassIndex(int cls_id) const { return static_cast<typename T::index_type>(cls_id); }
105  inline const T *GetClass(int cls_id) const { return T::Get(this->GetClassIndex(cls_id)); }
106  inline const typename T::spec_type *GetSpec(int cls_id, int id) const { return this->GetClass(cls_id)->GetSpec(id); }
107 
108  bool HasClassChoice() const override { return T::GetUIClassCount() > 1; }
109 
110  int GetClassCount() const override { return T::GetClassCount(); }
111  int GetTypeCount(int cls_id) const override { return this->GetClass(cls_id)->GetSpecCount(); }
112 
113  PickerItem GetPickerItem(const typename T::spec_type *spec, int cls_id = -1, int id = -1) const
114  {
115  if (spec == nullptr) return {0, 0, cls_id, id};
116  return {spec->grf_prop.grffile == nullptr ? 0 : spec->grf_prop.grffile->grfid, spec->grf_prop.local_id, spec->class_index, spec->index};
117  }
118 
119  PickerItem GetPickerItem(int cls_id, int id) const override
120  {
121  return GetPickerItem(GetClass(cls_id)->GetSpec(id), cls_id, id);
122  }
123 
124  std::set<PickerItem> UpdateSavedItems(const std::set<PickerItem> &src) override
125  {
126  if (src.empty()) return {};
127 
128  std::set<PickerItem> dst;
129  for (const auto &item : src) {
130  const auto *spec = T::GetByGrf(item.grfid, item.local_id);
131  if (spec == nullptr) {
132  dst.insert({item.grfid, item.local_id, -1, -1});
133  } else {
134  dst.insert(GetPickerItem(spec));
135  }
136  }
137  return dst;
138  }
139 };
140 
143 };
144 
147 
149 public:
151  PFM_ALL = 0,
152  PFM_USED = 1,
153  PFM_SAVED = 2,
154  };
155 
157  PFI_CLASS = 1U << 0,
158  PFI_TYPE = 1U << 1,
159  PFI_POSITION = 1U << 2,
160  PFI_VALIDATE = 1U << 3,
161  };
162 
163  static const int PREVIEW_WIDTH = 64;
164  static const int PREVIEW_HEIGHT = 48;
165  static const int PREVIEW_LEFT = 31;
166  static const int PREVIEW_BOTTOM = 31;
167 
168  static const uint EDITBOX_MAX_SIZE = 16;
169 
170  bool has_class_picker = false;
171  bool has_type_picker = false;
172 
174  void Close(int data = 0) override;
175  void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override;
176  void DrawWidget(const Rect &r, WidgetID widget) const override;
177  void OnResize() override;
178  void OnClick(Point pt, WidgetID widget, int click_count) override;
179  void OnInvalidateData(int data = 0, bool gui_scope = true) override;
180  EventState OnHotkey(int hotkey) override;
181  void OnEditboxChanged(WidgetID wid) override;
182 
186  };
187 
188 protected:
189  void ConstructWindow();
190 
191  PickerCallbacks &callbacks;
192 
193 private:
195  PickerFilterData class_string_filter;
197 
198  void BuildPickerClassList();
199  void EnsureSelectedClassIsValid();
200  void EnsureSelectedClassIsVisible();
201 
203  PickerFilterData type_string_filter;
205 
206  void RefreshUsedTypeList();
207  void BuildPickerTypeList();
208  void EnsureSelectedTypeIsValid();
209  void EnsureSelectedTypeIsVisible();
210 
211  IntervalTimer<TimerGameCalendar> yearly_interval = {{TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [this](auto) {
212  this->SetDirty();
213  }};
214 
215  IntervalTimer<TimerWindow> refresh_interval = {std::chrono::seconds(3), [this](auto) {
216  RefreshUsedTypeList();
217  }};
218 };
219 
220 class NWidgetBase;
221 std::unique_ptr<NWidgetBase> MakePickerClassWidgets();
222 std::unique_ptr<NWidgetBase> MakePickerTypeWidgets();
223 
224 #endif /* PICKER_GUI_H */
Baseclass for nested widgets.
Definition: widget_type.h:144
Helper for PickerCallbacks when the class system is based on NewGRFClass.
Definition: picker_gui.h:100
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:124
PickerItem GetPickerItem(int cls_id, int id) const override
Get data about an item.
Definition: picker_gui.h:119
int GetClassCount() const override
Get the number of classes.
Definition: picker_gui.h:110
int GetTypeCount(int cls_id) const override
Get the number of types in a class.
Definition: picker_gui.h:111
bool HasClassChoice() const override
Are there multiple classes to chose from?
Definition: picker_gui.h:108
Class for PickerClassWindow to collect information and retain state.
Definition: picker_gui.h:37
virtual int GetSelectedClass() const =0
Get the index of the selected class.
Filtering type_last_filtering
Default filtering of PickerTypeList.
Definition: picker_gui.h:89
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:91
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 std::set< PickerItem > UpdateSavedItems(const std::set< PickerItem > &src)=0
Update link between grfid/localidx and class_index/index in saved items.
virtual bool HasClassChoice() const =0
Are there multiple classes to chose from?
Listing type_last_sorting
Default sorting of PickerTypeList.
Definition: picker_gui.h:88
std::set< PickerItem > used
Set of items used in the current game by the current company.
Definition: picker_gui.h:94
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.
virtual void DrawType(int x, int y, int cls_id, int id) const =0
Draw preview image of an item.
Filtering class_last_filtering
Default filtering of PickerClassList.
Definition: picker_gui.h:86
virtual int GetSelectedType() const =0
Get the selected type.
uint8_t mode
Bitmask of PickerFilterModes.
Definition: picker_gui.h:92
std::set< PickerItem > saved
Set of saved favourite items.
Definition: picker_gui.h:95
Listing class_last_sorting
Default sorting of PickerClassList.
Definition: picker_gui.h:85
Base class for windows opened from a toolbar.
Definition: window_gui.h:986
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
Definition: picker_gui.cpp:240
bool has_class_picker
Set if this window has a class picker 'component'.
Definition: picker_gui.h:170
static const int PREVIEW_LEFT
Offset from left edge to draw preview.
Definition: picker_gui.h:165
@ PFM_USED
Show used types.
Definition: picker_gui.h:152
@ PFM_ALL
Show all classes.
Definition: picker_gui.h:151
@ PFM_SAVED
Show saved types.
Definition: picker_gui.h:153
PickerTypeList types
List of types.
Definition: picker_gui.h:202
QueryString class_editbox
Filter editbox.
Definition: picker_gui.h:196
bool has_type_picker
Set if this window has a type picker 'component'.
Definition: picker_gui.h:171
void BuildPickerClassList()
Builds the filter list of classes.
Definition: picker_gui.cpp:451
PickerClassWindowHotkeys
Enum referring to the Hotkeys in the picker window.
Definition: picker_gui.h:184
@ PCWHK_FOCUS_FILTER_BOX
Focus the edit box for editing the filter string.
Definition: picker_gui.h:185
void BuildPickerTypeList()
Builds the filter list of types.
Definition: picker_gui.cpp:520
void OnResize() override
Called after the window got resized.
Definition: picker_gui.cpp:324
PickerFilterInvalidation
Definition: picker_gui.h:156
@ PFI_POSITION
Update scroll positions.
Definition: picker_gui.h:159
@ PFI_VALIDATE
Validate selected item.
Definition: picker_gui.h:160
@ PFI_CLASS
Refresh the class list.
Definition: picker_gui.h:157
@ PFI_TYPE
Refresh the type list.
Definition: picker_gui.h:158
static const int PREVIEW_WIDTH
Width of each preview button.
Definition: picker_gui.h:163
QueryString type_editbox
Filter editbox.
Definition: picker_gui.h:204
static const int PREVIEW_BOTTOM
Offset from bottom edge to draw preview.
Definition: picker_gui.h:166
EventState OnHotkey(int hotkey) override
A hotkey has been pressed.
Definition: picker_gui.cpp:412
static const uint EDITBOX_MAX_SIZE
The maximum number of characters for the filter edit box.
Definition: picker_gui.h:168
PickerClassList classes
List of classes.
Definition: picker_gui.h:194
static const int PREVIEW_HEIGHT
Height of each preview button.
Definition: picker_gui.h:164
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition: window.cpp:940
std::unique_ptr< NWidgetBase > MakePickerTypeWidgets()
Create nested widgets for the type picker widgets.
Definition: picker_gui.cpp:646
std::unique_ptr< NWidgetBase > MakePickerClassWidgets()
Create nested widgets for the class picker widgets.
Definition: picker_gui.cpp:623
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.
Definition: strings_type.h:16
Dimensions (a width and height) of a rectangle in 2D.
Data structure describing what to show in the list (filter criteria).
Definition: sortlist_type.h:35
Data structure describing how to show the list (what sort direction and criteria).
Definition: sortlist_type.h:30
const PickerCallbacks * callbacks
Callbacks for filter functions to access to callbacks.
Definition: picker_gui.h:142
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:159
Data structure for an opened window.
Definition: window_gui.h:273
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:18
EventState
State of handling an event.
Definition: window_type.h:743