Changeset - r13560:251ed15297e0
[Not reviewed]
master
0 9 0
rubidium - 15 years ago 2009-11-15 13:36:30
rubidium@openttd.org
(svn r18092) -Codechange: remove support for the unnested widgets
9 files changed with 90 insertions and 806 deletions:
0 comments (0 inline, 0 general)
src/misc_gui.cpp
Show inline comments
 
@@ -1184,8 +1184,7 @@ bool QueryString::HasEditBoxFocus(const 
 
{
 
	if (w->IsWidgetGloballyFocused(wid)) return true;
 
	if (w->window_class != WC_OSK || _focused_window != w->parent) return false;
 
	return (w->parent->focused_widget != NULL && w->parent->focused_widget->type == WWT_EDITBOX) ||
 
		(w->parent->nested_focus != NULL && w->parent->nested_focus->type == WWT_EDITBOX);
 
	return w->parent->nested_focus != NULL && w->parent->nested_focus->type == WWT_EDITBOX;
 
}
 

	
 
HandleEditBoxResult QueryString::HandleEditBoxKey(Window *w, int wid, uint16 key, uint16 keycode, Window::EventState &state)
 
@@ -1248,29 +1247,13 @@ void QueryString::HandleEditBox(Window *
 

	
 
void QueryString::DrawEditBox(Window *w, int wid)
 
{
 
	int left;
 
	int right;
 
	int top;
 
	int bottom;
 
	if (w->widget == NULL) {
 
		const NWidgetBase *wi = w->GetWidget<NWidgetBase>(wid);
 

	
 
		assert((wi->type & WWT_MASK) == WWT_EDITBOX);
 
	const NWidgetBase *wi = w->GetWidget<NWidgetBase>(wid);
 

	
 
		left   = wi->pos_x;
 
		right  = wi->pos_x + wi->current_x - 1;
 
		top    = wi->pos_y;
 
		bottom = wi->pos_y + wi->current_y - 1;
 
	} else {
 
		const Widget *wi = &w->widget[wid];
 

	
 
		assert((wi->type & WWT_MASK) == WWT_EDITBOX);
 

	
 
		left   = wi->left;
 
		right  = wi->right;
 
		top    = wi->top;
 
		bottom = wi->bottom;
 
	}
 
	assert((wi->type & WWT_MASK) == WWT_EDITBOX);
 
	int left   = wi->pos_x;
 
	int right  = wi->pos_x + wi->current_x - 1;
 
	int top    = wi->pos_y;
 
	int bottom = wi->pos_y + wi->current_y - 1;
 

	
 
	GfxFillRect(left + 1, top + 1, right - 1, bottom - 1, 215);
 

	
src/network/network_gui.cpp
Show inline comments
 
@@ -207,12 +207,6 @@ public:
 
		}
 
	}
 

	
 
	void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl)
 
	{
 
		/* We don't need to support the old version anymore! */
 
		NOT_REACHED();
 
	}
 

	
 
	/* virtual */ void Draw(const Window *w)
 
	{
 
		int i = 0;
src/osk_gui.cpp
Show inline comments
 
@@ -75,14 +75,9 @@ struct OskWindow : public Window {
 
		this->parent = parent;
 
		assert(parent != NULL);
 

	
 
		if (parent->widget != NULL) {
 
			this->caption = (parent->widget[button].data != STR_NULL) ? parent->widget[button].data : parent->caption;
 
		}
 
		if (parent->nested_array != NULL) {
 
			NWidgetCore *par_wid = parent->GetWidget<NWidgetCore>(button);
 
			assert(par_wid != NULL);
 
			this->caption = (par_wid->widget_data != STR_NULL) ? par_wid->widget_data : parent->caption;
 
		}
 
		NWidgetCore *par_wid = parent->GetWidget<NWidgetCore>(button);
 
		assert(par_wid != NULL);
 
		this->caption = (par_wid->widget_data != STR_NULL) ? par_wid->widget_data : parent->caption;
 

	
 
		this->qs         = parent;
 
		this->text_btn   = button;
src/toolbar_gui.cpp
Show inline comments
 
@@ -1002,12 +1002,6 @@ public:
 
		}
 
	}
 

	
 
	void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl)
 
	{
 
		/* We don't need to support the old version anymore! */
 
		NOT_REACHED();
 
	}
 

	
 
	/* virtual */ void Draw(const Window *w)
 
	{
 
		/* Draw brown-red toolbar bg. */
src/widget.cpp
Show inline comments
 
@@ -136,41 +136,6 @@ static void ScrollbarClickPositioning(Wi
 

	
 
/** Special handling for the scrollbar widget type.
 
 * Handles the special scrolling buttons and other scrolling.
 
 * @param w  Window on which a scroll was performed.
 
 * @param wi Pointer to the scrollbar widget.
 
 * @param x  The X coordinate of the mouse click.
 
 * @param y  The Y coordinate of the mouse click.
 
 */
 
void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y)
 
{
 
	int mi, ma;
 

	
 
	switch (wi->type) {
 
		case WWT_SCROLLBAR:
 
			/* vertical scroller */
 
			mi = wi->top;
 
			ma = wi->bottom;
 
			break;
 

	
 
		case WWT_SCROLL2BAR:
 
			/* 2nd vertical scroller */
 
			mi = wi->top;
 
			ma = wi->bottom;
 
			break;
 

	
 
		case  WWT_HSCROLLBAR:
 
			/* horizontal scroller */
 
			mi = wi->left;
 
			ma = wi->right;
 
			break;
 

	
 
		default: NOT_REACHED();
 
	}
 
	ScrollbarClickPositioning(w, wi->type, x, y, mi, ma);
 
}
 

	
 
/** Special handling for the scrollbar widget type.
 
 * Handles the special scrolling buttons and other scrolling.
 
 * @param w Window on which a scroll was performed.
 
 * @param nw Pointer to the scrollbar widget.
 
 * @param x The X coordinate of the mouse click.
 
@@ -213,24 +178,8 @@ void ScrollbarClickHandler(Window *w, co
 
 */
 
int GetWidgetFromPos(const Window *w, int x, int y)
 
{
 
	if (w->nested_root != NULL) {
 
		NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y);
 
		return (nw != NULL) ? nw->index : -1;
 
	}
 

	
 
	int found_index = -1;
 
	/* Go through the widgets and check if we find the widget that the coordinate is inside. */
 
	for (uint index = 0; index < w->widget_count; index++) {
 
		const Widget *wi = &w->widget[index];
 
		if (wi->type == WWT_EMPTY || wi->type == WWT_FRAME) continue;
 

	
 
		if (x >= wi->left && x <= wi->right && y >= wi->top &&  y <= wi->bottom &&
 
				!w->IsWidgetHidden(index)) {
 
			found_index = index;
 
		}
 
	}
 

	
 
	return found_index;
 
	NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y);
 
	return (nw != NULL) ? nw->index : -1;
 
}
 

	
 
/**
 
@@ -595,122 +544,7 @@ static inline void DrawDropdown(const Re
 
 */
 
void Window::DrawWidgets() const
 
{
 
	if (this->nested_root != NULL) {
 
		this->nested_root->Draw(this);
 

	
 
		if (this->flags4 & WF_WHITE_BORDER_MASK) {
 
			DrawFrameRect(0, 0, this->width - 1, this->height - 1, COLOUR_WHITE, FR_BORDERONLY);
 
		}
 

	
 
		return;
 
	}
 

	
 
	const DrawPixelInfo *dpi = _cur_dpi;
 

	
 
	for (uint i = 0; i < this->widget_count; i++) {
 
		const Widget *wi = &this->widget[i];
 
		bool clicked = this->IsWidgetLowered(i);
 
		Rect r;
 

	
 
		if (dpi->left > (r.right = wi->right) ||
 
				dpi->left + dpi->width <= (r.left = wi->left) ||
 
				dpi->top > (r.bottom = wi->bottom) ||
 
				dpi->top + dpi->height <= (r.top = wi->top) ||
 
				this->IsWidgetHidden(i)) {
 
			continue;
 
		}
 

	
 
		switch (wi->type & WWT_MASK) {
 
		case WWT_IMGBTN:
 
		case WWT_IMGBTN_2:
 
			DrawImageButtons(r, wi->type, wi->colour, clicked, wi->data);
 
			break;
 

	
 
		case WWT_PANEL:
 
			assert(wi->data == 0);
 
			DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->colour, (clicked) ? FR_LOWERED : FR_NONE);
 
			break;
 

	
 
		case WWT_EDITBOX:
 
			DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->colour, FR_LOWERED | FR_DARKENED);
 
			break;
 

	
 
		case WWT_TEXTBTN:
 
		case WWT_TEXTBTN_2:
 
			DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->colour, (clicked) ? FR_LOWERED : FR_NONE);
 
			/* FALL THROUGH */
 

	
 
		case WWT_LABEL:
 
			DrawLabel(r, wi->type, clicked, wi->data);
 
			break;
 

	
 
		case WWT_TEXT:
 
			DrawText(r, (TextColour)wi->colour, wi->data);
 
			break;
 

	
 
		case WWT_INSET:
 
			DrawInset(r, wi->colour, wi->data);
 
			break;
 

	
 
		case WWT_MATRIX:
 
			DrawMatrix(r, wi->colour, clicked, wi->data);
 
			break;
 

	
 
		/* vertical scrollbar */
 
		case WWT_SCROLLBAR:
 
			assert(wi->data == 0);
 
			DrawVerticalScrollbar(r, wi->colour, (this->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_UP,
 
								(this->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_MIDDLE,
 
								(this->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_DOWN, &this->vscroll);
 
			break;
 

	
 
		case WWT_SCROLL2BAR:
 
			assert(wi->data == 0);
 
			DrawVerticalScrollbar(r, wi->colour, (this->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_UP | WF_SCROLL2),
 
								(this->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_MIDDLE | WF_SCROLL2),
 
								(this->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_DOWN | WF_SCROLL2), &this->vscroll2);
 
			break;
 

	
 
		/* horizontal scrollbar */
 
		case WWT_HSCROLLBAR:
 
			assert(wi->data == 0);
 
			DrawHorizontalScrollbar(r, wi->colour, (this->flags4 & (WF_SCROLL_UP | WF_HSCROLL)) == (WF_SCROLL_UP | WF_HSCROLL),
 
								(this->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL)) == (WF_SCROLL_MIDDLE | WF_HSCROLL),
 
								(this->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL)) == (WF_SCROLL_DOWN | WF_HSCROLL), &this->hscroll);
 
			break;
 

	
 
		case WWT_FRAME:
 
			DrawFrame(r, wi->colour, wi->data);
 
			break;
 

	
 
		case WWT_STICKYBOX:
 
			assert(wi->data == 0);
 
			DrawStickyBox(r, wi->colour, !!(this->flags4 & WF_STICKY));
 
			break;
 

	
 
		case WWT_RESIZEBOX:
 
			assert(wi->data == 0);
 
			DrawResizeBox(r, wi->colour, wi->left < (this->width / 2), !!(this->flags4 & WF_SIZING));
 
			break;
 

	
 
		case WWT_CLOSEBOX:
 
			DrawCloseBox(r, wi->colour, wi->data);
 
			break;
 

	
 
		case WWT_CAPTION:
 
			DrawCaption(r, wi->colour, this->owner, wi->data);
 
			break;
 

	
 
		case WWT_DROPDOWN:
 
			DrawDropdown(r, wi->colour, clicked, wi->data);
 
			break;
 
		}
 

	
 
		if (this->IsWidgetDisabled(i)) {
 
			GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, _colour_gradient[wi->colour & 0xF][2], FILLRECT_CHECKER);
 
		}
 
	}
 

	
 
	this->nested_root->Draw(this);
 

	
 
	if (this->flags4 & WF_WHITE_BORDER_MASK) {
 
		DrawFrameRect(0, 0, this->width - 1, this->height - 1, COLOUR_WHITE, FR_BORDERONLY);
 
@@ -726,17 +560,13 @@ void Window::DrawSortButtonState(int wid
 
{
 
	if (state == SBS_OFF) return;
 

	
 
	assert(this->nested_array != NULL);
 
	const NWidgetBase *nwid = this->GetWidget<NWidgetBase>(widget);
 

	
 
	int offset = this->IsWidgetLowered(widget) ? 1 : 0;
 
	int base, top;
 
	if (this->widget != NULL) {
 
		base = offset + (_dynlang.text_dir == TD_LTR ? this->widget[widget].right - WD_SORTBUTTON_ARROW_WIDTH : this->widget[widget].left);
 
		top = this->widget[widget].top;
 
	} else {
 
		assert(this->nested_array != NULL);
 
		const NWidgetBase *nwid = this->GetWidget<NWidgetBase>(widget);
 
		base = offset + nwid->pos_x + (_dynlang.text_dir == TD_LTR ? nwid->current_x - WD_SORTBUTTON_ARROW_WIDTH : 0);
 
		top = nwid->pos_y;
 
	}
 
	int base = offset + nwid->pos_x + (_dynlang.text_dir == TD_LTR ? nwid->current_x - WD_SORTBUTTON_ARROW_WIDTH : 0);
 
	int top = nwid->pos_y;
 

	
 
	DrawString(base, base + WD_SORTBUTTON_ARROW_WIDTH, top + 1 + offset, state == SBS_DOWN ? DOWNARROW : UPARROW, TC_BLACK, SA_CENTER);
 
}
 

	
 
@@ -868,19 +698,6 @@ inline void NWidgetBase::StoreSizePositi
 
}
 

	
 
/**
 
 * @fn void NWidgetBase::StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl)
 
 * Store all child widgets with a valid index into the widget array.
 
 * @param widgets     Widget array to store the nested widgets in.
 
 * @param length      Length of the array.
 
 * @param left_moving Left edge of the widget may move due to resizing (right edge if \a rtl).
 
 * @param top_moving  Top edge of the widget may move due to resizing.
 
 * @param rtl         Adapt for right-to-left languages (position contents of horizontal containers backwards).
 
 *
 
 * @note When storing a nested widget, the function should check first that the type in the \a widgets array is #WWT_LAST.
 
 *       This is used to detect double widget allocations as well as holes in the widget array.
 
 */
 

	
 
/**
 
 * @fn void Draw(const Window *w)
 
 * Draw the widgets of the tree.
 
 * The function calls #Window::DrawWidget for each widget with a non-negative index, after the widget itself is painted.
 
@@ -1009,40 +826,6 @@ void NWidgetCore::FillNestedArray(NWidge
 
	if (this->index >= 0 && (uint)(this->index) < length) array[this->index] = this;
 
}
 

	
 
void NWidgetCore::StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl)
 
{
 
	if (this->index < 0) return;
 

	
 
	assert(this->index < length);
 
	Widget *w = widgets + this->index;
 
	assert(w->type == WWT_LAST);
 

	
 
	DisplayFlags flags = RESIZE_NONE; // resize flags.
 
	/* Compute vertical resizing. */
 
	if (top_moving) {
 
		flags |= RESIZE_TB; // Only 1 widget can resize in the widget array.
 
	} else if (this->resize_y > 0) {
 
		flags |= RESIZE_BOTTOM;
 
	}
 
	/* Compute horizontal resizing. */
 
	if (left_moving) {
 
		flags |= RESIZE_LR; // Only 1 widget can resize in the widget array.
 
	} else if (this->resize_x > 0) {
 
		flags |= RESIZE_RIGHT;
 
	}
 

	
 
	/* Copy nested widget data into its widget array entry. */
 
	w->type = this->type;
 
	w->display_flags = flags;
 
	w->colour = this->colour;
 
	w->left = this->pos_x;
 
	w->right = this->pos_x + this->smallest_x - 1;
 
	w->top = this->pos_y;
 
	w->bottom = this->pos_y + this->smallest_y - 1;
 
	w->data = this->widget_data;
 
	w->tooltips = this->tool_tip;
 
}
 

	
 
NWidgetCore *NWidgetCore::GetWidgetFromPos(int x, int y)
 
{
 
	return (IsInsideBS(x, this->pos_x, this->current_x) && IsInsideBS(y, this->pos_y, this->current_y)) ? this : NULL;
 
@@ -1223,13 +1006,6 @@ void NWidgetStacked::AssignSizePosition(
 
	}
 
}
 

	
 
void NWidgetStacked::StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl)
 
{
 
	for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
 
		child_wid->StoreWidgets(widgets, length, left_moving, top_moving, rtl);
 
	}
 
}
 

	
 
void NWidgetStacked::FillNestedArray(NWidgetBase **array, uint length)
 
{
 
	if (this->index >= 0 && (uint)(this->index) < length) array[this->index] = this;
 
@@ -1432,17 +1208,6 @@ void NWidgetHorizontal::AssignSizePositi
 
	}
 
}
 

	
 
void NWidgetHorizontal::StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl)
 
{
 
	NWidgetBase *child_wid = rtl ? this->tail : this->head;
 
	while (child_wid != NULL) {
 
		child_wid->StoreWidgets(widgets, length, left_moving, top_moving, rtl);
 
		left_moving |= (child_wid->resize_x > 0);
 

	
 
		child_wid = rtl ? child_wid->prev : child_wid->next;
 
	}
 
}
 

	
 
/** Horizontal left-to-right container widget. */
 
NWidgetHorizontalLTR::NWidgetHorizontalLTR(NWidContainerFlags flags) : NWidgetHorizontal(flags)
 
{
 
@@ -1454,11 +1219,6 @@ void NWidgetHorizontalLTR::AssignSizePos
 
	NWidgetHorizontal::AssignSizePosition(sizing, x, y, given_width, given_height, allow_resize_x, allow_resize_y, false);
 
}
 

	
 
void NWidgetHorizontalLTR::StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl)
 
{
 
	NWidgetHorizontal::StoreWidgets(widgets, length, left_moving, top_moving, false);
 
}
 

	
 
/** Vertical container widget. */
 
NWidgetVertical::NWidgetVertical(NWidContainerFlags flags) : NWidgetPIPContainer(NWID_VERTICAL, flags)
 
{
 
@@ -1569,14 +1329,6 @@ void NWidgetVertical::AssignSizePosition
 
	}
 
}
 

	
 
void NWidgetVertical::StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl)
 
{
 
	for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
 
		child_wid->StoreWidgets(widgets, length, left_moving, top_moving, rtl);
 
		top_moving |= (child_wid->resize_y > 0);
 
	}
 
}
 

	
 
/**
 
 * Generic spacer widget.
 
 * @param length Horizontal size of the spacer widget.
 
@@ -1598,11 +1350,6 @@ void NWidgetSpacer::FillNestedArray(NWid
 
{
 
}
 

	
 
void NWidgetSpacer::StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl)
 
{
 
	/* Spacer widgets are never stored in the widget array. */
 
}
 

	
 
void NWidgetSpacer::Draw(const Window *w)
 
{
 
	/* Spacer widget is never visible. */
 
@@ -1728,12 +1475,6 @@ void NWidgetBackground::AssignSizePositi
 
	}
 
}
 

	
 
void NWidgetBackground::StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl)
 
{
 
	NWidgetCore::StoreWidgets(widgets, length, left_moving, top_moving, rtl);
 
	if (this->child != NULL) this->child->StoreWidgets(widgets, length, left_moving, top_moving, rtl);
 
}
 

	
 
void NWidgetBackground::FillNestedArray(NWidgetBase **array, uint length)
 
{
 
	if (this->index >= 0 && (uint)(this->index) < length) array[this->index] = this;
 
@@ -1823,11 +1564,6 @@ void NWidgetViewport::SetupSmallestSize(
 
	this->smallest_y = this->min_y;
 
}
 

	
 
void NWidgetViewport::StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl)
 
{
 
	NOT_REACHED();
 
}
 

	
 
void NWidgetViewport::Draw(const Window *w)
 
{
 
	if (this->disp_flags & ND_NO_TRANSPARENCY) {
 
@@ -2264,44 +2000,6 @@ bool NWidgetLeaf::ButtonHit(const Point 
 
	}
 
}
 

	
 
/**
 
 * Intialize nested widget tree and convert to widget array.
 
 * @param nwid Nested widget tree.
 
 * @param rtl  Direction of the language.
 
 * @param biggest_index Biggest index used in the nested widget tree.
 
 * @return Widget array with the converted widgets.
 
 * @note Caller should release returned widget array with \c free(widgets).
 
 * @ingroup NestedWidgets
 
 */
 
static Widget *InitializeNWidgets(NWidgetBase *nwid, bool rtl, int biggest_index)
 
{
 
	/* Initialize nested widgets. */
 
	nwid->SetupSmallestSize(NULL, false);
 
	nwid->AssignSizePosition(ST_ARRAY, 0, 0, nwid->smallest_x, nwid->smallest_y, (nwid->resize_x > 0), (nwid->resize_y > 0), rtl);
 

	
 
	/* Construct a local widget array and initialize all its types to #WWT_LAST. */
 
	Widget *widgets = MallocT<Widget>(biggest_index + 2);
 
	int i;
 
	for (i = 0; i < biggest_index + 2; i++) {
 
		widgets[i].type = WWT_LAST;
 
	}
 

	
 
	/* Store nested widgets in the array. */
 
	nwid->StoreWidgets(widgets, biggest_index + 1, false, false, rtl);
 

	
 
	/* Check that all widgets are used. */
 
	for (i = 0; i < biggest_index + 2; i++) {
 
		if (widgets[i].type == WWT_LAST) break;
 
	}
 
	assert(i == biggest_index + 1);
 

	
 
	/* Fill terminating widget */
 
	static const Widget last_widget = {WIDGETS_END};
 
	widgets[biggest_index + 1] = last_widget;
 

	
 
	return widgets;
 
}
 

	
 
/* == Conversion code from NWidgetPart array to NWidgetBase* tree == */
 

	
 
/**
 
@@ -2515,30 +2213,3 @@ NWidgetContainer *MakeNWidgets(const NWi
 
	MakeWidgetTree(parts, count, container, biggest_index);
 
	return container;
 
}
 

	
 
/**
 
 * Construct a #Widget array from a nested widget parts array, taking care of all the steps and checks.
 
 * Also cache the result and use the cache if possible.
 
 * @param[in] parts        Array with parts of the widgets.
 
 * @param     parts_length Length of the \a parts array.
 
 * @param     wid_cache    Pointer to the cache for storing the generated widget array (use \c NULL to prevent caching).
 
 * @return Cached value if available, otherwise the generated widget array. If \a wid_cache is \c NULL, the caller should free the returned array.
 
 *
 
 * @pre Before the first call, \c *wid_cache should be \c NULL.
 
 * @post The widget array stored in the \c *wid_cache should be free-ed by the caller.
 
 */
 
const Widget *InitializeWidgetArrayFromNestedWidgets(const NWidgetPart *parts, int parts_length, Widget **wid_cache)
 
{
 
	const bool rtl = false; // Direction of the language is left-to-right
 

	
 
	if (wid_cache != NULL && *wid_cache != NULL) return *wid_cache;
 

	
 
	assert(parts != NULL && parts_length > 0);
 
	int biggest_index = -1;
 
	NWidgetContainer *nwid = MakeNWidgets(parts, parts_length, &biggest_index);
 
	Widget *gen_wid = InitializeNWidgets(nwid, rtl, biggest_index);
 
	delete nwid;
 

	
 
	if (wid_cache != NULL) *wid_cache = gen_wid;
 
	return gen_wid;
 
}
src/widget_type.h
Show inline comments
 
@@ -142,24 +142,6 @@ enum WidgetType {
 
	WWT_PUSHIMGBTN  = WWT_IMGBTN  | WWB_PUSHBUTTON,
 
};
 

	
 
/** Marker for the "end of widgets" in a Window(Desc) widget table. */
 
#define WIDGETS_END WWT_LAST, RESIZE_NONE, INVALID_COLOUR, 0, 0, 0, 0, 0, STR_NULL
 

	
 
/**
 
 * Window widget data structure
 
 */
 
struct Widget {
 
	WidgetType type;                  ///< Widget type
 
	DisplayFlags display_flags;       ///< Resize direction, alignment, etc. during resizing
 
	Colours colour;                   ///< Widget colour, see docs/ottd-colourtext-palette.png
 
	int16 left;                       ///< The left edge of the widget
 
	int16 right;                      ///< The right edge of the widget
 
	int16 top;                        ///< The top edge of the widget
 
	int16 bottom;                     ///< The bottom edge of the widget
 
	uint16 data;                      ///< The String/Image or special code (list-matrixes) of a widget
 
	StringID tooltips;                ///< Tooltips that are shown when rightclicking on a widget
 
};
 

	
 
/** Different forms of sizing nested widgets, using NWidgetBase::AssignSizePosition() */
 
enum SizingType {
 
	ST_ARRAY,    ///< Initialize nested widget tree to generate a #Widget * array.
 
@@ -184,7 +166,6 @@ public:
 
	virtual void SetupSmallestSize(Window *w, bool init_array) = 0;
 
	virtual void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool allow_resize_x, bool allow_resize_y, bool rtl) = 0;
 

	
 
	virtual void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl) = 0;
 
	virtual void FillNestedArray(NWidgetBase **array, uint length) = 0;
 

	
 
	virtual NWidgetCore *GetWidgetFromPos(int x, int y) = 0;
 
@@ -311,7 +292,6 @@ public:
 
	inline void SetDisabled(bool disabled);
 
	inline bool IsDisabled() const;
 

	
 
	void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl);
 
	/* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
 
	/* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
 

	
 
@@ -393,7 +373,6 @@ public:
 

	
 
	void SetupSmallestSize(Window *w, bool init_array);
 
	void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool allow_resize_x, bool allow_resize_y, bool rtl);
 
	void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl);
 
	/* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
 

	
 
	/* virtual */ void Draw(const Window *w);
 
@@ -439,8 +418,6 @@ public:
 

	
 
	void SetupSmallestSize(Window *w, bool init_array);
 
	void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool allow_resize_x, bool allow_resize_y, bool rtl);
 

	
 
	void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl);
 
};
 

	
 
/** Horizontal container that doesn't change the direction of the widgets for RTL languages.
 
@@ -450,8 +427,6 @@ public:
 
	NWidgetHorizontalLTR(NWidContainerFlags flags = NC_NONE);
 

	
 
	void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool allow_resize_x, bool allow_resize_y, bool rtl);
 

	
 
	void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl);
 
};
 

	
 
/** Vertical container.
 
@@ -462,8 +437,6 @@ public:
 

	
 
	void SetupSmallestSize(Window *w, bool init_array);
 
	void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool allow_resize_x, bool allow_resize_y, bool rtl);
 

	
 
	void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl);
 
};
 

	
 

	
 
@@ -474,7 +447,6 @@ public:
 
	NWidgetSpacer(int length, int height);
 

	
 
	void SetupSmallestSize(Window *w, bool init_array);
 
	void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl);
 
	/* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
 

	
 
	/* virtual */ void Draw(const Window *w);
 
@@ -495,7 +467,6 @@ public:
 
	void SetupSmallestSize(Window *w, bool init_array);
 
	void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool allow_resize_x, bool allow_resize_y, bool rtl);
 

	
 
	void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl);
 
	/* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
 

	
 
	/* virtual */ void Draw(const Window *w);
 
@@ -520,7 +491,6 @@ public:
 
	NWidgetViewport(int index);
 

	
 
	/* virtual */ void SetupSmallestSize(Window *w, bool init_array);
 
	/* virtual */ void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl);
 
	/* virtual */ void Draw(const Window *w);
 
	/* virtual */ Scrollbar *FindScrollbar(Window *w, bool allow_next = true);
 

	
 
@@ -547,8 +517,6 @@ private:
 
	static Dimension closebox_dimension;  ///< Cached size of a closebox widget.
 
};
 

	
 
bool CompareWidgetArrays(const Widget *orig, const Widget *gen, bool report = true);
 

	
 
/**
 
 * @defgroup NestedWidgetParts Hierarchical widget parts
 
 * To make nested widgets easier to enter, nested widget parts have been created. They allow the tree to be defined in a flat array of parts.
 
@@ -829,6 +797,4 @@ static inline NWidgetPart NWidgetFunctio
 

	
 
NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count, int *biggest_index, NWidgetContainer *container = NULL);
 

	
 
const Widget *InitializeWidgetArrayFromNestedWidgets(const NWidgetPart *parts, int parts_length, Widget **wid_cache);
 

	
 
#endif /* WIDGET_TYPE_H */
src/widgets/dropdown.cpp
Show inline comments
 
@@ -326,27 +326,16 @@ void ShowDropDownList(Window *w, DropDow
 
	 * down list window. */
 
	Rect wi_rect;
 
	Colours wi_colour;
 
	if (w->nested_array != NULL) {
 
		NWidgetCore *nwi = w->GetWidget<NWidgetCore>(button);
 
		wi_rect.left   = nwi->pos_x;
 
		wi_rect.right  = nwi->pos_x + nwi->current_x - 1;
 
		wi_rect.top    = nwi->pos_y;
 
		wi_rect.bottom = nwi->pos_y + nwi->current_y - 1;
 
		wi_colour = nwi->colour;
 
	NWidgetCore *nwi = w->GetWidget<NWidgetCore>(button);
 
	wi_rect.left   = nwi->pos_x;
 
	wi_rect.right  = nwi->pos_x + nwi->current_x - 1;
 
	wi_rect.top    = nwi->pos_y;
 
	wi_rect.bottom = nwi->pos_y + nwi->current_y - 1;
 
	wi_colour = nwi->colour;
 

	
 
		if (nwi->type == NWID_BUTTON_DRPDOWN) {
 
			nwi->disp_flags |= ND_DROPDOWN_ACTIVE;
 
		} else {
 
			w->LowerWidget(button);
 
		}
 
	if (nwi->type == NWID_BUTTON_DRPDOWN) {
 
		nwi->disp_flags |= ND_DROPDOWN_ACTIVE;
 
	} else {
 
		const Widget *wi = &w->widget[button];
 
		wi_rect.left   = wi->left;
 
		wi_rect.right  = wi->right;
 
		wi_rect.top    = wi->top;
 
		wi_rect.bottom = wi->bottom;
 
		wi_colour = wi->colour;
 

	
 
		w->LowerWidget(button);
 
	}
 
	w->SetWidgetDirty(button);
src/window.cpp
Show inline comments
 
@@ -74,23 +74,10 @@ WindowDesc::WindowDesc(int16 left, int16
 
	this->flags = flags;
 
	this->nwid_parts = nwid_parts;
 
	this->nwid_length = nwid_length;
 
	this->new_widgets = NULL;
 
}
 

	
 
/** Get widget array of the window description. */
 
const Widget *WindowDesc::GetWidgets() const
 
{
 
	if (this->nwid_parts != NULL) {
 
		InitializeWidgetArrayFromNestedWidgets(this->nwid_parts, this->nwid_length, &this->new_widgets);
 
	}
 
	const Widget *wids = this->new_widgets;
 
	assert(wids != NULL);
 
	return wids;
 
}
 

	
 
WindowDesc::~WindowDesc()
 
{
 
	free(this->new_widgets);
 
}
 

	
 
/**
 
@@ -103,10 +90,6 @@ void SetFocusedWindow(Window *w)
 

	
 
	/* Invalidate focused widget */
 
	if (_focused_window != NULL) {
 
		if (_focused_window->focused_widget != NULL) {
 
			uint focused_widget_id = _focused_window->focused_widget - _focused_window->widget;
 
			_focused_window->SetWidgetDirty(focused_widget_id);
 
		}
 
		if (_focused_window->nested_focus != NULL) _focused_window->nested_focus->SetDirty(_focused_window);
 
	}
 

	
 
@@ -131,10 +114,7 @@ bool EditBoxInGlobalFocus()
 
	/* The console does not have an edit box so a special case is needed. */
 
	if (_focused_window->window_class == WC_CONSOLE) return true;
 

	
 
	if (_focused_window->nested_array != NULL) {
 
		return _focused_window->nested_focus != NULL && _focused_window->nested_focus->type == WWT_EDITBOX;
 
	}
 
	return _focused_window->focused_widget != NULL && _focused_window->focused_widget->type == WWT_EDITBOX;
 
	return _focused_window->nested_focus != NULL && _focused_window->nested_focus->type == WWT_EDITBOX;
 
}
 

	
 
/**
 
@@ -144,33 +124,18 @@ bool EditBoxInGlobalFocus()
 
 */
 
bool Window::SetFocusedWidget(byte widget_index)
 
{
 
	if (this->widget != NULL) {
 
		/* Do nothing if widget_index is already focused, or if it wasn't a valid widget. */
 
		if (widget_index >= this->widget_count || this->widget + widget_index == this->focused_widget) return false;
 

	
 
		if (this->focused_widget != NULL) {
 
			/* Repaint the widget that lost focus. A focused edit box may else leave the caret on the screen. */
 
			this->SetWidgetDirty(this->focused_widget - this->widget);
 
		}
 
		this->focused_widget = &this->widget[widget_index];
 
		return true;
 
	}
 
	/* Do nothing if widget_index is already focused, or if it wasn't a valid widget. */
 
	if (widget_index >= this->nested_array_size) return false;
 

	
 
	if (this->nested_array != NULL) {
 
		/* Do nothing if widget_index is already focused, or if it wasn't a valid widget. */
 
		if (widget_index >= this->nested_array_size) return false;
 

	
 
		assert(this->nested_array[widget_index] != NULL); // Setting focus to a non-existing widget is a bad idea.
 
		if (this->nested_focus != NULL) {
 
			if (this->GetWidget<NWidgetCore>(widget_index) == this->nested_focus) return false;
 
	assert(this->nested_array[widget_index] != NULL); // Setting focus to a non-existing widget is a bad idea.
 
	if (this->nested_focus != NULL) {
 
		if (this->GetWidget<NWidgetCore>(widget_index) == this->nested_focus) return false;
 

	
 
			/* Repaint the widget that lost focus. A focused edit box may else leave the caret on the screen. */
 
			this->nested_focus->SetDirty(this);
 
		}
 
		this->nested_focus = this->GetWidget<NWidgetCore>(widget_index);
 
		return true;
 
		/* Repaint the widget that lost focus. A focused edit box may else leave the caret on the screen. */
 
		this->nested_focus->SetDirty(this);
 
	}
 
	NOT_REACHED();
 
	this->nested_focus = this->GetWidget<NWidgetCore>(widget_index);
 
	return true;
 
}
 

	
 
/**
 
@@ -195,27 +160,6 @@ void CDECL Window::SetWidgetsDisabledSta
 
}
 

	
 
/**
 
 * Sets the hidden/shown status of a list of widgets.
 
 * By default, widgets are visible.
 
 * On certain conditions, they have to be hidden.
 
 * @param hidden_stat status to use ie. hidden = true, visible = false
 
 * @param widgets list of widgets ended by WIDGET_LIST_END
 
 */
 
void CDECL Window::SetWidgetsHiddenState(bool hidden_stat, int widgets, ...)
 
{
 
	va_list wdg_list;
 

	
 
	va_start(wdg_list, widgets);
 

	
 
	while (widgets != WIDGET_LIST_END) {
 
		SetWidgetHiddenState(widgets, hidden_stat);
 
		widgets = va_arg(wdg_list, int);
 
	}
 

	
 
	va_end(wdg_list);
 
}
 

	
 
/**
 
 * Sets the lowered/raised status of a list of widgets.
 
 * @param lowered_stat status to use ie: lowered = true, raised = false
 
 * @param widgets list of widgets ended by WIDGET_LIST_END
 
@@ -240,21 +184,11 @@ void CDECL Window::SetWidgetsLoweredStat
 
 */
 
void Window::RaiseButtons(bool autoraise)
 
{
 
	if (this->widget != NULL) {
 
		for (uint i = 0; i < this->widget_count; i++) {
 
			if ((!autoraise || (this->widget[i].type & WWB_PUSHBUTTON)) && this->IsWidgetLowered(i)) {
 
				this->RaiseWidget(i);
 
				this->SetWidgetDirty(i);
 
			}
 
		}
 
	}
 
	if (this->nested_array != NULL) {
 
		for (uint i = 0; i < this->nested_array_size; i++) {
 
			if (this->nested_array[i] != NULL && (this->nested_array[i]->type & ~WWB_PUSHBUTTON) < WWT_LAST &&
 
					(!autoraise || (this->nested_array[i]->type & WWB_PUSHBUTTON)) && this->IsWidgetLowered(i)) {
 
				this->RaiseWidget(i);
 
				this->SetWidgetDirty(i);
 
			}
 
	for (uint i = 0; i < this->nested_array_size; i++) {
 
		if (this->nested_array[i] != NULL && (this->nested_array[i]->type & ~WWB_PUSHBUTTON) < WWT_LAST &&
 
				(!autoraise || (this->nested_array[i]->type & WWB_PUSHBUTTON)) && this->IsWidgetLowered(i)) {
 
			this->RaiseWidget(i);
 
			this->SetWidgetDirty(i);
 
		}
 
	}
 
}
 
@@ -265,15 +199,7 @@ void Window::RaiseButtons(bool autoraise
 
 */
 
void Window::SetWidgetDirty(byte widget_index) const
 
{
 
	if (this->widget != NULL) {
 
		const Widget *wi = &this->widget[widget_index];
 

	
 
		/* Don't redraw the window if the widget is invisible or of no-type */
 
		if (wi->type == WWT_EMPTY || IsWidgetHidden(widget_index)) return;
 

	
 
		SetDirtyBlocks(this->left + wi->left, this->top + wi->top, this->left + wi->right + 1, this->top + wi->bottom + 1);
 
	}
 
	if (this->nested_array != NULL) this->nested_array[widget_index]->SetDirty(this);
 
	this->nested_array[widget_index]->SetDirty(this);
 
}
 

	
 
/**
 
@@ -288,18 +214,6 @@ void Window::HandleButtonClick(byte widg
 
	this->SetWidgetDirty(widget);
 
}
 

	
 
/**
 
 * Return a widget of the requested type from the window.
 
 * @param widget_type the widget type to look for
 
 */
 
const Widget *Window::GetWidgetOfType(WidgetType widget_type) const
 
{
 
	for (uint i = 0; i < this->widget_count; i++) {
 
		if (this->widget[i].type == widget_type) return &this->widget[i];
 
	}
 
	return NULL;
 
}
 

	
 
static void StartWindowDrag(Window *w);
 
static void StartWindowSizing(Window *w, bool to_left);
 

	
 
@@ -314,19 +228,9 @@ static void DispatchLeftClickEvent(Windo
 
{
 
	int widget_index = 0;
 
	if (w->desc_flags & WDF_DEF_WIDGET) {
 
		const Widget *wi = NULL;
 
		const NWidgetCore *nw = NULL;
 
		WidgetType widget_type;
 
		if (w->widget != NULL) {
 
			widget_index = GetWidgetFromPos(w, x, y);
 
			wi = &w->widget[widget_index];
 
			widget_type = (widget_index >= 0) ? wi->type : WWT_EMPTY;
 
		} else {
 
			assert(w->nested_root != NULL);
 
			nw = w->nested_root->GetWidgetFromPos(x, y);
 
			widget_index = (nw != NULL) ? nw->index : -1;
 
			widget_type = (widget_index >= 0) ? nw->type : WWT_EMPTY;
 
		}
 
		const NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y);
 
		widget_index = (nw != NULL) ? nw->index : -1;
 
		WidgetType widget_type = (widget_index >= 0) ? nw->type : WWT_EMPTY;
 

	
 
		bool focused_widget_changed = false;
 
		/* If clicked on a window that previously did dot have focus */
 
@@ -353,9 +257,7 @@ static void DispatchLeftClickEvent(Windo
 
		 * So unless the clicked widget is the caption bar, change focus to this widget */
 
		if (widget_type != WWT_CAPTION) {
 
			/* Close the OSK window if a edit box loses focus */
 
			if ((w->widget != NULL && w->focused_widget != NULL && w->focused_widget->type == WWT_EDITBOX && // An edit box was previously selected
 
						w->focused_widget != wi && w->window_class != WC_OSK) ||                 // and focus is going to change and it is not the OSK window
 
					(w->nested_root != NULL && w->nested_focus != NULL &&  w->nested_focus->type == WWT_EDITBOX &&
 
			if ((w->nested_root != NULL && w->nested_focus != NULL &&  w->nested_focus->type == WWT_EDITBOX &&
 
						w->nested_focus != nw && w->window_class != WC_OSK)) {
 
				DeleteWindowById(WC_OSK, 0);
 
			}
 
@@ -383,11 +285,7 @@ static void DispatchLeftClickEvent(Windo
 
					break;
 
			}
 
		} else if (widget_type == WWT_SCROLLBAR || widget_type == WWT_SCROLL2BAR || widget_type == WWT_HSCROLLBAR) {
 
			if (wi != NULL) {
 
				ScrollbarClickHandler(w, wi, x, y);
 
			} else {
 
				ScrollbarClickHandler(w, nw, x, y);
 
			}
 
			ScrollbarClickHandler(w, nw, x, y);
 
		} else if (widget_type == WWT_EDITBOX && !focused_widget_changed) { // Only open the OSK window if clicking on an already focused edit box
 
			/* Open the OSK window if clicked on an edit box */
 
			QueryStringBaseWindow *qs = dynamic_cast<QueryStringBaseWindow *>(w);
 
@@ -415,7 +313,7 @@ static void DispatchLeftClickEvent(Windo
 
		if ((w->desc_flags & WDF_RESIZABLE) && widget_type == WWT_RESIZEBOX) {
 
			/* When the resize widget is on the left size of the window
 
			 * we assume that that button is used to resize to the left. */
 
			int left_pos = (wi != NULL) ? wi->left : nw->pos_x;
 
			int left_pos = nw->pos_x;
 
			StartWindowSizing(w, left_pos < (w->width / 2));
 
			w->SetWidgetDirty(widget_index);
 
			return;
 
@@ -446,21 +344,13 @@ static void DispatchLeftClickEvent(Windo
 
static void DispatchRightClickEvent(Window *w, int x, int y)
 
{
 
	int widget = 0;
 
	StringID tooltip = 0;
 

	
 
	/* default tooltips handler? */
 
	if (w->desc_flags & WDF_STD_TOOLTIPS) {
 
		if (w->nested_root != NULL) {
 
			NWidgetCore *wid = w->nested_root->GetWidgetFromPos(x, y);
 
			if (wid == NULL || wid->index < 0) return;
 
			widget = wid->index;
 
			tooltip = wid->tool_tip;
 
		}
 
		if (w->widget != NULL) {
 
			widget = GetWidgetFromPos(w, x, y);
 
			if (widget < 0) return; // exit if clicked outside of widgets
 
			tooltip = w->widget[widget].tooltips;
 
		}
 
		NWidgetCore *wid = w->nested_root->GetWidgetFromPos(x, y);
 
		if (wid == NULL || wid->index < 0) return;
 
		widget = wid->index;
 
		StringID tooltip = wid->tool_tip;
 

	
 
		if (tooltip != 0) {
 
			GuiShowTooltips(tooltip);
 
@@ -484,16 +374,6 @@ static void DispatchMouseWheelEvent(Wind
 
	if (widget < 0) return;
 

	
 
	Scrollbar *sb = NULL;
 
	if (w->widget != NULL) {
 
		const Widget *wi1 = &w->widget[widget];
 
		const Widget *wi2 = &w->widget[widget + 1];
 
		if (wi1->type == WWT_SCROLLBAR || wi2->type == WWT_SCROLLBAR) {
 
			sb = &w->vscroll;
 
		} else if (wi1->type == WWT_SCROLL2BAR || wi2->type == WWT_SCROLL2BAR) {
 
			sb = &w->vscroll2;
 
		}
 
	}
 

	
 
	if (w->nested_array != NULL && (uint)widget < w->nested_array_size) sb = w->GetWidget<NWidgetCore>(widget)->FindScrollbar(w);
 

	
 
	if (sb != NULL && sb->GetCount() > sb->GetCapacity()) {
 
@@ -698,7 +578,6 @@ Window::~Window()
 

	
 
	this->SetDirty();
 

	
 
	free(this->widget);
 
	free(this->nested_array); // Contents is released through deletion of #nested_root.
 
	delete this->nested_root;
 

	
 
@@ -885,76 +764,43 @@ static void BringWindowToFront(Window *w
 
}
 

	
 
/**
 
 * Assign widgets to a new window by initialising its widget pointers, and by
 
 * copying the widget array \a widget to \c w->widget to allow for resizable
 
 * windows.
 
 * @param w Window on which to attach the widget array
 
 * @param widget pointer of widget array to fill the window with
 
 *
 
 * @post \c w->widget points to allocated memory and contains the copied widget array except for the terminating widget,
 
 *       \c w->widget_count contains number of widgets in the allocated memory.
 
 */
 
static void AssignWidgetToWindow(Window *w, const Widget *widget)
 
{
 
	if (widget != NULL) {
 
		uint index = 1;
 

	
 
		for (const Widget *wi = widget; wi->type != WWT_LAST; wi++) index++;
 

	
 
		w->widget = MallocT<Widget>(index);
 
		memcpy(w->widget, widget, sizeof(*w->widget) * index);
 
		w->widget_count = index - 1;
 
	} else {
 
		w->widget = NULL;
 
		w->widget_count = 0;
 
	}
 
}
 

	
 
/**
 
 * Initializes the data (except the position and initial size) of a new Window.
 
 * @param cls           Class of the window, used for identification and grouping. @see WindowClass
 
 * @param *widget       Pointer to the widget array, it is \c NULL when nested widgets are used. @see Widget
 
 * @param window_number Number being assigned to the new window
 
 * @param desc_flags    Window flags. @see WindowDefaultFlag
 
 * @return Window pointer of the newly created window
 
 * @pre If nested widgets are used (\a widget is \c NULL), #nested_root and #nested_array_size must be initialized.
 
 *      In addition, #nested_array is either \c NULL, or already initialized.
 
 */
 
void Window::InitializeData(WindowClass cls, const Widget *widget, int window_number, uint32 desc_flags)
 
void Window::InitializeData(WindowClass cls, int window_number, uint32 desc_flags)
 
{
 
	/* Set up window properties; some of them are needed to set up smallest size below */
 
	this->window_class = cls;
 
	this->flags4 = WF_WHITE_BORDER_MASK; // just opened windows have a white border
 
	this->owner = INVALID_OWNER;
 
	this->focused_widget = NULL;
 
	this->nested_focus = NULL;
 
	this->window_number = window_number;
 
	this->desc_flags = desc_flags;
 

	
 
	/* If available, initialize nested widget tree. */
 
	if (widget == NULL) {
 
		if (this->nested_array == NULL) {
 
			this->nested_array = CallocT<NWidgetBase *>(this->nested_array_size);
 
			this->nested_root->SetupSmallestSize(this, true);
 
		} else {
 
			this->nested_root->SetupSmallestSize(this, false);
 
		}
 
		/* Initialize to smallest size. */
 
		this->nested_root->AssignSizePosition(ST_SMALLEST, 0, 0, this->nested_root->smallest_x, this->nested_root->smallest_y, false, false, false);
 
	if (this->nested_array == NULL) {
 
		this->nested_array = CallocT<NWidgetBase *>(this->nested_array_size);
 
		this->nested_root->SetupSmallestSize(this, true);
 
	} else {
 
		this->nested_root->SetupSmallestSize(this, false);
 
	}
 
	/* Else, all data members of nested widgets have been set to 0 by the #ZeroedMemoryAllocator base class. */
 
	/* Initialize to smallest size. */
 
	this->nested_root->AssignSizePosition(ST_SMALLEST, 0, 0, this->nested_root->smallest_x, this->nested_root->smallest_y, false, false, false);
 

	
 
	/* Further set up window properties,
 
	 * this->left, this->top, this->width, this->height, this->resize.width, and this->resize.height are initialized later. */
 
	AssignWidgetToWindow(this, widget);
 
	this->resize.step_width  = (this->nested_root != NULL) ? this->nested_root->resize_x : 1;
 
	this->resize.step_height = (this->nested_root != NULL) ? this->nested_root->resize_y : 1;
 

	
 
	/* Give focus to the opened window unless it is the OSK window or a text box
 
	 * of focused window has focus (so we don't interrupt typing). But if the new
 
	 * window has a text box, then take focus anyway. */
 
	bool has_editbox = (this->widget != NULL && this->GetWidgetOfType(WWT_EDITBOX) != NULL) ||
 
			(this->nested_root != NULL && this->nested_root->GetWidgetOfType(WWT_EDITBOX) != NULL);
 
	bool has_editbox = this->nested_root != NULL && this->nested_root->GetWidgetOfType(WWT_EDITBOX) != NULL;
 
	if (this->window_class != WC_OSK && (!EditBoxInGlobalFocus() || has_editbox)) SetFocusedWindow(this);
 

	
 
	/* Hacky way of specifying always-on-top windows. These windows are
 
@@ -1075,15 +921,6 @@ void Window::FindWindowPlacementAndResiz
 
}
 

	
 
/**
 
 * Resize window towards the default size given in the window description.
 
 * @param desc the description to get the default size from.
 
 */
 
void Window::FindWindowPlacementAndResize(const WindowDesc *desc)
 
{
 
	this->FindWindowPlacementAndResize(desc->default_width, desc->default_height);
 
}
 

	
 
/**
 
 * Decide whether a given rectangle is a good place to open a completely visible new window.
 
 * The new window should be within screen borders, and not overlap with another already
 
 * existing window (except for the main window in the background).
 
@@ -1305,21 +1142,6 @@ static Point LocalGetWindowPlacement(con
 
}
 

	
 
/**
 
 * Set the positions of a new window from a WindowDesc and open it.
 
 *
 
 * @param *desc         The pointer to the WindowDesc to be created
 
 * @param window_number the window number of the new window
 
 *
 
 * @return Window pointer of the newly created window
 
 */
 
Window::Window(const WindowDesc *desc, WindowNumber window_number)
 
{
 
	this->InitializeData(desc->cls, desc->GetWidgets(), window_number, desc->flags);
 
	Point pt = LocalGetWindowPlacement(desc, desc->minimum_width, desc->minimum_height, window_number);
 
	this->InitializePositionSize(pt.x, pt.y, desc->minimum_width, desc->minimum_height);
 
}
 

	
 
/**
 
 * Perform the first part of the initialization of a nested widget tree.
 
 * Construct a nested widget tree in #nested_root, and optionally fill the #nested_array array to provide quick access to the uninitialized widgets.
 
 * This is mainly useful for setting very basic properties.
 
@@ -1347,7 +1169,7 @@ void Window::CreateNestedTree(const Wind
 
 */
 
void Window::FinishInitNested(const WindowDesc *desc, WindowNumber window_number)
 
{
 
	this->InitializeData(desc->cls, NULL, window_number, desc->flags);
 
	this->InitializeData(desc->cls, window_number, desc->flags);
 
	Point pt = this->OnInitialPosition(desc, this->nested_root->smallest_x, this->nested_root->smallest_y, window_number);
 
	this->InitializePositionSize(pt.x, pt.y, this->nested_root->smallest_x, this->nested_root->smallest_y);
 
	this->FindWindowPlacementAndResize(desc->default_width, desc->default_height);
 
@@ -1511,10 +1333,7 @@ static bool HandleMouseOver()
 
	if (w != NULL) {
 
		/* send an event in client coordinates. */
 
		Point pt = { _cursor.pos.x - w->left, _cursor.pos.y - w->top };
 
		int widget = 0;
 
		if (w->widget != NULL) {
 
			widget = GetWidgetFromPos(w, pt.x, pt.y);
 
		}
 
		int widget = w->nested_root->GetWidgetFromPos(pt.x, pt.y)->index;
 
		w->OnMouseOver(pt, widget);
 
	}
 

	
 
@@ -1537,52 +1356,14 @@ void ResizeWindow(Window *w, int delta_x
 

	
 
	w->SetDirty();
 

	
 
	if (w->nested_root != NULL) {
 
		uint new_xinc = max(0, (w->nested_root->resize_x == 0) ? 0 : (int)(w->nested_root->current_x - w->nested_root->smallest_x) + delta_x);
 
		uint new_yinc = max(0, (w->nested_root->resize_y == 0) ? 0 : (int)(w->nested_root->current_y - w->nested_root->smallest_y) + delta_y);
 
		assert(w->nested_root->resize_x == 0 || new_xinc % w->nested_root->resize_x == 0);
 
		assert(w->nested_root->resize_y == 0 || new_yinc % w->nested_root->resize_y == 0);
 

	
 
		w->nested_root->AssignSizePosition(ST_RESIZE, 0, 0, w->nested_root->smallest_x + new_xinc, w->nested_root->smallest_y + new_yinc, false, false, false);
 
		w->width  = w->nested_root->current_x;
 
		w->height = w->nested_root->current_y;
 
	} else {
 
		assert(w->widget != NULL);
 

	
 
		bool resize_height = false;
 
		bool resize_width = false;
 
		for (Widget *wi = w->widget; wi->type != WWT_LAST; wi++) {
 
			/* Isolate the resizing flags */
 
			byte rsizeflag = GB(wi->display_flags, 0, 4);
 

	
 
			if (rsizeflag == RESIZE_NONE) continue;
 
	uint new_xinc = max(0, (w->nested_root->resize_x == 0) ? 0 : (int)(w->nested_root->current_x - w->nested_root->smallest_x) + delta_x);
 
	uint new_yinc = max(0, (w->nested_root->resize_y == 0) ? 0 : (int)(w->nested_root->current_y - w->nested_root->smallest_y) + delta_y);
 
	assert(w->nested_root->resize_x == 0 || new_xinc % w->nested_root->resize_x == 0);
 
	assert(w->nested_root->resize_y == 0 || new_yinc % w->nested_root->resize_y == 0);
 

	
 
			/* Resize the widget based on its resize-flag */
 
			if (rsizeflag & RESIZE_LEFT) {
 
				wi->left += delta_x;
 
				resize_width = true;
 
			}
 

	
 
			if (rsizeflag & RESIZE_RIGHT) {
 
				wi->right += delta_x;
 
				resize_width = true;
 
			}
 

	
 
			if (rsizeflag & RESIZE_TOP) {
 
				wi->top += delta_y;
 
				resize_height = true;
 
			}
 

	
 
			if (rsizeflag & RESIZE_BOTTOM) {
 
				wi->bottom += delta_y;
 
				resize_height = true;
 
			}
 
		}
 

	
 
		/* We resized at least 1 widget, so let's resize the window totally */
 
		if (resize_width)  w->width  += delta_x;
 
		if (resize_height) w->height += delta_y;
 
	}
 
	w->nested_root->AssignSizePosition(ST_RESIZE, 0, 0, w->nested_root->smallest_x + new_xinc, w->nested_root->smallest_y + new_yinc, false, false, false);
 
	w->width  = w->nested_root->current_x;
 
	w->height = w->nested_root->current_y;
 
	w->SetDirty();
 
}
 

	
 
@@ -1758,22 +1539,12 @@ static bool HandleWindowDragging()
 

	
 
			/* Search for the title bar rectangle. */
 
			Rect caption_rect;
 
			if (w->widget != NULL) {
 
				const Widget *caption = w->GetWidgetOfType(WWT_CAPTION);
 
				assert(caption != NULL);
 
				caption_rect.left   = caption->left;
 
				caption_rect.right  = caption->right;
 
				caption_rect.top    = caption->top;
 
				caption_rect.bottom = caption->bottom;
 
			} else {
 
				assert(w->nested_root != NULL);
 
				const NWidgetBase *caption = w->nested_root->GetWidgetOfType(WWT_CAPTION);
 
				assert(caption != NULL);
 
				caption_rect.left   = caption->pos_x;
 
				caption_rect.right  = caption->pos_x + caption->current_x;
 
				caption_rect.top    = caption->pos_y;
 
				caption_rect.bottom = caption->pos_y + caption->current_y;
 
			}
 
			const NWidgetBase *caption = w->nested_root->GetWidgetOfType(WWT_CAPTION);
 
			assert(caption != NULL);
 
			caption_rect.left   = caption->pos_x;
 
			caption_rect.right  = caption->pos_x + caption->current_x;
 
			caption_rect.top    = caption->pos_y;
 
			caption_rect.bottom = caption->pos_y + caption->current_y;
 

	
 
			/* Make sure the window doesn't leave the screen */
 
			nx = Clamp(nx, MIN_VISIBLE_TITLE_BAR - caption_rect.right, _screen.width - MIN_VISIBLE_TITLE_BAR - caption_rect.left);
src/window_gui.h
Show inline comments
 
@@ -143,9 +143,6 @@ struct WindowDesc : ZeroedMemoryAllocato
 
	uint32 flags;                  ///< Flags. @see WindowDefaultFlags
 
	const NWidgetPart *nwid_parts; ///< Nested widget parts describing the window.
 
	int16 nwid_length;             ///< Length of the #nwid_parts array.
 
	mutable Widget *new_widgets;   ///< Widgets generated from #nwid_parts.
 

	
 
	const Widget *GetWidgets() const;
 
};
 

	
 
/**
 
@@ -334,13 +331,11 @@ struct Window : ZeroedMemoryAllocator {
 
	};
 

	
 
protected:
 
	void InitializeData(WindowClass cls, const Widget *widget, int window_number, uint32 desc_flags);
 
	void InitializeData(WindowClass cls, int window_number, uint32 desc_flags);
 
	void InitializePositionSize(int x, int y, int min_width, int min_height);
 
	void FindWindowPlacementAndResize(int def_width, int def_height);
 
	void FindWindowPlacementAndResize(const WindowDesc *desc);
 

	
 
public:
 
	Window(const WindowDesc *desc, WindowNumber number = 0);
 
	Window();
 

	
 
	virtual ~Window();
 
@@ -382,10 +377,7 @@ public:
 
	Owner owner;        ///< The owner of the content shown in this window. Company colour is acquired from this variable.
 

	
 
	ViewportData *viewport;          ///< Pointer to viewport data, if present.
 
	Widget *widget;                  ///< Widgets of the window.
 
	uint widget_count;               ///< Number of widgets of the window.
 
	uint32 desc_flags;               ///< Window/widgets default flags setting. @see WindowDefaultFlag
 
	const Widget *focused_widget;    ///< Currently focused widget, or \c NULL if no widget has focus.
 
	const NWidgetCore *nested_focus; ///< Currently focused nested widget, or \c NULL if no nested widget has focus.
 
	NWidgetBase *nested_root;        ///< Root of the nested tree.
 
	NWidgetBase **nested_array;      ///< Array of pointers into the tree. Do not access directly, use #Window::GetWidget() instead.
 
@@ -414,14 +406,8 @@ public:
 
	 */
 
	inline void SetWidgetDisabledState(byte widget_index, bool disab_stat)
 
	{
 
		if (this->widget != NULL) {
 
			assert(widget_index < this->widget_count);
 
			SB(this->widget[widget_index].display_flags, WIDG_DISABLED, 1, !!disab_stat);
 
		}
 
		if (this->nested_array != NULL) {
 
			assert(widget_index < this->nested_array_size);
 
			if (this->nested_array[widget_index] != NULL) this->GetWidget<NWidgetCore>(widget_index)->SetDisabled(disab_stat);
 
		}
 
		assert(widget_index < this->nested_array_size);
 
		if (this->nested_array[widget_index] != NULL) this->GetWidget<NWidgetCore>(widget_index)->SetDisabled(disab_stat);
 
	}
 

	
 
	/**
 
@@ -449,54 +435,8 @@ public:
 
	 */
 
	inline bool IsWidgetDisabled(byte widget_index) const
 
	{
 
		if (this->nested_array != NULL) {
 
			assert(widget_index < this->nested_array_size);
 
			return this->GetWidget<NWidgetCore>(widget_index)->IsDisabled();
 
		}
 
		assert(widget_index < this->widget_count);
 
		return HasBit(this->widget[widget_index].display_flags, WIDG_DISABLED);
 
	}
 

	
 
	/**
 
	 * Sets the hidden/shown status of a widget.
 
	 * By default, widgets are visible.
 
	 * On certain conditions, they have to be hidden.
 
	 * @param widget_index index of this widget in the window
 
	 * @param hidden_stat status to use ie. hidden = true, visible = false
 
	 */
 
	inline void SetWidgetHiddenState(byte widget_index, bool hidden_stat)
 
	{
 
		assert(widget_index < this->widget_count);
 
		SB(this->widget[widget_index].display_flags, WIDG_HIDDEN, 1, !!hidden_stat);
 
	}
 

	
 
	/**
 
	 * Sets a widget hidden.
 
	 * @param widget_index index of this widget in the window
 
	 */
 
	inline void HideWidget(byte widget_index)
 
	{
 
		SetWidgetHiddenState(widget_index, true);
 
	}
 

	
 
	/**
 
	 * Sets a widget visible.
 
	 * @param widget_index index of this widget in the window
 
	 */
 
	inline void ShowWidget(byte widget_index)
 
	{
 
		SetWidgetHiddenState(widget_index, false);
 
	}
 

	
 
	/**
 
	 * Gets the visibility of a widget.
 
	 * @param widget_index index of this widget in the window
 
	 * @return status of the widget ie: hidden = true, visible = false
 
	 */
 
	inline bool IsWidgetHidden(byte widget_index) const
 
	{
 
		assert(widget_index < this->widget_count);
 
		return HasBit(this->widget[widget_index].display_flags, WIDG_HIDDEN);
 
		assert(widget_index < this->nested_array_size);
 
		return this->GetWidget<NWidgetCore>(widget_index)->IsDisabled();
 
	}
 

	
 
	/**
 
@@ -506,8 +446,7 @@ public:
 
	 */
 
	inline bool IsWidgetFocused(byte widget_index) const
 
	{
 
		return (this->widget != NULL && this->focused_widget == &this->widget[widget_index]) ||
 
			(this->nested_focus != NULL && this->nested_focus->index == widget_index);
 
		return this->nested_focus != NULL && this->nested_focus->index == widget_index;
 
	}
 

	
 
	/**
 
@@ -528,14 +467,8 @@ public:
 
	 */
 
	inline void SetWidgetLoweredState(byte widget_index, bool lowered_stat)
 
	{
 
		if (this->widget != NULL) {
 
			assert(widget_index < this->widget_count);
 
			SB(this->widget[widget_index].display_flags, WIDG_LOWERED, 1, !!lowered_stat);
 
		}
 
		if (this->nested_array != NULL) {
 
			assert(widget_index < this->nested_array_size);
 
			this->GetWidget<NWidgetCore>(widget_index)->SetLowered(lowered_stat);
 
		}
 
		assert(widget_index < this->nested_array_size);
 
		this->GetWidget<NWidgetCore>(widget_index)->SetLowered(lowered_stat);
 
	}
 

	
 
	/**
 
@@ -544,15 +477,9 @@ public:
 
	 */
 
	inline void ToggleWidgetLoweredState(byte widget_index)
 
	{
 
		if (this->widget != NULL) {
 
			assert(widget_index < this->widget_count);
 
			ToggleBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
 
		}
 
		if (this->nested_array != NULL) {
 
			assert(widget_index < this->nested_array_size);
 
			bool lowered_state = this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
 
			this->GetWidget<NWidgetCore>(widget_index)->SetLowered(!lowered_state);
 
		}
 
		assert(widget_index < this->nested_array_size);
 
		bool lowered_state = this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
 
		this->GetWidget<NWidgetCore>(widget_index)->SetLowered(!lowered_state);
 
	}
 

	
 
	/**
 
@@ -580,18 +507,13 @@ public:
 
	 */
 
	inline bool IsWidgetLowered(byte widget_index) const
 
	{
 
		if (this->nested_array != NULL) {
 
			assert(widget_index < this->nested_array_size);
 
			return this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
 
		}
 
		assert(widget_index < this->widget_count);
 
		return HasBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
 
		assert(widget_index < this->nested_array_size);
 
		return this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
 
	}
 

	
 
	bool SetFocusedWidget(byte widget_index);
 

	
 
	void HandleButtonClick(byte widget);
 
	const Widget *GetWidgetOfType(WidgetType widget_type) const;
 

	
 
	void RaiseButtons(bool autoraise = false);
 
	void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
 
@@ -961,7 +883,6 @@ Window *GetCallbackWnd();
 
void SetFocusedWindow(Window *w);
 
bool EditBoxInGlobalFocus();
 

	
 
void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y);
 
void ScrollbarClickHandler(Window *w, const NWidgetCore *nw, int x, int y);
 

	
 
#endif /* WINDOW_GUI_H */
0 comments (0 inline, 0 general)