26#include "table/strings.h"
38 return std::make_unique<DropDownListDividerItem>(-1);
57 return std::make_unique<DropDownListStringItem>(std::move(str), value, masked, shaded);
72 return std::make_unique<DropDownListIconItem>(sprite, palette,
GetString(str), value, masked, shaded);
81 return std::make_unique<DropDownListIconItem>(dim, sprite, palette,
GetString(str), value, masked, shaded);
96 return std::make_unique<DropDownListCheckedItem>(indent, checked,
GetString(str), value, masked, shaded);
99static constexpr std::initializer_list<NWidgetPart> _nested_dropdown_menu_widgets = {
103 NWidget(
WWT_EDITBOX, COLOUR_END,
WID_DM_FILTER),
SetResize(1, 0),
SetFill(1, 0),
SetPadding(2),
SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
121 _nested_dropdown_menu_widgets
132 bool drag_mode =
true;
167 assert(!this->list.empty());
187 if (this->persistent_filter_text !=
nullptr && !this->persistent_filter_text->empty()) {
188 this->editbox.text.
Assign(*this->persistent_filter_text);
196 void Close([[maybe_unused]]
int data = 0)
override
202 if (this->persistent_filter_text !=
nullptr) {
203 *this->persistent_filter_text = this->editbox.text.
GetText();
206 Point pt = _cursor.pos;
246 if (desired.height < available_height)
return;
249 uint avg_height =
list.height / (uint)this->list.size();
252 desired.width = std::max(
list.width, desired.width - NWidgetScrollbar::GetVerticalDimension().width);
263 for (
const auto &item : this->list) {
286 widget_dim.width = std::max<uint>(widget_dim.width, button_rect.
Width());
289 uint available_height_below = std::max(
GetMainViewBottom() - button_rect.bottom - 1, 0);
290 uint available_height_above = std::max(button_rect.top - 1 -
GetMainViewTop(), 0);
293 if (widget_dim.height > available_height_below && available_height_above > available_height_below) {
301 this->position.
y = button_rect.bottom + 1;
307 this->position.
x = button_rect.right + 1 - (int)(widget_dim.width + (list_dim.height > widget_dim.height ? NWidgetScrollbar::GetVerticalDimension().width : 0));
309 this->position.
x = button_rect.left;
312 this->initial_dim = widget_dim;
313 this->items_dim = widget_dim;
318 this->vscroll->
SetStepSize(list_dim.height / this->list.size());
322 if (this->above) this->vscroll->
SetPosition(INT_MAX);
332 return this->position;
343 if (
GetWidgetFromPos(
this, _cursor.pos.x - this->left, _cursor.pos.y - this->top) < 0)
return false;
346 int click_y = _cursor.pos.y - this->
top - r.top;
350 for (
const auto &item : this->list) {
352 int item_height = item->Height();
355 if (y > y_end)
break;
356 if (click_y >= y && click_y < y + item_height) {
357 if (item->masked || !item->Selectable())
return false;
358 result = item->result;
359 click_result = item->OnClick(r.
WithY(0, item_height - 1), {_cursor.pos.x - this->left, click_y - y});
376 if (this->string_filter.
IsEmpty())
return true;
382 return this->string_filter.
GetState();
392 if (ir.
Height() == 0)
return;
398 tmp_dpi.left += ir.left;
399 tmp_dpi.top += ir.top;
405 for (
const auto &item : this->list) {
407 int item_height = item->Height();
410 if (y > y_end)
break;
411 if (y > -item_height) {
414 bool selected = (this->selected_result == item->result) && item->Selectable() && this->selected_click_result < 0;
417 item->Draw(full, full.
Shrink(
WidgetDimensions::scaled.dropdowntext, RectPadding::zero), selected, selected ? this->selected_click_result : -1, colour);
426 int result, click_result;
428 this->click_delay = 4;
429 this->selected_result = result;
430 this->selected_click_result = click_result;
437 if (this->scrolling == 0)
return;
446 if (this->click_delay != 0 && --this->click_delay == 0) {
450 this->
parent->OnDropdownSelect(this->parent_button, this->selected_result, this->selected_click_result);
454 if (this->drag_mode) {
455 int result, click_result;
458 this->drag_mode =
false;
463 this->click_delay = 2;
467 this->scrolling = -1;
478 if (this->selected_result != result || this->selected_click_result != click_result) {
479 this->selected_result = result;
480 this->selected_click_result = click_result;
488 this->list = std::move(
list);
492 this->
InitializePositionSize(this->position.
x, this->position.y, this->nested_root->smallest_x, this->nested_root->smallest_y);
510 uint old_height = this->items_dim.height;
514 if (old_height != this->items_dim.height) {
534void ReplaceDropDownList(
Window *parent,
DropDownList &&list, std::optional<int> selected_result)
537 if (ddw !=
nullptr) ddw->ReplaceList(std::move(list), selected_result);
548 for (
const auto &item : list) {
549 dim.height += item->Height();
550 dim.width = std::max(dim.width, item->Width());
571 new DropdownWindow(w, std::move(list), selected, button, wi_rect, wi_colour, options, persistent_filter_text);
593 Rect wi_rect = nwi->GetCurrentRect();
594 Colours wi_colour = nwi->
colour;
611 ShowDropDownListAt(w, std::move(list), selected, button, wi_rect, wi_colour, options, persistent_filter_text);
627void ShowDropDownMenu(
Window *w, std::span<const StringID> strings,
int selected,
WidgetID button, uint32_t disabled_mask, uint32_t hidden_mask, uint width, DropDownOptions options, std::string *
const persistent_filter_text)
632 for (
auto string : strings) {
633 if (!
HasBit(hidden_mask, i)) {
639 if (!list.empty())
ShowDropDownList(w, std::move(list), selected, button, width, options, persistent_filter_text);
Class for backupping variables and making sure they are restored later.
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Timpl & Reset()
Reset all bits.
constexpr Timpl & Set()
Set all bits.
Base list item class from which others are derived.
virtual void FilterText(StringFilter &string_filter) const
Add text from this dropdown item to a string filter.
An interval timer will fire every interval, and will continue to fire until it is deleted.
void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, WidgetID button, Rect wi_rect, Colours wi_colour, DropDownOptions options, std::string *const persistent_filter_text)
Show a drop down list.
void ShowDropDownMenu(Window *w, std::span< const StringID > strings, int selected, WidgetID button, uint32_t disabled_mask, uint32_t hidden_mask, uint width, DropDownOptions options, std::string *const persistent_filter_text)
Show a dropdown menu window near a widget of the parent window.
std::unique_ptr< DropDownListItem > MakeDropDownListDividerItem()
Creates new DropDownListDividerItem.
static WindowDesc _dropdown_desc(WDP_MANUAL, {}, 0, 0, WC_DROPDOWN_MENU, WC_NONE, {}, _nested_dropdown_menu_widgets)
Window description for dropdown menus.
std::unique_ptr< DropDownListItem > MakeDropDownListIconItem(SpriteID sprite, PaletteID palette, StringID str, int value, bool masked, bool shaded)
Creates new DropDownListIconItem.
std::unique_ptr< DropDownListItem > MakeDropDownListStringItem(StringID str, int value, bool masked, bool shaded)
Creates new DropDownListStringItem.
std::unique_ptr< DropDownListItem > MakeDropDownListCheckedItem(bool checked, StringID str, int value, bool masked, bool shaded, uint indent)
Creates new DropDownListCheckedItem.
Dimension GetDropDownListDimension(const DropDownList &list)
Determine width and height required to fully display a DropDownList.
void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width, DropDownOptions options, std::string *const persistent_filter_text)
Show a drop down list.
Common drop down list components.
Functions related to the drop down widget.
Types 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.
@ InstantClose
Set if releasing mouse button should close the list regardless of where the cursor is.
@ Persist
Set if this dropdown should stay open after an option is selected.
@ Filterable
Set if the dropdown is filterable.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
bool _left_button_clicked
Is left mouse button clicked?
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.
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
@ FS_NORMAL
Index of the normal font in the font tables.
uint32_t PaletteID
The number of the palette.
void SetDirty() const
Mark entire window as dirty (in need of re-paint).
#define Rect
Macro that prevents name conflicts between included headers.
#define Point
Macro that prevents name conflicts between included headers.
static constexpr PixelColour PC_BLACK
Black palette colour.
Base for the GUIs that have an edit box in them.
A number of safeguards to prevent using unsafe methods.
void SndClickBeep()
Play a beep sound for a click event if enabled in settings.
Functions related to sound.
Definition of base types and functions in a cross-platform compatible way.
Searching and filtering using a stringterm.
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
TextDirection _current_text_dir
Text direction of the currently selected language.
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
@ TD_RTL
Text is written right-to-left by default.
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.
Point OnInitialPosition(int16_t sm_width, int16_t sm_height, int window_number) override
Compute the initial position of the window.
WidgetID parent_button
Parent widget number where the window is dropped from.
DropdownWindow(Window *parent, DropDownList &&list, int selected, WidgetID button, const Rect wi_rect, Colours wi_colour, DropDownOptions options, std::string *const persistent_filter_text)
Create a dropdown menu.
void OnMouseLoop() override
Called for every mouse loop run, which is at least once per (game) tick.
Dimension initial_dim
Initial dimension of dropdown menu before filtering.
StringFilter string_filter
String filter for filter text.
uint GetVisibleHeight() const
Get the height of the dropdown list, excluding filtered items.
void UpdateSizeAndPosition()
Update size and position of window to fit dropdown list into available space.
const IntervalTimer< TimerWindow > scroll_interval
Rate limit how fast scrolling happens.
Rect wi_rect
Rect of the button that opened the dropdown.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Dimension items_dim
Calculated cropped and padded dimension for the items widget.
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.
std::string *const persistent_filter_text
Unmanaged pointer to string for retaining filter text.
uint8_t click_delay
Timer to delay selection.
int selected_result
Result value of the selected item in the list.
QueryString editbox
Editbox for filter text.
bool above
Set if the drop down list is above the drop down widget instead of below.
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
DropDownOptions options
Options for this drop down menu.
void OnResize() override
Called after the window got resized.
bool FilterByText(const DropDownListItem &item) const
Filter individual dropdown item.
DropDownList list
List with dropdown menu items.
void UpdateFilter()
Apply text filter to the items in the dropdown list, resizing the window as necessary.
int selected_click_result
Click result value, from the OnClick handler of the selected item.
uint GetFilterBoxHeight() const
Get height of filter edit panel.
void OnEditboxChanged(WidgetID wid) override
The text in an editbox has been edited.
void FitAvailableHeight(Dimension &desired, const Dimension &list, uint available_height)
Fit dropdown list into available height, rounding to average item size.
bool GetDropDownItem(int &result, int &click_result)
Find the dropdown item under the cursor.
Point position
Position of the topleft corner of the window.
int scrolling
If non-zero, auto-scroll the item list (one time).
void OnFocusLost(bool closing) override
The window has lost focus.
Data stored about a string that can be modified in the GUI.
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.
Rect WithHeight(int height, bool end=false) const
Copy Rect and set its height.
int Height() const
Get height of Rect.
Rect WithY(int new_top, int new_bottom) const
Create a new Rect, replacing the top and bottom coordiates.
Rect Translate(int x, int y) const
Copy and translate Rect by x,y pixels.
bool IsEmpty() const
Check whether any filter words were entered.
void SetFilterTerm(std::string_view str)
Set the term to filter on.
void ResetState()
Reset the matching state to process a new item.
bool GetState() const
Get the matching state of the current item.
std::string_view GetText() const
Get the current text.
void Assign(std::string_view text)
Copy a string into the textbuffer.
High level window description.
int16_t GetDefaultWidth() const
Determine default width of window.
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.
virtual void Close(int data=0)
Hide the window and all its child windows, and mark them for a later deletion.
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.
void InitializePositionSize(int x, int y, int min_width, int min_height)
Set the position and smallest size of the window.
Window * parent
Parent window.
ResizeInfo resize
Resize information.
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
WindowDesc & window_desc
Window description.
bool SetFocusedWidget(WidgetID widget_index)
Set focus within this window to the given widget.
virtual void FindWindowPlacementAndResize(int def_width, int def_height, bool allow_resize)
Resize window towards the default size.
Window * FindChildWindow(WindowClass wc=WC_INVALID) const
Find the Window whose parent pointer points to this window.
int top
y position of top edge of the window
Window(WindowDesc &desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
WindowFlags flags
Window flags.
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
int height
Height of the window (number of pixels down in y direction).
WindowNumber window_number
Window number within the window class.
Definition of Interval and OneShot timers.
Definition of the Window system.
int GetMainViewTop()
Return the top of the main view available for general use.
void CloseWindowByClass(WindowClass cls, int data)
Close all windows of a given class.
int GetMainViewBottom()
Return the bottom of the main view available for general use.
Window functions not directly related to making/drawing windows.
Functions, definitions and such used only by the GUI.
@ WhiteBorder
Window white border counter bit mask.
@ WDP_MANUAL
Manually align the window (so no automatic location finding).
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
@ WC_DROPDOWN_MENU
Drop down menu; Window numbers:
Functions related to zooming.