Go to the documentation of this file.
22 #include "table/strings.h"
192 d.height -= offset.y;
245 case SA_LEFT: p.x = r.left;
break;
247 case SA_RIGHT: p.x = r.right + 1 - d.width;
break;
248 default: NOT_REACHED();
251 case SA_TOP: p.y = r.top;
break;
253 case SA_BOTTOM: p.y = r.bottom + 1 - d.height;
break;
254 default: NOT_REACHED();
271 int rev_base = top + bottom;
274 button_size = NWidgetScrollbar::GetHorizontalDimension().width;
276 button_size = NWidgetScrollbar::GetVerticalDimension().height;
279 bottom -= button_size;
281 int height = (bottom - top);
286 if (count != 0) top += height * pos / count;
288 if (cap > count) cap = count;
289 if (count != 0) bottom -= (count - pos - cap) * height / count;
293 pt.x = rev_base - bottom;
294 pt.y = rev_base - top;
316 bool changed =
false;
321 button_size = NWidgetScrollbar::GetHorizontalDimension().width;
324 button_size = NWidgetScrollbar::GetVerticalDimension().height;
326 if (pos < mi + button_size) {
329 if (_scroller_click_timeout <= 1) {
330 _scroller_click_timeout = 3;
334 }
else if (pos >= ma - button_size) {
338 if (_scroller_click_timeout <= 1) {
339 _scroller_click_timeout = 3;
348 }
else if (pos > pt.y) {
351 _scrollbar_start_pos = pt.x - mi - button_size;
352 _scrollbar_size = ma - mi - button_size * 2;
354 _cursorpos_drag_start = _cursor.
pos;
387 assert(scrollbar !=
nullptr);
402 return (nw !=
nullptr) ? nw->
index : -1;
416 assert(colour < COLOUR_END);
428 Rect outer = {left, top, right, bottom};
432 GfxFillRect(outer.left, outer.top, inner.left - 1, outer.bottom, dark);
433 GfxFillRect(inner.left, outer.top, outer.right, inner.top - 1, dark);
434 GfxFillRect(inner.right + 1, inner.top, outer.right, inner.bottom, light);
435 GfxFillRect(inner.left, inner.bottom + 1, outer.right, outer.bottom, light);
436 interior = (flags &
FR_DARKENED ? medium_dark : medium_light);
438 GfxFillRect(outer.left, outer.top, inner.left - 1, inner.bottom, light);
439 GfxFillRect(inner.left, outer.top, inner.right, inner.top - 1, light);
440 GfxFillRect(inner.right + 1, outer.top, outer.right, inner.bottom, dark);
441 GfxFillRect(outer.left, inner.bottom + 1, outer.right, outer.bottom, dark);
442 interior = medium_dark;
445 GfxFillRect(inner.left, inner.top, inner.right, inner.bottom, interior);
455 d.height -= offset.y;
459 DrawSprite(img, pal, p.x + o - offset.x, p.y + o - offset.y);
476 if ((type & WWT_MASK) ==
WWT_IMGBTN_2 && clicked) img++;
477 DrawSpriteIgnorePadding(img, PAL_NONE, r, clicked, align);
491 if (str == STR_NULL)
return;
496 DrawString(r.left + o, r.right + o, p.y + o, str, colour, align);
510 if (str != STR_NULL)
DrawString(r.left, r.right, p.y, str, colour, align);
536 static inline void DrawMatrix(
const Rect &r, Colours colour,
bool clicked, uint16 data, uint resize_x, uint resize_y)
542 if (num_columns == 0) {
543 column_width = resize_x;
544 num_columns = r.
Width() / column_width;
546 column_width = r.
Width() / num_columns;
552 row_height = resize_y;
553 num_rows = r.
Height() / row_height;
555 row_height = r.
Height() / num_rows;
561 for (
int ctr = num_columns; ctr > 1; ctr--) {
567 for (
int ctr = num_rows; ctr > 1; ctr--) {
575 for (
int ctr = num_columns; ctr > 1; ctr--) {
581 for (
int ctr = num_rows; ctr > 1; ctr--) {
598 int height = NWidgetScrollbar::GetVerticalDimension().height;
608 GfxFillRect(r.left, r.top + height, r.right, r.bottom - height, c2);
612 int left = r.left + r.
Width() * 3 / 11;
613 int right = r.left + r.
Width() * 8 / 11;
618 GfxFillRect(left - bl, r.top + height, left - 1, r.bottom - height, c1);
619 GfxFillRect(left, r.top + height, left + br - 1, r.bottom - height, c2);
620 GfxFillRect(right - bl, r.top + height, right - 1, r.bottom - height, c1);
621 GfxFillRect(right, r.top + height, right + br - 1, r.bottom - height, c2);
638 int width = NWidgetScrollbar::GetHorizontalDimension().width;
647 GfxFillRect(r.left + width, r.top, r.right - width, r.bottom, c2);
651 int top = r.top + r.
Height() * 3 / 11;
652 int bottom = r.top + r.
Height() * 8 / 11;
657 GfxFillRect(r.left + width, top - bt, r.right - width, top - 1, c1);
658 GfxFillRect(r.left + width, top, r.right - width, top + bb - 1, c2);
659 GfxFillRect(r.left + width, bottom - bt, r.right - width, bottom - 1, c1);
660 GfxFillRect(r.left + width, bottom, r.right - width, bottom + bb - 1, c2);
710 GfxFillRect(outer.left, inner.top, inner.left - 1, inner.bottom, c1);
711 GfxFillRect(inner.left, inside.top, inside.left - 1, inside.bottom, c2);
714 GfxFillRect(inside.right + 1, inner.top, inner.right, inside.bottom, c1);
715 GfxFillRect(inner.right + 1, outer.top, outer.right, inner.bottom, c2);
718 GfxFillRect(inner.left, inside.bottom + 1, inner.right, inner.bottom, c1);
719 GfxFillRect(outer.left, inner.bottom + 1, outer.right, outer.bottom, c2);
786 if (colour != COLOUR_WHITE)
DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, FR_NONE);
790 d.height -= offset.y;
816 if (str != STR_NULL) {
841 if (str != STR_NULL) {
848 if (str != STR_NULL) {
869 const NWidgetBase *widget = this->GetWidget<NWidgetBase>(i);
870 if (widget ==
nullptr || !widget->IsHighlighted())
continue;
872 Rect outer = widget->GetCurrentRect();
877 GfxFillRect(outer.left, outer.top, inner.left, inner.bottom, colour);
878 GfxFillRect(inner.left + 1, outer.top, inner.right - 1, inner.top, colour);
879 GfxFillRect(inner.right, outer.top, outer.right, inner.bottom, colour);
880 GfxFillRect(outer.left + 1, inner.bottom, outer.right - 1, outer.bottom, colour);
895 Rect r = this->GetWidget<NWidgetBase>(widget)->GetCurrentRect();
898 Dimension dim = NWidgetScrollbar::GetVerticalDimension();
909 return NWidgetScrollbar::GetVerticalDimension().width + 1;
1027 int abs_top = w->
top + this->
pos_y;
1046 return (this->
type == tp) ? this :
nullptr;
1049 void NWidgetBase::AdjustPaddingForZoom()
1066 void NWidgetResizeBase::AdjustPaddingForZoom()
1072 NWidgetBase::AdjustPaddingForZoom();
1096 this->min_x = std::max(this->min_x,
min_x);
1097 this->min_y = std::max(this->min_y,
min_y);
1168 this->index =
index;
1206 this->align =
align;
1211 if (this->
index >= 0 && (uint)(this->
index) < length) array[this->
index] =
this;
1225 this->
head =
nullptr;
1226 this->
tail =
nullptr;
1229 NWidgetContainer::~NWidgetContainer()
1231 while (this->
head !=
nullptr) {
1236 this->
tail =
nullptr;
1241 if (this->
type == tp)
return this;
1242 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1244 if (nwid !=
nullptr)
return nwid;
1249 void NWidgetContainer::AdjustPaddingForZoom()
1251 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1252 child_wid->AdjustPaddingForZoom();
1254 NWidgetBase::AdjustPaddingForZoom();
1263 assert(wid->
next ==
nullptr && wid->
prev ==
nullptr);
1265 if (this->
head ==
nullptr) {
1269 assert(this->
tail !=
nullptr);
1270 assert(this->
tail->
next ==
nullptr);
1280 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1281 child_wid->FillNestedArray(array, length);
1293 void NWidgetStacked::SetIndex(
int index)
1295 this->index =
index;
1298 void NWidgetStacked::AdjustPaddingForZoom()
1300 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1301 child_wid->AdjustPaddingForZoom();
1303 NWidgetContainer::AdjustPaddingForZoom();
1308 if (this->
index >= 0 && init_array) {
1324 this->
fill_x = fill.width;
1325 this->
fill_y = fill.height;
1334 this->
fill_x = (this->
head !=
nullptr) ? 1 : 0;
1335 this->
fill_y = (this->
head !=
nullptr) ? 1 : 0;
1338 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1339 child_wid->SetupSmallestSize(w, init_array);
1341 this->
smallest_x = std::max(this->
smallest_x, child_wid->smallest_x + child_wid->padding.Horizontal());
1342 this->
smallest_y = std::max(this->
smallest_y, child_wid->smallest_y + child_wid->padding.Vertical());
1357 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1358 uint hor_step = (sizing ==
ST_SMALLEST) ? 1 : child_wid->GetHorizontalStepSize(sizing);
1359 uint child_width =
ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding.Horizontal(), hor_step);
1360 uint child_pos_x = (rtl ? child_wid->padding.right : child_wid->padding.left);
1362 uint vert_step = (sizing ==
ST_SMALLEST) ? 1 : child_wid->GetVerticalStepSize(sizing);
1363 uint child_height =
ComputeMaxSize(child_wid->smallest_y, given_height - child_wid->padding.Vertical(), vert_step);
1364 uint child_pos_y = child_wid->padding.top;
1366 child_wid->AssignSizePosition(sizing, x + child_pos_x, y + child_pos_y, child_width, child_height, rtl);
1372 if (this->
index >= 0 && (uint)(this->
index) < length) array[this->
index] =
this;
1381 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; plane++, child_wid = child_wid->
next) {
1397 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; plane++, child_wid = child_wid->
next) {
1416 this->flags = flags;
1419 void NWidgetPIPContainer::AdjustPaddingForZoom()
1424 NWidgetContainer::AdjustPaddingForZoom();
1449 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1458 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1460 if (nwid !=
nullptr)
return nwid;
1481 uint max_vert_fill = 0;
1482 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1483 child_wid->SetupSmallestSize(w, init_array);
1484 longest = std::max(longest, child_wid->smallest_x);
1485 max_vert_fill = std::max(max_vert_fill, child_wid->GetVerticalStepSize(
ST_SMALLEST));
1486 this->
smallest_y = std::max(this->
smallest_y, child_wid->smallest_y + child_wid->padding.Vertical());
1489 [[maybe_unused]] uint max_smallest = this->
smallest_y + 3 * max_vert_fill;
1492 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1493 uint step_size = child_wid->GetVerticalStepSize(
ST_SMALLEST);
1494 uint child_height = child_wid->smallest_y + child_wid->padding.Vertical();
1495 if (step_size > 1 && child_height < cur_height) {
1496 uint remainder = (cur_height - child_height) % step_size;
1497 if (remainder > 0) {
1498 cur_height += step_size - remainder;
1499 assert(cur_height < max_smallest);
1509 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1510 if (child_wid->fill_x == 1) child_wid->smallest_x = longest;
1515 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1516 if (child_wid->next !=
nullptr) {
1517 child_wid->padding.right += this->
pip_inter;
1519 child_wid->padding.right += this->
pip_post;
1522 this->
smallest_x += child_wid->smallest_x + child_wid->padding.Horizontal();
1523 if (child_wid->fill_x > 0) {
1524 if (this->
fill_x == 0 || this->
fill_x > child_wid->fill_x) this->
fill_x = child_wid->fill_x;
1528 if (child_wid->resize_x > 0) {
1542 uint additional_length = given_width;
1545 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1546 additional_length -= child_wid->smallest_x + child_wid->padding.Horizontal();
1568 int num_changing_childs = 0;
1569 uint biggest_stepsize = 0;
1570 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1571 uint hor_step = child_wid->GetHorizontalStepSize(sizing);
1574 biggest_stepsize = std::max(biggest_stepsize, hor_step);
1576 child_wid->current_x = child_wid->smallest_x;
1579 uint vert_step = (sizing ==
ST_SMALLEST) ? 1 : child_wid->GetVerticalStepSize(sizing);
1580 child_wid->current_y =
ComputeMaxSize(child_wid->smallest_y, given_height - child_wid->padding.Vertical(), vert_step);
1585 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1586 uint hor_step = child_wid->GetHorizontalStepSize(sizing);
1587 if (hor_step == biggest_stepsize) {
1588 num_changing_childs++;
1594 while (biggest_stepsize > 0) {
1595 uint next_biggest_stepsize = 0;
1596 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1597 uint hor_step = child_wid->GetHorizontalStepSize(sizing);
1598 if (hor_step > biggest_stepsize)
continue;
1599 if (hor_step == biggest_stepsize) {
1600 uint increment = additional_length / num_changing_childs;
1601 num_changing_childs--;
1602 if (hor_step > 1) increment -= increment % hor_step;
1603 child_wid->current_x = child_wid->smallest_x + increment;
1604 additional_length -= increment;
1607 next_biggest_stepsize = std::max(next_biggest_stepsize, hor_step);
1609 biggest_stepsize = next_biggest_stepsize;
1611 if (num_changing_childs == 0 && (
flags &
NC_BIGFIRST) && biggest_stepsize > 0) {
1613 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1614 uint hor_step = child_wid->GetHorizontalStepSize(sizing);
1615 if (hor_step == biggest_stepsize) {
1616 num_changing_childs++;
1621 assert(num_changing_childs == 0);
1624 uint position = rtl ? this->
current_x : 0;
1626 while (child_wid !=
nullptr) {
1627 uint child_width = child_wid->
current_x;
1628 uint child_x = x + (rtl ? position - child_width - child_wid->
padding.left : position + child_wid->
padding.left);
1629 uint child_y = y + child_wid->
padding.top;
1633 position = rtl ? position - padded_child_width : position + padded_child_width;
1635 child_wid = child_wid->
next;
1666 uint max_hor_fill = 0;
1667 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1668 child_wid->SetupSmallestSize(w, init_array);
1669 highest = std::max(highest, child_wid->smallest_y);
1670 max_hor_fill = std::max(max_hor_fill, child_wid->GetHorizontalStepSize(
ST_SMALLEST));
1671 this->
smallest_x = std::max(this->
smallest_x, child_wid->smallest_x + child_wid->padding.Horizontal());
1674 [[maybe_unused]] uint max_smallest = this->
smallest_x + 3 * max_hor_fill;
1677 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1678 uint step_size = child_wid->GetHorizontalStepSize(
ST_SMALLEST);
1679 uint child_width = child_wid->smallest_x + child_wid->padding.Horizontal();
1680 if (step_size > 1 && child_width < cur_width) {
1681 uint remainder = (cur_width - child_width) % step_size;
1682 if (remainder > 0) {
1683 cur_width += step_size - remainder;
1684 assert(cur_width < max_smallest);
1694 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1695 if (child_wid->fill_y == 1) child_wid->smallest_y = highest;
1700 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1701 if (child_wid->next !=
nullptr) {
1702 child_wid->padding.bottom += this->
pip_inter;
1704 child_wid->padding.bottom += this->
pip_post;
1707 this->
smallest_y += child_wid->smallest_y + child_wid->padding.Vertical();
1708 if (child_wid->fill_y > 0) {
1709 if (this->
fill_y == 0 || this->
fill_y > child_wid->fill_y) this->
fill_y = child_wid->fill_y;
1713 if (child_wid->resize_y > 0) {
1727 uint additional_length = given_height;
1730 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1731 additional_length -= child_wid->smallest_y + child_wid->padding.Vertical();
1744 int num_changing_childs = 0;
1745 uint biggest_stepsize = 0;
1746 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1747 uint vert_step = child_wid->GetVerticalStepSize(sizing);
1748 if (vert_step > 0) {
1750 biggest_stepsize = std::max(biggest_stepsize, vert_step);
1752 child_wid->current_y = child_wid->smallest_y;
1755 uint hor_step = (sizing ==
ST_SMALLEST) ? 1 : child_wid->GetHorizontalStepSize(sizing);
1756 child_wid->current_x =
ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding.Horizontal(), hor_step);
1761 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1762 uint vert_step = child_wid->GetVerticalStepSize(sizing);
1763 if (vert_step == biggest_stepsize) {
1764 num_changing_childs++;
1770 while (biggest_stepsize > 0) {
1771 uint next_biggest_stepsize = 0;
1772 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1773 uint vert_step = child_wid->GetVerticalStepSize(sizing);
1774 if (vert_step > biggest_stepsize)
continue;
1775 if (vert_step == biggest_stepsize) {
1776 uint increment = additional_length / num_changing_childs;
1777 num_changing_childs--;
1778 if (vert_step > 1) increment -= increment % vert_step;
1779 child_wid->current_y = child_wid->smallest_y + increment;
1780 additional_length -= increment;
1783 next_biggest_stepsize = std::max(next_biggest_stepsize, vert_step);
1785 biggest_stepsize = next_biggest_stepsize;
1787 if (num_changing_childs == 0 && (
flags &
NC_BIGFIRST) && biggest_stepsize > 0) {
1789 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1790 uint vert_step = child_wid->GetVerticalStepSize(sizing);
1791 if (vert_step == biggest_stepsize) {
1792 num_changing_childs++;
1797 assert(num_changing_childs == 0);
1801 for (
NWidgetBase *child_wid = this->
head; child_wid !=
nullptr; child_wid = child_wid->
next) {
1802 uint child_x = x + (rtl ? child_wid->padding.right : child_wid->padding.left);
1803 uint child_height = child_wid->current_y;
1805 child_wid->AssignSizePosition(sizing, child_x, y + position + child_wid->padding.top, child_wid->current_x, child_height, rtl);
1806 position += child_height + child_wid->padding.Vertical();
1850 void NWidgetMatrix::SetIndex(
int index)
1852 this->index =
index;
1855 void NWidgetMatrix::SetColour(Colours colour)
1867 if (this->clicked >= 0 && this->
sb !=
nullptr && this->
widgets_x != 0) {
1883 this->count =
count;
1885 if (this->
sb ==
nullptr || this->
widgets_x == 0)
return;
1912 assert(this->
head !=
nullptr);
1913 assert(this->
head->
next ==
nullptr);
1915 if (this->
index >= 0 && init_array) {
1922 assert(nw !=
nullptr);
1935 this->
fill_x = fill.width;
1936 this->
fill_y = fill.height;
1967 if (this->
index >= 0 && (uint)(this->
index) < length) array[this->
index] =
this;
1976 int start_x, start_y, base_offs_x, base_offs_y;
1981 int widget_col = (rtl ?
1983 x - (int)this->
pip_pre - (
int)this->
pos_x - base_offs_x
1988 int sub_wid = (widget_row + start_y) * this->
widgets_x + start_x + widget_col;
1989 if (sub_wid >= this->
count)
return nullptr;
1992 assert(child !=
nullptr);
1998 SB(child->
index, 16, 16, sub_wid);
2013 _cur_dpi = &tmp_dpi;
2017 assert(child !=
nullptr);
2018 int start_x, start_y, base_offs_x, base_offs_y;
2021 int offs_y = base_offs_y;
2022 for (
int y = start_y; y < start_y + this->
widgets_y + 1; y++, offs_y += this->
widget_h) {
2024 if (offs_y + child->
smallest_y <= 0)
continue;
2025 if (offs_y >= (
int)this->
current_y)
break;
2030 int offs_x = base_offs_x;
2033 if (offs_x + child->
smallest_x <= 0)
continue;
2034 if (offs_x >= (
int)this->
current_x)
continue;
2037 int sub_wid = y * this->widgets_x + x;
2038 if (sub_wid >= this->
count)
break;
2042 SB(child->
index, 16, 16, sub_wid);
2064 if (this->
sb !=
nullptr) {
2072 base_offs_x += sub_x;
2074 base_offs_x -= sub_x;
2093 this->child =
child;
2097 NWidgetBackground::~NWidgetBackground()
2099 if (this->
child !=
nullptr)
delete this->
child;
2111 if (this->
child ==
nullptr) {
2129 if (this->
child ==
nullptr) {
2132 this->
child->
SetPIP(pip_pre, pip_inter, pip_post);
2135 void NWidgetBackground::AdjustPaddingForZoom()
2137 if (
child !=
nullptr)
child->AdjustPaddingForZoom();
2138 NWidgetCore::AdjustPaddingForZoom();
2143 if (init_array && this->
index >= 0) {
2147 if (this->
child !=
nullptr) {
2158 if (w ==
nullptr)
return;
2186 d =
maxdim(d, background);
2188 if (this->
index >= 0) {
2190 switch (this->
type) {
2191 default: NOT_REACHED();
2201 this->
fill_x = fill.width;
2202 this->
fill_y = fill.height;
2212 if (this->
child !=
nullptr) {
2222 if (this->
index >= 0 && (uint)(this->
index) < length) array[this->
index] =
this;
2230 Rect r = this->GetCurrentRect();
2233 if (dpi->left > r.right || dpi->left + dpi->width <= r.left || dpi->top > r.bottom || dpi->top + dpi->height <= r.top)
return;
2235 switch (this->
type) {
2268 if (nwid ==
nullptr) nwid =
this;
2277 if (nwid ==
nullptr && this->
type == tp) nwid =
this;
2288 if (init_array && this->
index >= 0) {
2334 if (vp !=
nullptr) {
2376 int new_pos = list_position;
2448 switch (this->
type) {
2452 this->
SetDataTip(0x0, STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST);
2458 this->
SetDataTip(0x0, STR_TOOLTIP_VSCROLL_BAR_SCROLLS_LIST);
2461 default: NOT_REACHED();
2467 if (init_array && this->
index >= 0) {
2474 switch (this->
type) {
2476 this->
SetMinimalSizeAbsolute(NWidgetScrollbar::GetHorizontalDimension().width * 3, NWidgetScrollbar::GetHorizontalDimension().height);
2480 this->
SetMinimalSizeAbsolute(NWidgetScrollbar::GetVerticalDimension().width, NWidgetScrollbar::GetVerticalDimension().height * 3);
2483 default: NOT_REACHED();
2494 Rect r = this->GetCurrentRect();
2497 if (dpi->left > r.right || dpi->left + dpi->width <= r.left || dpi->top > r.bottom || dpi->top + dpi->height <= r.top)
return;
2514 void NWidgetScrollbar::InvalidateDimensionCache()
2520 Dimension NWidgetScrollbar::GetVerticalDimension()
2530 Dimension NWidgetScrollbar::GetHorizontalDimension()
2598 case NWID_PUSHBUTTON_DROPDOWN:
2613 this->
SetDataTip(data, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS);
2619 this->
SetDataTip(STR_NULL, STR_TOOLTIP_STICKY);
2625 this->
SetDataTip(STR_NULL, STR_TOOLTIP_SHADE);
2631 this->
SetDataTip(STR_NULL, STR_TOOLTIP_DEBUG);
2637 this->
SetDataTip(STR_NULL, STR_TOOLTIP_DEFSIZE);
2643 this->
SetDataTip(STR_NULL, STR_TOOLTIP_RESIZE);
2649 this->
SetDataTip(STR_NULL, STR_TOOLTIP_CLOSE_WINDOW);
2665 if (this->
index >= 0 && init_array) {
2674 switch (this->
type) {
2743 size.width = std::max(size.width,
ScaleGUITrad(30) + sprite_size.width);
2810 case NWID_PUSHBUTTON_DROPDOWN: {
2832 this->
fill_x = fill.width;
2833 this->
fill_y = fill.height;
2847 new_dpi.left += this->
pos_x;
2848 new_dpi.top += this->
pos_y;
2851 _cur_dpi = &new_dpi;
2853 Rect r = this->GetCurrentRect();
2856 switch (this->
type) {
2885 case AWV_LEFT: sprite = SPR_ARROW_LEFT;
break;
2886 case AWV_RIGHT: sprite = SPR_ARROW_RIGHT;
break;
2887 default: NOT_REACHED();
2909 if (query !=
nullptr) query->DrawEditBox(w, this->
index);
2952 case NWID_PUSHBUTTON_DROPDOWN:
2979 int button_width = this->
pos_x + this->
current_x - NWidgetLeaf::dropdown_dimension.width;
2980 return pt.x < button_width;
2982 int button_left = this->
pos_x + NWidgetLeaf::dropdown_dimension.width;
2983 return pt.x >= button_left;
3011 while (count > num_used) {
3012 switch (parts->
type) {
3014 if (*dest !=
nullptr)
return num_used;
3019 if (*dest !=
nullptr)
return num_used;
3025 if (*dest !=
nullptr)
return num_used;
3033 if (*dest !=
nullptr)
return num_used;
3035 *biggest_index = std::max(*biggest_index, (
int)parts->u.
widget.
index);
3040 if (*dest !=
nullptr)
return num_used;
3046 if (*dest !=
nullptr)
return num_used;
3052 *biggest_index = std::max(*biggest_index, (
int)parts->u.
widget.
index);
3057 if (*dest !=
nullptr)
return num_used;
3060 *dest = parts->u.
func_ptr(&biggest);
3061 *biggest_index = std::max(*biggest_index, biggest);
3068 if (nwrb !=
nullptr) {
3069 assert(parts->u.
xy.x >= 0 && parts->u.
xy.y >= 0);
3077 if (nwrb !=
nullptr) {
3078 assert(parts->u.
xy.x >= 0 && parts->u.
xy.y >= 0);
3086 if (nwrb !=
nullptr) {
3095 if (nwc !=
nullptr) {
3103 if (nwc !=
nullptr) {
3111 if (nwrb !=
nullptr) nwrb->
SetFill(parts->u.
xy.x, parts->u.
xy.y);
3117 if (nwc !=
nullptr) {
3125 if (*dest !=
nullptr) (*dest)->SetPadding(parts->u.
padding);
3139 if (nwc !=
nullptr) {
3149 if (*dest !=
nullptr)
return num_used;
3151 *biggest_index = std::max(*biggest_index, (
int)parts->u.
widget.
index);
3156 if (*dest !=
nullptr)
return num_used;
3158 *biggest_index = std::max(*biggest_index, (
int)parts->u.
widget.
index);
3162 if (*dest !=
nullptr)
return num_used;
3167 *biggest_index = std::max(*biggest_index, (
int)parts->u.
widget.
index);
3172 if (*dest !=
nullptr)
return num_used;
3175 *biggest_index = std::max(*biggest_index, (
int)parts->u.
widget.
index);
3200 assert(*parent ==
nullptr || (nwid_cont !=
nullptr && nwid_parent ==
nullptr) || (nwid_cont ==
nullptr && nwid_parent !=
nullptr));
3205 bool fill_sub =
false;
3206 int num_used =
MakeNWidget(parts, count - total_used, &sub_widget, &fill_sub, biggest_index);
3208 total_used += num_used;
3211 if (sub_widget ==
nullptr)
break;
3218 int num_used =
MakeWidgetTree(parts, count - total_used, &sub_ptr, biggest_index);
3220 total_used += num_used;
3224 if (nwid_cont !=
nullptr) nwid_cont->
Add(sub_widget);
3225 if (nwid_parent !=
nullptr) nwid_parent->
Add(sub_widget);
3226 if (nwid_cont ==
nullptr && nwid_parent ==
nullptr) {
3227 *parent = sub_widget;
3232 if (count == total_used)
return total_used;
3234 assert(total_used < count);
3236 return total_used + 1;
3252 *biggest_index = -1;
3274 *biggest_index = -1;
3278 int num_used =
MakeWidgetTree(parts, count, &nwid, biggest_index);
3279 assert(nwid !=
nullptr);
3286 *shade_select =
nullptr;
3296 root->
Add(*shade_select);
3298 (*shade_select)->
Add(body);
3300 *shade_select =
nullptr;
3308 *biggest_index = std::max(*biggest_index, biggest2);
3325 assert(max_length >= 1);
3334 for (
int widnum = widget_first; widnum <= widget_last; widnum++) {
3336 if (hor_length == max_length) {
3342 if (hor ==
nullptr) {
3355 *biggest_index = widget_last;
3356 if (vert ==
nullptr)
return hor;
3358 if (hor_length > 0 && hor_length < max_length) {
3365 if (hor !=
nullptr) vert->
Add(hor);
@ ES_HANDLED
The passed event is handled.
uint8 lines
Number of text lines.
int Height() const
Get height of Rect.
@ SA_HOR_MASK
Mask for horizontal alignment.
void AddDirtyBlock(int left, int top, int right, int bottom)
Extend the internal _invalid_rect rectangle to contain the rectangle defined by the given parameters.
@ WF_SIZING
Window is being resized.
SortButtonState
State of a sort direction button.
bool newgrf_developer_tools
activate NewGRF developer tools and allow modifying NewGRFs in an existing game
@ PALETTE_TEXT_RECOLOUR
Set if palette is actually a magic text recolour.
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
Dimensions (a width and height) of a rectangle in 2D.
void DrawSortButtonState(int widget, SortButtonState state) const
Draw a sort button's up or down arrow symbol.
NWidgetBase * nested_root
Root of the nested tree.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
TransparencyOptionBits _transparency_opt
The bits that should be transparent.
virtual void DrawWidget(const Rect &r, int widget) const
Draw the contents of a nested widget.
@ TD_LTR
Text is written left-to-right by default.
@ TO_LOADING
loading indicators
int width
Screen width of the viewport.
ViewportData * viewport
Pointer to viewport data, if present.
int height
Screen height of the viewport.
@ FILLRECT_RECOLOUR
Apply a recolour sprite to the screen content.
FrameFlags
Flags to describe the look of the frame.
int top
Screen coordinate top edge of the viewport.
virtual bool IsNewGRFInspectable() const
Is the data related to this window NewGRF inspectable?
@ WF_STICKY
Window is made sticky by user.
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
static const PaletteID PALETTE_TO_TRANSPARENT
This sets the sprite to transparent.
@ FILLRECT_CHECKER
Draw only every second pixel, used for greying-out.
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
ZoomLevel
All zoom levels we know.
@ SA_BOTTOM
Bottom align the text.
StringAlignment
How to align the to-be drawn text.
ClientSettings _settings_client
The current settings for this game.
int DrawString(int left, int right, int top, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Owner owner
The owner of the content shown in this window. Company colour is acquired from this variable.
@ FR_LOWERED
If set the frame is lowered and the background colour brighter (ie. buttons when pressed)
Rect Expand(int s) const
Copy and expand Rect by s pixels.
@ SA_RIGHT
Right align the text (must be a single bit).
@ SA_VERT_CENTER
Vertically center the text.
Owner
Enum for all companies/owners.
@ FR_TRANSPARENT
Makes the background transparent if set.
byte _colour_gradient[COLOUR_END][8]
All 16 colour gradients 8 colours per gradient from darkest (0) to lightest (7)
Rect WithHeight(int height, bool end=false) const
Copy Rect and set its height.
Data stored about a string that can be modified in the GUI.
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize)
Return the string dimension in pixels.
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
virtual void SetStringParameters(int widget) const
Initialize string parameters for a widget.
Padding dimensions to apply to each side of a Rect.
const NWID * GetWidget(uint widnum) const
Get the nested widget with number widnum from the nested widget tree.
Colours _company_colours[MAX_COMPANIES]
NOSAVE: can be determined from company structs.
Data structure for viewport, display of a part of the world.
@ FS_NORMAL
Index of the normal font in the font tables.
@ SA_TOP
Top align the text.
int height
Height of the window (number of pixels down in y direction)
@ WF_WHITE_BORDER
Window white border counter bit mask.
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
int left
Screen coordinate left edge of the viewport.
static T SB(T &x, const uint8 s, const uint8 n, const U d)
Set n bits in x starting at bit s to d.
static bool IsInsideBS(const T x, const size_t base, const size_t size)
Checks if a value is between a window started at some base point.
uint Horizontal() const
Get total horizontal padding of RectPadding.
Base class that provides memory initialization on dynamically created objects.
@ ES_NOT_HANDLED
The passed event is not handled.
static const PaletteID PALETTE_NEWSPAPER
Recolour sprite for newspaper-greying.
static int ScaleSpriteTrad(int value)
Scale traditional pixel dimensions to GUI zoom level, for drawing sprites.
static const byte _string_colourmap[17]
Colour mapping for TextColour.
const QueryString * GetQueryString(uint widnum) const
Return the querystring associated to a editbox.
@ SA_FORCE
Force the alignment, i.e. don't swap for RTL languages.
@ MAX_COMPANIES
Maximum number of companies.
uint TransparencyOptionBits
transparency option bits
int left
x position of left edge of the window
WindowFlags flags
Window flags.
Rect WithWidth(int width, bool end) const
Copy Rect and set its width.
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
int virtual_width
width << zoom
Coordinates of a point in 2D.
@ WF_HIGHLIGHTED
Window has a widget that has a highlight.
uint8 spacing
Extra spacing around lines.
void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen.
uint Vertical() const
Get total vertical padding of RectPadding.
int mouse_capture_widget
Widgetindex of current mouse capture widget (e.g. dragged scrollbar). -1 if no widget has mouse captu...
@ SA_HOR_CENTER
Horizontally center the text.
NWidgetBase ** nested_array
Array of pointers into the tree. Do not access directly, use Window::GetWidget() instead.
bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int height)
Set up a clipping area for only drawing into a certain area.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
uint32 StringID
Numeric value that represents a string, independent of the selected language.
@ SBS_DOWN
Sort ascending.
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
static int ScaleByZoom(int value, ZoomLevel zoom)
Scale by zoom level, usually shift left (when zoom > ZOOM_LVL_NORMAL) When shifting right,...
@ SA_VERT_MASK
Mask for vertical alignment.
bool IsShaded() const
Is window shaded currently?
#define FONT_HEIGHT_NORMAL
Height of characters in the normal (FS_NORMAL) font.
uint32 PaletteID
The number of the palette.
TextColour colour
TextColour for DrawString.
bool _window_highlight_colour
If false, highlight is white, otherwise the by the widget defined colour.
EventState
State of handling an event.
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
Update size and resize step of a widget in the window.
int top
y position of top edge of the window
void DrawViewport() const
Draw the viewport of this window.
@ SA_LEFT
Left align the text.
static int CenterBounds(int min, int max, int size)
Determine where to draw a centred object inside a widget.
@ SA_CENTER
Center both horizontally and vertically.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
int width
width of the window (number of pixels to the right in x direction)
ZoomLevel zoom
The zoom level of the viewport.
static int SortButtonWidth()
Get width of up/down arrow of sort button state.
@ FR_DARKENED
If set the background is darker, allows for lowered frames with normal background colour when used wi...
static uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
FontSize
Available font sizes.
Data structure for an opened window.
void DrawWidgets() const
Paint all widgets of a window.
@ ZOOM_LVL_OUT_4X
Zoomed 4 times out.
int virtual_height
height << zoom
int Width() const
Get width of Rect.
@ SBS_OFF
Do not sort (with this button).
uint nested_array_size
Size of the nested array.
bool scale_bevels
bevels are scaled with GUI scale.
Specification of a rectangle with absolute coordinates of all edges.
Point pos
logical mouse position
int GetRowFromWidget(int clickpos, int widget, int padding, int line_height=-1) const
Compute the row of a widget that a user clicked in.
void InitializeWindowViewport(Window *w, int x, int y, int width, int height, uint32 follow_flags, ZoomLevel zoom)
Initialize viewport of the window for use.
FontSize size
Font size of text lines.
@ TD_RTL
Text is written right-to-left by default.
TextDirection _current_text_dir
Text direction of the currently selected language.
int LeastCommonMultiple(int a, int b)
Compute least common multiple (lcm) of arguments a and b, the smallest integer value that is a multip...
GUISettings gui
settings related to the GUI
@ FR_BORDERONLY
Draw border only, no background.
Data about how and where to blit pixels.