# HG changeset patch # User peter1138 # Date 1218132669 0 # Node ID c529be2a15c5c62e8e47c3b421b6cc18cf0fbc41 # Parent f5d0c061f0481ba9e6858ec835af0b017e49c3d1 (svn r14014) -Codechange: Add support for automatically sizing drop down lists to the widest list item. diff -r f5d0c061f048 -r c529be2a15c5 src/widgets/dropdown.cpp --- a/src/widgets/dropdown.cpp Thu Aug 07 13:07:51 2008 +0000 +++ b/src/widgets/dropdown.cpp Thu Aug 07 18:11:09 2008 +0000 @@ -26,6 +26,13 @@ GfxFillRect(x + 1, y + 4, x + width - 2, y + 4, c2); } +uint DropDownListStringItem::Width() const +{ + char buffer[512]; + GetString(buffer, this->String(), lastof(buffer)); + return GetStringBoundingBox(buffer).width; +} + void DropDownListStringItem::Draw(int x, int y, uint width, uint height, bool sel, int bg_colour) const { DrawStringTruncated(x + 2, y, this->String(), sel ? TC_WHITE : TC_BLACK, width); @@ -232,6 +239,19 @@ /* The preferred position is just below the dropdown calling widget */ int top = w->top + wi->bottom + 1; + bool auto_width = (width == UINT_MAX); + + if (auto_width) { + /* Find the longest item in the list */ + width = 0; + for (DropDownList::const_iterator it = list->begin(); it != list->end(); ++it) { + const DropDownListItem *item = *it; + width = max(width, item->Width() + 5); + } + } else if (width == 0) { + width = wi->right - wi->left + 1; + } + /* Total length of list */ int list_height = 0; @@ -264,11 +284,12 @@ int rows = (screen_bottom - 4 - top) / avg_height; height = rows * avg_height; scroll = true; + /* Add space for the scroll bar if we automatically determined + * the width of the list. */ + if (auto_width) width += 12; } } - if (width == 0) width = wi->right - wi->left + 1; - DropdownWindow *dw = new DropdownWindow( w->left + wi->left, top, diff -r f5d0c061f048 -r c529be2a15c5 src/widgets/dropdown_type.h --- a/src/widgets/dropdown_type.h Thu Aug 07 13:07:51 2008 +0000 +++ b/src/widgets/dropdown_type.h Thu Aug 07 18:11:09 2008 +0000 @@ -22,6 +22,7 @@ virtual bool Selectable() const { return false; } virtual uint Height(uint width) const { return 10; } + virtual uint Width() const { return 0; } virtual void Draw(int x, int y, uint width, uint height, bool sel, int bg_colour) const; }; @@ -36,6 +37,7 @@ virtual ~DropDownListStringItem() {} virtual bool Selectable() const { return true; } + virtual uint Width() const; virtual void Draw(int x, int y, uint width, uint height, bool sel, int bg_colour) const; virtual StringID String() const { return this->string; } }; @@ -68,6 +70,8 @@ * @param button The widget within the parent window that is used to determine * the list's location. * @param width Override the width determined by the selected widget. + * If UINT_MAX then the width is determined by the widest item + * in the list. */ void ShowDropDownList(Window *w, DropDownList *list, int selected, int button, uint width = 0);