Codechange: Use std::unique_ptr for all NWidgets.

This commit is contained in:
Peter Nelson 2023-12-30 07:36:22 +00:00 committed by Peter Nelson
parent 9a3934ae23
commit 7124b4eef1
15 changed files with 200 additions and 212 deletions

View File

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

View File

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

View File

@ -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
@ -866,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[] = {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2122,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[] = {
@ -2159,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:
@ -2168,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;
@ -2514,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[] = {

View File

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

View File

@ -1297,11 +1297,11 @@ 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;
this->children.emplace_back(wid);
this->children.push_back(std::move(wid));
}
void NWidgetContainer::FillWidgetLookup(WidgetLookup &widget_lookup)
@ -2121,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.
@ -2141,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));
}
/**
@ -2163,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);
@ -2182,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);
@ -3043,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);
@ -3104,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);
@ -3112,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);
@ -3120,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;
@ -3149,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");
@ -3165,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");
@ -3176,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;
@ -3186,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++;
@ -3233,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;
}
}
@ -3279,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);
}
/**
@ -3300,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));
}
/**
@ -3343,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);
@ -3357,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;
}

View File

@ -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.
@ -446,7 +447,7 @@ public:
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;
@ -631,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);
@ -649,7 +649,7 @@ public:
NWidgetBase *GetWidgetOfType(WidgetType tp) override;
private:
NWidgetPIPContainer *child; ///< Child widget.
std::unique_ptr<NWidgetPIPContainer> child; ///< Child widget.
};
/**
@ -1029,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.
@ -1353,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();

View File

@ -1088,7 +1088,6 @@ Window::~Window()
assert(*this->z_position == nullptr);
if (this->viewport != nullptr) DeleteWindowViewport(this);
delete this->nested_root;
}
/**

View File

@ -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).