mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-05 22:04:57 +00:00
(svn r18092) -Codechange: remove support for the unnested widgets
This commit is contained in:
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->IsWidgetGloballyFocused(wid)) return true;
|
||||||
if (w->window_class != WC_OSK || _focused_window != w->parent) return false;
|
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) ||
|
return w->parent->nested_focus != NULL && w->parent->nested_focus->type == WWT_EDITBOX;
|
||||||
(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)
|
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)
|
void QueryString::DrawEditBox(Window *w, int wid)
|
||||||
{
|
{
|
||||||
int left;
|
const NWidgetBase *wi = w->GetWidget<NWidgetBase>(wid);
|
||||||
int right;
|
|
||||||
int top;
|
|
||||||
int bottom;
|
|
||||||
if (w->widget == NULL) {
|
|
||||||
const NWidgetBase *wi = w->GetWidget<NWidgetBase>(wid);
|
|
||||||
|
|
||||||
assert((wi->type & WWT_MASK) == WWT_EDITBOX);
|
assert((wi->type & WWT_MASK) == WWT_EDITBOX);
|
||||||
|
int left = wi->pos_x;
|
||||||
left = wi->pos_x;
|
int right = wi->pos_x + wi->current_x - 1;
|
||||||
right = wi->pos_x + wi->current_x - 1;
|
int top = wi->pos_y;
|
||||||
top = wi->pos_y;
|
int bottom = wi->pos_y + wi->current_y - 1;
|
||||||
bottom = wi->pos_y + wi->current_y - 1;
|
|
||||||
} else {
|
|
||||||
const Widget *wi = &w->widget[wid];
|
|
||||||
|
|
||||||
assert((wi->type & WWT_MASK) == WWT_EDITBOX);
|
|
||||||
|
|
||||||
left = wi->left;
|
|
||||||
right = wi->right;
|
|
||||||
top = wi->top;
|
|
||||||
bottom = wi->bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
GfxFillRect(left + 1, top + 1, right - 1, bottom - 1, 215);
|
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)
|
/* virtual */ void Draw(const Window *w)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -75,14 +75,9 @@ struct OskWindow : public Window {
|
|||||||
this->parent = parent;
|
this->parent = parent;
|
||||||
assert(parent != NULL);
|
assert(parent != NULL);
|
||||||
|
|
||||||
if (parent->widget != NULL) {
|
NWidgetCore *par_wid = parent->GetWidget<NWidgetCore>(button);
|
||||||
this->caption = (parent->widget[button].data != STR_NULL) ? parent->widget[button].data : parent->caption;
|
assert(par_wid != NULL);
|
||||||
}
|
this->caption = (par_wid->widget_data != STR_NULL) ? par_wid->widget_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->qs = parent;
|
this->qs = parent;
|
||||||
this->text_btn = button;
|
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)
|
/* virtual */ void Draw(const Window *w)
|
||||||
{
|
{
|
||||||
/* Draw brown-red toolbar bg. */
|
/* Draw brown-red toolbar bg. */
|
||||||
|
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();
|
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.
|
/** Special handling for the scrollbar widget type.
|
||||||
* Handles the special scrolling buttons and other scrolling.
|
* Handles the special scrolling buttons and other scrolling.
|
||||||
* @param w Window on which a scroll was performed.
|
* @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)
|
int GetWidgetFromPos(const Window *w, int x, int y)
|
||||||
{
|
{
|
||||||
if (w->nested_root != NULL) {
|
NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y);
|
||||||
NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y);
|
return (nw != NULL) ? nw->index : -1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -595,122 +544,7 @@ static inline void DrawDropdown(const Rect &r, Colours colour, bool clicked, Str
|
|||||||
*/
|
*/
|
||||||
void Window::DrawWidgets() const
|
void Window::DrawWidgets() const
|
||||||
{
|
{
|
||||||
if (this->nested_root != NULL) {
|
this->nested_root->Draw(this);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (this->flags4 & WF_WHITE_BORDER_MASK) {
|
if (this->flags4 & WF_WHITE_BORDER_MASK) {
|
||||||
DrawFrameRect(0, 0, this->width - 1, this->height - 1, COLOUR_WHITE, FR_BORDERONLY);
|
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;
|
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 offset = this->IsWidgetLowered(widget) ? 1 : 0;
|
||||||
int base, top;
|
int base = offset + nwid->pos_x + (_dynlang.text_dir == TD_LTR ? nwid->current_x - WD_SORTBUTTON_ARROW_WIDTH : 0);
|
||||||
if (this->widget != NULL) {
|
int top = nwid->pos_y;
|
||||||
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;
|
|
||||||
}
|
|
||||||
DrawString(base, base + WD_SORTBUTTON_ARROW_WIDTH, top + 1 + offset, state == SBS_DOWN ? DOWNARROW : UPARROW, TC_BLACK, SA_CENTER);
|
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;
|
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)
|
* @fn void Draw(const Window *w)
|
||||||
* Draw the widgets of the tree.
|
* 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;
|
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)
|
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;
|
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)
|
void NWidgetStacked::FillNestedArray(NWidgetBase **array, uint length)
|
||||||
{
|
{
|
||||||
if (this->index >= 0 && (uint)(this->index) < length) array[this->index] = this;
|
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. */
|
/** Horizontal left-to-right container widget. */
|
||||||
NWidgetHorizontalLTR::NWidgetHorizontalLTR(NWidContainerFlags flags) : NWidgetHorizontal(flags)
|
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);
|
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. */
|
/** Vertical container widget. */
|
||||||
NWidgetVertical::NWidgetVertical(NWidContainerFlags flags) : NWidgetPIPContainer(NWID_VERTICAL, flags)
|
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.
|
* Generic spacer widget.
|
||||||
* @param length Horizontal size of the 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)
|
void NWidgetSpacer::Draw(const Window *w)
|
||||||
{
|
{
|
||||||
/* Spacer widget is never visible. */
|
/* 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)
|
void NWidgetBackground::FillNestedArray(NWidgetBase **array, uint length)
|
||||||
{
|
{
|
||||||
if (this->index >= 0 && (uint)(this->index) < length) array[this->index] = this;
|
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;
|
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)
|
void NWidgetViewport::Draw(const Window *w)
|
||||||
{
|
{
|
||||||
if (this->disp_flags & ND_NO_TRANSPARENCY) {
|
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 == */
|
/* == 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);
|
MakeWidgetTree(parts, count, container, biggest_index);
|
||||||
return container;
|
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,
|
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() */
|
/** Different forms of sizing nested widgets, using NWidgetBase::AssignSizePosition() */
|
||||||
enum SizingType {
|
enum SizingType {
|
||||||
ST_ARRAY, ///< Initialize nested widget tree to generate a #Widget * array.
|
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 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 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 void FillNestedArray(NWidgetBase **array, uint length) = 0;
|
||||||
|
|
||||||
virtual NWidgetCore *GetWidgetFromPos(int x, int y) = 0;
|
virtual NWidgetCore *GetWidgetFromPos(int x, int y) = 0;
|
||||||
@ -311,7 +292,6 @@ public:
|
|||||||
inline void SetDisabled(bool disabled);
|
inline void SetDisabled(bool disabled);
|
||||||
inline bool IsDisabled() const;
|
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 */ void FillNestedArray(NWidgetBase **array, uint length);
|
||||||
/* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
|
/* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
|
||||||
|
|
||||||
@ -393,7 +373,6 @@ public:
|
|||||||
|
|
||||||
void SetupSmallestSize(Window *w, bool init_array);
|
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 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 FillNestedArray(NWidgetBase **array, uint length);
|
||||||
|
|
||||||
/* virtual */ void Draw(const Window *w);
|
/* virtual */ void Draw(const Window *w);
|
||||||
@ -439,8 +418,6 @@ public:
|
|||||||
|
|
||||||
void SetupSmallestSize(Window *w, bool init_array);
|
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 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.
|
/** Horizontal container that doesn't change the direction of the widgets for RTL languages.
|
||||||
@ -450,8 +427,6 @@ public:
|
|||||||
NWidgetHorizontalLTR(NWidContainerFlags flags = NC_NONE);
|
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 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.
|
/** Vertical container.
|
||||||
@ -462,8 +437,6 @@ public:
|
|||||||
|
|
||||||
void SetupSmallestSize(Window *w, bool init_array);
|
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 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);
|
NWidgetSpacer(int length, int height);
|
||||||
|
|
||||||
void SetupSmallestSize(Window *w, bool init_array);
|
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 FillNestedArray(NWidgetBase **array, uint length);
|
||||||
|
|
||||||
/* virtual */ void Draw(const Window *w);
|
/* virtual */ void Draw(const Window *w);
|
||||||
@ -495,7 +467,6 @@ public:
|
|||||||
void SetupSmallestSize(Window *w, bool init_array);
|
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 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 FillNestedArray(NWidgetBase **array, uint length);
|
||||||
|
|
||||||
/* virtual */ void Draw(const Window *w);
|
/* virtual */ void Draw(const Window *w);
|
||||||
@ -520,7 +491,6 @@ public:
|
|||||||
NWidgetViewport(int index);
|
NWidgetViewport(int index);
|
||||||
|
|
||||||
/* virtual */ void SetupSmallestSize(Window *w, bool init_array);
|
/* 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 */ void Draw(const Window *w);
|
||||||
/* virtual */ Scrollbar *FindScrollbar(Window *w, bool allow_next = true);
|
/* virtual */ Scrollbar *FindScrollbar(Window *w, bool allow_next = true);
|
||||||
|
|
||||||
@ -547,8 +517,6 @@ private:
|
|||||||
static Dimension closebox_dimension; ///< Cached size of a closebox widget.
|
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
|
* @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.
|
* 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);
|
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 */
|
#endif /* WIDGET_TYPE_H */
|
||||||
|
@ -326,27 +326,16 @@ void ShowDropDownList(Window *w, DropDownList *list, int selected, int button, u
|
|||||||
* down list window. */
|
* down list window. */
|
||||||
Rect wi_rect;
|
Rect wi_rect;
|
||||||
Colours wi_colour;
|
Colours wi_colour;
|
||||||
if (w->nested_array != NULL) {
|
NWidgetCore *nwi = w->GetWidget<NWidgetCore>(button);
|
||||||
NWidgetCore *nwi = w->GetWidget<NWidgetCore>(button);
|
wi_rect.left = nwi->pos_x;
|
||||||
wi_rect.left = nwi->pos_x;
|
wi_rect.right = nwi->pos_x + nwi->current_x - 1;
|
||||||
wi_rect.right = nwi->pos_x + nwi->current_x - 1;
|
wi_rect.top = nwi->pos_y;
|
||||||
wi_rect.top = nwi->pos_y;
|
wi_rect.bottom = nwi->pos_y + nwi->current_y - 1;
|
||||||
wi_rect.bottom = nwi->pos_y + nwi->current_y - 1;
|
wi_colour = nwi->colour;
|
||||||
wi_colour = nwi->colour;
|
|
||||||
|
|
||||||
if (nwi->type == NWID_BUTTON_DRPDOWN) {
|
if (nwi->type == NWID_BUTTON_DRPDOWN) {
|
||||||
nwi->disp_flags |= ND_DROPDOWN_ACTIVE;
|
nwi->disp_flags |= ND_DROPDOWN_ACTIVE;
|
||||||
} else {
|
|
||||||
w->LowerWidget(button);
|
|
||||||
}
|
|
||||||
} else {
|
} 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->LowerWidget(button);
|
||||||
}
|
}
|
||||||
w->SetWidgetDirty(button);
|
w->SetWidgetDirty(button);
|
||||||
|
331
src/window.cpp
331
src/window.cpp
@ -74,23 +74,10 @@ WindowDesc::WindowDesc(int16 left, int16 top, int16 min_width, int16 min_height,
|
|||||||
this->flags = flags;
|
this->flags = flags;
|
||||||
this->nwid_parts = nwid_parts;
|
this->nwid_parts = nwid_parts;
|
||||||
this->nwid_length = nwid_length;
|
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()
|
WindowDesc::~WindowDesc()
|
||||||
{
|
{
|
||||||
free(this->new_widgets);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,10 +90,6 @@ void SetFocusedWindow(Window *w)
|
|||||||
|
|
||||||
/* Invalidate focused widget */
|
/* Invalidate focused widget */
|
||||||
if (_focused_window != NULL) {
|
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);
|
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. */
|
/* 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->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->nested_focus != NULL && _focused_window->nested_focus->type == WWT_EDITBOX;
|
|
||||||
}
|
|
||||||
return _focused_window->focused_widget != NULL && _focused_window->focused_widget->type == WWT_EDITBOX;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -144,33 +124,18 @@ bool EditBoxInGlobalFocus()
|
|||||||
*/
|
*/
|
||||||
bool Window::SetFocusedWidget(byte widget_index)
|
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. */
|
||||||
/* 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 (widget_index >= this->widget_count || this->widget + widget_index == this->focused_widget) return false;
|
|
||||||
|
|
||||||
if (this->focused_widget != NULL) {
|
assert(this->nested_array[widget_index] != NULL); // Setting focus to a non-existing widget is a bad idea.
|
||||||
/* Repaint the widget that lost focus. A focused edit box may else leave the caret on the screen. */
|
if (this->nested_focus != NULL) {
|
||||||
this->SetWidgetDirty(this->focused_widget - this->widget);
|
if (this->GetWidget<NWidgetCore>(widget_index) == this->nested_focus) return false;
|
||||||
}
|
|
||||||
this->focused_widget = &this->widget[widget_index];
|
/* Repaint the widget that lost focus. A focused edit box may else leave the caret on the screen. */
|
||||||
return true;
|
this->nested_focus->SetDirty(this);
|
||||||
}
|
}
|
||||||
|
this->nested_focus = this->GetWidget<NWidgetCore>(widget_index);
|
||||||
if (this->nested_array != NULL) {
|
return true;
|
||||||
/* Do nothing if widget_index is already focused, or if it wasn't a valid widget. */
|
|
||||||
if (widget_index >= this->nested_array_size) return false;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
NOT_REACHED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -194,27 +159,6 @@ void CDECL Window::SetWidgetsDisabledState(bool disab_stat, int widgets, ...)
|
|||||||
va_end(wdg_list);
|
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.
|
* Sets the lowered/raised status of a list of widgets.
|
||||||
* @param lowered_stat status to use ie: lowered = true, raised = false
|
* @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)
|
void Window::RaiseButtons(bool autoraise)
|
||||||
{
|
{
|
||||||
if (this->widget != NULL) {
|
for (uint i = 0; i < this->nested_array_size; i++) {
|
||||||
for (uint i = 0; i < this->widget_count; i++) {
|
if (this->nested_array[i] != NULL && (this->nested_array[i]->type & ~WWB_PUSHBUTTON) < WWT_LAST &&
|
||||||
if ((!autoraise || (this->widget[i].type & WWB_PUSHBUTTON)) && this->IsWidgetLowered(i)) {
|
(!autoraise || (this->nested_array[i]->type & WWB_PUSHBUTTON)) && this->IsWidgetLowered(i)) {
|
||||||
this->RaiseWidget(i);
|
this->RaiseWidget(i);
|
||||||
this->SetWidgetDirty(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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,15 +199,7 @@ void Window::RaiseButtons(bool autoraise)
|
|||||||
*/
|
*/
|
||||||
void Window::SetWidgetDirty(byte widget_index) const
|
void Window::SetWidgetDirty(byte widget_index) const
|
||||||
{
|
{
|
||||||
if (this->widget != NULL) {
|
this->nested_array[widget_index]->SetDirty(this);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -288,18 +214,6 @@ void Window::HandleButtonClick(byte widget)
|
|||||||
this->SetWidgetDirty(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 StartWindowDrag(Window *w);
|
||||||
static void StartWindowSizing(Window *w, bool to_left);
|
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;
|
int widget_index = 0;
|
||||||
if (w->desc_flags & WDF_DEF_WIDGET) {
|
if (w->desc_flags & WDF_DEF_WIDGET) {
|
||||||
const Widget *wi = NULL;
|
const NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y);
|
||||||
const NWidgetCore *nw = NULL;
|
widget_index = (nw != NULL) ? nw->index : -1;
|
||||||
WidgetType widget_type;
|
WidgetType widget_type = (widget_index >= 0) ? nw->type : WWT_EMPTY;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool focused_widget_changed = false;
|
bool focused_widget_changed = false;
|
||||||
/* If clicked on a window that previously did dot have focus */
|
/* 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 */
|
* So unless the clicked widget is the caption bar, change focus to this widget */
|
||||||
if (widget_type != WWT_CAPTION) {
|
if (widget_type != WWT_CAPTION) {
|
||||||
/* Close the OSK window if a edit box loses focus */
|
/* 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
|
if ((w->nested_root != NULL && w->nested_focus != NULL && w->nested_focus->type == WWT_EDITBOX &&
|
||||||
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 &&
|
|
||||||
w->nested_focus != nw && w->window_class != WC_OSK)) {
|
w->nested_focus != nw && w->window_class != WC_OSK)) {
|
||||||
DeleteWindowById(WC_OSK, 0);
|
DeleteWindowById(WC_OSK, 0);
|
||||||
}
|
}
|
||||||
@ -383,11 +285,7 @@ static void DispatchLeftClickEvent(Window *w, int x, int y, bool double_click)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (widget_type == WWT_SCROLLBAR || widget_type == WWT_SCROLL2BAR || widget_type == WWT_HSCROLLBAR) {
|
} else if (widget_type == WWT_SCROLLBAR || widget_type == WWT_SCROLL2BAR || widget_type == WWT_HSCROLLBAR) {
|
||||||
if (wi != NULL) {
|
ScrollbarClickHandler(w, nw, x, y);
|
||||||
ScrollbarClickHandler(w, wi, x, y);
|
|
||||||
} else {
|
|
||||||
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
|
} 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 */
|
/* Open the OSK window if clicked on an edit box */
|
||||||
QueryStringBaseWindow *qs = dynamic_cast<QueryStringBaseWindow *>(w);
|
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) {
|
if ((w->desc_flags & WDF_RESIZABLE) && widget_type == WWT_RESIZEBOX) {
|
||||||
/* When the resize widget is on the left size of the window
|
/* When the resize widget is on the left size of the window
|
||||||
* we assume that that button is used to resize to the left. */
|
* 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));
|
StartWindowSizing(w, left_pos < (w->width / 2));
|
||||||
w->SetWidgetDirty(widget_index);
|
w->SetWidgetDirty(widget_index);
|
||||||
return;
|
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)
|
static void DispatchRightClickEvent(Window *w, int x, int y)
|
||||||
{
|
{
|
||||||
int widget = 0;
|
int widget = 0;
|
||||||
StringID tooltip = 0;
|
|
||||||
|
|
||||||
/* default tooltips handler? */
|
/* default tooltips handler? */
|
||||||
if (w->desc_flags & WDF_STD_TOOLTIPS) {
|
if (w->desc_flags & WDF_STD_TOOLTIPS) {
|
||||||
if (w->nested_root != NULL) {
|
NWidgetCore *wid = w->nested_root->GetWidgetFromPos(x, y);
|
||||||
NWidgetCore *wid = w->nested_root->GetWidgetFromPos(x, y);
|
if (wid == NULL || wid->index < 0) return;
|
||||||
if (wid == NULL || wid->index < 0) return;
|
widget = wid->index;
|
||||||
widget = wid->index;
|
StringID tooltip = wid->tool_tip;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tooltip != 0) {
|
if (tooltip != 0) {
|
||||||
GuiShowTooltips(tooltip);
|
GuiShowTooltips(tooltip);
|
||||||
@ -484,16 +374,6 @@ static void DispatchMouseWheelEvent(Window *w, int widget, int wheel)
|
|||||||
if (widget < 0) return;
|
if (widget < 0) return;
|
||||||
|
|
||||||
Scrollbar *sb = NULL;
|
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 (w->nested_array != NULL && (uint)widget < w->nested_array_size) sb = w->GetWidget<NWidgetCore>(widget)->FindScrollbar(w);
|
||||||
|
|
||||||
if (sb != NULL && sb->GetCount() > sb->GetCapacity()) {
|
if (sb != NULL && sb->GetCount() > sb->GetCapacity()) {
|
||||||
@ -698,7 +578,6 @@ Window::~Window()
|
|||||||
|
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
|
|
||||||
free(this->widget);
|
|
||||||
free(this->nested_array); // Contents is released through deletion of #nested_root.
|
free(this->nested_array); // Contents is released through deletion of #nested_root.
|
||||||
delete this->nested_root;
|
delete this->nested_root;
|
||||||
|
|
||||||
@ -884,77 +763,44 @@ static void BringWindowToFront(Window *w)
|
|||||||
w->SetDirty();
|
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.
|
* 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 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 window_number Number being assigned to the new window
|
||||||
* @param desc_flags Window flags. @see WindowDefaultFlag
|
* @param desc_flags Window flags. @see WindowDefaultFlag
|
||||||
* @return Window pointer of the newly created window
|
* @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.
|
* @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.
|
* 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 */
|
/* Set up window properties; some of them are needed to set up smallest size below */
|
||||||
this->window_class = cls;
|
this->window_class = cls;
|
||||||
this->flags4 = WF_WHITE_BORDER_MASK; // just opened windows have a white border
|
this->flags4 = WF_WHITE_BORDER_MASK; // just opened windows have a white border
|
||||||
this->owner = INVALID_OWNER;
|
this->owner = INVALID_OWNER;
|
||||||
this->focused_widget = NULL;
|
|
||||||
this->nested_focus = NULL;
|
this->nested_focus = NULL;
|
||||||
this->window_number = window_number;
|
this->window_number = window_number;
|
||||||
this->desc_flags = desc_flags;
|
this->desc_flags = desc_flags;
|
||||||
|
|
||||||
/* If available, initialize nested widget tree. */
|
/* If available, initialize nested widget tree. */
|
||||||
if (widget == NULL) {
|
if (this->nested_array == NULL) {
|
||||||
if (this->nested_array == NULL) {
|
this->nested_array = CallocT<NWidgetBase *>(this->nested_array_size);
|
||||||
this->nested_array = CallocT<NWidgetBase *>(this->nested_array_size);
|
this->nested_root->SetupSmallestSize(this, true);
|
||||||
this->nested_root->SetupSmallestSize(this, true);
|
} else {
|
||||||
} else {
|
this->nested_root->SetupSmallestSize(this, false);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
/* 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,
|
/* Further set up window properties,
|
||||||
* this->left, this->top, this->width, this->height, this->resize.width, and this->resize.height are initialized later. */
|
* 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_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;
|
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
|
/* 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
|
* of focused window has focus (so we don't interrupt typing). But if the new
|
||||||
* window has a text box, then take focus anyway. */
|
* window has a text box, then take focus anyway. */
|
||||||
bool has_editbox = (this->widget != NULL && this->GetWidgetOfType(WWT_EDITBOX) != NULL) ||
|
bool has_editbox = this->nested_root != NULL && this->nested_root->GetWidgetOfType(WWT_EDITBOX) != NULL;
|
||||||
(this->nested_root != NULL && this->nested_root->GetWidgetOfType(WWT_EDITBOX) != NULL);
|
|
||||||
if (this->window_class != WC_OSK && (!EditBoxInGlobalFocus() || has_editbox)) SetFocusedWindow(this);
|
if (this->window_class != WC_OSK && (!EditBoxInGlobalFocus() || has_editbox)) SetFocusedWindow(this);
|
||||||
|
|
||||||
/* Hacky way of specifying always-on-top windows. These windows are
|
/* 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();
|
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.
|
* 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
|
* 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);
|
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.
|
* 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.
|
* 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)
|
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);
|
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->InitializePositionSize(pt.x, pt.y, this->nested_root->smallest_x, this->nested_root->smallest_y);
|
||||||
this->FindWindowPlacementAndResize(desc->default_width, desc->default_height);
|
this->FindWindowPlacementAndResize(desc->default_width, desc->default_height);
|
||||||
@ -1511,10 +1333,7 @@ static bool HandleMouseOver()
|
|||||||
if (w != NULL) {
|
if (w != NULL) {
|
||||||
/* send an event in client coordinates. */
|
/* send an event in client coordinates. */
|
||||||
Point pt = { _cursor.pos.x - w->left, _cursor.pos.y - w->top };
|
Point pt = { _cursor.pos.x - w->left, _cursor.pos.y - w->top };
|
||||||
int widget = 0;
|
int widget = w->nested_root->GetWidgetFromPos(pt.x, pt.y)->index;
|
||||||
if (w->widget != NULL) {
|
|
||||||
widget = GetWidgetFromPos(w, pt.x, pt.y);
|
|
||||||
}
|
|
||||||
w->OnMouseOver(pt, widget);
|
w->OnMouseOver(pt, widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1537,52 +1356,14 @@ void ResizeWindow(Window *w, int delta_x, int delta_y)
|
|||||||
|
|
||||||
w->SetDirty();
|
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_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);
|
||||||
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_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);
|
||||||
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->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->width = w->nested_root->current_x;
|
||||||
w->height = w->nested_root->current_y;
|
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;
|
|
||||||
|
|
||||||
/* 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->SetDirty();
|
w->SetDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1758,22 +1539,12 @@ static bool HandleWindowDragging()
|
|||||||
|
|
||||||
/* Search for the title bar rectangle. */
|
/* Search for the title bar rectangle. */
|
||||||
Rect caption_rect;
|
Rect caption_rect;
|
||||||
if (w->widget != NULL) {
|
const NWidgetBase *caption = w->nested_root->GetWidgetOfType(WWT_CAPTION);
|
||||||
const Widget *caption = w->GetWidgetOfType(WWT_CAPTION);
|
assert(caption != NULL);
|
||||||
assert(caption != NULL);
|
caption_rect.left = caption->pos_x;
|
||||||
caption_rect.left = caption->left;
|
caption_rect.right = caption->pos_x + caption->current_x;
|
||||||
caption_rect.right = caption->right;
|
caption_rect.top = caption->pos_y;
|
||||||
caption_rect.top = caption->top;
|
caption_rect.bottom = caption->pos_y + caption->current_y;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure the window doesn't leave the screen */
|
/* 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);
|
nx = Clamp(nx, MIN_VISIBLE_TITLE_BAR - caption_rect.right, _screen.width - MIN_VISIBLE_TITLE_BAR - caption_rect.left);
|
||||||
|
105
src/window_gui.h
105
src/window_gui.h
@ -143,9 +143,6 @@ struct WindowDesc : ZeroedMemoryAllocator {
|
|||||||
uint32 flags; ///< Flags. @see WindowDefaultFlags
|
uint32 flags; ///< Flags. @see WindowDefaultFlags
|
||||||
const NWidgetPart *nwid_parts; ///< Nested widget parts describing the window.
|
const NWidgetPart *nwid_parts; ///< Nested widget parts describing the window.
|
||||||
int16 nwid_length; ///< Length of the #nwid_parts array.
|
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:
|
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 InitializePositionSize(int x, int y, int min_width, int min_height);
|
||||||
void FindWindowPlacementAndResize(int def_width, int def_height);
|
void FindWindowPlacementAndResize(int def_width, int def_height);
|
||||||
void FindWindowPlacementAndResize(const WindowDesc *desc);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Window(const WindowDesc *desc, WindowNumber number = 0);
|
|
||||||
Window();
|
Window();
|
||||||
|
|
||||||
virtual ~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.
|
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.
|
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
|
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.
|
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_root; ///< Root of the nested tree.
|
||||||
NWidgetBase **nested_array; ///< Array of pointers into the tree. Do not access directly, use #Window::GetWidget() instead.
|
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)
|
inline void SetWidgetDisabledState(byte widget_index, bool disab_stat)
|
||||||
{
|
{
|
||||||
if (this->widget != NULL) {
|
assert(widget_index < this->nested_array_size);
|
||||||
assert(widget_index < this->widget_count);
|
if (this->nested_array[widget_index] != NULL) this->GetWidget<NWidgetCore>(widget_index)->SetDisabled(disab_stat);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -449,54 +435,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline bool IsWidgetDisabled(byte widget_index) const
|
inline bool IsWidgetDisabled(byte widget_index) const
|
||||||
{
|
{
|
||||||
if (this->nested_array != NULL) {
|
assert(widget_index < this->nested_array_size);
|
||||||
assert(widget_index < this->nested_array_size);
|
return this->GetWidget<NWidgetCore>(widget_index)->IsDisabled();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -506,8 +446,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline bool IsWidgetFocused(byte widget_index) const
|
inline bool IsWidgetFocused(byte widget_index) const
|
||||||
{
|
{
|
||||||
return (this->widget != NULL && this->focused_widget == &this->widget[widget_index]) ||
|
return this->nested_focus != NULL && this->nested_focus->index == widget_index;
|
||||||
(this->nested_focus != NULL && this->nested_focus->index == widget_index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -528,14 +467,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline void SetWidgetLoweredState(byte widget_index, bool lowered_stat)
|
inline void SetWidgetLoweredState(byte widget_index, bool lowered_stat)
|
||||||
{
|
{
|
||||||
if (this->widget != NULL) {
|
assert(widget_index < this->nested_array_size);
|
||||||
assert(widget_index < this->widget_count);
|
this->GetWidget<NWidgetCore>(widget_index)->SetLowered(lowered_stat);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -544,15 +477,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline void ToggleWidgetLoweredState(byte widget_index)
|
inline void ToggleWidgetLoweredState(byte widget_index)
|
||||||
{
|
{
|
||||||
if (this->widget != NULL) {
|
assert(widget_index < this->nested_array_size);
|
||||||
assert(widget_index < this->widget_count);
|
bool lowered_state = this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
|
||||||
ToggleBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
|
this->GetWidget<NWidgetCore>(widget_index)->SetLowered(!lowered_state);
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -580,18 +507,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline bool IsWidgetLowered(byte widget_index) const
|
inline bool IsWidgetLowered(byte widget_index) const
|
||||||
{
|
{
|
||||||
if (this->nested_array != NULL) {
|
assert(widget_index < this->nested_array_size);
|
||||||
assert(widget_index < this->nested_array_size);
|
return this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
|
||||||
return this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
|
|
||||||
}
|
|
||||||
assert(widget_index < this->widget_count);
|
|
||||||
return HasBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetFocusedWidget(byte widget_index);
|
bool SetFocusedWidget(byte widget_index);
|
||||||
|
|
||||||
void HandleButtonClick(byte widget);
|
void HandleButtonClick(byte widget);
|
||||||
const Widget *GetWidgetOfType(WidgetType widget_type) const;
|
|
||||||
|
|
||||||
void RaiseButtons(bool autoraise = false);
|
void RaiseButtons(bool autoraise = false);
|
||||||
void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
|
void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
|
||||||
@ -961,7 +883,6 @@ Window *GetCallbackWnd();
|
|||||||
void SetFocusedWindow(Window *w);
|
void SetFocusedWindow(Window *w);
|
||||||
bool EditBoxInGlobalFocus();
|
bool EditBoxInGlobalFocus();
|
||||||
|
|
||||||
void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y);
|
|
||||||
void ScrollbarClickHandler(Window *w, const NWidgetCore *nw, int x, int y);
|
void ScrollbarClickHandler(Window *w, const NWidgetCore *nw, int x, int y);
|
||||||
|
|
||||||
#endif /* WINDOW_GUI_H */
|
#endif /* WINDOW_GUI_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user