changeset 9868:d06bace3c21c draft

(svn r14014) -Codechange: Add support for automatically sizing drop down lists to the widest list item.
author peter1138 <peter1138@openttd.org>
date Thu, 07 Aug 2008 18:11:09 +0000
parents 7e3f85c2fd92
children 3cc11b73fa26
files src/widgets/dropdown.cpp src/widgets/dropdown_type.h
diffstat 2 files changed, 27 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/widgets/dropdown.cpp
+++ b/src/widgets/dropdown.cpp
@@ -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,
--- a/src/widgets/dropdown_type.h
+++ b/src/widgets/dropdown_type.h
@@ -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);