/** * 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>(DDM_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 (DropDownList::const_iterator 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, DropDownList *list, int selected, int button, bool instant_close, const Point &position, const Dimension &size, Colours wi_colour, bool scroll) : Window() { this->position = position; this->CreateNestedTree(&_dropdown_desc); this->vscroll = this->GetScrollbar(DDM_SCROLL); uint items_width = size.width - (scroll ? WD_VSCROLLBAR_WIDTH : 0); NWidgetCore *nwi = this->GetWidget<NWidgetCore>(DDM_ITEMS); nwi->SetMinimalSize(items_width, size.height + 4); nwi->colour = wi_colour; nwi = this->GetWidget<NWidgetCore>(DDM_SCROLL); nwi->colour = wi_colour; this->GetWidget<NWidgetStacked>(DDM_SHOW_SCROLL)->SetDisplayedPlane(scroll ? 0 : SZSP_NONE); this->FinishInitNested(&_dropdown_desc, 0); this->flags4 &= ~WF_WHITE_BORDER_MASK; /* Total length of list */ int list_height = 0; for (DropDownList::const_iterator it = list->begin(); it != list->end(); ++it) { DropDownListItem *item = *it; list_height += item->Height(items_width); } /* Capacity is the average number of items visible */ this->vscroll->SetCapacity(size.height * (uint16)list->size() / list_height); this->vscroll->SetCount((uint16)list->size()); 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 = true; this->instant_close = instant_close; }