/** * Find the dropdown item under the cursor. * @param value [out] Selected item, if function returns \c true. * @return Cursor points to a dropdown item. */ bool GetDropDownItem(int &value) { if (GetWidgetFromPos(this, _cursor.pos.x - this->left, _cursor.pos.y - this->top) < 0) return false; NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_DM_ITEMS); int y = _cursor.pos.y - this->top - nwi->pos_y - 2; int width = nwi->current_x - 4; int pos = this->vscroll->GetPosition(); const DropDownList *list = this->list; for (const DropDownListItem * const *it = list->Begin(); it != list->End(); ++it) { /* Skip items that are scrolled up */ if (--pos >= 0) continue; const DropDownListItem *item = *it; int item_height = item->Height(width); if (y < item_height) { if (item->masked || !item->Selectable()) return false; value = item->result; return true; } y -= item_height; } return false; }
/** * 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; }