10 #include "../stdafx.h" 11 #include "../window_gui.h" 12 #include "../string_func.h" 13 #include "../strings_func.h" 14 #include "../window_func.h" 15 #include "../guitimer_func.h" 20 #include "../safeguards.h" 23 void DropDownListItem::Draw(
int left,
int right,
int top,
int bottom,
bool sel, Colours bg_colour)
const 28 int mid = top + this->Height(0) / 2;
29 GfxFillRect(left + 1, mid - 2, right - 1, mid - 2, c1);
30 GfxFillRect(left + 1, mid - 1, right - 1, mid - 1, c2);
33 uint DropDownListStringItem::Width()
const 36 GetString(buffer, this->String(),
lastof(buffer));
40 void DropDownListStringItem::Draw(
int left,
int right,
int top,
int bottom,
bool sel, Colours bg_colour)
const 54 char buffer1[512], buffer2[512];
55 GetString(buffer1, static_cast<const DropDownListStringItem*>(first.get())->String(),
lastof(buffer1));
56 GetString(buffer2, static_cast<const DropDownListStringItem*>(second.get())->String(),
lastof(buffer2));
60 StringID DropDownListParamStringItem::String()
const 62 for (uint i = 0; i <
lengthof(this->decode_params); i++)
SetDParam(i, this->decode_params[i]);
66 StringID DropDownListCharStringItem::String()
const 76 this->sprite_y = (FONT_HEIGHT_NORMAL - dim.height) / 2;
84 uint DropDownListIconItem::Height(uint width)
const 89 uint DropDownListIconItem::Width()
const 94 void DropDownListIconItem::Draw(
int left,
int right,
int top,
int bottom,
bool sel, Colours bg_colour)
const 101 void DropDownListIconItem::SetDimension(
Dimension d)
106 static const NWidgetPart _nested_dropdown_menu_widgets[] = {
119 _nested_dropdown_menu_widgets,
lengthof(_nested_dropdown_menu_widgets)
150 :
Window(&_dropdown_desc), list(std::move(list))
152 assert(this->list.size() > 0);
154 this->position = position;
156 this->CreateNestedTree();
160 uint items_width = size.width - (scroll ? NWidgetScrollbar::GetVerticalDimension().width : 0);
170 this->FinishInitNested(0);
175 for (
const auto &item : this->list) {
176 list_height += item->Height(items_width);
180 this->vscroll->
SetCapacity(size.height * (uint16)this->list.size() / list_height);
181 this->vscroll->
SetCount((uint16)this->list.size());
185 this->parent_button = button;
186 this->selected_index = selected;
187 this->click_delay = 0;
188 this->drag_mode =
true;
189 this->instant_close = instant_close;
205 w2->
OnDropdownClose(pt, this->parent_button, this->selected_index, this->instant_close);
211 return this->position;
224 int y = _cursor.
pos.y - this->top - nwi->
pos_y - 2;
228 for (
const auto &item : this->list) {
230 if (--pos >= 0)
continue;
232 int item_height = item->Height(width);
234 if (y < item_height) {
235 if (item->masked || !item->Selectable())
return false;
236 value = item->result;
250 Colours colour = this->GetWidget<NWidgetCore>(widget)->colour;
254 for (
const auto &item : this->list) {
255 int item_height = item->Height(r.right - r.left + 1);
258 if (--pos >= 0)
continue;
260 if (y + item_height < r.bottom) {
261 bool selected = (this->selected_index == item->result);
264 item->Draw(r.left, r.right, y, y + item_height, selected, colour);
278 if (this->GetDropDownItem(item)) {
279 this->click_delay = 4;
280 this->selected_index = item;
287 if (!this->scrolling_timer.
Elapsed(delta_ms))
return;
290 if (this->scrolling != 0) {
310 if (this->click_delay != 0 && --this->click_delay == 0) {
321 if (this->drag_mode) {
325 this->drag_mode =
false;
326 if (!this->GetDropDownItem(item)) {
327 if (this->instant_close)
delete this;
330 this->click_delay = 2;
332 if (_cursor.
pos.y <= this->top + 2) {
334 this->scrolling = -1;
336 }
else if (_cursor.
pos.y >= this->top + this->height - 2) {
342 if (!this->GetDropDownItem(item))
return;
345 if (this->selected_index != item) {
346 this->selected_index = item;
371 int top = w->
top + wi_rect.bottom + 1;
374 uint width = wi_rect.right - wi_rect.left + 1;
377 uint max_item_width = 0;
382 for (
const auto &item : list) {
383 height += item->Height(width);
384 if (auto_width) max_item_width =
max(max_item_width, item->Width() + 5);
397 if (height > available_height) {
402 if (available_height_above > available_height) {
404 available_height = available_height_above;
408 if (height > available_height) {
410 uint avg_height = height / (uint)list.size();
413 assert(available_height >= avg_height);
416 uint rows = available_height / avg_height;
417 height = rows * avg_height;
420 max_item_width += NWidgetScrollbar::GetVerticalDimension().width;
425 top = w->
top + wi_rect.top - height - 4;
429 if (auto_width) width =
max(width, max_item_width);
459 wi_rect.left = nwi->
pos_x;
461 wi_rect.top = nwi->
pos_y;
463 Colours wi_colour = nwi->
colour;
474 wi_rect.left = wi_rect.right + 1 - width;
476 wi_rect.right = wi_rect.left + width - 1;
480 ShowDropDownListAt(w, std::move(list), selected, button, wi_rect, wi_colour, auto_width, instant_close);
499 if (!
HasBit(hidden_mask, i)) {
504 if (!list.empty())
ShowDropDownList(w, std::move(list), selected, button, width);
515 FOR_ALL_WINDOWS_FROM_BACK(w) {
519 assert(dw !=
nullptr);
524 return parent_button;
void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask, uint width)
Show a dropdown menu window near a widget of the parent window.
uint32 PaletteID
The number of the palette.
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...
Point pos
logical mouse position
virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number)
Compute the initial position of the window.
High level window description.
int left
x position of left edge of the window
bool instant_close
Close the window when the mouse button is raised.
void SetWidgetDirty(byte widget_index) const
Invalidate a widget, i.e.
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
bool Elapsed(uint delta)
Test if a timer has elapsed.
byte _colour_gradient[COLOUR_END][8]
All 16 colour gradients 8 colours per gradient from darkest (0) to lightest (7)
WindowClass parent_wnd_class
Parent window class.
int selected_index
Index of the selected item in the list.
int top
y position of top edge of the window
virtual void OnMouseLoop()
Called for every mouse loop run, which is at least once per (game) tick.
#define lastof(x)
Get the last element of an fixed size array.
WindowClass
Window classes.
#define CLRBITS(x, y)
Clears several bits in a variable.
static T max(const T a, const T b)
Returns the maximum of two values.
int HideDropDownMenu(Window *pw)
Delete the drop-down menu from window pw.
bool _left_button_clicked
Is left mouse button clicked?
void ShowDropDownList(Window *w, DropDownList &&list, int selected, int button, uint width, bool auto_width, bool instant_close)
Show a drop down list.
int GetMainViewBottom()
Return the bottom of the main view available for general use.
Data structure for an opened window.
byte click_delay
Timer to delay selection.
void SetDParamStr(uint n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
std::vector< std::unique_ptr< const DropDownListItem > > DropDownList
A drop down list is a collection of drop down list items.
#define FONT_HEIGHT_NORMAL
Height of characters in the normal (FS_NORMAL) font.
bool masked
Masked and unselectable item.
static bool NatSortFunc(std::unique_ptr< const DropDownListItem > const &first, std::unique_ptr< const DropDownListItem > const &second)
Natural sorting comparator function for DropDownList::sort().
int GetMainViewTop()
Return the top of the main view available for general use.
void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, int button, Rect wi_rect, Colours wi_colour, bool auto_width, bool instant_close)
Show a drop down list.
const DropDownList list
List with dropdown menu items.
static const uint MILLISECONDS_PER_TICK
The number of milliseconds per game tick.
void LowerWidget(byte widget_index)
Marks a widget as lowered.
DropdownWindow(Window *parent, DropDownList &&list, int selected, int button, bool instant_close, const Point &position, const Dimension &size, Colours wi_colour, bool scroll)
Create a dropdown menu.
virtual void OnDropdownSelect(int widget, int index)
A dropdown option associated to this window has been selected.
int DrawString(int left, int right, int top, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
#define lengthof(x)
Return the length of an fixed size array.
Types related to the drop down widget.
uint32 StringID
Numeric value that represents a string, independent of the selected language.
int scrolling
If non-zero, auto-scroll the item list (one time).
static const uint8 PC_BLACK
Black palette colour.
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize)
Return the string dimension in pixels.
Draw only every second pixel, used for greying-out.
No window, redirects to WC_MAIN_WINDOW.
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
Delete a window by its class and window number (if it is open).
WindowNumber parent_wnd_num
Parent window number.
bool GetDropDownItem(int &value)
Find the dropdown item under the cursor.
virtual void OnClick(Point pt, int widget, int click_count)
A click with the left mouse button has been made on the window.
int strnatcmp(const char *s1, const char *s2, bool ignore_garbage_at_front)
Compares two strings using case insensitive natural sort.
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
TextDirection _current_text_dir
Text direction of the currently selected language.
int result
Result code to return to window on selection.
This window won't get focus/make any other window lose focus when click.
Point position
Position of the topleft corner of the window.
GUITimer scrolling_timer
Timer for auto-scroll of the item list.
int parent_button
Parent widget number where the window is dropped from.
virtual void DrawWidget(const Rect &r, int widget) const
Draw the contents of a nested widget.
Coordinates of a point in 2D.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Offset at right to draw the frame rectangular area.
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
int32 WindowNumber
Number to differentiate different windows of the same class.
WindowClass window_class
Window class.
Specification of a rectangle with absolute coordinates of all edges.
Text is written right-to-left by default.
WindowNumber window_number
Window number within the window class.
String list item with parameters.
Manually align the window (so no automatic location finding)
virtual void OnDropdownClose(Point pt, int widget, int index, bool instant_close)
A dropdown window associated to this window has been closed.
virtual void OnRealtimeTick(uint delta_ms)
Called periodically.
const NWID * GetWidget(uint widnum) const
Get the nested widget with number widnum from the nested widget tree.
Window white border counter bit mask.
Dimensions (a width and height) of a rectangle in 2D.
Offset at left to draw the frame rectangular area.
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Drop down menu; Window numbers:
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.