OpenTTD Source
20240915-master-g3784a3d3d6
|
Go to the documentation of this file.
38 static std::vector<PickerCallbacks *> &GetPickerCallbacks()
40 static std::vector<PickerCallbacks *> callbacks;
44 PickerCallbacks::PickerCallbacks(
const std::string &ini_group) : ini_group(ini_group)
46 GetPickerCallbacks().push_back(
this);
49 PickerCallbacks::~PickerCallbacks()
51 auto &callbacks = GetPickerCallbacks();
52 callbacks.erase(std::find(callbacks.begin(), callbacks.end(),
this));
63 if (group ==
nullptr)
return;
65 callbacks.
saved.clear();
67 std::array<uint8_t, 4> grfid_buf;
69 std::string_view str = item.
name;
72 auto grfid_pos = str.find(
'|');
73 if (grfid_pos == std::string_view::npos)
continue;
75 std::string_view grfid_str = str.substr(0, grfid_pos);
78 str = str.substr(grfid_pos + 1);
79 uint32_t grfid = grfid_buf[0] | (grfid_buf[1] << 8) | (grfid_buf[2] << 16) | (grfid_buf[3] << 24);
81 auto [ptr, err] = std::from_chars(str.data(), str.data() + str.size(), localid);
83 if (err == std::errc{} && ptr == str.data() + str.size()) {
84 callbacks.
saved.insert({grfid, localid, 0, 0});
100 std::string key = fmt::format(
"{:08X}|{}",
BSWAP32(item.grfid), item.local_id);
140 int r = a.class_index - b.class_index;
141 if (r == 0) r = a.index - b.index;
162 this->window_number = window_number;
168 void PickerWindow::ConstructWindow()
173 bool isActive = this->callbacks.
IsActive();
184 if (
auto *nwid = this->GetWidget<NWidgetStacked>(
WID_PW_CLASS_SEL); nwid !=
nullptr) {
186 bool is_vertical = (nwid->parent->parent->type ==
NWID_VERTICAL);
193 this->class_string_filter.
callbacks = &this->callbacks;
203 this->callbacks.
used.clear();
215 if (
auto *nwid = this->GetWidget<NWidgetStacked>(
WID_PW_TYPE_SEL); nwid !=
nullptr) {
217 bool is_vertical = (nwid->parent->parent->type ==
NWID_VERTICAL);
224 this->type_string_filter.
callbacks = &this->callbacks;
238 this->callbacks.Close(data);
248 size.height = 5 *
resize.height;
254 size.width +=
resize.width;
255 fill.width =
resize.width;
270 void PickerWindow::DrawWidget(
const Rect &r,
WidgetID widget)
const
278 const int y_step = this->GetWidget<NWidgetResizeBase>(widget)->resize_y;
279 auto [first, last] = vscroll->GetVisibleRangeIterators(this->
classes);
280 for (
auto it = first; it != last; ++it) {
289 assert(this->GetWidget<NWidgetBase>(widget)->GetParentWidget<NWidgetMatrix>()->GetCurrentElement() <
static_cast<int>(this->
types.size()));
290 const auto &item = this->
types[this->GetWidget<NWidgetBase>(widget)->GetParentWidget<
NWidgetMatrix>()->GetCurrentElement()];
299 this->callbacks.
DrawType(x, y, item.class_index, item.index);
300 if (this->callbacks.
saved.contains(item)) {
301 DrawSprite(SPR_BLOT, PALETTE_TO_YELLOW, 0, 0);
303 if (this->callbacks.
used.contains(item)) {
334 if (it == this->
classes.end())
return;
359 int sel = this->GetWidget<NWidgetBase>(widget)->GetParentWidget<
NWidgetMatrix>()->GetCurrentElement();
360 assert(sel < (
int)this->
types.size());
361 const auto &item = this->
types[sel];
364 auto it = this->callbacks.
saved.find(item);
365 if (it == std::end(this->callbacks.
saved)) {
366 this->callbacks.
saved.insert(item);
368 this->callbacks.
saved.erase(it);
386 void PickerWindow::OnInvalidateData(
int data,
bool gui_scope)
388 if (!gui_scope)
return;
394 if ((data &
PFI_VALIDATE) != 0) this->EnsureSelectedClassIsValid();
395 if ((data &
PFI_POSITION) != 0) this->EnsureSelectedClassIsVisible();
398 if ((data &
PFI_VALIDATE) != 0) this->EnsureSelectedTypeIsValid();
399 if ((data &
PFI_POSITION) != 0) this->EnsureSelectedTypeIsVisible();
426 void PickerWindow::OnEditboxChanged(
WidgetID wid)
458 for (
int i = 0; i < count; i++) {
460 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;
461 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;
473 void PickerWindow::EnsureSelectedClassIsValid()
476 if (std::binary_search(std::begin(this->
classes), std::end(this->
classes), class_index))
return;
479 class_index = this->
classes.front();
483 for (
int i = 0; i < count; i++) {
494 void PickerWindow::EnsureSelectedClassIsVisible()
497 if (this->
classes.empty())
return;
500 if (it == std::end(this->
classes))
return;
502 int pos =
static_cast<int>(std::distance(std::begin(this->
classes), it));
506 void PickerWindow::RefreshUsedTypeList()
510 this->callbacks.
used.clear();
529 this->
types.reserve(this->callbacks.
used.size());
531 if (!show_all && item.class_index != cls_id)
continue;
533 this->
types.emplace_back(item);
535 }
else if (filter_saved) {
537 this->
types.reserve(this->callbacks.
saved.size());
540 if (item.class_index == -1)
continue;
541 if (!show_all && item.class_index != cls_id)
continue;
543 this->
types.emplace_back(item);
545 }
else if (show_all) {
549 this->
types.reserve(total);
551 for (
int class_index : this->classes) {
553 for (
int i = 0; i < count; i++) {
560 if (cls_id >= 0 && cls_id < this->callbacks.
GetClassCount()) {
562 this->
types.reserve(count);
563 for (
int i = 0; i < count; i++) {
578 void PickerWindow::EnsureSelectedTypeIsValid()
582 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;
584 if (!this->
types.empty()) {
585 class_index = this->
types.front().class_index;
586 index = this->
types.front().index;
590 for (
int i = 0; i < count; i++) {
600 void PickerWindow::EnsureSelectedTypeIsVisible()
603 if (this->
types.empty()) {
611 auto it = std::find_if(std::begin(this->
types), std::end(this->
types), [class_index, index](
const auto &item) {
return item.class_index == class_index && item.index == index; });
612 if (it == std::end(this->
types))
return;
614 int pos =
static_cast<int>(std::distance(std::begin(this->
types), it));
621 static constexpr
NWidgetPart picker_class_widgets[] = {
625 NWidget(
WWT_EDITBOX, COLOUR_DARK_GREEN,
WID_PW_CLASS_FILTER),
SetMinimalSize(144, 0),
SetPadding(2),
SetFill(1, 0),
SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
644 static constexpr
NWidgetPart picker_type_widgets[] = {
648 NWidget(
WWT_EDITBOX, COLOUR_DARK_GREEN,
WID_PW_TYPE_FILTER),
SetPadding(2),
SetResize(1, 0),
SetFill(1, 0),
SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
666 NWidget(
WWT_EMPTY, INVALID_COLOUR,
WID_PW_TYPE_NAME),
SetPadding(
WidgetDimensions::unscaled.framerect),
SetResize(1, 0),
SetFill(1, 0),
SetMinimalTextLines(1, 0),
@ ES_HANDLED
The passed event is handled.
uint8_t GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
bool has_type_picker
Set if this window has a type picker 'component'.
virtual StringID GetClassName(int id) const =0
Get the name of a class.
Filtering type_last_filtering
Default filtering of PickerTypeList.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
int Height() const
Get height of Rect.
static const int PREVIEW_HEIGHT
Height of each preview button.
static const std::initializer_list< PickerTypeList::SortFunction *const > _type_sorter_funcs
Sort functions of the PickerTypeList.
static const int PREVIEW_WIDTH
Width of each preview button.
@ PFM_ALL
Show all classes.
const PickerCallbacks * callbacks
Callbacks for filter functions to access to callbacks.
void SetFocusedWindow(Window *w)
Set the window that has the focus.
@ PFM_USED
Show used types.
Class for PickerClassWindow to collect information and retain state.
Dimensions (a width and height) of a rectangle in 2D.
void SetFilterState(bool state)
Enable or disable the filter.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
bool IsEmpty() const
Check whether any filter words were entered.
static void PickerSaveConfig(IniFile &ini, const PickerCallbacks &callbacks)
Save favourites of a picker to config.
void SetFilterTerm(const char *str)
Set the term to filter on.
A single "line" in an ini file.
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
static bool TypeIDSorter(PickerItem const &a, PickerItem const &b)
Sort types by id.
@ PFI_POSITION
Update scroll positions.
A group within an ini file.
virtual int GetTypeCount(int cls_id) const =0
Get the number of types in a class.
virtual void FillUsedItems(std::set< PickerItem > &items)=0
Fill a set with all items that are used by the current player.
Listing type_last_sorting
Default sorting of PickerTypeList.
@ PCWHK_FOCUS_FILTER_BOX
Focus the edit box for editing the filter string.
bool _ctrl_pressed
Is Ctrl pressed?
@ SND_15_BEEP
19 == 0x13 GUI button click
@ FILLRECT_CHECKER
Draw only every second pixel, used for greying-out.
virtual int GetSelectedClass() const =0
Get the index of the selected class.
ClientSettings _settings_client
The current settings for this game.
std::list< IniItem > items
all items in the group
constexpr uint Vertical() const
Get total vertical padding of RectPadding.
void AddLine(const char *str)
Pass another text line from the current item to the filter.
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.
virtual void SetSelectedType(int id) const =0
Set the selected type.
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
virtual StringID GetClassTooltip() const =0
Get the tooltip string for the class list.
void SetFilterFuncs(std::span< FilterFunction *const > n_funcs)
Hand the filter function pointers to the GUIList.
const NWidgetCore * nested_focus
Currently focused nested widget, or nullptr if no nested widget has focus.
bool NeedRebuild() const
Check if a rebuild is needed.
virtual int GetSelectedType() const =0
Get the selected type.
void Clear()
Clear all items in the group.
char *const buf
buffer in which text is saved
static const int MAX_CHAR_LENGTH
Max. length of UTF-8 encoded unicode character.
virtual void DrawType(int x, int y, int cls_id, int id) const =0
Draw preview image of an item.
virtual bool HasClassChoice() const =0
Are there multiple classes to chose from?
High level window description.
constexpr uint Horizontal() const
Get total horizontal padding of RectPadding.
int ScaleGUITrad(int value)
Scale traditional pixel dimensions to GUI zoom level.
uint8_t mode
Bitmask of PickerFilterModes.
static const std::initializer_list< PickerClassList::FilterFunction *const > _class_filter_funcs
Filter functions of the PickerClassList.
Filtering class_last_filtering
Default filtering of PickerClassList.
PickerClassList classes
List of classes.
EventState OnHotkey(int hotkey) override
A hotkey has been pressed.
ResizeInfo resize
Resize information.
static uint32_t BSWAP32(uint32_t x)
Perform a 32 bits endianness bitswap on x.
SoundSettings sound
sound effect settings
@ FS_NORMAL
Index of the normal font in the font tables.
bool Filter(FilterFunction *decide, F filter_data)
Filter the list.
void BuildPickerClassList()
Builds the filter list of classes.
@ ES_NOT_HANDLED
The passed event is not handled.
void OnResize() override
Called after the window got resized.
@ PFI_VALIDATE
Validate selected item.
void Close([[maybe_unused]] int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
void BuildPickerTypeList()
Builds the filter list of types.
virtual int GetClassCount() const =0
Get the number of classes.
static const int PREVIEW_LEFT
Offset from left edge to draw preview.
virtual bool IsTypeAvailable(int cls_id, int id) const =0
Test if an item is currently buildable.
virtual StringID GetTypeName(int cls_id, int id) const =0
Get the item of a type.
Listing class_last_sorting
Default sorting of PickerClassList.
std::unique_ptr< NWidgetBase > MakePickerTypeWidgets()
Create nested widgets for the type picker widgets.
@ PFI_CLASS
Refresh the class list.
QueryString class_editbox
Filter editbox.
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
IniGroup & GetOrCreateGroup(std::string_view name)
Get the group with the given name, and if it doesn't exist create a new group.
Coordinates of a point in 2D.
bool IsWidgetDisabled(WidgetID widget_index) const
Gets the enabled/disabled status of a widget.
virtual bool IsActive() const =0
Should picker class/type selection be enabled?
WindowNumber window_number
Window number within the window class.
bool SetFocusedWidget(WidgetID widget_index)
Set focus within this window to the given widget.
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.
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing)
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
virtual PickerItem GetPickerItem(int cls_id, int id) const =0
Get data about an item.
bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int height)
Set up a clipping area for only drawing into a certain area.
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
std::set< PickerItem > saved
Set of saved favourite items.
void ForceRebuild()
Force that a rebuild is needed.
std::map< WidgetID, QueryString * > querystrings
QueryString associated to WWT_EDITBOX widgets.
static void PickerLoadConfig(const IniFile &ini, PickerCallbacks &callbacks)
Load favourites of a picker from config.
int cancel_button
Widget button of parent window to simulate when pressing CANCEL in OSK.
@ WC_SELECT_STATION
Select station (when joining stations); Window numbers:
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
static bool TypeTagNameFilter(PickerItem const *item, PickerFilterData &filter)
Filter types by class name.
Ini file that supports both loading and saving.
virtual void SetSelectedClass(int id) const =0
Set the selected class.
void ResetState()
Reset the matching state to process a new item.
static const std::initializer_list< PickerClassList::SortFunction *const > _class_sorter_funcs
Sort functions of the PickerClassList.
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
int ScaleSpriteTrad(int value)
Scale traditional pixel dimensions to GUI zoom level, for drawing sprites.
std::string GetString(StringID string)
Resolve the given StringID into a std::string with all the associated DParam lookups and formatting.
EventState
State of handling an event.
const IniGroup * GetGroup(std::string_view name) const
Get the group with the given name.
bool GetState() const
Get the matching state of the current item.
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Base class for windows opened from a toolbar.
static const int ACTION_CLEAR
Clear editbox.
virtual std::set< PickerItem > UpdateSavedItems(const std::set< PickerItem > &src)=0
Update link between grfid/localidx and class_index/index in saved items.
std::string name
The name of this item.
@ SA_CENTER
Center both horizontally and vertically.
bool click_beep
Beep on a random selection of buttons.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
int width
width of the window (number of pixels to the right in x direction)
const std::string ini_group
Ini Group for saving favourites.
void RebuildDone()
Notify the sortlist that the rebuild is done.
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.
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
static bool ClassTagNameFilter(int const *item, PickerFilterData &filter)
Filter classes by class name.
static const int PREVIEW_BOTTOM
Offset from bottom edge to draw preview.
static bool ClassIDSorter(int const &a, int const &b)
Sort classes by id.
static const std::initializer_list< PickerTypeList::FilterFunction *const > _type_filter_funcs
Filter functions of the PickerTypeList.
std::unique_ptr< NWidgetBase > MakePickerClassWidgets()
Create nested widgets for the class picker widgets.
Data structure for an opened window.
IniItem & CreateItem(std::string_view name)
Create an item with the given name.
bool has_class_picker
Set if this window has a class picker 'component'.
std::set< PickerItem > used
Set of items used in the current game by the current company.
int Width() const
Get width of Rect.
QueryString type_editbox
Filter editbox.
Specification of a rectangle with absolute coordinates of all edges.
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
bool Sort(Comp compare)
Sort the list.
@ PFM_SAVED
Show saved types.
void SetFiltering(Filtering f)
Import filter conditions.
constexpr T ToggleBit(T &x, const uint8_t y)
Toggles a bit in a variable.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
void SetSortFuncs(std::span< SortFunction *const > n_funcs)
Hand the sort function pointers to the GUIList.
virtual StringID GetTypeTooltip() const =0
Get the tooltip string for the type grid.
Data about how and where to blit pixels.
void SetListing(Listing l)
Import sort conditions.
@ PFI_TYPE
Refresh the type list.
PickerTypeList types
List of types.
constexpr debug_inline bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.