Changeset - r12427:88c1949f3666
[Not reviewed]
master
0 4 0
alberth - 15 years ago 2009-07-18 10:46:55
alberth@openttd.org
(svn r16871) -Codechange: Generalize GetWidgetContentSize to UpdateWidgetSize for better control over widget size and resize steps.
4 files changed with 174 insertions and 131 deletions:
0 comments (0 inline, 0 general)
src/intro_gui.cpp
Show inline comments
 
@@ -83,16 +83,18 @@ struct SelectGameWindow : public Window 
 
		}
 
	}
 

	
 
	virtual Dimension GetWidgetContentSize(int widget)
 
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *resize)
 
	{
 
		Dimension d = {0, 0};
 
		if (widget == SGI_DIFFICULTIES) {
 
			for (uint i = STR_DIFFICULTY_LEVEL_EASY; i <= STR_DIFFICULTY_LEVEL_CUSTOM; i++) {
 
				SetDParam(0, i);
 
				d = maxdim(d, GetStringBoundingBox(STR_INTRO_DIFFICULTY));
 
			}
 
		if (widget != SGI_DIFFICULTIES) return;
 

	
 
		Dimension textdim = {0, 0};
 
		for (uint i = STR_DIFFICULTY_LEVEL_EASY; i <= STR_DIFFICULTY_LEVEL_CUSTOM; i++) {
 
			SetDParam(0, i);
 
			textdim = maxdim(textdim, GetStringBoundingBox(STR_INTRO_DIFFICULTY));
 
		}
 
		return d;
 
		textdim.width += padding.width;
 
		textdim.height += padding.height;
 
		*size = maxdim(*size, textdim);
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget)
src/town_gui.cpp
Show inline comments
 
@@ -643,18 +643,19 @@ public:
 
		}
 
	}
 

	
 
	virtual Dimension GetWidgetContentSize(int widget)
 
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *resize)
 
	{
 
		Dimension d = {0, 0};
 
		switch (widget) {
 
			case TDW_SORTNAME:
 
			case TDW_SORTPOPULATION: {
 
				d = GetStringBoundingBox(this->nested_array[widget]->widget_data);
 
				d.width += WD_SORTBUTTON_ARROW_WIDTH * 2; // Doubled since the word is centered, also looks nice.
 
				Dimension d = GetStringBoundingBox(this->nested_array[widget]->widget_data);
 
				d.width += padding.width + WD_SORTBUTTON_ARROW_WIDTH * 2; // Doubled since the word is centered, also looks nice.
 
				d.height += padding.height;
 
				*size = maxdim(*size, d);
 
				break;
 
			}
 

	
 
			case TDW_CENTERTOWN:
 
			case TDW_CENTERTOWN: {
 
				Dimension d = {0, 0};
 
				for (uint i = 0; i < this->towns.Length(); i++) {
 
					const Town *t = this->towns[i];
 

	
 
@@ -664,15 +665,21 @@ public:
 
					SetDParam(1, 10000000); // 10^7
 
					d = maxdim(d, GetStringBoundingBox(STR_TOWN_DIRECTORY_TOWN));
 
				}
 
				d.width += 2 + 2; // Text is rendered with 2 pixel offset at both sides.
 
				d.width += padding.width + 2 + 2; // Text is rendered with 2 pixel offset at both sides.
 
				d.height += padding.height;
 
				*size = maxdim(*size, d);
 
				resize->height = d.height;
 
				break;
 

	
 
			case TDW_EMPTYBOTTOM:
 
			}
 
			case TDW_EMPTYBOTTOM: {
 
				SetDParam(0, 1000000000); // 10^9
 
				d = GetStringBoundingBox(STR_TOWN_POPULATION);
 
				Dimension d = GetStringBoundingBox(STR_TOWN_POPULATION);
 
				d.width += padding.width;
 
				d.height += padding.height;
 
				*size = maxdim(*size, d);
 
				break;
 
			}
 
		}
 
		return d;
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget)
src/widget.cpp
Show inline comments
 
@@ -892,7 +892,7 @@ NWidgetBase::NWidgetBase(WidgetType tp) 
 
 *
 
 * The smallest size of a widget is the smallest size that a widget needs to
 
 * display itself properly. In addition, filling and resizing of the widget are computed.
 
 * If \a w is not \c NULL, the function calls #Window::GetWidgetContentSize for each leaf widget and
 
 * If \a w is not \c NULL, the function calls #Window::UpdateWidgetSize for each leaf widget and
 
 * background widget without child with a non-negative index.
 
 *
 
 * @param w Optional window owning the widget.
 
@@ -1692,12 +1692,18 @@ void NWidgetBackground::SetupSmallestSiz
 
		this->resize_y = this->child->resize_y;
 
	} else {
 
		Dimension d = {this->min_x, this->min_y};
 
		Dimension resize  = {this->resize_x, this->resize_y};
 
		if (w != NULL) { // A non-NULL window pointer acts as switch to turn dynamic widget size on.
 
			if (this->index >= 0) d = maxdim(d, w->GetWidgetContentSize(this->index));
 
			if (this->type == WWT_FRAME || this->type == WWT_INSET) d = maxdim(d, GetStringBoundingBox(this->widget_data));
 
			if (this->index >= 0) {
 
				static const Dimension padding = {0, 0};
 
				w->UpdateWidgetSize(this->index, &d, padding, &resize);
 
			}
 
		}
 
		this->smallest_x = d.width;
 
		this->smallest_y = d.height;
 
		this->resize_x = resize.width;
 
		this->resize_y = resize.height;
 
	}
 
}
 

	
 
@@ -1887,109 +1893,138 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, 
 

	
 
void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array)
 
{
 
	Dimension d = {this->min_x, this->min_y}; // At least minimal size is needed.
 

	
 
	if (w != NULL) { // A non-NULL window pointer acts as switch to turn dynamic widget sizing on.
 
		Dimension d2 = {0, 0};
 
		if (this->index >= 0) {
 
			if (init_array) {
 
				assert(w->nested_array_size > (uint)this->index);
 
				w->nested_array[this->index] = this;
 
			}
 
			d2 = maxdim(d2, w->GetWidgetContentSize(this->index)); // If appropriate, ask window for smallest size.
 
		}
 

	
 
		/* Check size requirements of the widget itself too.
 
		 * Also, add the offset used for rendering.
 
		 */
 
		switch (this->type) {
 
			case WWT_EMPTY:
 
			case WWT_MATRIX:
 
			case WWT_SCROLLBAR:
 
			case WWT_SCROLL2BAR:
 
			case WWT_HSCROLLBAR:
 
				break;
 
	if (w == NULL) { // Conversion to widget array.
 
		this->smallest_x = this->min_x;
 
		this->smallest_y = this->min_y;
 
		/* All other data is already at the right place. */
 
		return;
 
	}
 

	
 
			case WWT_STICKYBOX:
 
				if (NWidgetLeaf::stickybox_dimension.width == 0) {
 
					NWidgetLeaf::stickybox_dimension = maxdim(GetSpriteSize(SPR_PIN_UP), GetSpriteSize(SPR_PIN_DOWN));
 
					NWidgetLeaf::stickybox_dimension.width += WD_STICKYBOX_LEFT + WD_STICKYBOX_RIGHT;
 
					NWidgetLeaf::stickybox_dimension.height += WD_STICKYBOX_TOP + WD_STICKYBOX_BOTTOM;
 
				}
 
				d2 = maxdim(d2, NWidgetLeaf::stickybox_dimension);
 
				break;
 

	
 
			case WWT_RESIZEBOX:
 
				if (NWidgetLeaf::resizebox_dimension.width == 0) {
 
					NWidgetLeaf::resizebox_dimension = maxdim(GetSpriteSize(SPR_WINDOW_RESIZE_LEFT), GetSpriteSize(SPR_WINDOW_RESIZE_RIGHT));
 
					NWidgetLeaf::resizebox_dimension.width += WD_RESIZEBOX_LEFT + WD_RESIZEBOX_RIGHT;
 
					NWidgetLeaf::resizebox_dimension.height += WD_RESIZEBOX_TOP + WD_RESIZEBOX_BOTTOM;
 
				}
 
				d2 = maxdim(d2, NWidgetLeaf::resizebox_dimension);
 
				break;
 

	
 
			case WWT_PUSHBTN:
 
			case WWT_EDITBOX:
 
				d2.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
 
				d2.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
 
				break;
 
	if (this->index >= 0 && init_array) { // Fill w->nested_array[]
 
		assert(w->nested_array_size > (uint)this->index);
 
		w->nested_array[this->index] = this;
 
	}
 

	
 
			case WWT_IMGBTN:
 
			case WWT_PUSHIMGBTN:
 
				d2 = maxdim(d2, GetSpriteSize(this->widget_data));
 
				d2.height += WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM;
 
				d2.width += WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT;
 
				break;
 

	
 
			case WWT_IMGBTN_2:
 
				d2 = maxdim(d2, GetSpriteSize(this->widget_data));
 
				d2 = maxdim(d2, GetSpriteSize(this->widget_data + 1));
 
				d2.height += WD_IMGBTN2_TOP + WD_IMGBTN2_BOTTOM;
 
				d2.width += WD_IMGBTN2_LEFT + WD_IMGBTN2_RIGHT;
 
				break;
 

	
 
			case WWT_CLOSEBOX:
 
				if (NWidgetLeaf::closebox_dimension.width == 0) {
 
					NWidgetLeaf::closebox_dimension = maxdim(GetStringBoundingBox(STR_BLACK_CROSS), GetStringBoundingBox(STR_SILVER_CROSS));
 
					NWidgetLeaf::closebox_dimension.width += WD_CLOSEBOX_LEFT + WD_CLOSEBOX_RIGHT;
 
					NWidgetLeaf::closebox_dimension.height += WD_CLOSEBOX_TOP + WD_CLOSEBOX_BOTTOM;
 
				}
 
				d2 = maxdim(d2, NWidgetLeaf::closebox_dimension);
 
				break;
 
	/* A non-NULL window pointer acts as switch to turn dynamic widget sizing on. */
 
	Dimension size = {this->min_x, this->min_y};
 
	Dimension resize = {this->resize_x, this->resize_y};
 
	/* Get padding, and update size with the real content size if appropriate. */
 
	const Dimension *padding = NULL;
 
	switch (this->type) {
 
		case WWT_EMPTY:
 
		case WWT_MATRIX:
 
		case WWT_SCROLLBAR:
 
		case WWT_SCROLL2BAR:
 
		case WWT_HSCROLLBAR: {
 
			static const Dimension extra = {0, 0};
 
			padding = &extra;
 
			break;
 
		}
 
		case WWT_STICKYBOX: {
 
			static const Dimension extra = {WD_STICKYBOX_LEFT + WD_STICKYBOX_RIGHT, WD_STICKYBOX_TOP + WD_STICKYBOX_BOTTOM};
 
			padding = &extra;
 
			if (NWidgetLeaf::stickybox_dimension.width == 0) {
 
				NWidgetLeaf::stickybox_dimension = maxdim(GetSpriteSize(SPR_PIN_UP), GetSpriteSize(SPR_PIN_DOWN));
 
				NWidgetLeaf::stickybox_dimension.width += extra.width;
 
				NWidgetLeaf::stickybox_dimension.height += extra.height;
 
			}
 
			size = maxdim(size, NWidgetLeaf::stickybox_dimension);
 
			break;
 
		}
 
		case WWT_RESIZEBOX: {
 
			static const Dimension extra = {WD_RESIZEBOX_LEFT + WD_RESIZEBOX_RIGHT, WD_RESIZEBOX_TOP + WD_RESIZEBOX_BOTTOM};
 
			padding = &extra;
 
			if (NWidgetLeaf::resizebox_dimension.width == 0) {
 
				NWidgetLeaf::resizebox_dimension = maxdim(GetSpriteSize(SPR_WINDOW_RESIZE_LEFT), GetSpriteSize(SPR_WINDOW_RESIZE_RIGHT));
 
				NWidgetLeaf::resizebox_dimension.width += extra.width;
 
				NWidgetLeaf::resizebox_dimension.height += extra.height;
 
			}
 
			size = maxdim(size, NWidgetLeaf::resizebox_dimension);
 
			break;
 
		}
 
		case WWT_PUSHBTN:
 
		case WWT_EDITBOX: {
 
			static const Dimension extra = {WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM};
 
			padding = &extra;
 
			break;
 
		}
 
		case WWT_IMGBTN:
 
		case WWT_PUSHIMGBTN: {
 
			static const Dimension extra = {WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT,  WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM};
 
			padding = &extra;
 
			Dimension d2 = GetSpriteSize(this->widget_data);
 
			d2.width += extra.width;
 
			d2.height += extra.height;
 
			size = maxdim(size, d2);
 
			break;
 
		}
 
		case WWT_IMGBTN_2: {
 
			static const Dimension extra = {WD_IMGBTN2_LEFT + WD_IMGBTN2_RIGHT,  WD_IMGBTN2_TOP + WD_IMGBTN2_BOTTOM};
 
			padding = &extra;
 
			Dimension d2 = maxdim(GetSpriteSize(this->widget_data), GetSpriteSize(this->widget_data + 1));
 
			d2.width += extra.width;
 
			d2.height += extra.height;
 
			size = maxdim(size, d2);
 
			break;
 
		}
 
		case WWT_CLOSEBOX: {
 
			static const Dimension extra = {WD_CLOSEBOX_LEFT + WD_CLOSEBOX_RIGHT, WD_CLOSEBOX_TOP + WD_CLOSEBOX_BOTTOM};
 
			padding = &extra;
 
			if (NWidgetLeaf::closebox_dimension.width == 0) {
 
				NWidgetLeaf::closebox_dimension = maxdim(GetStringBoundingBox(STR_BLACK_CROSS), GetStringBoundingBox(STR_SILVER_CROSS));
 
				NWidgetLeaf::closebox_dimension.width += extra.width;
 
				NWidgetLeaf::closebox_dimension.height += extra.height;
 
			}
 
			size = maxdim(size, NWidgetLeaf::closebox_dimension);
 
			break;
 
		}
 
		case WWT_TEXTBTN:
 
		case WWT_PUSHTXTBTN:
 
		case WWT_TEXTBTN_2: {
 
			static const Dimension extra = {WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT,  WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM};
 
			padding = &extra;
 
			Dimension d2 = GetStringBoundingBox(this->widget_data);
 
			d2.width += extra.width;
 
			d2.height += extra.height;
 
			size = maxdim(size, d2);
 
			break;
 
		}
 
		case WWT_LABEL:
 
		case WWT_TEXT: {
 
			static const Dimension extra = {0, 0};
 
			padding = &extra;
 
			size = maxdim(size, GetStringBoundingBox(this->widget_data));
 
			break;
 
		}
 
		case WWT_CAPTION: {
 
			static const Dimension extra = {WD_CAPTIONTEXT_LEFT + WD_CAPTIONTEXT_RIGHT, WD_CAPTIONTEXT_TOP + WD_CAPTIONTEXT_BOTTOM};
 
			padding = &extra;
 
			Dimension d2 = GetStringBoundingBox(this->widget_data);
 
			d2.width += extra.width;
 
			d2.height += extra.height;
 
			size = maxdim(size, d2);
 
			break;
 
		}
 
		case WWT_DROPDOWN: {
 
			static const Dimension extra = {WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT, WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM};
 
			padding = &extra;
 
			Dimension d2 = GetStringBoundingBox(this->widget_data);
 
			d2.width += extra.width;
 
			d2.height += extra.height;
 
			size = maxdim(size, d2);
 
			break;
 
		}
 
		default:
 
			NOT_REACHED();
 
	}
 

	
 
			case WWT_TEXTBTN:
 
			case WWT_PUSHTXTBTN:
 
			case WWT_TEXTBTN_2:
 
				d2 = maxdim(d2, GetStringBoundingBox(this->widget_data));
 
				d2.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
 
				d2.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
 
				break;
 

	
 
			case WWT_LABEL:
 
			case WWT_TEXT:
 
				d2 = maxdim(d2, GetStringBoundingBox(this->widget_data));
 
				break;
 
	if (this->index >= 0) w->UpdateWidgetSize(this->index, &size, *padding, &resize);
 

	
 
			case WWT_CAPTION:
 
				d2 = maxdim(d2, GetStringBoundingBox(this->widget_data));
 
				d2.width += WD_CAPTIONTEXT_LEFT + WD_CAPTIONTEXT_RIGHT;
 
				d2.height += WD_CAPTIONTEXT_TOP + WD_CAPTIONTEXT_BOTTOM;
 
				break;
 

	
 
			case WWT_DROPDOWN:
 
				d2 = maxdim(d2, GetStringBoundingBox(this->widget_data));
 
				d2.width += WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT;
 
				d2.height += WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM;
 
				break;
 

	
 
			default:
 
				NOT_REACHED();
 
		}
 
		d = maxdim(d, d2);
 
	}
 
	this->smallest_x = d.width;
 
	this->smallest_y = d.height;
 
	/* All other data is already at the right place. */
 
	this->smallest_x = size.width;
 
	this->smallest_y = size.height;
 
	this->resize_x = resize.width;
 
	this->resize_y = resize.height;
 
	/* this->fill_x and this->fill_y are already correct. */
 
}
 

	
 
void NWidgetLeaf::Draw(const Window *w)
src/window_gui.h
Show inline comments
 
@@ -521,18 +521,17 @@ public:
 
	virtual void DrawWidget(const Rect &r, int widget) const {}
 

	
 
	/**
 
	 * Compute size of the contents of a widget.
 
	 * If no useful size can be computed, return null-size (both width and height \c 0).
 
	 * @param widget Number of the widget to get the size of.
 
	 * @return Size of the contents of the widget.
 
	 * @note If the contents ever becomes larger than what is returned here, the window should be re-initialized (with #Window::ReInit),
 
	 *       and this function should return a larger size.
 
	 * Update size and resize step of a widget in the window.
 
	 * After retrieval of the minimal size and the resize-steps of a widget, this function is called to allow further refinement,
 
	 * typically by computing the real maximal size of the content. Afterwards, \a size is taken to be the minimal size of the widget
 
	 * and \a resize is taken to contain the resize steps. For the convenience of the callee, \a padding contains the amount of
 
	 * padding between the content and the edge of the widget. This should be added to the returned size.
 
	 * @param widget  Widget number.
 
	 * @param size    Size of the widget.
 
	 * @param padding Recommended amount of space between the widget content and the widget edge.
 
	 * @param resize  Resize step of the widget.
 
	 */
 
	virtual Dimension GetWidgetContentSize(int widget)
 
	{
 
		Dimension d = {0, 0};
 
		return d;
 
	}
 
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *resize) {}
 

	
 
	/**
 
	 * Called when window gains focus
0 comments (0 inline, 0 general)