(svn r18092) -Codechange: remove support for the unnested widgets

replace/41b28d7194a279bdc17475d4fbe2ea6ec885a466
rubidium 15 years ago
parent 7337a0553c
commit aeb9f8e715

@ -1184,8 +1184,7 @@ bool QueryString::HasEditBoxFocus(const Window *w, int wid) 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 *w, int wid)
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);
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);
const NWidgetBase *wi = w->GetWidget<NWidgetBase>(wid);
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);

@ -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;

@ -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;

@ -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. */

@ -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;
}

@ -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 NWidgetFunction(NWidgetFunctionType *func_ptr)
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 */

@ -326,27 +326,16 @@ void ShowDropDownList(Window *w, DropDownList *list, int selected, int button, u
* 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;
if (nwi->type == NWID_BUTTON_DRPDOWN) {
nwi->disp_flags |= ND_DROPDOWN_ACTIVE;
} else {
w->LowerWidget(button);
}
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 {
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);

@ -74,23 +74,10 @@ WindowDesc::WindowDesc(int16 left, int16 top, int16 min_width, int16 min_height,
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;
/* 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->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;
}
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;
}
/**
@ -194,27 +159,6 @@ void CDECL Window::SetWidgetsDisabledState(bool disab_stat, int widgets, ...)
va_end(wdg_list);
}
/**
* 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
@ -240,21 +184,11 @@ void CDECL Window::SetWidgetsLoweredState(bool lowered_stat, int widgets, ...)
*/
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 widget)
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(Window *w, int x, int y, bool double_click)
{
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(Window *w, int x, int y, bool double_click)
* 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(Window *w, int x, int y, bool double_click)
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(Window *w, int x, int y, bool double_click)
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(Window *w, int x, int y, bool double_click)
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(Window *w, int widget, int wheel)
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;
@ -884,77 +763,44 @@ static void BringWindowToFront(Window *w)
w->SetDirty();
}
/**
* 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
@ -1074,15 +920,6 @@ void Window::FindWindowPlacementAndResize(int def_width, int def_height)
this->SetDirty();
}
/**
* 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
@ -1304,21 +1141,6 @@ static Point LocalGetWindowPlacement(const WindowDesc *desc, int16 sm_width, int
return LocalGetWindowPlacement(desc, sm_width, sm_height, window_number);
}
/**
* 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.
@ -1347,7 +1169,7 @@ void Window::CreateNestedTree(const WindowDesc *desc, bool fill_nested)
*/
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, int delta_y)
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);

@ -143,9 +143,6 @@ struct WindowDesc : ZeroedMemoryAllocator {
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 */

Loading…
Cancel
Save