mirror of https://github.com/OpenTTD/OpenTTD
Compare commits
3 Commits
628092f133
...
934545a674
Author | SHA1 | Date |
---|---|---|
|
934545a674 | |
|
7124b4eef1 | |
|
9a3934ae23 |
|
@ -675,7 +675,7 @@ void SetYearEngineAgingStops()
|
|||
* @param aging_date The date used for age calculations.
|
||||
* @param seed Random seed.
|
||||
*/
|
||||
void StartupOneEngine(Engine *e, TimerGameCalendar::Date aging_date, uint32_t seed)
|
||||
void StartupOneEngine(Engine *e, const TimerGameCalendar::YearMonthDay &aging_ymd, uint32_t seed)
|
||||
{
|
||||
const EngineInfo *ei = &e->info;
|
||||
|
||||
|
@ -699,7 +699,11 @@ void StartupOneEngine(Engine *e, TimerGameCalendar::Date aging_date, uint32_t se
|
|||
* Note: TTDP uses fixed 1922 */
|
||||
e->intro_date = ei->base_intro <= TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year + 2, 0, 1) ? ei->base_intro : (TimerGameCalendar::Date)GB(r, 0, 9) + ei->base_intro;
|
||||
if (e->intro_date <= TimerGameCalendar::date) {
|
||||
e->age = (aging_date - e->intro_date).base() >> 5;
|
||||
TimerGameCalendar::YearMonthDay intro_ymd = TimerGameCalendar::ConvertDateToYMD(e->intro_date);
|
||||
int aging_months = aging_ymd.year.base() * 12 + aging_ymd.month;
|
||||
int intro_months = intro_ymd.year.base() * 12 + intro_ymd.month;
|
||||
if (intro_ymd.day > 1) intro_months++; // Engines are introduced at the first month start at/after intro date.
|
||||
e->age = aging_months - intro_months;
|
||||
e->company_avail = MAX_UVALUE(CompanyMask);
|
||||
e->flags |= ENGINE_AVAILABLE;
|
||||
}
|
||||
|
@ -756,10 +760,11 @@ void StartupEngines()
|
|||
{
|
||||
/* Aging of vehicles stops, so account for that when starting late */
|
||||
const TimerGameCalendar::Date aging_date = std::min(TimerGameCalendar::date, TimerGameCalendar::ConvertYMDToDate(_year_engine_aging_stops, 0, 1));
|
||||
TimerGameCalendar::YearMonthDay aging_ymd = TimerGameCalendar::ConvertDateToYMD(aging_date);
|
||||
uint32_t seed = Random();
|
||||
|
||||
for (Engine *e : Engine::Iterate()) {
|
||||
StartupOneEngine(e, aging_date, seed);
|
||||
StartupOneEngine(e, aging_ymd, seed);
|
||||
}
|
||||
for (Engine *e : Engine::Iterate()) {
|
||||
CalcEngineReliability(e, false);
|
||||
|
|
|
@ -27,7 +27,7 @@ bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company);
|
|||
bool IsEngineRefittable(EngineID engine);
|
||||
void SetYearEngineAgingStops();
|
||||
void CalcEngineReliability(Engine *e, bool new_month);
|
||||
void StartupOneEngine(Engine *e, TimerGameCalendar::Date aging_date, uint32_t seed);
|
||||
void StartupOneEngine(Engine *e, const TimerGameCalendar::YearMonthDay &aging_ymd, uint32_t seed);
|
||||
|
||||
uint GetTotalCapacityOfArticulatedParts(EngineID engine);
|
||||
|
||||
|
|
|
@ -109,19 +109,19 @@ struct GraphLegendWindow : Window {
|
|||
* Construct a vertical list of buttons, one for each company.
|
||||
* @return Panel with company buttons.
|
||||
*/
|
||||
static NWidgetBase *MakeNWidgetCompanyLines()
|
||||
static std::unique_ptr<NWidgetBase> MakeNWidgetCompanyLines()
|
||||
{
|
||||
NWidgetVertical *vert = new NWidgetVertical(NC_EQUALSIZE);
|
||||
auto vert = std::make_unique<NWidgetVertical>(NC_EQUALSIZE);
|
||||
vert->SetPadding(2, 2, 2, 2);
|
||||
uint sprite_height = GetSpriteSize(SPR_COMPANY_ICON, nullptr, ZOOM_LVL_OUT_4X).height;
|
||||
|
||||
for (WidgetID widnum = WID_GL_FIRST_COMPANY; widnum <= WID_GL_LAST_COMPANY; widnum++) {
|
||||
NWidgetBackground *panel = new NWidgetBackground(WWT_PANEL, COLOUR_BROWN, widnum);
|
||||
auto panel = std::make_unique<NWidgetBackground>(WWT_PANEL, COLOUR_BROWN, widnum);
|
||||
panel->SetMinimalSize(246, sprite_height + WidgetDimensions::unscaled.framerect.Vertical());
|
||||
panel->SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical(), FS_NORMAL);
|
||||
panel->SetFill(1, 1);
|
||||
panel->SetDataTip(0x0, STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP);
|
||||
vert->Add(panel);
|
||||
vert->Add(std::move(panel));
|
||||
}
|
||||
return vert;
|
||||
}
|
||||
|
@ -1337,7 +1337,7 @@ CompanyID PerformanceRatingDetailWindow::company = INVALID_COMPANY;
|
|||
* Make a vertical list of panels for outputting score details.
|
||||
* @return Panel with performance details.
|
||||
*/
|
||||
static NWidgetBase *MakePerformanceDetailPanels()
|
||||
static std::unique_ptr<NWidgetBase> MakePerformanceDetailPanels()
|
||||
{
|
||||
const StringID performance_tips[] = {
|
||||
STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP,
|
||||
|
@ -1354,18 +1354,18 @@ static NWidgetBase *MakePerformanceDetailPanels()
|
|||
|
||||
static_assert(lengthof(performance_tips) == SCORE_END - SCORE_BEGIN);
|
||||
|
||||
NWidgetVertical *vert = new NWidgetVertical(NC_EQUALSIZE);
|
||||
auto vert = std::make_unique<NWidgetVertical>(NC_EQUALSIZE);
|
||||
for (WidgetID widnum = WID_PRD_SCORE_FIRST; widnum <= WID_PRD_SCORE_LAST; widnum++) {
|
||||
NWidgetBackground *panel = new NWidgetBackground(WWT_PANEL, COLOUR_BROWN, widnum);
|
||||
auto panel = std::make_unique<NWidgetBackground>(WWT_PANEL, COLOUR_BROWN, widnum);
|
||||
panel->SetFill(1, 1);
|
||||
panel->SetDataTip(0x0, performance_tips[widnum - WID_PRD_SCORE_FIRST]);
|
||||
vert->Add(panel);
|
||||
vert->Add(std::move(panel));
|
||||
}
|
||||
return vert;
|
||||
}
|
||||
|
||||
/** Make a number of rows with buttons for each company for the performance rating detail window. */
|
||||
NWidgetBase *MakeCompanyButtonRowsGraphGUI()
|
||||
std::unique_ptr<NWidgetBase> MakeCompanyButtonRowsGraphGUI()
|
||||
{
|
||||
return MakeCompanyButtonRows(WID_PRD_COMPANY_FIRST, WID_PRD_COMPANY_LAST, COLOUR_BROWN, 8, STR_PERFORMANCE_DETAIL_SELECT_COMPANY_TOOLTIP);
|
||||
}
|
||||
|
|
|
@ -454,54 +454,54 @@ void LinkGraphOverlay::SetCompanyMask(CompanyMask company_mask)
|
|||
}
|
||||
|
||||
/** Make a number of rows with buttons for each company for the linkgraph legend window. */
|
||||
NWidgetBase *MakeCompanyButtonRowsLinkGraphGUI()
|
||||
std::unique_ptr<NWidgetBase> MakeCompanyButtonRowsLinkGraphGUI()
|
||||
{
|
||||
return MakeCompanyButtonRows(WID_LGL_COMPANY_FIRST, WID_LGL_COMPANY_LAST, COLOUR_GREY, 3, STR_NULL);
|
||||
}
|
||||
|
||||
NWidgetBase *MakeSaturationLegendLinkGraphGUI()
|
||||
std::unique_ptr<NWidgetBase> MakeSaturationLegendLinkGraphGUI()
|
||||
{
|
||||
NWidgetVertical *panel = new NWidgetVertical(NC_EQUALSIZE);
|
||||
auto panel = std::make_unique<NWidgetVertical>(NC_EQUALSIZE);
|
||||
for (uint i = 0; i < lengthof(LinkGraphOverlay::LINK_COLOURS[0]); ++i) {
|
||||
NWidgetBackground * wid = new NWidgetBackground(WWT_PANEL, COLOUR_DARK_GREEN, i + WID_LGL_SATURATION_FIRST);
|
||||
auto wid = std::make_unique<NWidgetBackground>(WWT_PANEL, COLOUR_DARK_GREEN, i + WID_LGL_SATURATION_FIRST);
|
||||
wid->SetMinimalSize(50, 0);
|
||||
wid->SetMinimalTextLines(1, 0, FS_SMALL);
|
||||
wid->SetFill(1, 1);
|
||||
wid->SetResize(0, 0);
|
||||
panel->Add(wid);
|
||||
panel->Add(std::move(wid));
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
|
||||
NWidgetBase *MakeCargoesLegendLinkGraphGUI()
|
||||
std::unique_ptr<NWidgetBase> MakeCargoesLegendLinkGraphGUI()
|
||||
{
|
||||
uint num_cargo = static_cast<uint>(_sorted_cargo_specs.size());
|
||||
static const uint ENTRIES_PER_COL = 5;
|
||||
NWidgetHorizontal *panel = new NWidgetHorizontal(NC_EQUALSIZE);
|
||||
NWidgetVertical *col = nullptr;
|
||||
auto panel = std::make_unique<NWidgetHorizontal>(NC_EQUALSIZE);
|
||||
std::unique_ptr<NWidgetVertical> col = nullptr;
|
||||
|
||||
for (uint i = 0; i < num_cargo; ++i) {
|
||||
if (i % ENTRIES_PER_COL == 0) {
|
||||
if (col != nullptr) panel->Add(col);
|
||||
col = new NWidgetVertical(NC_EQUALSIZE);
|
||||
if (col != nullptr) panel->Add(std::move(col));
|
||||
col = std::make_unique<NWidgetVertical>(NC_EQUALSIZE);
|
||||
}
|
||||
NWidgetBackground * wid = new NWidgetBackground(WWT_PANEL, COLOUR_GREY, i + WID_LGL_CARGO_FIRST);
|
||||
auto wid = std::make_unique<NWidgetBackground>(WWT_PANEL, COLOUR_GREY, i + WID_LGL_CARGO_FIRST);
|
||||
wid->SetMinimalSize(25, 0);
|
||||
wid->SetMinimalTextLines(1, 0, FS_SMALL);
|
||||
wid->SetFill(1, 1);
|
||||
wid->SetResize(0, 0);
|
||||
col->Add(wid);
|
||||
col->Add(std::move(wid));
|
||||
}
|
||||
/* Fill up last row */
|
||||
for (uint i = num_cargo; i < Ceil(num_cargo, ENTRIES_PER_COL); ++i) {
|
||||
NWidgetSpacer *spc = new NWidgetSpacer(25, 0);
|
||||
auto spc = std::make_unique<NWidgetSpacer>(25, 0);
|
||||
spc->SetMinimalTextLines(1, 0, FS_SMALL);
|
||||
spc->SetFill(1, 1);
|
||||
spc->SetResize(0, 0);
|
||||
col->Add(spc);
|
||||
col->Add(std::move(spc));
|
||||
}
|
||||
/* If there are no cargo specs defined, then col won't have been created so don't add it. */
|
||||
if (col != nullptr) panel->Add(col);
|
||||
if (col != nullptr) panel->Add(std::move(col));
|
||||
return panel;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,21 +89,21 @@ class NWidgetServerListHeader : public NWidgetContainer {
|
|||
public:
|
||||
NWidgetServerListHeader() : NWidgetContainer(NWID_HORIZONTAL)
|
||||
{
|
||||
NWidgetLeaf *leaf = new NWidgetLeaf(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_NAME, STR_NETWORK_SERVER_LIST_GAME_NAME, STR_NETWORK_SERVER_LIST_GAME_NAME_TOOLTIP);
|
||||
auto leaf = std::make_unique<NWidgetLeaf>(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_NAME, STR_NETWORK_SERVER_LIST_GAME_NAME, STR_NETWORK_SERVER_LIST_GAME_NAME_TOOLTIP);
|
||||
leaf->SetResize(1, 0);
|
||||
leaf->SetFill(1, 0);
|
||||
this->Add(leaf);
|
||||
this->Add(std::move(leaf));
|
||||
|
||||
this->Add(new NWidgetLeaf(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_CLIENTS, STR_NETWORK_SERVER_LIST_CLIENTS_CAPTION, STR_NETWORK_SERVER_LIST_CLIENTS_CAPTION_TOOLTIP));
|
||||
this->Add(new NWidgetLeaf(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_MAPSIZE, STR_NETWORK_SERVER_LIST_MAP_SIZE_CAPTION, STR_NETWORK_SERVER_LIST_MAP_SIZE_CAPTION_TOOLTIP));
|
||||
this->Add(new NWidgetLeaf(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_DATE, STR_NETWORK_SERVER_LIST_DATE_CAPTION, STR_NETWORK_SERVER_LIST_DATE_CAPTION_TOOLTIP));
|
||||
this->Add(new NWidgetLeaf(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_YEARS, STR_NETWORK_SERVER_LIST_YEARS_CAPTION, STR_NETWORK_SERVER_LIST_YEARS_CAPTION_TOOLTIP));
|
||||
this->Add(std::make_unique<NWidgetLeaf>(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_CLIENTS, STR_NETWORK_SERVER_LIST_CLIENTS_CAPTION, STR_NETWORK_SERVER_LIST_CLIENTS_CAPTION_TOOLTIP));
|
||||
this->Add(std::make_unique<NWidgetLeaf>(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_MAPSIZE, STR_NETWORK_SERVER_LIST_MAP_SIZE_CAPTION, STR_NETWORK_SERVER_LIST_MAP_SIZE_CAPTION_TOOLTIP));
|
||||
this->Add(std::make_unique<NWidgetLeaf>(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_DATE, STR_NETWORK_SERVER_LIST_DATE_CAPTION, STR_NETWORK_SERVER_LIST_DATE_CAPTION_TOOLTIP));
|
||||
this->Add(std::make_unique<NWidgetLeaf>(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_YEARS, STR_NETWORK_SERVER_LIST_YEARS_CAPTION, STR_NETWORK_SERVER_LIST_YEARS_CAPTION_TOOLTIP));
|
||||
|
||||
leaf = new NWidgetLeaf(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_INFO, STR_EMPTY, STR_NETWORK_SERVER_LIST_INFO_ICONS_TOOLTIP);
|
||||
leaf = std::make_unique<NWidgetLeaf>(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_INFO, STR_EMPTY, STR_NETWORK_SERVER_LIST_INFO_ICONS_TOOLTIP);
|
||||
leaf->SetMinimalSize(14 + GetSpriteSize(SPR_LOCK, nullptr, ZOOM_LVL_OUT_4X).width
|
||||
+ GetSpriteSize(SPR_BLOT, nullptr, ZOOM_LVL_OUT_4X).width, 12);
|
||||
leaf->SetFill(0, 1);
|
||||
this->Add(leaf);
|
||||
this->Add(std::move(leaf));
|
||||
}
|
||||
|
||||
void SetupSmallestSize(Window *w) override
|
||||
|
@ -115,18 +115,18 @@ public:
|
|||
this->resize_y = 0; // We never resize in this direction
|
||||
|
||||
/* First initialise some variables... */
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
child_wid->SetupSmallestSize(w);
|
||||
this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.Vertical());
|
||||
}
|
||||
|
||||
/* ... then in a second pass make sure the 'current' sizes are set. Won't change for most widgets. */
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
child_wid->current_x = child_wid->smallest_x;
|
||||
child_wid->current_y = this->smallest_y;
|
||||
}
|
||||
|
||||
this->smallest_x = this->head->smallest_x + this->tail->smallest_x; // First and last are always shown, rest not
|
||||
this->smallest_x = this->children.front()->smallest_x + this->children.back()->smallest_x; // First and last are always shown, rest not
|
||||
}
|
||||
|
||||
void AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl) override
|
||||
|
@ -138,27 +138,38 @@ public:
|
|||
this->current_x = given_width;
|
||||
this->current_y = given_height;
|
||||
|
||||
given_width -= this->tail->smallest_x;
|
||||
given_width -= this->children.back()->smallest_x;
|
||||
/* The first and last widget are always visible, determine which other should be visible */
|
||||
for (NWidgetBase *child_wid = this->head->next; child_wid->next != nullptr; child_wid = child_wid->next) {
|
||||
if (given_width > ScaleGUITrad(MINIMUM_NAME_WIDTH_BEFORE_NEW_HEADER) + child_wid->smallest_x && child_wid->prev->current_x != 0) {
|
||||
given_width -= child_wid->smallest_x;
|
||||
child_wid->current_x = child_wid->smallest_x; /* Make visible. */
|
||||
} else {
|
||||
child_wid->current_x = 0; /* Make invisible. */
|
||||
if (this->children.size() > 2) {
|
||||
auto first = std::next(std::begin(this->children));
|
||||
auto last = std::prev(std::end(this->children));
|
||||
for (auto it = first; it != last; ++it) {
|
||||
auto &child_wid = *it;
|
||||
if (given_width > ScaleGUITrad(MINIMUM_NAME_WIDTH_BEFORE_NEW_HEADER) + child_wid->smallest_x && (*std::prev(it))->current_x != 0) {
|
||||
given_width -= child_wid->smallest_x;
|
||||
child_wid->current_x = child_wid->smallest_x; /* Make visible. */
|
||||
} else {
|
||||
child_wid->current_x = 0; /* Make invisible. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* All remaining space goes to the first (name) widget */
|
||||
this->head->current_x = given_width;
|
||||
this->children.front()->current_x = given_width;
|
||||
|
||||
/* Now assign the widgets to their rightful place */
|
||||
uint position = 0; // Place to put next child relative to origin of the container.
|
||||
for (NWidgetBase *child_wid = rtl ? this->tail : this->head; child_wid != nullptr; child_wid = rtl ? child_wid->prev : child_wid->next) {
|
||||
auto assign_position = [&](const std::unique_ptr<NWidgetBase> &child_wid) {
|
||||
if (child_wid->current_x != 0) {
|
||||
child_wid->AssignSizePosition(sizing, x + position, y, child_wid->current_x, this->current_y, rtl);
|
||||
position += child_wid->current_x;
|
||||
}
|
||||
};
|
||||
|
||||
if (rtl) {
|
||||
std::for_each(std::rbegin(this->children), std::rend(this->children), assign_position);
|
||||
} else {
|
||||
std::for_each(std::begin(this->children), std::end(this->children), assign_position);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -855,9 +866,9 @@ GUIGameServerList::FilterFunction * const NetworkGameWindow::filter_funcs[] = {
|
|||
&NGameSearchFilter
|
||||
};
|
||||
|
||||
static NWidgetBase *MakeResizableHeader()
|
||||
static std::unique_ptr<NWidgetBase> MakeResizableHeader()
|
||||
{
|
||||
return new NWidgetServerListHeader();
|
||||
return std::make_unique<NWidgetServerListHeader>();
|
||||
}
|
||||
|
||||
static const NWidgetPart _nested_network_game_widgets[] = {
|
||||
|
|
|
@ -1600,27 +1600,22 @@ NewGRFWindow::GUIGRFConfigList::FilterFunction * const NewGRFWindow::filter_func
|
|||
* - two column mode, put the #acs and the #avs underneath each other and the #inf next to it, or
|
||||
* - three column mode, put the #avs, #acs, and #inf each in its own column.
|
||||
*/
|
||||
class NWidgetNewGRFDisplay : public NWidgetContainer {
|
||||
class NWidgetNewGRFDisplay : public NWidgetBase {
|
||||
public:
|
||||
static const uint MAX_EXTRA_INFO_WIDTH; ///< Maximal additional width given to the panel.
|
||||
static const uint MIN_EXTRA_FOR_3_COLUMNS; ///< Minimal additional width needed before switching to 3 columns.
|
||||
|
||||
NWidgetBase *avs; ///< Widget with the available grfs list and buttons.
|
||||
NWidgetBase *acs; ///< Widget with the active grfs list and buttons.
|
||||
NWidgetBase *inf; ///< Info panel.
|
||||
std::unique_ptr<NWidgetBase> avs; ///< Widget with the available grfs list and buttons.
|
||||
std::unique_ptr<NWidgetBase> acs; ///< Widget with the active grfs list and buttons.
|
||||
std::unique_ptr<NWidgetBase> inf; ///< Info panel.
|
||||
bool editable; ///< Editable status of the parent NewGRF window (if \c false, drop all widgets that make the window editable).
|
||||
|
||||
NWidgetNewGRFDisplay(NWidgetBase *avs, NWidgetBase *acs, NWidgetBase *inf) : NWidgetContainer(NWID_HORIZONTAL)
|
||||
NWidgetNewGRFDisplay(std::unique_ptr<NWidgetBase> &&avs, std::unique_ptr<NWidgetBase> &&acs, std::unique_ptr<NWidgetBase> &&inf) : NWidgetBase(NWID_CUSTOM)
|
||||
, avs(std::move(avs))
|
||||
, acs(std::move(acs))
|
||||
, inf(std::move(inf))
|
||||
, editable(true) // Temporary setting, 'real' value is set in SetupSmallestSize().
|
||||
{
|
||||
this->avs = avs;
|
||||
this->acs = acs;
|
||||
this->inf = inf;
|
||||
|
||||
this->Add(this->avs);
|
||||
this->Add(this->acs);
|
||||
this->Add(this->inf);
|
||||
|
||||
this->editable = true; // Temporary setting, 'real' value is set in SetupSmallestSize().
|
||||
}
|
||||
|
||||
void SetupSmallestSize(Window *w) override
|
||||
|
@ -1785,6 +1780,13 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void FillWidgetLookup(WidgetLookup &widget_lookup) override
|
||||
{
|
||||
this->avs->FillWidgetLookup(widget_lookup);
|
||||
this->acs->FillWidgetLookup(widget_lookup);
|
||||
this->inf->FillWidgetLookup(widget_lookup);
|
||||
}
|
||||
|
||||
NWidgetCore *GetWidgetFromPos(int x, int y) override
|
||||
{
|
||||
if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return nullptr;
|
||||
|
@ -1937,13 +1939,13 @@ static const NWidgetPart _nested_newgrf_infopanel_widgets[] = {
|
|||
};
|
||||
|
||||
/** Construct nested container widget for managing the lists and the info panel of the NewGRF GUI. */
|
||||
NWidgetBase* NewGRFDisplay()
|
||||
std::unique_ptr<NWidgetBase> NewGRFDisplay()
|
||||
{
|
||||
NWidgetBase *avs = MakeNWidgets(std::begin(_nested_newgrf_availables_widgets), std::end(_nested_newgrf_availables_widgets), nullptr);
|
||||
NWidgetBase *acs = MakeNWidgets(std::begin(_nested_newgrf_actives_widgets), std::end(_nested_newgrf_actives_widgets), nullptr);
|
||||
NWidgetBase *inf = MakeNWidgets(std::begin(_nested_newgrf_infopanel_widgets), std::end(_nested_newgrf_infopanel_widgets), nullptr);
|
||||
std::unique_ptr<NWidgetBase> avs = MakeNWidgets(std::begin(_nested_newgrf_availables_widgets), std::end(_nested_newgrf_availables_widgets), nullptr);
|
||||
std::unique_ptr<NWidgetBase> acs = MakeNWidgets(std::begin(_nested_newgrf_actives_widgets), std::end(_nested_newgrf_actives_widgets), nullptr);
|
||||
std::unique_ptr<NWidgetBase> inf = MakeNWidgets(std::begin(_nested_newgrf_infopanel_widgets), std::end(_nested_newgrf_infopanel_widgets), nullptr);
|
||||
|
||||
return new NWidgetNewGRFDisplay(avs, acs, inf);
|
||||
return std::make_unique<NWidgetNewGRFDisplay>(std::move(avs), std::move(acs), std::move(inf));
|
||||
}
|
||||
|
||||
/* Widget definition of the manage newgrfs window */
|
||||
|
|
|
@ -222,32 +222,32 @@ static const int KEY_PADDING = 6; // Vertical padding for remaining key rows
|
|||
* @param widdata Data value of the key widget.
|
||||
* @note Key width is measured in 1/2 keys to allow for 1/2 key shifting between rows.
|
||||
*/
|
||||
static void AddKey(NWidgetHorizontal *hor, int pad_y, int num_half, WidgetType widtype, WidgetID widnum, uint16_t widdata)
|
||||
static void AddKey(std::unique_ptr<NWidgetHorizontal> &hor, int pad_y, int num_half, WidgetType widtype, WidgetID widnum, uint16_t widdata)
|
||||
{
|
||||
int key_width = HALF_KEY_WIDTH + (INTER_KEY_SPACE + HALF_KEY_WIDTH) * (num_half - 1);
|
||||
|
||||
if (widtype == NWID_SPACER) {
|
||||
if (!hor->IsEmpty()) key_width += INTER_KEY_SPACE;
|
||||
NWidgetSpacer *spc = new NWidgetSpacer(key_width, 0);
|
||||
auto spc = std::make_unique<NWidgetSpacer>(key_width, 0);
|
||||
spc->SetMinimalTextLines(1, pad_y, FS_NORMAL);
|
||||
hor->Add(spc);
|
||||
hor->Add(std::move(spc));
|
||||
} else {
|
||||
if (!hor->IsEmpty()) {
|
||||
NWidgetSpacer *spc = new NWidgetSpacer(INTER_KEY_SPACE, 0);
|
||||
auto spc = std::make_unique<NWidgetSpacer>(INTER_KEY_SPACE, 0);
|
||||
spc->SetMinimalTextLines(1, pad_y, FS_NORMAL);
|
||||
hor->Add(spc);
|
||||
hor->Add(std::move(spc));
|
||||
}
|
||||
NWidgetLeaf *leaf = new NWidgetLeaf(widtype, COLOUR_GREY, widnum, widdata, STR_NULL);
|
||||
auto leaf = std::make_unique<NWidgetLeaf>(widtype, COLOUR_GREY, widnum, widdata, STR_NULL);
|
||||
leaf->SetMinimalSize(key_width, 0);
|
||||
leaf->SetMinimalTextLines(1, pad_y, FS_NORMAL);
|
||||
hor->Add(leaf);
|
||||
hor->Add(std::move(leaf));
|
||||
}
|
||||
}
|
||||
|
||||
/** Construct the top row keys (cancel, ok, backspace). */
|
||||
static NWidgetBase *MakeTopKeys()
|
||||
static std::unique_ptr<NWidgetBase> MakeTopKeys()
|
||||
{
|
||||
NWidgetHorizontal *hor = new NWidgetHorizontal();
|
||||
auto hor = std::make_unique<NWidgetHorizontal>();
|
||||
|
||||
AddKey(hor, TOP_KEY_PADDING, 6 * 2, WWT_TEXTBTN, WID_OSK_CANCEL, STR_BUTTON_CANCEL);
|
||||
AddKey(hor, TOP_KEY_PADDING, 6 * 2, WWT_TEXTBTN, WID_OSK_OK, STR_BUTTON_OK );
|
||||
|
@ -256,9 +256,9 @@ static NWidgetBase *MakeTopKeys()
|
|||
}
|
||||
|
||||
/** Construct the row containing the digit keys. */
|
||||
static NWidgetBase *MakeNumberKeys()
|
||||
static std::unique_ptr<NWidgetBase> MakeNumberKeys()
|
||||
{
|
||||
NWidgetHorizontal *hor = new NWidgetHorizontalLTR();
|
||||
std::unique_ptr<NWidgetHorizontal> hor = std::make_unique<NWidgetHorizontalLTR>();
|
||||
|
||||
for (WidgetID widnum = WID_OSK_NUMBERS_FIRST; widnum <= WID_OSK_NUMBERS_LAST; widnum++) {
|
||||
AddKey(hor, KEY_PADDING, 2, WWT_PUSHBTN, widnum, 0x0);
|
||||
|
@ -267,9 +267,9 @@ static NWidgetBase *MakeNumberKeys()
|
|||
}
|
||||
|
||||
/** Construct the qwerty row keys. */
|
||||
static NWidgetBase *MakeQwertyKeys()
|
||||
static std::unique_ptr<NWidgetBase> MakeQwertyKeys()
|
||||
{
|
||||
NWidgetHorizontal *hor = new NWidgetHorizontalLTR();
|
||||
std::unique_ptr<NWidgetHorizontal> hor = std::make_unique<NWidgetHorizontalLTR>();
|
||||
|
||||
AddKey(hor, KEY_PADDING, 3, WWT_PUSHIMGBTN, WID_OSK_SPECIAL, SPR_OSK_SPECIAL);
|
||||
for (WidgetID widnum = WID_OSK_QWERTY_FIRST; widnum <= WID_OSK_QWERTY_LAST; widnum++) {
|
||||
|
@ -280,9 +280,9 @@ static NWidgetBase *MakeQwertyKeys()
|
|||
}
|
||||
|
||||
/** Construct the asdfg row keys. */
|
||||
static NWidgetBase *MakeAsdfgKeys()
|
||||
static std::unique_ptr<NWidgetBase> MakeAsdfgKeys()
|
||||
{
|
||||
NWidgetHorizontal *hor = new NWidgetHorizontalLTR();
|
||||
std::unique_ptr<NWidgetHorizontal> hor = std::make_unique<NWidgetHorizontalLTR>();
|
||||
|
||||
AddKey(hor, KEY_PADDING, 4, WWT_IMGBTN, WID_OSK_CAPS, SPR_OSK_CAPS);
|
||||
for (WidgetID widnum = WID_OSK_ASDFG_FIRST; widnum <= WID_OSK_ASDFG_LAST; widnum++) {
|
||||
|
@ -292,9 +292,9 @@ static NWidgetBase *MakeAsdfgKeys()
|
|||
}
|
||||
|
||||
/** Construct the zxcvb row keys. */
|
||||
static NWidgetBase *MakeZxcvbKeys()
|
||||
static std::unique_ptr<NWidgetBase> MakeZxcvbKeys()
|
||||
{
|
||||
NWidgetHorizontal *hor = new NWidgetHorizontalLTR();
|
||||
std::unique_ptr<NWidgetHorizontal> hor = std::make_unique<NWidgetHorizontalLTR>();
|
||||
|
||||
AddKey(hor, KEY_PADDING, 3, WWT_IMGBTN, WID_OSK_SHIFT, SPR_OSK_SHIFT);
|
||||
for (WidgetID widnum = WID_OSK_ZXCVB_FIRST; widnum <= WID_OSK_ZXCVB_LAST; widnum++) {
|
||||
|
@ -305,9 +305,9 @@ static NWidgetBase *MakeZxcvbKeys()
|
|||
}
|
||||
|
||||
/** Construct the spacebar row keys. */
|
||||
static NWidgetBase *MakeSpacebarKeys()
|
||||
static std::unique_ptr<NWidgetBase> MakeSpacebarKeys()
|
||||
{
|
||||
NWidgetHorizontal *hor = new NWidgetHorizontal();
|
||||
auto hor = std::make_unique<NWidgetHorizontal>();
|
||||
|
||||
AddKey(hor, KEY_PADDING, 8, NWID_SPACER, 0, 0);
|
||||
AddKey(hor, KEY_PADDING, 13, WWT_PUSHTXTBTN, WID_OSK_SPACE, STR_EMPTY);
|
||||
|
|
|
@ -399,6 +399,7 @@ static bool FixTTOEngines()
|
|||
}
|
||||
|
||||
TimerGameCalendar::Date aging_date = std::min(TimerGameCalendar::date + CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR, TimerGameCalendar::ConvertYMDToDate(2050, 0, 1));
|
||||
TimerGameCalendar::YearMonthDay aging_ymd = TimerGameCalendar::ConvertDateToYMD(aging_date);
|
||||
|
||||
for (EngineID i = 0; i < 256; i++) {
|
||||
int oi = ttd_to_tto[i];
|
||||
|
@ -407,7 +408,7 @@ static bool FixTTOEngines()
|
|||
if (oi == 255) {
|
||||
/* Default engine is used */
|
||||
TimerGameCalendar::date += CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR;
|
||||
StartupOneEngine(e, aging_date, 0);
|
||||
StartupOneEngine(e, aging_ymd, 0);
|
||||
CalcEngineReliability(e, false);
|
||||
e->intro_date -= CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR;
|
||||
TimerGameCalendar::date -= CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR;
|
||||
|
|
|
@ -1229,7 +1229,7 @@ struct ScriptDebugWindow : public Window {
|
|||
};
|
||||
|
||||
/** Make a number of rows with buttons for each company for the Script debug window. */
|
||||
NWidgetBase *MakeCompanyButtonRowsScriptDebug()
|
||||
std::unique_ptr<NWidgetBase> MakeCompanyButtonRowsScriptDebug()
|
||||
{
|
||||
return MakeCompanyButtonRows(WID_SCRD_COMPANY_BUTTON_START, WID_SCRD_COMPANY_BUTTON_END, COLOUR_GREY, 8, STR_AI_DEBUG_SELECT_AI_TOOLTIP);
|
||||
}
|
||||
|
|
|
@ -1852,8 +1852,9 @@ public:
|
|||
|
||||
void SetupSmallestSize(Window *w) override
|
||||
{
|
||||
NWidgetBase *display = this->head;
|
||||
NWidgetBase *bar = display->next;
|
||||
assert(this->children.size() == 2);
|
||||
NWidgetBase *display = this->children.front().get();
|
||||
NWidgetBase *bar = this->children.back().get();
|
||||
|
||||
display->SetupSmallestSize(w);
|
||||
bar->SetupSmallestSize(w);
|
||||
|
@ -1875,8 +1876,9 @@ public:
|
|||
this->current_x = given_width;
|
||||
this->current_y = given_height;
|
||||
|
||||
NWidgetBase *display = this->head;
|
||||
NWidgetBase *bar = display->next;
|
||||
assert(this->children.size() == 2);
|
||||
NWidgetBase *display = this->children.front().get();
|
||||
NWidgetBase *bar = this->children.back().get();
|
||||
|
||||
if (sizing == ST_SMALLEST) {
|
||||
this->smallest_x = given_width;
|
||||
|
@ -1942,12 +1944,12 @@ static const NWidgetPart _nested_smallmap_bar[] = {
|
|||
EndContainer(),
|
||||
};
|
||||
|
||||
static NWidgetBase *SmallMapDisplay()
|
||||
static std::unique_ptr<NWidgetBase> SmallMapDisplay()
|
||||
{
|
||||
NWidgetContainer *map_display = new NWidgetSmallmapDisplay;
|
||||
std::unique_ptr<NWidgetBase> map_display = std::make_unique<NWidgetSmallmapDisplay>();
|
||||
|
||||
MakeNWidgets(std::begin(_nested_smallmap_display), std::end(_nested_smallmap_display), map_display);
|
||||
MakeNWidgets(std::begin(_nested_smallmap_bar), std::end(_nested_smallmap_bar), map_display);
|
||||
map_display = MakeNWidgets(std::begin(_nested_smallmap_display), std::end(_nested_smallmap_display), std::move(map_display));
|
||||
map_display = MakeNWidgets(std::begin(_nested_smallmap_bar), std::end(_nested_smallmap_bar), std::move(map_display));
|
||||
return map_display;
|
||||
}
|
||||
|
||||
|
|
|
@ -716,18 +716,18 @@ const StringID CompanyStationsWindow::sorter_names[] = {
|
|||
* Make a horizontal row of cargo buttons, starting at widget #WID_STL_CARGOSTART.
|
||||
* @return Horizontal row.
|
||||
*/
|
||||
static NWidgetBase *CargoWidgets()
|
||||
static std::unique_ptr<NWidgetBase> CargoWidgets()
|
||||
{
|
||||
NWidgetHorizontal *container = new NWidgetHorizontal();
|
||||
auto container = std::make_unique<NWidgetHorizontal>();
|
||||
|
||||
for (uint i = 0; i < _sorted_standard_cargo_specs.size(); i++) {
|
||||
NWidgetBackground *panel = new NWidgetBackground(WWT_PANEL, COLOUR_GREY, WID_STL_CARGOSTART + i);
|
||||
auto panel = std::make_unique<NWidgetBackground>(WWT_PANEL, COLOUR_GREY, WID_STL_CARGOSTART + i);
|
||||
panel->SetMinimalSize(14, 0);
|
||||
panel->SetMinimalTextLines(1, 0, FS_NORMAL);
|
||||
panel->SetResize(0, 0);
|
||||
panel->SetFill(0, 1);
|
||||
panel->SetDataTip(0, STR_STATION_LIST_USE_CTRL_TO_SELECT_MORE);
|
||||
container->Add(panel);
|
||||
container->Add(std::move(panel));
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
|
|
@ -90,9 +90,8 @@ TEST_CASE_METHOD(WindowDescTestsFixture, "WindowDesc - NWidgetPart validity")
|
|||
INFO(fmt::format("{}:{}", window_desc->file, window_desc->line));
|
||||
|
||||
NWidgetStacked *shade_select = nullptr;
|
||||
NWidgetBase *root = nullptr;
|
||||
std::unique_ptr<NWidgetBase> root = nullptr;
|
||||
|
||||
REQUIRE_NOTHROW(root = MakeWindowNWidgetTree(window_desc->nwid_begin, window_desc->nwid_end, &shade_select));
|
||||
CHECK((root != nullptr));
|
||||
delete root;
|
||||
}
|
||||
|
|
|
@ -1347,7 +1347,7 @@ public:
|
|||
|
||||
uint nbuttons = 0;
|
||||
/* First initialise some variables... */
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
child_wid->SetupSmallestSize(w);
|
||||
this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.Vertical());
|
||||
if (this->IsButton(child_wid->type)) {
|
||||
|
@ -1359,7 +1359,7 @@ public:
|
|||
}
|
||||
|
||||
/* ... then in a second pass make sure the 'current' heights are set. Won't change ever. */
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
child_wid->current_y = this->smallest_y;
|
||||
if (!this->IsButton(child_wid->type)) {
|
||||
child_wid->current_x = child_wid->smallest_x;
|
||||
|
@ -1381,12 +1381,13 @@ public:
|
|||
uint arrangable_count, button_count, spacer_count;
|
||||
const WidgetID *arrangement = GetButtonArrangement(given_width, arrangable_count, button_count, spacer_count);
|
||||
|
||||
/* Create us ourselves a quick lookup table */
|
||||
NWidgetBase *widgets[WID_TN_END];
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
child_wid->current_x = 0; /* Hide widget, it will be revealed in the next step. */
|
||||
if (child_wid->type == NWID_SPACER) continue;
|
||||
widgets[((NWidgetCore*)child_wid)->index] = child_wid;
|
||||
/* Create us ourselves a quick lookup table from WidgetID to slot. */
|
||||
std::map<WidgetID, uint> lookup;
|
||||
for (auto it = std::begin(this->children); it != std::end(this->children); ++it) {
|
||||
NWidgetBase *nwid = it->get();
|
||||
nwid->current_x = 0; /* Hide widget, it will be revealed in the next step. */
|
||||
if (nwid->type == NWID_SPACER) continue;
|
||||
lookup[dynamic_cast<NWidgetCore *>(nwid)->index] = std::distance(this->children.begin(), it);
|
||||
}
|
||||
|
||||
/* Now assign the widgets to their rightful place */
|
||||
|
@ -1397,12 +1398,13 @@ public:
|
|||
uint button_i = 0;
|
||||
|
||||
/* Index into the arrangement indices. The macro lastof cannot be used here! */
|
||||
const WidgetID *cur_wid = rtl ? &arrangement[arrangable_count - 1] : arrangement;
|
||||
const WidgetID *slotp = rtl ? &arrangement[arrangable_count - 1] : arrangement;
|
||||
for (uint i = 0; i < arrangable_count; i++) {
|
||||
NWidgetBase *child_wid = widgets[*cur_wid];
|
||||
/* If we have to give space to the spacers, do that */
|
||||
if (spacer_space != 0) {
|
||||
NWidgetBase *possible_spacer = rtl ? child_wid->next : child_wid->prev;
|
||||
uint slot = lookup[*slotp];
|
||||
auto &child_wid = this->children[slot];
|
||||
/* If we have space to give to the spacers, do that. */
|
||||
if (spacer_space > 0 && slot > 0 && slot < this->children.size() - 1) {
|
||||
const auto &possible_spacer = this->children[slot + (rtl ? 1 : -1)];
|
||||
if (possible_spacer != nullptr && possible_spacer->type == NWID_SPACER) {
|
||||
uint add = spacer_space / (spacer_count - spacer_i);
|
||||
position += add;
|
||||
|
@ -1423,9 +1425,9 @@ public:
|
|||
position += child_wid->current_x;
|
||||
|
||||
if (rtl) {
|
||||
cur_wid--;
|
||||
slotp--;
|
||||
} else {
|
||||
cur_wid++;
|
||||
slotp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1783,7 +1785,7 @@ class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer {
|
|||
|
||||
/* Find the size of panel_widths */
|
||||
uint i = 0;
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
if (child_wid->type == NWID_SPACER || this->IsButton(child_wid->type)) continue;
|
||||
|
||||
assert(i < lengthof(this->panel_widths));
|
||||
|
@ -2120,7 +2122,7 @@ struct MainToolbarWindow : Window {
|
|||
}};
|
||||
};
|
||||
|
||||
static NWidgetBase *MakeMainToolbar()
|
||||
static std::unique_ptr<NWidgetBase> MakeMainToolbar()
|
||||
{
|
||||
/** Sprites to use for the different toolbar buttons */
|
||||
static const SpriteID toolbar_button_sprites[] = {
|
||||
|
@ -2157,7 +2159,7 @@ static NWidgetBase *MakeMainToolbar()
|
|||
SPR_IMG_SWITCH_TOOLBAR, // WID_TN_SWITCH_BAR
|
||||
};
|
||||
|
||||
NWidgetMainToolbarContainer *hor = new NWidgetMainToolbarContainer();
|
||||
auto hor = std::make_unique<NWidgetMainToolbarContainer>();
|
||||
for (WidgetID i = 0; i < WID_TN_END; i++) {
|
||||
switch (i) {
|
||||
case WID_TN_SMALL_MAP:
|
||||
|
@ -2166,12 +2168,12 @@ static NWidgetBase *MakeMainToolbar()
|
|||
case WID_TN_ZOOM_IN:
|
||||
case WID_TN_BUILDING_TOOLS_START:
|
||||
case WID_TN_MUSIC_SOUND:
|
||||
hor->Add(new NWidgetSpacer(0, 0));
|
||||
hor->Add(std::make_unique<NWidgetSpacer>(0, 0));
|
||||
break;
|
||||
}
|
||||
NWidgetLeaf *leaf = new NWidgetLeaf(i == WID_TN_SAVE ? WWT_IMGBTN_2 : WWT_IMGBTN, COLOUR_GREY, i, toolbar_button_sprites[i], STR_TOOLBAR_TOOLTIP_PAUSE_GAME + i);
|
||||
auto leaf = std::make_unique<NWidgetLeaf>(i == WID_TN_SAVE ? WWT_IMGBTN_2 : WWT_IMGBTN, COLOUR_GREY, i, toolbar_button_sprites[i], STR_TOOLBAR_TOOLTIP_PAUSE_GAME + i);
|
||||
leaf->SetMinimalSize(20, 20);
|
||||
hor->Add(leaf);
|
||||
hor->Add(std::move(leaf));
|
||||
}
|
||||
|
||||
return hor;
|
||||
|
@ -2512,9 +2514,9 @@ static const NWidgetPart _nested_toolb_scen_inner_widgets[] = {
|
|||
NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SWITCH_BAR), SetDataTip(SPR_IMG_SWITCH_TOOLBAR, STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR),
|
||||
};
|
||||
|
||||
static NWidgetBase *MakeScenarioToolbar()
|
||||
static std::unique_ptr<NWidgetBase> MakeScenarioToolbar()
|
||||
{
|
||||
return MakeNWidgets(std::begin(_nested_toolb_scen_inner_widgets), std::end(_nested_toolb_scen_inner_widgets), new NWidgetScenarioToolbarContainer());
|
||||
return MakeNWidgets(std::begin(_nested_toolb_scen_inner_widgets), std::end(_nested_toolb_scen_inner_widgets), std::make_unique<NWidgetScenarioToolbarContainer>());
|
||||
}
|
||||
|
||||
static const NWidgetPart _nested_toolb_scen_widgets[] = {
|
||||
|
|
|
@ -256,7 +256,7 @@ public:
|
|||
* get producing the correct result than dynamically building the widgets is.
|
||||
* @see NWidgetFunctionType
|
||||
*/
|
||||
static NWidgetBase *MakeTreeTypeButtons()
|
||||
static std::unique_ptr<NWidgetBase> MakeTreeTypeButtons()
|
||||
{
|
||||
const byte type_base = _tree_base_by_landscape[_settings_game.game_creation.landscape];
|
||||
const byte type_count = _tree_count_by_landscape[_settings_game.game_creation.landscape];
|
||||
|
@ -266,20 +266,20 @@ static NWidgetBase *MakeTreeTypeButtons()
|
|||
const int num_rows = CeilDiv(type_count, num_columns);
|
||||
byte cur_type = type_base;
|
||||
|
||||
NWidgetVertical *vstack = new NWidgetVertical(NC_EQUALSIZE);
|
||||
auto vstack = std::make_unique<NWidgetVertical>(NC_EQUALSIZE);
|
||||
vstack->SetPIP(0, 1, 0);
|
||||
|
||||
for (int row = 0; row < num_rows; row++) {
|
||||
NWidgetHorizontal *hstack = new NWidgetHorizontal(NC_EQUALSIZE);
|
||||
auto hstack = std::make_unique<NWidgetHorizontal>(NC_EQUALSIZE);
|
||||
hstack->SetPIP(0, 1, 0);
|
||||
vstack->Add(hstack);
|
||||
for (int col = 0; col < num_columns; col++) {
|
||||
if (cur_type > type_base + type_count) break;
|
||||
NWidgetBackground *button = new NWidgetBackground(WWT_PANEL, COLOUR_GREY, WID_BT_TYPE_BUTTON_FIRST + cur_type);
|
||||
auto button = std::make_unique<NWidgetBackground>(WWT_PANEL, COLOUR_GREY, WID_BT_TYPE_BUTTON_FIRST + cur_type);
|
||||
button->SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP);
|
||||
hstack->Add(button);
|
||||
hstack->Add(std::move(button));
|
||||
cur_type++;
|
||||
}
|
||||
vstack->Add(std::move(hstack));
|
||||
}
|
||||
|
||||
return vstack;
|
||||
|
|
339
src/widget.cpp
339
src/widget.cpp
|
@ -1275,30 +1275,10 @@ 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 : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor container baseclass.
|
||||
* @param tp Type of the container.
|
||||
*/
|
||||
NWidgetContainer::NWidgetContainer(WidgetType tp) : NWidgetBase(tp)
|
||||
{
|
||||
this->head = nullptr;
|
||||
this->tail = nullptr;
|
||||
}
|
||||
|
||||
NWidgetContainer::~NWidgetContainer()
|
||||
{
|
||||
while (this->head != nullptr) {
|
||||
NWidgetBase *wid = this->head->next;
|
||||
delete this->head;
|
||||
this->head = wid;
|
||||
}
|
||||
this->tail = nullptr;
|
||||
}
|
||||
|
||||
NWidgetBase *NWidgetContainer::GetWidgetOfType(WidgetType tp)
|
||||
{
|
||||
if (this->type == tp) return this;
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
NWidgetBase *nwid = child_wid->GetWidgetOfType(tp);
|
||||
if (nwid != nullptr) return nwid;
|
||||
}
|
||||
|
@ -1307,7 +1287,7 @@ NWidgetBase *NWidgetContainer::GetWidgetOfType(WidgetType tp)
|
|||
|
||||
void NWidgetContainer::AdjustPaddingForZoom()
|
||||
{
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
child_wid->AdjustPaddingForZoom();
|
||||
}
|
||||
NWidgetBase::AdjustPaddingForZoom();
|
||||
|
@ -1317,35 +1297,23 @@ void NWidgetContainer::AdjustPaddingForZoom()
|
|||
* Append widget \a wid to container.
|
||||
* @param wid Widget to append.
|
||||
*/
|
||||
void NWidgetContainer::Add(NWidgetBase *wid)
|
||||
void NWidgetContainer::Add(std::unique_ptr<NWidgetBase> &&wid)
|
||||
{
|
||||
assert(wid != nullptr);
|
||||
wid->parent = this;
|
||||
assert(wid->next == nullptr && wid->prev == nullptr);
|
||||
|
||||
if (this->head == nullptr) {
|
||||
this->head = wid;
|
||||
this->tail = wid;
|
||||
} else {
|
||||
assert(this->tail != nullptr);
|
||||
assert(this->tail->next == nullptr);
|
||||
|
||||
this->tail->next = wid;
|
||||
wid->prev = this->tail;
|
||||
this->tail = wid;
|
||||
}
|
||||
this->children.push_back(std::move(wid));
|
||||
}
|
||||
|
||||
void NWidgetContainer::FillWidgetLookup(WidgetLookup &widget_lookup)
|
||||
{
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
child_wid->FillWidgetLookup(widget_lookup);
|
||||
}
|
||||
}
|
||||
|
||||
void NWidgetContainer::Draw(const Window *w)
|
||||
{
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
child_wid->Draw(w);
|
||||
}
|
||||
|
||||
|
@ -1356,7 +1324,7 @@ NWidgetCore *NWidgetContainer::GetWidgetFromPos(int x, int y)
|
|||
{
|
||||
if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return nullptr;
|
||||
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
NWidgetCore *nwid = child_wid->GetWidgetFromPos(x, y);
|
||||
if (nwid != nullptr) return nwid;
|
||||
}
|
||||
|
@ -1372,7 +1340,7 @@ NWidgetStacked::NWidgetStacked(WidgetID index) : NWidgetContainer(NWID_SELECTION
|
|||
|
||||
void NWidgetStacked::AdjustPaddingForZoom()
|
||||
{
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
child_wid->AdjustPaddingForZoom();
|
||||
}
|
||||
NWidgetContainer::AdjustPaddingForZoom();
|
||||
|
@ -1401,11 +1369,11 @@ void NWidgetStacked::SetupSmallestSize(Window *w)
|
|||
/* First sweep, recurse down and compute minimal size and filling. */
|
||||
this->smallest_x = 0;
|
||||
this->smallest_y = 0;
|
||||
this->fill_x = (this->head != nullptr) ? 1 : 0;
|
||||
this->fill_y = (this->head != nullptr) ? 1 : 0;
|
||||
this->resize_x = (this->head != nullptr) ? 1 : 0;
|
||||
this->resize_y = (this->head != nullptr) ? 1 : 0;
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
this->fill_x = this->IsEmpty() ? 0 : 1;
|
||||
this->fill_y = this->IsEmpty() ? 0 : 1;
|
||||
this->resize_x = this->IsEmpty() ? 0 : 1;
|
||||
this->resize_y = this->IsEmpty() ? 0 : 1;
|
||||
for (const auto &child_wid : this->children) {
|
||||
child_wid->SetupSmallestSize(w);
|
||||
|
||||
this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.Horizontal());
|
||||
|
@ -1424,7 +1392,7 @@ void NWidgetStacked::AssignSizePosition(SizingType sizing, int x, int y, uint gi
|
|||
|
||||
if (this->shown_plane >= SZSP_BEGIN) return;
|
||||
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
uint hor_step = (sizing == ST_SMALLEST) ? 1 : child_wid->GetHorizontalStepSize(sizing);
|
||||
uint child_width = ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding.Horizontal(), hor_step);
|
||||
uint child_pos_x = (rtl ? child_wid->padding.right : child_wid->padding.left);
|
||||
|
@ -1447,16 +1415,9 @@ void NWidgetStacked::Draw(const Window *w)
|
|||
{
|
||||
if (this->shown_plane >= SZSP_BEGIN) return;
|
||||
|
||||
int plane = 0;
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; plane++, child_wid = child_wid->next) {
|
||||
if (plane == this->shown_plane) {
|
||||
child_wid->Draw(w);
|
||||
DrawOutline(w, this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
NOT_REACHED();
|
||||
assert(static_cast<size_t>(this->shown_plane) < this->children.size());
|
||||
this->children[shown_plane]->Draw(w);
|
||||
DrawOutline(w, this);
|
||||
}
|
||||
|
||||
NWidgetCore *NWidgetStacked::GetWidgetFromPos(int x, int y)
|
||||
|
@ -1464,13 +1425,9 @@ NWidgetCore *NWidgetStacked::GetWidgetFromPos(int x, int y)
|
|||
if (this->shown_plane >= SZSP_BEGIN) return nullptr;
|
||||
|
||||
if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return nullptr;
|
||||
int plane = 0;
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; plane++, child_wid = child_wid->next) {
|
||||
if (plane == this->shown_plane) {
|
||||
return child_wid->GetWidgetFromPos(x, y);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
if (static_cast<size_t>(this->shown_plane) >= this->children.size()) return nullptr;
|
||||
return this->children[shown_plane]->GetWidgetFromPos(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1552,7 +1509,7 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w)
|
|||
/* 1a. Forward call, collect longest/widest child length. */
|
||||
uint longest = 0; // Longest child found.
|
||||
uint max_vert_fill = 0; // Biggest vertical fill step.
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
child_wid->SetupSmallestSize(w);
|
||||
longest = std::max(longest, child_wid->smallest_x);
|
||||
max_vert_fill = std::max(max_vert_fill, child_wid->GetVerticalStepSize(ST_SMALLEST));
|
||||
|
@ -1564,7 +1521,7 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w)
|
|||
[[maybe_unused]] uint max_smallest = this->smallest_y + 3 * max_vert_fill; // Upper limit to computing smallest height.
|
||||
uint cur_height = this->smallest_y;
|
||||
for (;;) {
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
uint step_size = child_wid->GetVerticalStepSize(ST_SMALLEST);
|
||||
uint child_height = child_wid->smallest_y + child_wid->padding.Vertical();
|
||||
if (step_size > 1 && child_height < cur_height) { // Small step sizes or already fitting children are not interesting.
|
||||
|
@ -1581,12 +1538,12 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w)
|
|||
}
|
||||
/* 2. For containers that must maintain equal width, extend child minimal size. */
|
||||
if (this->flags & NC_EQUALSIZE) {
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
if (child_wid->fill_x == 1) child_wid->smallest_x = longest;
|
||||
}
|
||||
}
|
||||
/* 3. Compute smallest, fill, and resize values of the container. */
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
this->smallest_x += child_wid->smallest_x + child_wid->padding.Horizontal();
|
||||
if (child_wid->fill_x > 0) {
|
||||
if (this->fill_x == 0 || this->fill_x > child_wid->fill_x) this->fill_x = child_wid->fill_x;
|
||||
|
@ -1609,7 +1566,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, int x, int y, uint
|
|||
|
||||
/* Compute additional width given to us. */
|
||||
uint additional_length = given_width - (this->pip_pre + this->gaps * this->pip_inter + this->pip_post);
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
if (child_wid->smallest_x != 0 || child_wid->fill_x != 0) additional_length -= child_wid->smallest_x + child_wid->padding.Horizontal();
|
||||
}
|
||||
|
||||
|
@ -1631,7 +1588,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, int x, int y, uint
|
|||
*/
|
||||
int num_changing_childs = 0; // Number of children that can change size.
|
||||
uint biggest_stepsize = 0;
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
uint hor_step = child_wid->GetHorizontalStepSize(sizing);
|
||||
if (hor_step > 0) {
|
||||
if (!(flags & NC_BIGFIRST)) num_changing_childs++;
|
||||
|
@ -1646,7 +1603,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, int x, int y, uint
|
|||
|
||||
/* First.5 loop: count how many children are of the biggest step size. */
|
||||
if ((flags & NC_BIGFIRST) && biggest_stepsize > 0) {
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
uint hor_step = child_wid->GetHorizontalStepSize(sizing);
|
||||
if (hor_step == biggest_stepsize) {
|
||||
num_changing_childs++;
|
||||
|
@ -1657,7 +1614,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, int x, int y, uint
|
|||
/* Second loop: Allocate the additional horizontal space over the resizing children, starting with the biggest resize steps. */
|
||||
while (biggest_stepsize > 0) {
|
||||
uint next_biggest_stepsize = 0;
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
uint hor_step = child_wid->GetHorizontalStepSize(sizing);
|
||||
if (hor_step > biggest_stepsize) continue; // Already done
|
||||
if (hor_step == biggest_stepsize) {
|
||||
|
@ -1674,7 +1631,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, int x, int y, uint
|
|||
|
||||
if (num_changing_childs == 0 && (flags & NC_BIGFIRST) && biggest_stepsize > 0) {
|
||||
/* Second.5 loop: count how many children are of the updated biggest step size. */
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
uint hor_step = child_wid->GetHorizontalStepSize(sizing);
|
||||
if (hor_step == biggest_stepsize) {
|
||||
num_changing_childs++;
|
||||
|
@ -1699,8 +1656,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, int x, int y, uint
|
|||
|
||||
/* Third loop: Compute position and call the child. */
|
||||
uint position = rtl ? this->current_x - pre : pre; // Place to put next child relative to origin of the container.
|
||||
NWidgetBase *child_wid = this->head;
|
||||
while (child_wid != nullptr) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
uint child_width = child_wid->current_x;
|
||||
uint child_x = x + (rtl ? position - child_width - child_wid->padding.left : position + child_wid->padding.left);
|
||||
uint child_y = y + child_wid->padding.top;
|
||||
|
@ -1710,8 +1666,6 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, int x, int y, uint
|
|||
uint padded_child_width = child_width + child_wid->padding.Horizontal() + inter;
|
||||
position = rtl ? position - padded_child_width : position + padded_child_width;
|
||||
}
|
||||
|
||||
child_wid = child_wid->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1744,7 +1698,7 @@ void NWidgetVertical::SetupSmallestSize(Window *w)
|
|||
/* 1a. Forward call, collect longest/widest child length. */
|
||||
uint highest = 0; // Highest child found.
|
||||
uint max_hor_fill = 0; // Biggest horizontal fill step.
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
child_wid->SetupSmallestSize(w);
|
||||
highest = std::max(highest, child_wid->smallest_y);
|
||||
max_hor_fill = std::max(max_hor_fill, child_wid->GetHorizontalStepSize(ST_SMALLEST));
|
||||
|
@ -1756,7 +1710,7 @@ void NWidgetVertical::SetupSmallestSize(Window *w)
|
|||
[[maybe_unused]] uint max_smallest = this->smallest_x + 3 * max_hor_fill; // Upper limit to computing smallest height.
|
||||
uint cur_width = this->smallest_x;
|
||||
for (;;) {
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
uint step_size = child_wid->GetHorizontalStepSize(ST_SMALLEST);
|
||||
uint child_width = child_wid->smallest_x + child_wid->padding.Horizontal();
|
||||
if (step_size > 1 && child_width < cur_width) { // Small step sizes or already fitting children are not interesting.
|
||||
|
@ -1773,12 +1727,12 @@ void NWidgetVertical::SetupSmallestSize(Window *w)
|
|||
}
|
||||
/* 2. For containers that must maintain equal width, extend children minimal size. */
|
||||
if (this->flags & NC_EQUALSIZE) {
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
if (child_wid->fill_y == 1) child_wid->smallest_y = highest;
|
||||
}
|
||||
}
|
||||
/* 3. Compute smallest, fill, and resize values of the container. */
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
this->smallest_y += child_wid->smallest_y + child_wid->padding.Vertical();
|
||||
if (child_wid->fill_y > 0) {
|
||||
if (this->fill_y == 0 || this->fill_y > child_wid->fill_y) this->fill_y = child_wid->fill_y;
|
||||
|
@ -1801,7 +1755,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, int x, int y, uint g
|
|||
|
||||
/* Compute additional height given to us. */
|
||||
uint additional_length = given_height - (this->pip_pre + this->gaps * this->pip_inter + this->pip_post);
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
if (child_wid->smallest_y != 0 || child_wid->fill_y != 0) additional_length -= child_wid->smallest_y + child_wid->padding.Vertical();
|
||||
}
|
||||
|
||||
|
@ -1814,7 +1768,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, int x, int y, uint g
|
|||
/* First loop: Find biggest stepsize, find number of children that want a piece of the pie, handle horizontal size for all children, handle vertical size for non-resizing child. */
|
||||
int num_changing_childs = 0; // Number of children that can change size.
|
||||
uint biggest_stepsize = 0;
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
uint vert_step = child_wid->GetVerticalStepSize(sizing);
|
||||
if (vert_step > 0) {
|
||||
if (!(flags & NC_BIGFIRST)) num_changing_childs++;
|
||||
|
@ -1829,7 +1783,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, int x, int y, uint g
|
|||
|
||||
/* First.5 loop: count how many children are of the biggest step size. */
|
||||
if ((this->flags & NC_BIGFIRST) && biggest_stepsize > 0) {
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
uint vert_step = child_wid->GetVerticalStepSize(sizing);
|
||||
if (vert_step == biggest_stepsize) {
|
||||
num_changing_childs++;
|
||||
|
@ -1840,7 +1794,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, int x, int y, uint g
|
|||
/* Second loop: Allocate the additional vertical space over the resizing children, starting with the biggest resize steps. */
|
||||
while (biggest_stepsize > 0) {
|
||||
uint next_biggest_stepsize = 0;
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
uint vert_step = child_wid->GetVerticalStepSize(sizing);
|
||||
if (vert_step > biggest_stepsize) continue; // Already done
|
||||
if (vert_step == biggest_stepsize) {
|
||||
|
@ -1857,7 +1811,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, int x, int y, uint g
|
|||
|
||||
if (num_changing_childs == 0 && (flags & NC_BIGFIRST) && biggest_stepsize > 0) {
|
||||
/* Second.5 loop: count how many children are of the updated biggest step size. */
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
uint vert_step = child_wid->GetVerticalStepSize(sizing);
|
||||
if (vert_step == biggest_stepsize) {
|
||||
num_changing_childs++;
|
||||
|
@ -1882,7 +1836,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, int x, int y, uint g
|
|||
|
||||
/* Third loop: Compute position and call the child. */
|
||||
uint position = pre; // Place to put next child relative to origin of the container.
|
||||
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
|
||||
for (const auto &child_wid : this->children) {
|
||||
uint child_x = x + (rtl ? child_wid->padding.right : child_wid->padding.left);
|
||||
uint child_height = child_wid->current_y;
|
||||
|
||||
|
@ -1974,7 +1928,7 @@ void NWidgetMatrix::SetCount(int count)
|
|||
* Then multiply that by the height of a widget, and add the pre
|
||||
* and post spacing "offsets". */
|
||||
count = CeilDiv(count, this->sb->IsVertical() ? this->widgets_x : this->widgets_y);
|
||||
count *= (this->sb->IsVertical() ? this->head->smallest_y : this->head->smallest_x) + this->pip_inter;
|
||||
count *= (this->sb->IsVertical() ? this->children.front()->smallest_y : this->children.front()->smallest_x) + this->pip_inter;
|
||||
if (count > 0) count -= this->pip_inter; // We counted an inter too much in the multiplication above
|
||||
count += this->pip_pre + this->pip_post;
|
||||
this->sb->SetCount(count);
|
||||
|
@ -2002,15 +1956,14 @@ int NWidgetMatrix::GetCurrentElement() const
|
|||
|
||||
void NWidgetMatrix::SetupSmallestSize(Window *w)
|
||||
{
|
||||
assert(this->head != nullptr);
|
||||
assert(this->head->next == nullptr);
|
||||
assert(this->children.size() == 1);
|
||||
|
||||
this->head->SetupSmallestSize(w);
|
||||
this->children.front()->SetupSmallestSize(w);
|
||||
|
||||
Dimension padding = { (uint)this->pip_pre + this->pip_post, (uint)this->pip_pre + this->pip_post};
|
||||
Dimension size = {this->head->smallest_x + padding.width, this->head->smallest_y + padding.height};
|
||||
Dimension size = {this->children.front()->smallest_x + padding.width, this->children.front()->smallest_y + padding.height};
|
||||
Dimension fill = {0, 0};
|
||||
Dimension resize = {this->pip_inter + this->head->smallest_x, this->pip_inter + this->head->smallest_y};
|
||||
Dimension resize = {this->pip_inter + this->children.front()->smallest_x, this->pip_inter + this->children.front()->smallest_y};
|
||||
|
||||
if (this->index >= 0) w->UpdateWidgetSize(this->index, &size, padding, &fill, &resize);
|
||||
|
||||
|
@ -2032,8 +1985,8 @@ void NWidgetMatrix::AssignSizePosition(SizingType, int x, int y, uint given_widt
|
|||
this->current_y = given_height;
|
||||
|
||||
/* Determine the size of the widgets, and the number of visible widgets on each of the axis. */
|
||||
this->widget_w = this->head->smallest_x + this->pip_inter;
|
||||
this->widget_h = this->head->smallest_y + this->pip_inter;
|
||||
this->widget_w = this->children.front()->smallest_x + this->pip_inter;
|
||||
this->widget_h = this->children.front()->smallest_y + this->pip_inter;
|
||||
|
||||
/* Account for the pip_inter is between widgets, so we need to account for that when
|
||||
* the division assumes pip_inter is used for all widgets. */
|
||||
|
@ -2072,7 +2025,7 @@ NWidgetCore *NWidgetMatrix::GetWidgetFromPos(int x, int y)
|
|||
this->current_element = (widget_row + start_y) * this->widgets_x + start_x + widget_col;
|
||||
if (this->current_element >= this->count) return nullptr;
|
||||
|
||||
NWidgetCore *child = dynamic_cast<NWidgetCore *>(this->head);
|
||||
NWidgetCore *child = dynamic_cast<NWidgetCore *>(this->children.front().get());
|
||||
assert(child != nullptr);
|
||||
child->AssignSizePosition(ST_RESIZE,
|
||||
this->pos_x + (rtl ? this->pip_post - widget_col * this->widget_w : this->pip_pre + widget_col * this->widget_w) + base_offs_x,
|
||||
|
@ -2096,7 +2049,7 @@ NWidgetCore *NWidgetMatrix::GetWidgetFromPos(int x, int y)
|
|||
AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
|
||||
|
||||
/* Get the appropriate offsets so we can draw the right widgets. */
|
||||
NWidgetCore *child = dynamic_cast<NWidgetCore *>(this->head);
|
||||
NWidgetCore *child = dynamic_cast<NWidgetCore *>(this->children.front().get());
|
||||
assert(child != nullptr);
|
||||
int start_x, start_y, base_offs_x, base_offs_y;
|
||||
this->GetScrollOffsets(start_x, start_y, base_offs_x, base_offs_y);
|
||||
|
@ -2168,19 +2121,14 @@ void NWidgetMatrix::GetScrollOffsets(int &start_x, int &start_y, int &base_offs_
|
|||
* vertical container will be inserted while adding the first
|
||||
* child widget.
|
||||
*/
|
||||
NWidgetBackground::NWidgetBackground(WidgetType tp, Colours colour, WidgetID index, NWidgetPIPContainer *child) : NWidgetCore(tp, colour, index, 1, 1, 0x0, STR_NULL)
|
||||
NWidgetBackground::NWidgetBackground(WidgetType tp, Colours colour, WidgetID index, std::unique_ptr<NWidgetPIPContainer> &&child) : NWidgetCore(tp, colour, index, 1, 1, 0x0, STR_NULL)
|
||||
{
|
||||
assert(tp == WWT_PANEL || tp == WWT_INSET || tp == WWT_FRAME);
|
||||
this->child = child;
|
||||
this->child = std::move(child);
|
||||
if (this->child != nullptr) this->child->parent = this;
|
||||
this->SetAlignment(SA_TOP | SA_LEFT);
|
||||
}
|
||||
|
||||
NWidgetBackground::~NWidgetBackground()
|
||||
{
|
||||
if (this->child != nullptr) delete this->child;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a child to the parent.
|
||||
* @param nwid Nested widget to add to the background widget.
|
||||
|
@ -2188,13 +2136,13 @@ NWidgetBackground::~NWidgetBackground()
|
|||
* Unless a child container has been given in the constructor, a parent behaves as a vertical container.
|
||||
* You can add several children to it, and they are put underneath each other.
|
||||
*/
|
||||
void NWidgetBackground::Add(NWidgetBase *nwid)
|
||||
void NWidgetBackground::Add(std::unique_ptr<NWidgetBase> &&nwid)
|
||||
{
|
||||
if (this->child == nullptr) {
|
||||
this->child = new NWidgetVertical();
|
||||
this->child = std::make_unique<NWidgetVertical>();
|
||||
}
|
||||
nwid->parent = this->child;
|
||||
this->child->Add(nwid);
|
||||
nwid->parent = this->child.get();
|
||||
this->child->Add(std::move(nwid));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2210,7 +2158,7 @@ void NWidgetBackground::Add(NWidgetBase *nwid)
|
|||
void NWidgetBackground::SetPIP(uint8_t pip_pre, uint8_t pip_inter, uint8_t pip_post)
|
||||
{
|
||||
if (this->child == nullptr) {
|
||||
this->child = new NWidgetVertical();
|
||||
this->child = std::make_unique<NWidgetVertical>();
|
||||
}
|
||||
this->child->parent = this;
|
||||
this->child->SetPIP(pip_pre, pip_inter, pip_post);
|
||||
|
@ -2229,7 +2177,7 @@ void NWidgetBackground::SetPIP(uint8_t pip_pre, uint8_t pip_inter, uint8_t pip_p
|
|||
void NWidgetBackground::SetPIPRatio(uint8_t pip_ratio_pre, uint8_t pip_ratio_inter, uint8_t pip_ratio_post)
|
||||
{
|
||||
if (this->child == nullptr) {
|
||||
this->child = new NWidgetVertical();
|
||||
this->child = std::make_unique<NWidgetVertical>();
|
||||
}
|
||||
this->child->parent = this;
|
||||
this->child->SetPIPRatio(pip_ratio_pre, pip_ratio_inter, pip_ratio_post);
|
||||
|
@ -3090,60 +3038,60 @@ bool NWidgetLeaf::ButtonHit(const Point &pt)
|
|||
* @param fill_dest Fill the composed widget with child widgets.
|
||||
* @return Pointer to remaining nested widget parts.
|
||||
*/
|
||||
static const NWidgetPart *MakeNWidget(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetBase **dest, bool *fill_dest)
|
||||
static const NWidgetPart *MakeNWidget(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, std::unique_ptr<NWidgetBase> &dest, bool *fill_dest)
|
||||
{
|
||||
*dest = nullptr;
|
||||
dest = nullptr;
|
||||
*fill_dest = false;
|
||||
|
||||
while (nwid_begin < nwid_end) {
|
||||
switch (nwid_begin->type) {
|
||||
case NWID_SPACER:
|
||||
if (*dest != nullptr) return nwid_begin;
|
||||
*dest = new NWidgetSpacer(0, 0);
|
||||
if (dest != nullptr) return nwid_begin;
|
||||
dest = std::make_unique<NWidgetSpacer>(0, 0);
|
||||
break;
|
||||
|
||||
case NWID_HORIZONTAL:
|
||||
if (*dest != nullptr) return nwid_begin;
|
||||
*dest = new NWidgetHorizontal(nwid_begin->u.cont_flags);
|
||||
if (dest != nullptr) return nwid_begin;
|
||||
dest = std::make_unique<NWidgetHorizontal>(nwid_begin->u.cont_flags);
|
||||
*fill_dest = true;
|
||||
break;
|
||||
|
||||
case NWID_HORIZONTAL_LTR:
|
||||
if (*dest != nullptr) return nwid_begin;
|
||||
*dest = new NWidgetHorizontalLTR(nwid_begin->u.cont_flags);
|
||||
if (dest != nullptr) return nwid_begin;
|
||||
dest = std::make_unique<NWidgetHorizontalLTR>(nwid_begin->u.cont_flags);
|
||||
*fill_dest = true;
|
||||
break;
|
||||
|
||||
case WWT_PANEL:
|
||||
case WWT_INSET:
|
||||
case WWT_FRAME:
|
||||
if (*dest != nullptr) return nwid_begin;
|
||||
*dest = new NWidgetBackground(nwid_begin->type, nwid_begin->u.widget.colour, nwid_begin->u.widget.index);
|
||||
if (dest != nullptr) return nwid_begin;
|
||||
dest = std::make_unique<NWidgetBackground>(nwid_begin->type, nwid_begin->u.widget.colour, nwid_begin->u.widget.index);
|
||||
*fill_dest = true;
|
||||
break;
|
||||
|
||||
case NWID_VERTICAL:
|
||||
if (*dest != nullptr) return nwid_begin;
|
||||
*dest = new NWidgetVertical(nwid_begin->u.cont_flags);
|
||||
if (dest != nullptr) return nwid_begin;
|
||||
dest = std::make_unique<NWidgetVertical>(nwid_begin->u.cont_flags);
|
||||
*fill_dest = true;
|
||||
break;
|
||||
|
||||
case NWID_MATRIX: {
|
||||
if (*dest != nullptr) return nwid_begin;
|
||||
*dest = new NWidgetMatrix(nwid_begin->u.widget.colour, nwid_begin->u.widget.index);
|
||||
if (dest != nullptr) return nwid_begin;
|
||||
dest = std::make_unique<NWidgetMatrix>(nwid_begin->u.widget.colour, nwid_begin->u.widget.index);
|
||||
*fill_dest = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case WPT_FUNCTION: {
|
||||
if (*dest != nullptr) return nwid_begin;
|
||||
*dest = nwid_begin->u.func_ptr();
|
||||
if (dest != nullptr) return nwid_begin;
|
||||
dest = nwid_begin->u.func_ptr();
|
||||
*fill_dest = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case WPT_RESIZE: {
|
||||
NWidgetResizeBase *nwrb = dynamic_cast<NWidgetResizeBase *>(*dest);
|
||||
NWidgetResizeBase *nwrb = dynamic_cast<NWidgetResizeBase *>(dest.get());
|
||||
if (unlikely(nwrb == nullptr)) throw std::runtime_error("WPT_RESIZE requires NWidgetResizeBase");
|
||||
assert(nwid_begin->u.xy.x >= 0 && nwid_begin->u.xy.y >= 0);
|
||||
nwrb->SetResize(nwid_begin->u.xy.x, nwid_begin->u.xy.y);
|
||||
|
@ -3151,7 +3099,7 @@ static const NWidgetPart *MakeNWidget(const NWidgetPart *nwid_begin, const NWidg
|
|||
}
|
||||
|
||||
case WPT_MINSIZE: {
|
||||
NWidgetResizeBase *nwrb = dynamic_cast<NWidgetResizeBase *>(*dest);
|
||||
NWidgetResizeBase *nwrb = dynamic_cast<NWidgetResizeBase *>(dest.get());
|
||||
if (unlikely(nwrb == nullptr)) throw std::runtime_error("WPT_MINSIZE requires NWidgetResizeBase");
|
||||
assert(nwid_begin->u.xy.x >= 0 && nwid_begin->u.xy.y >= 0);
|
||||
nwrb->SetMinimalSize(nwid_begin->u.xy.x, nwid_begin->u.xy.y);
|
||||
|
@ -3159,7 +3107,7 @@ static const NWidgetPart *MakeNWidget(const NWidgetPart *nwid_begin, const NWidg
|
|||
}
|
||||
|
||||
case WPT_MINTEXTLINES: {
|
||||
NWidgetResizeBase *nwrb = dynamic_cast<NWidgetResizeBase *>(*dest);
|
||||
NWidgetResizeBase *nwrb = dynamic_cast<NWidgetResizeBase *>(dest.get());
|
||||
if (unlikely(nwrb == nullptr)) throw std::runtime_error("WPT_MINTEXTLINES requires NWidgetResizeBase");
|
||||
assert(nwid_begin->u.text_lines.size >= FS_BEGIN && nwid_begin->u.text_lines.size < FS_END);
|
||||
nwrb->SetMinimalTextLines(nwid_begin->u.text_lines.lines, nwid_begin->u.text_lines.spacing, nwid_begin->u.text_lines.size);
|
||||
|
@ -3167,28 +3115,28 @@ static const NWidgetPart *MakeNWidget(const NWidgetPart *nwid_begin, const NWidg
|
|||
}
|
||||
|
||||
case WPT_TEXTSTYLE: {
|
||||
NWidgetCore *nwc = dynamic_cast<NWidgetCore *>(*dest);
|
||||
NWidgetCore *nwc = dynamic_cast<NWidgetCore *>(dest.get());
|
||||
if (unlikely(nwc == nullptr)) throw std::runtime_error("WPT_TEXTSTYLE requires NWidgetCore");
|
||||
nwc->SetTextStyle(nwid_begin->u.text_style.colour, nwid_begin->u.text_style.size);
|
||||
break;
|
||||
}
|
||||
|
||||
case WPT_ALIGNMENT: {
|
||||
NWidgetCore *nwc = dynamic_cast<NWidgetCore *>(*dest);
|
||||
NWidgetCore *nwc = dynamic_cast<NWidgetCore *>(dest.get());
|
||||
if (unlikely(nwc == nullptr)) throw std::runtime_error("WPT_ALIGNMENT requires NWidgetCore");
|
||||
nwc->SetAlignment(nwid_begin->u.align.align);
|
||||
break;
|
||||
}
|
||||
|
||||
case WPT_FILL: {
|
||||
NWidgetResizeBase *nwrb = dynamic_cast<NWidgetResizeBase *>(*dest);
|
||||
NWidgetResizeBase *nwrb = dynamic_cast<NWidgetResizeBase *>(dest.get());
|
||||
if (unlikely(nwrb == nullptr)) throw std::runtime_error("WPT_FILL requires NWidgetResizeBase");
|
||||
nwrb->SetFill(nwid_begin->u.xy.x, nwid_begin->u.xy.y);
|
||||
break;
|
||||
}
|
||||
|
||||
case WPT_DATATIP: {
|
||||
NWidgetCore *nwc = dynamic_cast<NWidgetCore *>(*dest);
|
||||
NWidgetCore *nwc = dynamic_cast<NWidgetCore *>(dest.get());
|
||||
if (unlikely(nwc == nullptr)) throw std::runtime_error("WPT_DATATIP requires NWidgetCore");
|
||||
nwc->widget_data = nwid_begin->u.data_tip.data;
|
||||
nwc->tool_tip = nwid_begin->u.data_tip.tooltip;
|
||||
|
@ -3196,15 +3144,15 @@ static const NWidgetPart *MakeNWidget(const NWidgetPart *nwid_begin, const NWidg
|
|||
}
|
||||
|
||||
case WPT_PADDING:
|
||||
if (unlikely(*dest == nullptr)) throw std::runtime_error("WPT_PADDING requires NWidgetBase");
|
||||
(*dest)->SetPadding(nwid_begin->u.padding);
|
||||
if (unlikely(dest == nullptr)) throw std::runtime_error("WPT_PADDING requires NWidgetBase");
|
||||
dest->SetPadding(nwid_begin->u.padding);
|
||||
break;
|
||||
|
||||
case WPT_PIPSPACE: {
|
||||
NWidgetPIPContainer *nwc = dynamic_cast<NWidgetPIPContainer *>(*dest);
|
||||
NWidgetPIPContainer *nwc = dynamic_cast<NWidgetPIPContainer *>(dest.get());
|
||||
if (nwc != nullptr) nwc->SetPIP(nwid_begin->u.pip.pre, nwid_begin->u.pip.inter, nwid_begin->u.pip.post);
|
||||
|
||||
NWidgetBackground *nwb = dynamic_cast<NWidgetBackground *>(*dest);
|
||||
NWidgetBackground *nwb = dynamic_cast<NWidgetBackground *>(dest.get());
|
||||
if (nwb != nullptr) nwb->SetPIP(nwid_begin->u.pip.pre, nwid_begin->u.pip.inter, nwid_begin->u.pip.post);
|
||||
|
||||
if (unlikely(nwc == nullptr && nwb == nullptr)) throw std::runtime_error("WPT_PIPSPACE requires NWidgetPIPContainer or NWidgetBackground");
|
||||
|
@ -3212,10 +3160,10 @@ static const NWidgetPart *MakeNWidget(const NWidgetPart *nwid_begin, const NWidg
|
|||
}
|
||||
|
||||
case WPT_PIPRATIO: {
|
||||
NWidgetPIPContainer *nwc = dynamic_cast<NWidgetPIPContainer *>(*dest);
|
||||
NWidgetPIPContainer *nwc = dynamic_cast<NWidgetPIPContainer *>(dest.get());
|
||||
if (nwc != nullptr) nwc->SetPIPRatio(nwid_begin->u.pip.pre, nwid_begin->u.pip.inter, nwid_begin->u.pip.post);
|
||||
|
||||
NWidgetBackground *nwb = dynamic_cast<NWidgetBackground *>(*dest);
|
||||
NWidgetBackground *nwb = dynamic_cast<NWidgetBackground *>(dest.get());
|
||||
if (nwb != nullptr) nwb->SetPIPRatio(nwid_begin->u.pip.pre, nwid_begin->u.pip.inter, nwid_begin->u.pip.post);
|
||||
|
||||
if (unlikely(nwc == nullptr && nwb == nullptr)) throw std::runtime_error("WPT_PIPRATIO requires NWidgetPIPContainer or NWidgetBackground");
|
||||
|
@ -3223,7 +3171,7 @@ static const NWidgetPart *MakeNWidget(const NWidgetPart *nwid_begin, const NWidg
|
|||
}
|
||||
|
||||
case WPT_SCROLLBAR: {
|
||||
NWidgetCore *nwc = dynamic_cast<NWidgetCore *>(*dest);
|
||||
NWidgetCore *nwc = dynamic_cast<NWidgetCore *>(dest.get());
|
||||
if (unlikely(nwc == nullptr)) throw std::runtime_error("WPT_SCROLLBAR requires NWidgetCore");
|
||||
nwc->scrollbar_index = nwid_begin->u.widget.index;
|
||||
break;
|
||||
|
@ -3233,27 +3181,27 @@ static const NWidgetPart *MakeNWidget(const NWidgetPart *nwid_begin, const NWidg
|
|||
return nwid_begin;
|
||||
|
||||
case NWID_VIEWPORT:
|
||||
if (*dest != nullptr) return nwid_begin;
|
||||
*dest = new NWidgetViewport(nwid_begin->u.widget.index);
|
||||
if (dest != nullptr) return nwid_begin;
|
||||
dest = std::make_unique<NWidgetViewport>(nwid_begin->u.widget.index);
|
||||
break;
|
||||
|
||||
case NWID_HSCROLLBAR:
|
||||
case NWID_VSCROLLBAR:
|
||||
if (*dest != nullptr) return nwid_begin;
|
||||
*dest = new NWidgetScrollbar(nwid_begin->type, nwid_begin->u.widget.colour, nwid_begin->u.widget.index);
|
||||
if (dest != nullptr) return nwid_begin;
|
||||
dest = std::make_unique<NWidgetScrollbar>(nwid_begin->type, nwid_begin->u.widget.colour, nwid_begin->u.widget.index);
|
||||
break;
|
||||
|
||||
case NWID_SELECTION: {
|
||||
if (*dest != nullptr) return nwid_begin;
|
||||
*dest = new NWidgetStacked(nwid_begin->u.widget.index);
|
||||
if (dest != nullptr) return nwid_begin;
|
||||
dest = std::make_unique<NWidgetStacked>(nwid_begin->u.widget.index);
|
||||
*fill_dest = true;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (*dest != nullptr) return nwid_begin;
|
||||
if (dest != nullptr) return nwid_begin;
|
||||
assert((nwid_begin->type & WWT_MASK) < WWT_LAST || (nwid_begin->type & WWT_MASK) == NWID_BUTTON_DROPDOWN);
|
||||
*dest = new NWidgetLeaf(nwid_begin->type, nwid_begin->u.widget.colour, nwid_begin->u.widget.index, 0x0, STR_NULL);
|
||||
dest = std::make_unique<NWidgetLeaf>(nwid_begin->type, nwid_begin->u.widget.colour, nwid_begin->u.widget.index, 0x0, STR_NULL);
|
||||
break;
|
||||
}
|
||||
nwid_begin++;
|
||||
|
@ -3280,33 +3228,32 @@ bool IsContainerWidgetType(WidgetType tp)
|
|||
* @param parent Pointer or container to use for storing the child widgets (*parent == nullptr or *parent == container or background widget).
|
||||
* @return Pointer to remaining nested widget parts.
|
||||
*/
|
||||
static const NWidgetPart *MakeWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetBase **parent)
|
||||
static const NWidgetPart *MakeWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, std::unique_ptr<NWidgetBase> &parent)
|
||||
{
|
||||
/* If *parent == nullptr, only the first widget is read and returned. Otherwise, *parent must point to either
|
||||
* a #NWidgetContainer or a #NWidgetBackground object, and parts are added as much as possible. */
|
||||
NWidgetContainer *nwid_cont = dynamic_cast<NWidgetContainer *>(*parent);
|
||||
NWidgetBackground *nwid_parent = dynamic_cast<NWidgetBackground *>(*parent);
|
||||
assert(*parent == nullptr || (nwid_cont != nullptr && nwid_parent == nullptr) || (nwid_cont == nullptr && nwid_parent != nullptr));
|
||||
NWidgetContainer *nwid_cont = dynamic_cast<NWidgetContainer *>(parent.get());
|
||||
NWidgetBackground *nwid_parent = dynamic_cast<NWidgetBackground *>(parent.get());
|
||||
assert(parent == nullptr || (nwid_cont != nullptr && nwid_parent == nullptr) || (nwid_cont == nullptr && nwid_parent != nullptr));
|
||||
|
||||
for (;;) {
|
||||
NWidgetBase *sub_widget = nullptr;
|
||||
std::unique_ptr<NWidgetBase> sub_widget = nullptr;
|
||||
bool fill_sub = false;
|
||||
nwid_begin = MakeNWidget(nwid_begin, nwid_end, &sub_widget, &fill_sub);
|
||||
nwid_begin = MakeNWidget(nwid_begin, nwid_end, sub_widget, &fill_sub);
|
||||
|
||||
/* Break out of loop when end reached */
|
||||
if (sub_widget == nullptr) break;
|
||||
|
||||
/* If sub-widget is a container, recursively fill that container. */
|
||||
if (fill_sub && IsContainerWidgetType(sub_widget->type)) {
|
||||
NWidgetBase *sub_ptr = sub_widget;
|
||||
nwid_begin = MakeWidgetTree(nwid_begin, nwid_end, &sub_ptr);
|
||||
nwid_begin = MakeWidgetTree(nwid_begin, nwid_end, sub_widget);
|
||||
}
|
||||
|
||||
/* Add sub_widget to parent container if available, otherwise return the widget to the caller. */
|
||||
if (nwid_cont != nullptr) nwid_cont->Add(sub_widget);
|
||||
if (nwid_parent != nullptr) nwid_parent->Add(sub_widget);
|
||||
if (nwid_cont != nullptr) nwid_cont->Add(std::move(sub_widget));
|
||||
if (nwid_parent != nullptr) nwid_parent->Add(std::move(sub_widget));
|
||||
if (nwid_cont == nullptr && nwid_parent == nullptr) {
|
||||
*parent = sub_widget;
|
||||
parent = std::move(sub_widget);
|
||||
return nwid_begin;
|
||||
}
|
||||
}
|
||||
|
@ -3326,15 +3273,14 @@ static const NWidgetPart *MakeWidgetTree(const NWidgetPart *nwid_begin, const NW
|
|||
* @return Root of the nested widget tree, a vertical container containing the entire GUI.
|
||||
* @ingroup NestedWidgetParts
|
||||
*/
|
||||
NWidgetContainer *MakeNWidgets(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetContainer *container)
|
||||
std::unique_ptr<NWidgetBase> MakeNWidgets(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, std::unique_ptr<NWidgetBase> &&container)
|
||||
{
|
||||
if (container == nullptr) container = new NWidgetVertical();
|
||||
NWidgetBase *cont_ptr = container;
|
||||
[[maybe_unused]] const NWidgetPart *nwid_part = MakeWidgetTree(nwid_begin, nwid_end, &cont_ptr);
|
||||
if (container == nullptr) container = std::make_unique<NWidgetVertical>();
|
||||
[[maybe_unused]] const NWidgetPart *nwid_part = MakeWidgetTree(nwid_begin, nwid_end, container);
|
||||
#ifdef WITH_ASSERT
|
||||
if (unlikely(nwid_part != nwid_end)) throw std::runtime_error("Did not consume all NWidgetParts");
|
||||
#endif
|
||||
return container;
|
||||
return std::move(container);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3347,38 +3293,33 @@ NWidgetContainer *MakeNWidgets(const NWidgetPart *nwid_begin, const NWidgetPart
|
|||
* @return Root of the nested widget tree, a vertical container containing the entire GUI.
|
||||
* @ingroup NestedWidgetParts
|
||||
*/
|
||||
NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetStacked **shade_select)
|
||||
std::unique_ptr<NWidgetBase> MakeWindowNWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetStacked **shade_select)
|
||||
{
|
||||
*shade_select = nullptr;
|
||||
|
||||
/* Read the first widget recursively from the array. */
|
||||
NWidgetBase *nwid = nullptr;
|
||||
nwid_begin = MakeWidgetTree(nwid_begin, nwid_end, &nwid);
|
||||
std::unique_ptr<NWidgetBase> nwid = nullptr;
|
||||
nwid_begin = MakeWidgetTree(nwid_begin, nwid_end, nwid);
|
||||
assert(nwid != nullptr);
|
||||
|
||||
NWidgetContainer *root = new NWidgetVertical;
|
||||
root->Add(nwid);
|
||||
if (nwid_begin == nwid_end) { // There is no body at all.
|
||||
*shade_select = nullptr;
|
||||
NWidgetHorizontal *hor_cont = dynamic_cast<NWidgetHorizontal *>(nwid.get());
|
||||
|
||||
auto root = std::make_unique<NWidgetVertical>();
|
||||
root->Add(std::move(nwid));
|
||||
if (nwid_begin == nwid_end) return root; // There is no body at all.
|
||||
|
||||
if (hor_cont != nullptr && hor_cont->GetWidgetOfType(WWT_CAPTION) != nullptr && hor_cont->GetWidgetOfType(WWT_SHADEBOX) != nullptr) {
|
||||
/* If the first widget has a title bar and a shade box, silently add a shade selection widget in the tree. */
|
||||
auto shade_stack = std::make_unique<NWidgetStacked>(-1);
|
||||
*shade_select = shade_stack.get();
|
||||
/* Load the remaining parts into the shade stack. */
|
||||
shade_stack->Add(MakeNWidgets(nwid_begin, nwid_end, std::make_unique<NWidgetVertical>()));
|
||||
root->Add(std::move(shade_stack));
|
||||
return root;
|
||||
}
|
||||
|
||||
/* If the first widget looks like a titlebar, treat it as such.
|
||||
* If it has a shading box, silently add a shade selection widget in the tree. */
|
||||
NWidgetHorizontal *hor_cont = dynamic_cast<NWidgetHorizontal *>(nwid);
|
||||
NWidgetContainer *body;
|
||||
if (hor_cont != nullptr && hor_cont->GetWidgetOfType(WWT_CAPTION) != nullptr && hor_cont->GetWidgetOfType(WWT_SHADEBOX) != nullptr) {
|
||||
*shade_select = new NWidgetStacked(-1);
|
||||
root->Add(*shade_select);
|
||||
body = new NWidgetVertical;
|
||||
(*shade_select)->Add(body);
|
||||
} else {
|
||||
*shade_select = nullptr;
|
||||
body = root;
|
||||
}
|
||||
|
||||
/* Load the remaining parts into 'body'. */
|
||||
MakeNWidgets(nwid_begin, nwid_end, body);
|
||||
|
||||
return root;
|
||||
/* Load the remaining parts into 'root'. */
|
||||
return MakeNWidgets(nwid_begin, nwid_end, std::move(root));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3390,11 +3331,11 @@ NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *nwid_begin, const NWi
|
|||
* @param button_tooltip The tooltip-string of every button.
|
||||
* @return Panel with rows of company buttons.
|
||||
*/
|
||||
NWidgetBase *MakeCompanyButtonRows(WidgetID widget_first, WidgetID widget_last, Colours button_colour, int max_length, StringID button_tooltip)
|
||||
std::unique_ptr<NWidgetBase> MakeCompanyButtonRows(WidgetID widget_first, WidgetID widget_last, Colours button_colour, int max_length, StringID button_tooltip)
|
||||
{
|
||||
assert(max_length >= 1);
|
||||
NWidgetVertical *vert = nullptr; // Storage for all rows.
|
||||
NWidgetHorizontal *hor = nullptr; // Storage for buttons in one row.
|
||||
std::unique_ptr<NWidgetVertical> vert = nullptr; // Storage for all rows.
|
||||
std::unique_ptr<NWidgetHorizontal> hor = nullptr; // Storage for buttons in one row.
|
||||
int hor_length = 0;
|
||||
|
||||
Dimension sprite_size = GetSpriteSize(SPR_COMPANY_ICON, nullptr, ZOOM_LVL_OUT_4X);
|
||||
|
@ -3404,33 +3345,33 @@ NWidgetBase *MakeCompanyButtonRows(WidgetID widget_first, WidgetID widget_last,
|
|||
for (WidgetID widnum = widget_first; widnum <= widget_last; widnum++) {
|
||||
/* Ensure there is room in 'hor' for another button. */
|
||||
if (hor_length == max_length) {
|
||||
if (vert == nullptr) vert = new NWidgetVertical();
|
||||
vert->Add(hor);
|
||||
if (vert == nullptr) vert = std::make_unique<NWidgetVertical>();
|
||||
vert->Add(std::move(hor));
|
||||
hor = nullptr;
|
||||
hor_length = 0;
|
||||
}
|
||||
if (hor == nullptr) {
|
||||
hor = new NWidgetHorizontal();
|
||||
hor = std::make_unique<NWidgetHorizontal>();
|
||||
hor_length = 0;
|
||||
}
|
||||
|
||||
NWidgetBackground *panel = new NWidgetBackground(WWT_PANEL, button_colour, widnum);
|
||||
auto panel = std::make_unique<NWidgetBackground>(WWT_PANEL, button_colour, widnum);
|
||||
panel->SetMinimalSize(sprite_size.width, sprite_size.height);
|
||||
panel->SetFill(1, 1);
|
||||
panel->SetResize(1, 0);
|
||||
panel->SetDataTip(0x0, button_tooltip);
|
||||
hor->Add(panel);
|
||||
hor->Add(std::move(panel));
|
||||
hor_length++;
|
||||
}
|
||||
if (vert == nullptr) return hor; // All buttons fit in a single row.
|
||||
|
||||
if (hor_length > 0 && hor_length < max_length) {
|
||||
/* Last row is partial, add a spacer at the end to force all buttons to the left. */
|
||||
NWidgetSpacer *spc = new NWidgetSpacer(sprite_size.width, sprite_size.height);
|
||||
auto spc = std::make_unique<NWidgetSpacer>(sprite_size.width, sprite_size.height);
|
||||
spc->SetFill(1, 1);
|
||||
spc->SetResize(1, 0);
|
||||
hor->Add(spc);
|
||||
hor->Add(std::move(spc));
|
||||
}
|
||||
if (hor != nullptr) vert->Add(hor);
|
||||
if (hor != nullptr) vert->Add(std::move(hor));
|
||||
return vert;
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@ enum WidgetType {
|
|||
NWID_BUTTON_DROPDOWN, ///< Button with a drop-down.
|
||||
NWID_HSCROLLBAR, ///< Horizontal scrollbar
|
||||
NWID_VSCROLLBAR, ///< Vertical scrollbar
|
||||
NWID_CUSTOM, ///< General Custom widget.
|
||||
|
||||
/* Nested widget part types. */
|
||||
WPT_RESIZE, ///< Widget part for specifying resizing.
|
||||
|
@ -235,9 +236,6 @@ public:
|
|||
int pos_x; ///< Horizontal position of top-left corner of the widget in the window.
|
||||
int pos_y; ///< Vertical position of top-left corner of the widget in the window.
|
||||
|
||||
NWidgetBase *next; ///< Pointer to next widget in container. Managed by parent container widget.
|
||||
NWidgetBase *prev; ///< Pointer to previous widget in container. Managed by parent container widget.
|
||||
|
||||
RectPadding padding; ///< Padding added to the widget. Managed by parent container widget. (parent container may swap left and right for RTL)
|
||||
RectPadding uz_padding; ///< Unscaled padding, for resize calculation.
|
||||
|
||||
|
@ -446,24 +444,22 @@ inline bool NWidgetCore::IsDisabled() const
|
|||
*/
|
||||
class NWidgetContainer : public NWidgetBase {
|
||||
public:
|
||||
NWidgetContainer(WidgetType tp);
|
||||
~NWidgetContainer();
|
||||
NWidgetContainer(WidgetType tp) : NWidgetBase(tp) { }
|
||||
|
||||
void AdjustPaddingForZoom() override;
|
||||
void Add(NWidgetBase *wid);
|
||||
void Add(std::unique_ptr<NWidgetBase> &&wid);
|
||||
void FillWidgetLookup(WidgetLookup &widget_lookup) override;
|
||||
|
||||
void Draw(const Window *w) override;
|
||||
NWidgetCore *GetWidgetFromPos(int x, int y) override;
|
||||
|
||||
/** Return whether the container is empty. */
|
||||
inline bool IsEmpty() { return head == nullptr; }
|
||||
inline bool IsEmpty() { return this->children.empty(); }
|
||||
|
||||
NWidgetBase *GetWidgetOfType(WidgetType tp) override;
|
||||
|
||||
protected:
|
||||
NWidgetBase *head; ///< Pointer to first widget in container.
|
||||
NWidgetBase *tail; ///< Pointer to last widget in container.
|
||||
std::vector<std::unique_ptr<NWidgetBase>> children; ///< Child widgets in contaier.
|
||||
};
|
||||
|
||||
/** Display planes with zero size for #NWidgetStacked. */
|
||||
|
@ -636,10 +632,9 @@ public:
|
|||
*/
|
||||
class NWidgetBackground : public NWidgetCore {
|
||||
public:
|
||||
NWidgetBackground(WidgetType tp, Colours colour, WidgetID index, NWidgetPIPContainer *child = nullptr);
|
||||
~NWidgetBackground();
|
||||
NWidgetBackground(WidgetType tp, Colours colour, WidgetID index, std::unique_ptr<NWidgetPIPContainer> &&child = nullptr);
|
||||
|
||||
void Add(NWidgetBase *nwid);
|
||||
void Add(std::unique_ptr<NWidgetBase> &&nwid);
|
||||
void SetPIP(uint8_t pip_pre, uint8_t pip_inter, uint8_t pip_post);
|
||||
void SetPIPRatio(uint8_t pip_ratio_pre, uint8_t pip_ratio_inter, uint8_t pip_ratio_post);
|
||||
|
||||
|
@ -654,7 +649,7 @@ public:
|
|||
NWidgetBase *GetWidgetOfType(WidgetType tp) override;
|
||||
|
||||
private:
|
||||
NWidgetPIPContainer *child; ///< Child widget.
|
||||
std::unique_ptr<NWidgetPIPContainer> child; ///< Child widget.
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1034,7 +1029,7 @@ struct NWidgetPartAlignment {
|
|||
* Pointer to function returning a nested widget.
|
||||
* @return Nested widget (tree).
|
||||
*/
|
||||
typedef NWidgetBase *NWidgetFunctionType();
|
||||
typedef std::unique_ptr<NWidgetBase> NWidgetFunctionType();
|
||||
|
||||
/**
|
||||
* Partial widget specification to allow NWidgets to be written nested.
|
||||
|
@ -1358,10 +1353,10 @@ static inline NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
|
|||
}
|
||||
|
||||
bool IsContainerWidgetType(WidgetType tp);
|
||||
NWidgetContainer *MakeNWidgets(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetContainer *container);
|
||||
NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetStacked **shade_select);
|
||||
std::unique_ptr<NWidgetBase> MakeNWidgets(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, std::unique_ptr<NWidgetBase> &&container);
|
||||
std::unique_ptr<NWidgetBase> MakeWindowNWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetStacked **shade_select);
|
||||
|
||||
NWidgetBase *MakeCompanyButtonRows(WidgetID widget_first, WidgetID widget_last, Colours button_colour, int max_length, StringID button_tooltip);
|
||||
std::unique_ptr<NWidgetBase> MakeCompanyButtonRows(WidgetID widget_first, WidgetID widget_last, Colours button_colour, int max_length, StringID button_tooltip);
|
||||
|
||||
void SetupWidgetDimensions();
|
||||
|
||||
|
|
|
@ -1088,7 +1088,6 @@ Window::~Window()
|
|||
assert(*this->z_position == nullptr);
|
||||
|
||||
if (this->viewport != nullptr) DeleteWindowViewport(this);
|
||||
delete this->nested_root;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -259,7 +259,7 @@ public:
|
|||
ViewportData *viewport; ///< Pointer to viewport data, if present.
|
||||
const NWidgetCore *nested_focus; ///< Currently focused nested widget, or \c nullptr if no nested widget has focus.
|
||||
std::map<int, QueryString*> querystrings; ///< QueryString associated to WWT_EDITBOX widgets.
|
||||
NWidgetBase *nested_root; ///< Root of the nested tree.
|
||||
std::unique_ptr<NWidgetBase> nested_root; ///< Root of the nested tree.
|
||||
WidgetLookup widget_lookup; ///< Indexed access to the nested widget tree. Do not access directly, use #Window::GetWidget() instead.
|
||||
NWidgetStacked *shade_select; ///< Selection widget (#NWID_SELECTION) to use for shading the window. If \c nullptr, window cannot shade.
|
||||
Dimension unshaded_size; ///< Last known unshaded size (only valid while shaded).
|
||||
|
|
Loading…
Reference in New Issue