(svn r18092) -Codechange: remove support for the unnested widgets
This commit is contained in:
347
src/widget.cpp
347
src/widget.cpp
@@ -134,41 +134,6 @@ static void ScrollbarClickPositioning(Window *w, WidgetType wtp, int x, int y, i
|
||||
w->SetDirty();
|
||||
}
|
||||
|
||||
/** 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.
|
||||
@@ -213,24 +178,8 @@ void ScrollbarClickHandler(Window *w, const NWidgetCore *nw, int x, int y)
|
||||
*/
|
||||
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 Rect &r, Colours colour, bool clicked, Str
|
||||
*/
|
||||
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 widget, SortButtonState state) const
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -867,19 +697,6 @@ inline void NWidgetBase::StoreSizePosition(SizingType sizing, uint x, uint y, ui
|
||||
if (sizing == ST_ARRAY && !allow_resize_y) this->resize_y = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
@@ -1009,40 +826,6 @@ void NWidgetCore::FillNestedArray(NWidgetBase **array, uint length)
|
||||
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(SizingType sizing, uint x, uint y, uint
|
||||
}
|
||||
}
|
||||
|
||||
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::AssignSizePosition(SizingType sizing, uint x, uint y, ui
|
||||
}
|
||||
}
|
||||
|
||||
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::AssignSizePosition(SizingType sizing, uint x, uint y,
|
||||
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(SizingType sizing, uint x, uint y, uint
|
||||
}
|
||||
}
|
||||
|
||||
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(NWidgetBase **array, uint length)
|
||||
{
|
||||
}
|
||||
|
||||
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::AssignSizePosition(SizingType sizing, uint x, uint y, ui
|
||||
}
|
||||
}
|
||||
|
||||
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(Window *w, bool init_array)
|
||||
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 &pt)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 NWidgetPart *parts, int count, int *biggest
|
||||
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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user