/** * Create a dropdown menu. * @param parent Parent window. * @param list Dropdown item list. * @param selected Index of the selected item in the list. * @param button Widget of the parent window doing the dropdown. * @param instant_close Close the window when the mouse button is raised. * @param position Topleft position of the dropdown menu window. * @param size Size of the dropdown menu window. * @param wi_colour Colour of the parent widget. * @param scroll Dropdown menu has a scrollbar. * @param widget Widgets of the dropdown menu window. */ DropdownWindow(Window *parent, const DropDownList *list, int selected, int button, bool instant_close, const Point &position, const Dimension &size, Colours wi_colour, bool scroll) : Window(&_dropdown_desc) { assert(list->Length() > 0); this->position = position; this->CreateNestedTree(); this->vscroll = this->GetScrollbar(WID_DM_SCROLL); uint items_width = size.width - (scroll ? NWidgetScrollbar::GetVerticalDimension().width : 0); NWidgetCore *nwi = this->GetWidget<NWidgetCore>(WID_DM_ITEMS); nwi->SetMinimalSize(items_width, size.height + 4); nwi->colour = wi_colour; nwi = this->GetWidget<NWidgetCore>(WID_DM_SCROLL); nwi->colour = wi_colour; this->GetWidget<NWidgetStacked>(WID_DM_SHOW_SCROLL)->SetDisplayedPlane(scroll ? 0 : SZSP_NONE); this->FinishInitNested(0); CLRBITS(this->flags, WF_WHITE_BORDER); /* Total length of list */ int list_height = 0; for (const DropDownListItem * const *it = list->Begin(); it != list->End(); ++it) { const DropDownListItem *item = *it; list_height += item->Height(items_width); } /* Capacity is the average number of items visible */ this->vscroll->SetCapacity(size.height * (uint16)list->Length() / list_height); this->vscroll->SetCount((uint16)list->Length()); this->parent_wnd_class = parent->window_class; this->parent_wnd_num = parent->window_number; this->parent_button = button; this->list = list; this->selected_index = selected; this->click_delay = 0; this->drag_mode = instant_close; this->instant_close = instant_close; this->left_button_state = _left_button_down; }
/** * Show a dropdown menu window near a widget of the parent window. * The result code of the items is their index in the \a strings list. * @param w Parent window that wants the dropdown menu. * @param strings Menu list, end with #INVALID_STRING_ID * @param selected Index of initial selected item. * @param button Button widget number of the parent window \a w that wants the dropdown menu. * @param disabled_mask Bitmask for disabled items (items with their bit set are displayed, but not selectable in the dropdown list). * @param hidden_mask Bitmask for hidden items (items with their bit set are not copied to the dropdown list). * @param width Width of the dropdown menu. If \c 0, use the width of parent widget \a button. */ void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask, uint width) { DropDownList *list = new DropDownList(); for (uint i = 0; strings[i] != INVALID_STRING_ID; i++) { if (!HasBit(hidden_mask, i)) { *list->Append() = new DropDownListStringItem(strings[i], i, HasBit(disabled_mask, i)); } } /* No entries in the list? */ if (list->Length() == 0) { delete list; return; } ShowDropDownList(w, list, selected, button, width); }