Changeset - r14030:1a6d55406e7d
[Not reviewed]
master
0 5 0
alberth - 15 years ago 2009-12-21 16:06:20
alberth@openttd.org
(svn r18583) -Codechange: Add WWT_SHADEBOX widget and its functions (heavily based on code by erikjanp).
5 files changed with 109 insertions and 6 deletions:
0 comments (0 inline, 0 general)
src/lang/english.txt
Show inline comments
 
@@ -226,12 +226,13 @@ STR_TOOLTIP_FILTER_CRITERIA             
 
STR_BUTTON_SORT_BY                                              :{BLACK}Sort by
 
STR_BUTTON_LOCATION                                             :{BLACK}Location
 
STR_BUTTON_RENAME                                               :{BLACK}Rename
 

	
 
STR_TOOLTIP_CLOSE_WINDOW                                        :{BLACK}Close window
 
STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS                              :{BLACK}Window title - drag this to move window
 
STR_TOOLTIP_SHADE                                               :{BLACK}Shade window - Only show the titlebar
 
STR_TOOLTIP_STICKY                                              :{BLACK}Mark this window as uncloseable by the 'Close All Windows' key
 
STR_TOOLTIP_RESIZE                                              :{BLACK}Click and drag to resize this window
 
STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW                           :{BLACK}Toggle large/small window size
 
STR_TOOLTIP_VSCROLL_BAR_SCROLLS_LIST                            :{BLACK}Scroll bar - scrolls list up/down
 
STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST                            :{BLACK}Scroll bar - scrolls list left/right
 
STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC                              :{BLACK}Demolish buildings etc. on a square of land
src/widget.cpp
Show inline comments
 
@@ -450,12 +450,24 @@ static inline void DrawFrame(const Rect 
 

	
 
	GfxFillRect(r.left + 1, r.bottom - 1, r.right - 1, r.bottom - 1, c1);
 
	GfxFillRect(r.left, r.bottom, r.right, r.bottom, c2);
 
}
 

	
 
/**
 
 * Draw a shade box.
 
 * @param r       Rectangle of the box.
 
 * @param colour  Colour of the shade box.
 
 * @param clicked Box is lowered.
 
 */
 
static inline void DrawShadeBox(const Rect &r, Colours colour, bool clicked)
 
{
 
	DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FR_LOWERED : FR_NONE);
 
	DrawSprite((clicked) ? SPR_WINDOW_SHADE : SPR_WINDOW_UNSHADE, PAL_NONE, r.left + WD_SHADEBOX_LEFT + clicked, r.top + WD_SHADEBOX_TOP + clicked);
 
}
 

	
 
/**
 
 * Draw a sticky box.
 
 * @param r       Rectangle of the box.
 
 * @param colour  Colour of the sticky box.
 
 * @param clicked Box is lowered.
 
 */
 
static inline void DrawStickyBox(const Rect &r, Colours colour, bool clicked)
 
@@ -1670,17 +1682,19 @@ void NWidgetViewport::UpdateViewportCoor
 
	}
 
}
 

	
 
/** Reset the cached dimensions. */
 
/* static */ void NWidgetLeaf::InvalidateDimensionCache()
 
{
 
	shadebox_dimension.width  = shadebox_dimension.height  = 0;
 
	stickybox_dimension.width = stickybox_dimension.height = 0;
 
	resizebox_dimension.width = resizebox_dimension.height = 0;
 
	closebox_dimension.width  = closebox_dimension.height  = 0;
 
}
 

	
 
Dimension NWidgetLeaf::shadebox_dimension  = {0, 0};
 
Dimension NWidgetLeaf::stickybox_dimension = {0, 0};
 
Dimension NWidgetLeaf::resizebox_dimension = {0, 0};
 
Dimension NWidgetLeaf::closebox_dimension  = {0, 0};
 

	
 
/**
 
 * Nested leaf widget.
 
@@ -1689,13 +1703,13 @@ Dimension NWidgetLeaf::closebox_dimensio
 
 * @param index  Index in the widget array used by the window system.
 
 * @param data   Data of the widget.
 
 * @param tip    Tooltip of the widget.
 
 */
 
NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data, StringID tip) : NWidgetCore(tp, colour, 1, 1, data, tip)
 
{
 
	assert(index >= 0 || tp == WWT_LABEL || tp == WWT_TEXT || tp == WWT_CAPTION || tp == WWT_RESIZEBOX || tp == WWT_STICKYBOX || tp == WWT_CLOSEBOX);
 
	assert(index >= 0 || tp == WWT_LABEL || tp == WWT_TEXT || tp == WWT_CAPTION || tp == WWT_RESIZEBOX || tp == WWT_SHADEBOX || tp == WWT_STICKYBOX || tp == WWT_CLOSEBOX);
 
	if (index >= 0) this->SetIndex(index);
 
	this->SetMinimalSize(0, 0);
 
	this->SetResize(0, 0);
 

	
 
	switch (tp) {
 
		case WWT_EMPTY:
 
@@ -1748,12 +1762,18 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, 
 
		case WWT_STICKYBOX:
 
			this->SetFill(0, 0);
 
			this->SetMinimalSize(WD_STICKYBOX_WIDTH, 14);
 
			this->SetDataTip(STR_NULL, STR_TOOLTIP_STICKY);
 
			break;
 

	
 
		case WWT_SHADEBOX:
 
			this->SetFill(0, 0);
 
			this->SetMinimalSize(WD_SHADEBOX_TOP, 14);
 
			this->SetDataTip(STR_NULL, STR_TOOLTIP_SHADE);
 
			break;
 

	
 
		case WWT_RESIZEBOX:
 
			this->SetFill(0, 0);
 
			this->SetMinimalSize(WD_RESIZEBOX_WIDTH, 12);
 
			this->SetDataTip(STR_NULL, STR_TOOLTIP_RESIZE);
 
			break;
 

	
 
@@ -1796,12 +1816,23 @@ void NWidgetLeaf::SetupSmallestSize(Wind
 
		}
 
		case WWT_MATRIX: {
 
			static const Dimension extra = {WD_MATRIX_LEFT + WD_MATRIX_RIGHT, WD_MATRIX_TOP + WD_MATRIX_BOTTOM};
 
			padding = &extra;
 
			break;
 
		}
 
		case WWT_SHADEBOX: {
 
			static const Dimension extra = {WD_SHADEBOX_LEFT + WD_SHADEBOX_RIGHT, WD_SHADEBOX_TOP + WD_SHADEBOX_BOTTOM};
 
			padding = &extra;
 
			if (NWidgetLeaf::shadebox_dimension.width == 0) {
 
				NWidgetLeaf::shadebox_dimension = maxdim(GetSpriteSize(SPR_WINDOW_SHADE), GetSpriteSize(SPR_WINDOW_UNSHADE));
 
				NWidgetLeaf::shadebox_dimension.width += extra.width;
 
				NWidgetLeaf::shadebox_dimension.height += extra.height;
 
			}
 
			size = maxdim(size, NWidgetLeaf::shadebox_dimension);
 
			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;
 
@@ -2007,12 +2038,17 @@ void NWidgetLeaf::Draw(const Window *w)
 
			assert(this->widget_data == 0);
 
			DrawHorizontalScrollbar(r, this->colour, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL)) == (WF_SCROLL_UP | WF_HSCROLL),
 
								(w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL)) == (WF_SCROLL_MIDDLE | WF_HSCROLL),
 
								(w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL)) == (WF_SCROLL_DOWN | WF_HSCROLL), &w->hscroll);
 
			break;
 

	
 
		case WWT_SHADEBOX:
 
			assert(this->widget_data == 0);
 
			DrawShadeBox(r, this->colour, w->IsShaded());
 
			break;
 

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

	
 
		case WWT_RESIZEBOX:
src/widget_type.h
Show inline comments
 
@@ -58,12 +58,13 @@ enum WidgetType {
 
	WWT_MATRIX,     ///< Grid of rows and columns. @see MatrixWidgetValues
 
	WWT_SCROLLBAR,  ///< Vertical scrollbar
 
	WWT_FRAME,      ///< Frame
 
	WWT_CAPTION,    ///< Window caption (window title between closebox and stickybox)
 

	
 
	WWT_HSCROLLBAR, ///< Horizontal scrollbar
 
	WWT_SHADEBOX,   ///< Shade box (at top-right of a window, between caption and stickybox)
 
	WWT_STICKYBOX,  ///< Sticky box (normally at top-right of a window)
 
	WWT_SCROLL2BAR, ///< 2nd vertical scrollbar
 
	WWT_RESIZEBOX,  ///< Resize box (normally at bottom-right of a window)
 
	WWT_CLOSEBOX,   ///< Close box (at top-left of a window)
 
	WWT_DROPDOWN,   ///< Drop down list
 
	WWT_EDITBOX,    ///< a textbox for typing
 
@@ -465,12 +466,13 @@ public:
 
	/* virtual */ Scrollbar *FindScrollbar(Window *w, bool allow_next = true) const;
 

	
 
	bool ButtonHit(const Point &pt);
 

	
 
	static void InvalidateDimensionCache();
 
private:
 
	static Dimension shadebox_dimension;  ///< Cached size of a shadebox widget.
 
	static Dimension stickybox_dimension; ///< Cached size of a stickybox widget.
 
	static Dimension resizebox_dimension; ///< Cached size of a resizebox widget.
 
	static Dimension closebox_dimension;  ///< Cached size of a closebox widget.
 
};
 

	
 
/**
src/window.cpp
Show inline comments
 
@@ -330,12 +330,17 @@ static void DispatchLeftClickEvent(Windo
 
			/* When the resize widget is on the left size of the window
 
			 * we assume that that button is used to resize to the left. */
 
			StartWindowSizing(w, (int)nw->pos_x < (w->width / 2));
 
			nw->SetDirty(w);
 
			return;
 

	
 
		case WWT_SHADEBOX:
 
			nw->SetDirty(w);
 
			w->SetShaded(!w->IsShaded());
 
			return;
 

	
 
		case WWT_STICKYBOX:
 
			w->flags4 ^= WF_STICKY;
 
			nw->SetDirty(w);
 
			return;
 

	
 
		default:
 
@@ -388,12 +393,19 @@ static void DispatchRightClickEvent(Wind
 
 * @param wheel scroll up or down
 
 */
 
static void DispatchMouseWheelEvent(Window *w, const NWidgetCore *nwid, int wheel)
 
{
 
	if (nwid == NULL) return;
 

	
 
	/* Using wheel on caption/shade-box shades or unshades the window. */
 
	if (nwid->type == WWT_CAPTION || nwid->type == WWT_SHADEBOX) {
 
		w->SetShaded(!w->IsShaded());
 
		return;
 
	}
 

	
 
	/* Scroll the widget attached to the scrollbar. */
 
	Scrollbar *sb = nwid->FindScrollbar(w);
 
	if (sb != NULL && sb->GetCount() > sb->GetCapacity()) {
 
		sb->UpdatePosition(wheel);
 
		w->SetDirty();
 
	}
 
}
 
@@ -529,12 +541,36 @@ void Window::ReInit(int rx, int ry)
 

	
 
	ResizeWindow(this, dx, dy);
 
	this->OnResize();
 
	this->SetDirty();
 
}
 

	
 
/** Set the shaded state of the window to \a make_shaded.
 
 * @param make_shaded If \c true, shade the window (roll up until just the title bar is visible), else unshade/unroll the window to its original size.
 
 * @note The method uses #Window::ReInit(), thus after the call, the whole window should be considered changed.
 
 */
 
void Window::SetShaded(bool make_shaded)
 
{
 
	if (this->shade_select == NULL) return;
 

	
 
	int desired = make_shaded ? STACKED_SELECTION_ZERO_SIZE : 0;
 
	if (this->shade_select->shown_plane != desired) {
 
		if (make_shaded) {
 
			this->unshaded_size.width  = this->width;
 
			this->unshaded_size.height = this->height;
 
			this->shade_select->SetDisplayedPlane(desired);
 
			this->ReInit();
 
		} else {
 
			this->shade_select->SetDisplayedPlane(desired);
 
			int dx = ((int)this->unshaded_size.width  > this->width)  ? (int)this->unshaded_size.width  - this->width  : 0;
 
			int dy = ((int)this->unshaded_size.height > this->height) ? (int)this->unshaded_size.height - this->height : 0;
 
			this->ReInit(dx, dy);
 
		}
 
	}
 
}
 

	
 
/** Find the Window whose parent pointer points to this window
 
 * @param w parent Window to find child of
 
 * @param wc Window class of the window to remove; WC_INVALID if class does not matter
 
 * @return a Window pointer that is the child of w, or NULL otherwise
 
 */
 
static Window *FindChildWindow(const Window *w, WindowClass wc)
 
@@ -708,22 +744,24 @@ void ChangeWindowOwner(Owner old_owner, 
 
		}
 
	}
 
}
 

	
 
static void BringWindowToFront(Window *w);
 

	
 
/** Find a window and make it the top-window on the screen. The window
 
 * gets a white border for a brief period of time to visualize its "activation"
 
/** Find a window and make it the top-window on the screen.
 
 * The window gets unshaded if it was shaded, and a white border is drawn at its edges for a brief period of time to visualize its "activation".
 
 * @param cls WindowClass of the window to activate
 
 * @param number WindowNumber of the window to activate
 
 * @return a pointer to the window thus activated */
 
Window *BringWindowToFrontById(WindowClass cls, WindowNumber number)
 
{
 
	Window *w = FindWindowById(cls, number);
 

	
 
	if (w != NULL) {
 
		if (w->IsShaded()) w->SetShaded(false); // Restore original window size if it was shaded.
 

	
 
		w->flags4 |= WF_WHITE_BORDER_MASK;
 
		BringWindowToFront(w);
 
		w->SetDirty();
 
	}
 

	
 
	return w;
 
@@ -1784,12 +1822,20 @@ static bool MaybeBringWindowToFront(Wind
 
			IsVitalWindow(w) ||
 
			w->window_class == WC_TOOLTIPS ||
 
			w->window_class == WC_DROPDOWN_MENU) {
 
		return true;
 
	}
 

	
 
	/* Use unshaded window size rather than current size for shaded windows. */
 
	int w_width  = w->width;
 
	int w_height = w->height;
 
	if (w->IsShaded()) {
 
		w_width  = w->unshaded_size.width;
 
		w_height = w->unshaded_size.height;
 
	}
 

	
 
	Window *u;
 
	FOR_ALL_WINDOWS_FROM_BACK_FROM(u, w->z_front) {
 
		/* A modal child will prevent the activation of the parent window */
 
		if (u->parent == w && (u->desc_flags & WDF_MODAL)) {
 
			u->flags4 |= WF_WHITE_BORDER_MASK;
 
			u->SetDirty();
 
@@ -1801,15 +1847,15 @@ static bool MaybeBringWindowToFront(Wind
 
				u->window_class == WC_TOOLTIPS ||
 
				u->window_class == WC_DROPDOWN_MENU) {
 
			continue;
 
		}
 

	
 
		/* Window sizes don't interfere, leave z-order alone */
 
		if (w->left + w->width <= u->left ||
 
		if (w->left + w_width <= u->left ||
 
				u->left + u->width <= w->left ||
 
				w->top  + w->height <= u->top ||
 
				w->top  + w_height <= u->top ||
 
				u->top + u->height <= w->top) {
 
			continue;
 
		}
 

	
 
		bring_to_front = true;
 
	}
 
@@ -2230,13 +2276,14 @@ void UpdateWindows()
 
		}
 
	}
 

	
 
	DrawDirtyBlocks();
 

	
 
	FOR_ALL_WINDOWS_FROM_BACK(w) {
 
		if (w->viewport != NULL) UpdateViewportPosition(w);
 
		/* Update viewport only if window is not shaded. */
 
		if (w->viewport != NULL && !w->IsShaded()) UpdateViewportPosition(w);
 
	}
 
	NetworkDrawChatMessage();
 
	/* Redraw mouse cursor in case it was hidden */
 
	DrawMouseCursor();
 
}
 

	
src/window_gui.h
Show inline comments
 
@@ -71,12 +71,19 @@ enum WidgetDrawDistances {
 
	/* WWT_MATRIX */
 
	WD_MATRIX_LEFT   = 2,       ///< Offset at left of a matrix cell.
 
	WD_MATRIX_RIGHT  = 2,       ///< Offset at right of a matrix cell.
 
	WD_MATRIX_TOP    = 3,       ///< Offset at top of a matrix cell.
 
	WD_MATRIX_BOTTOM = 1,       ///< Offset at bottom of a matrix cell.
 

	
 
	/* WWT_SHADEBOX */
 
	WD_SHADEBOX_WIDTH  = 12,    ///< Width of a standard shade box widget.
 
	WD_SHADEBOX_LEFT   = 2,     ///< Left offset of shade sprite.
 
	WD_SHADEBOX_RIGHT  = 2,     ///< Right offset of shade sprite.
 
	WD_SHADEBOX_TOP    = 3,     ///< Top offset of shade sprite.
 
	WD_SHADEBOX_BOTTOM = 3,     ///< Bottom offset of shade sprite.
 

	
 
	/* WWT_STICKYBOX */
 
	WD_STICKYBOX_WIDTH  = 12,   ///< Width of a standard sticky box widget.
 
	WD_STICKYBOX_LEFT   = 2,    ///< Left offset of sticky sprite.
 
	WD_STICKYBOX_RIGHT  = 2,    ///< Right offset of sticky sprite.
 
	WD_STICKYBOX_TOP    = 3,    ///< Top offset of sticky sprite.
 
	WD_STICKYBOX_BOTTOM = 3,    ///< Bottom offset of sticky sprite.
 
@@ -378,12 +385,14 @@ public:
 
	ViewportData *viewport;          ///< Pointer to viewport data, if present.
 
	uint32 desc_flags;               ///< Window/widgets default flags setting. @see WindowDefaultFlag
 
	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.
 
	uint nested_array_size;          ///< Size of the nested array.
 
	NWidgetStacked *shade_select;    ///< Selection widget (#NWID_SELECTION) to use for shading the window. If \c NULL, window cannot shade.
 
	Dimension unshaded_size;         ///< Last known unshaded size (only valid while shaded).
 

	
 
	Window *parent;                  ///< Parent window.
 
	Window *z_front;                 ///< The window in front of us in z-order.
 
	Window *z_back;                  ///< The window behind us in z-order.
 

	
 
	template <class NWID>
 
@@ -525,12 +534,20 @@ public:
 

	
 
	void DeleteChildWindows(WindowClass wc = WC_INVALID) const;
 

	
 
	void SetDirty() const;
 
	void ReInit(int rx = 0, int ry = 0);
 

	
 
	/** Is window shaded currently? */
 
	inline bool IsShaded() const
 
	{
 
		return this->shade_select != NULL && this->shade_select->shown_plane == STACKED_SELECTION_ZERO_SIZE;
 
	}
 

	
 
	void SetShaded(bool make_shaded);
 

	
 
	/**
 
	 * Mark this window's data as invalid (in need of re-computing)
 
	 * @param data The data to invalidate with
 
	 */
 
	void InvalidateData(int data = 0)
 
	{
0 comments (0 inline, 0 general)