Changeset - r15772:458710a0dfcd
[Not reviewed]
master
0 3 0
frosch - 14 years ago 2010-08-12 09:07:45
frosch@openttd.org
(svn r20456) -Codechange: Add separate nested widget class for scrollbars.
3 files changed with 130 insertions and 54 deletions:
0 comments (0 inline, 0 general)
src/widget.cpp
Show inline comments
 
@@ -1633,12 +1633,115 @@ void NWidgetViewport::UpdateViewportCoor
 

	
 
		vp->virtual_width  = ScaleByZoom(vp->width, vp->zoom);
 
		vp->virtual_height = ScaleByZoom(vp->height, vp->zoom);
 
	}
 
}
 

	
 
/**
 
 * Scrollbar widget.
 
 * @param tp     Scrollbar type. (horizontal/vertical)
 
 * @param colour Colour of the scrollbar.
 
 * @param index  Index in the widget array used by the window system.
 
 */
 
NWidgetScrollbar::NWidgetScrollbar(WidgetType tp, Colours colour, int index) : NWidgetCore(tp, colour, 1, 1, 0x0, STR_NULL)
 
{
 
	assert(tp == WWT_HSCROLLBAR || tp == WWT_SCROLLBAR || tp == WWT_SCROLL2BAR);
 
	this->SetIndex(index);
 

	
 
	switch (this->type) {
 
		case WWT_HSCROLLBAR:
 
			this->SetMinimalSize(30, WD_HSCROLLBAR_HEIGHT);
 
			this->SetResize(1, 0);
 
			this->SetFill(1, 0);
 
			this->SetDataTip(0x0, STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST);
 
			break;
 

	
 
		case WWT_SCROLLBAR:
 
		case WWT_SCROLL2BAR:
 
			this->SetMinimalSize(WD_VSCROLLBAR_WIDTH, 30);
 
			this->SetResize(0, 1);
 
			this->SetFill(0, 1);
 
			this->SetDataTip(0x0, STR_TOOLTIP_VSCROLL_BAR_SCROLLS_LIST);
 
			break;
 

	
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
void NWidgetScrollbar::SetupSmallestSize(Window *w, bool init_array)
 
{
 
	if (init_array && this->index >= 0) {
 
		assert(w->nested_array_size > (uint)this->index);
 
		w->nested_array[this->index] = this;
 
	}
 
	this->smallest_x = this->min_x;
 
	this->smallest_y = this->min_y;
 
}
 

	
 
void NWidgetScrollbar::Draw(const Window *w)
 
{
 
	if (this->current_x == 0 || this->current_y == 0) return;
 

	
 
	Rect r;
 
	r.left = this->pos_x;
 
	r.right = this->pos_x + this->current_x - 1;
 
	r.top = this->pos_y;
 
	r.bottom = this->pos_y + this->current_y - 1;
 

	
 
	const DrawPixelInfo *dpi = _cur_dpi;
 
	if (dpi->left > r.right || dpi->left + dpi->width <= r.left || dpi->top > r.bottom || dpi->top + dpi->height <= r.top) return;
 

	
 
	switch (this->type) {
 
		case WWT_HSCROLLBAR:
 
			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), this->GetScrollbar(w));
 
			break;
 

	
 
		case WWT_SCROLLBAR:
 
			assert(this->widget_data == 0);
 
			DrawVerticalScrollbar(r, this->colour, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_UP,
 
								(w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_MIDDLE,
 
								(w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_DOWN, this->GetScrollbar(w));
 
			break;
 

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

	
 
		default: NOT_REACHED();
 
	}
 

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

	
 
const Scrollbar *NWidgetScrollbar::GetScrollbar(const Window *w) const
 
{
 
	switch (this->type) {
 
		case WWT_HSCROLLBAR: return &w->old_hscroll;
 
		case WWT_SCROLLBAR:  return &w->old_vscroll;
 
		case WWT_SCROLL2BAR: return &w->old_vscroll2;
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
Scrollbar *NWidgetScrollbar::GetScrollbar(Window *w) const
 
{
 
	switch (this->type) {
 
		case WWT_HSCROLLBAR: return &w->old_hscroll;
 
		case WWT_SCROLLBAR:  return &w->old_vscroll;
 
		case WWT_SCROLL2BAR: return &w->old_vscroll2;
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
/** Reset the cached dimensions. */
 
/* static */ void NWidgetLeaf::InvalidateDimensionCache()
 
{
 
	shadebox_dimension.width  = shadebox_dimension.height  = 0;
 
	debugbox_dimension.width  = debugbox_dimension.height  = 0;
 
	stickybox_dimension.width = stickybox_dimension.height = 0;
 
@@ -1688,34 +1791,19 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, 
 

	
 
		case WWT_EDITBOX:
 
			this->SetMinimalSize(10, 0);
 
			this->SetFill(0, 0);
 
			break;
 

	
 
		case WWT_SCROLLBAR:
 
		case WWT_SCROLL2BAR:
 
			this->SetFill(0, 1);
 
			this->SetResize(0, 1);
 
			this->min_x = WD_VSCROLLBAR_WIDTH;
 
			this->SetDataTip(0x0, STR_TOOLTIP_VSCROLL_BAR_SCROLLS_LIST);
 
			break;
 

	
 
		case WWT_CAPTION:
 
			this->SetFill(1, 0);
 
			this->SetResize(1, 0);
 
			this->min_y = WD_CAPTION_HEIGHT;
 
			this->SetDataTip(data, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS);
 
			break;
 

	
 
		case WWT_HSCROLLBAR:
 
			this->SetFill(1, 0);
 
			this->SetResize(1, 0);
 
			this->min_y = WD_HSCROLLBAR_HEIGHT;
 
			this->SetDataTip(0x0, STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST);
 
			break;
 

	
 
		case WWT_STICKYBOX:
 
			this->SetFill(0, 0);
 
			this->SetMinimalSize(WD_STICKYBOX_WIDTH, 14);
 
			this->SetDataTip(STR_NULL, STR_TOOLTIP_STICKY);
 
			break;
 

	
 
@@ -1763,16 +1851,13 @@ void NWidgetLeaf::SetupSmallestSize(Wind
 
	Dimension size = {this->min_x, this->min_y};
 
	Dimension fill = {this->fill_x, this->fill_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_SCROLLBAR:
 
		case WWT_SCROLL2BAR:
 
		case WWT_HSCROLLBAR: {
 
		case WWT_EMPTY: {
 
			static const Dimension extra = {0, 0};
 
			padding = &extra;
 
			break;
 
		}
 
		case WWT_MATRIX: {
 
			static const Dimension extra = {WD_MATRIX_LEFT + WD_MATRIX_RIGHT, WD_MATRIX_TOP + WD_MATRIX_BOTTOM};
 
@@ -1990,38 +2075,17 @@ void NWidgetLeaf::Draw(const Window *w)
 
			break;
 

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

	
 
		case WWT_SCROLLBAR:
 
			assert(this->widget_data == 0);
 
			DrawVerticalScrollbar(r, this->colour, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_UP,
 
								(w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_MIDDLE,
 
								(w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_DOWN, &w->old_vscroll);
 
			break;
 

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

	
 
		case WWT_CAPTION:
 
			if (this->index >= 0) w->SetStringParameters(this->index);
 
			DrawCaption(r, this->colour, w->owner, this->widget_data);
 
			break;
 

	
 
		case WWT_HSCROLLBAR:
 
			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->old_hscroll);
 
			break;
 

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

	
 
		case WWT_DEBUGBOX:
 
@@ -2217,12 +2281,20 @@ static int MakeNWidget(const NWidgetPart
 
			case NWID_VIEWPORT:
 
				if (*dest != NULL) return num_used;
 
				*dest = new NWidgetViewport(parts->u.widget.index);
 
				*biggest_index = max(*biggest_index, (int)parts->u.widget.index);
 
				break;
 

	
 
			case WWT_HSCROLLBAR:
 
			case WWT_SCROLLBAR:
 
			case WWT_SCROLL2BAR:
 
				if (*dest != NULL) return num_used;
 
				*dest = new NWidgetScrollbar(parts->type, parts->u.widget.colour, parts->u.widget.index);
 
				*biggest_index = max(*biggest_index, (int)parts->u.widget.index);
 
				break;
 

	
 
			case NWID_SELECTION: {
 
				if (*dest != NULL) return num_used;
 
				NWidgetStacked *nws = new NWidgetStacked();
 
				*dest = nws;
 
				*fill_dest = true;
 
				nws->SetIndex(parts->u.widget.index);
src/widget_type.h
Show inline comments
 
@@ -499,12 +499,28 @@ public:
 

	
 
	void InitializeViewport(Window *w, uint32 follow_flags, ZoomLevel zoom);
 
	void UpdateViewportCoordinates(Window *w);
 
};
 

	
 
/**
 
 * Nested widget to display and control a scrollbar in a window.
 
 * Also assign the scrollbar to other widgets using #SetScrollbar() to make the mousewheel work.
 
 * @ingroup NestedWidgets
 
 */
 
class NWidgetScrollbar : public NWidgetCore {
 
public:
 
	NWidgetScrollbar(WidgetType tp, Colours colour, int index);
 

	
 
	/* virtual */ void SetupSmallestSize(Window *w, bool init_array);
 
	/* virtual */ void Draw(const Window *w);
 

	
 
	const Scrollbar *GetScrollbar(const Window *w) const;
 
	Scrollbar *GetScrollbar(Window *w) const;
 
};
 

	
 
/**
 
 * Leaf widget.
 
 * @ingroup NestedWidgets
 
 */
 
class NWidgetLeaf : public NWidgetCore {
 
public:
 
	NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data, StringID tip);
src/window.cpp
Show inline comments
 
@@ -134,35 +134,23 @@ void Scrollbar::SetCapacityFromWidget(Wi
 
 * Return the Scrollbar to a widget index.
 
 * @param widnum Scrollbar widget index
 
 * @return Scrollbar to the widget
 
 */
 
const Scrollbar *Window::GetScrollbar(uint widnum) const
 
{
 
	const NWidgetLeaf *wid = this->GetWidget<NWidgetLeaf>(widnum);
 
	switch (wid->type) {
 
		case WWT_HSCROLLBAR: return &this->old_hscroll;
 
		case WWT_SCROLLBAR:  return &this->old_vscroll;
 
		case WWT_SCROLL2BAR: return &this->old_vscroll2;
 
		default: NOT_REACHED();
 
	}
 
	return this->GetWidget<NWidgetScrollbar>(widnum)->GetScrollbar(this);
 
}
 

	
 
/**
 
 * Return the Scrollbar to a widget index.
 
 * @param widnum Scrollbar widget index
 
 * @return Scrollbar to the widget
 
 */
 
Scrollbar *Window::GetScrollbar(uint widnum)
 
{
 
	NWidgetLeaf *wid = this->GetWidget<NWidgetLeaf>(widnum);
 
	switch (wid->type) {
 
		case WWT_HSCROLLBAR: return &this->old_hscroll;
 
		case WWT_SCROLLBAR:  return &this->old_vscroll;
 
		case WWT_SCROLL2BAR: return &this->old_vscroll2;
 
		default: NOT_REACHED();
 
	}
 
	return this->GetWidget<NWidgetScrollbar>(widnum)->GetScrollbar(this);
 
}
 

	
 

	
 
/**
 
 * Set the window that has the focus
 
 * @param w The window to set the focus on
0 comments (0 inline, 0 general)