Changeset - r28351:b17bd3a7c49f
[Not reviewed]
master
0 16 0
Peter Nelson - 14 months ago 2023-10-16 10:13:36
peter1138@openttd.org
Codechange: Use std::map to provide indexed widget access.

This removes the need to determine the biggest widget index and replaces C-style memory handling.
16 files changed with 150 insertions and 212 deletions:
0 comments (0 inline, 0 general)
src/graph_gui.cpp
Show inline comments
 
@@ -107,11 +107,9 @@ struct GraphLegendWindow : Window {
 

	
 
/**
 
 * Construct a vertical list of buttons, one for each company.
 
 * @param biggest_index Storage for collecting the biggest index used in the returned tree.
 
 * @return Panel with company buttons.
 
 * @post \c *biggest_index contains the largest used index in the tree.
 
 */
 
static NWidgetBase *MakeNWidgetCompanyLines(int *biggest_index)
 
static NWidgetBase *MakeNWidgetCompanyLines()
 
{
 
	NWidgetVertical *vert = new NWidgetVertical(NC_EQUALSIZE);
 
	vert->SetPadding(2, 2, 2, 2);
 
@@ -125,7 +123,6 @@ static NWidgetBase *MakeNWidgetCompanyLi
 
		panel->SetDataTip(0x0, STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP);
 
		vert->Add(panel);
 
	}
 
	*biggest_index = WID_GL_LAST_COMPANY;
 
	return vert;
 
}
 

	
 
@@ -1338,11 +1335,9 @@ CompanyID PerformanceRatingDetailWindow:
 

	
 
/**
 
 * Make a vertical list of panels for outputting score details.
 
 * @param biggest_index Storage for collecting the biggest index used in the returned tree.
 
 * @return Panel with performance details.
 
 * @post \c *biggest_index contains the largest used index in the tree.
 
 */
 
static NWidgetBase *MakePerformanceDetailPanels(int *biggest_index)
 
static NWidgetBase *MakePerformanceDetailPanels()
 
{
 
	const StringID performance_tips[] = {
 
		STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP,
 
@@ -1366,14 +1361,13 @@ static NWidgetBase *MakePerformanceDetai
 
		panel->SetDataTip(0x0, performance_tips[widnum - WID_PRD_SCORE_FIRST]);
 
		vert->Add(panel);
 
	}
 
	*biggest_index = WID_PRD_SCORE_LAST;
 
	return vert;
 
}
 

	
 
/** Make a number of rows with buttons for each company for the performance rating detail window. */
 
NWidgetBase *MakeCompanyButtonRowsGraphGUI(int *biggest_index)
 
NWidgetBase *MakeCompanyButtonRowsGraphGUI()
 
{
 
	return MakeCompanyButtonRows(biggest_index, WID_PRD_COMPANY_FIRST, WID_PRD_COMPANY_LAST, COLOUR_BROWN, 8, STR_PERFORMANCE_DETAIL_SELECT_COMPANY_TOOLTIP);
 
	return MakeCompanyButtonRows(WID_PRD_COMPANY_FIRST, WID_PRD_COMPANY_LAST, COLOUR_BROWN, 8, STR_PERFORMANCE_DETAIL_SELECT_COMPANY_TOOLTIP);
 
}
 

	
 
static const NWidgetPart _nested_performance_rating_detail_widgets[] = {
src/linkgraph/linkgraph_gui.cpp
Show inline comments
 
@@ -454,12 +454,12 @@ void LinkGraphOverlay::SetCompanyMask(Co
 
}
 

	
 
/** Make a number of rows with buttons for each company for the linkgraph legend window. */
 
NWidgetBase *MakeCompanyButtonRowsLinkGraphGUI(int *biggest_index)
 
NWidgetBase *MakeCompanyButtonRowsLinkGraphGUI()
 
{
 
	return MakeCompanyButtonRows(biggest_index, WID_LGL_COMPANY_FIRST, WID_LGL_COMPANY_LAST, COLOUR_GREY, 3, STR_NULL);
 
	return MakeCompanyButtonRows(WID_LGL_COMPANY_FIRST, WID_LGL_COMPANY_LAST, COLOUR_GREY, 3, STR_NULL);
 
}
 

	
 
NWidgetBase *MakeSaturationLegendLinkGraphGUI(int *biggest_index)
 
NWidgetBase *MakeSaturationLegendLinkGraphGUI()
 
{
 
	NWidgetVertical *panel = new NWidgetVertical(NC_EQUALSIZE);
 
	for (uint i = 0; i < lengthof(LinkGraphOverlay::LINK_COLOURS[0]); ++i) {
 
@@ -470,11 +470,10 @@ NWidgetBase *MakeSaturationLegendLinkGra
 
		wid->SetResize(0, 0);
 
		panel->Add(wid);
 
	}
 
	*biggest_index = WID_LGL_SATURATION_LAST;
 
	return panel;
 
}
 

	
 
NWidgetBase *MakeCargoesLegendLinkGraphGUI(int *biggest_index)
 
NWidgetBase *MakeCargoesLegendLinkGraphGUI()
 
{
 
	uint num_cargo = static_cast<uint>(_sorted_cargo_specs.size());
 
	static const uint ENTRIES_PER_COL = 5;
 
@@ -503,7 +502,6 @@ NWidgetBase *MakeCargoesLegendLinkGraphG
 
	}
 
	/* 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);
 
	*biggest_index = WID_LGL_CARGO_LAST;
 
	return panel;
 
}
 

	
src/network/network_gui.cpp
Show inline comments
 
@@ -855,9 +855,8 @@ GUIGameServerList::FilterFunction * cons
 
	&NGameSearchFilter
 
};
 

	
 
static NWidgetBase *MakeResizableHeader(int *biggest_index)
 
static NWidgetBase *MakeResizableHeader()
 
{
 
	*biggest_index = std::max<int>(*biggest_index, WID_NG_INFO);
 
	return new NWidgetServerListHeader();
 
}
 

	
src/newgrf_gui.cpp
Show inline comments
 
@@ -1937,16 +1937,11 @@ static const NWidgetPart _nested_newgrf_
 
};
 

	
 
/** Construct nested container widget for managing the lists and the info panel of the NewGRF GUI. */
 
NWidgetBase* NewGRFDisplay(int *biggest_index)
 
NWidgetBase* NewGRFDisplay()
 
{
 
	NWidgetBase *avs = MakeNWidgets(std::begin(_nested_newgrf_availables_widgets), std::end(_nested_newgrf_availables_widgets), biggest_index, nullptr);
 

	
 
	int biggest2;
 
	NWidgetBase *acs = MakeNWidgets(std::begin(_nested_newgrf_actives_widgets), std::end(_nested_newgrf_actives_widgets), &biggest2, nullptr);
 
	*biggest_index = std::max(*biggest_index, biggest2);
 

	
 
	NWidgetBase *inf = MakeNWidgets(std::begin(_nested_newgrf_infopanel_widgets), std::end(_nested_newgrf_infopanel_widgets), &biggest2, nullptr);
 
	*biggest_index = std::max(*biggest_index, biggest2);
 
	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);
 

	
 
	return new NWidgetNewGRFDisplay(avs, acs, inf);
 
}
src/osk_gui.cpp
Show inline comments
 
@@ -220,10 +220,9 @@ static const int KEY_PADDING = 6;     //
 
 * @param widtype Widget type of the key. Must be either \c NWID_SPACER for an invisible key, or a \c WWT_* widget.
 
 * @param widnum  Widget number of the key.
 
 * @param widdata Data value of the key widget.
 
 * @param biggest_index Collected biggest widget index so far.
 
 * @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, int widnum, uint16_t widdata, int *biggest_index)
 
static void AddKey(NWidgetHorizontal *hor, int pad_y, int num_half, WidgetType widtype, int widnum, uint16_t widdata)
 
{
 
	int key_width = HALF_KEY_WIDTH + (INTER_KEY_SPACE + HALF_KEY_WIDTH) * (num_half - 1);
 

	
 
@@ -243,80 +242,78 @@ static void AddKey(NWidgetHorizontal *ho
 
		leaf->SetMinimalTextLines(1, pad_y, FS_NORMAL);
 
		hor->Add(leaf);
 
	}
 

	
 
	*biggest_index = std::max(*biggest_index, widnum);
 
}
 

	
 
/** Construct the top row keys (cancel, ok, backspace). */
 
static NWidgetBase *MakeTopKeys(int *biggest_index)
 
static NWidgetBase *MakeTopKeys()
 
{
 
	NWidgetHorizontal *hor = new NWidgetHorizontal();
 

	
 
	AddKey(hor, TOP_KEY_PADDING, 6 * 2, WWT_TEXTBTN,    WID_OSK_CANCEL,    STR_BUTTON_CANCEL, biggest_index);
 
	AddKey(hor, TOP_KEY_PADDING, 6 * 2, WWT_TEXTBTN,    WID_OSK_OK,        STR_BUTTON_OK,     biggest_index);
 
	AddKey(hor, TOP_KEY_PADDING, 2 * 2, WWT_PUSHIMGBTN, WID_OSK_BACKSPACE, SPR_OSK_BACKSPACE, biggest_index);
 
	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    );
 
	AddKey(hor, TOP_KEY_PADDING, 2 * 2, WWT_PUSHIMGBTN, WID_OSK_BACKSPACE, SPR_OSK_BACKSPACE);
 
	return hor;
 
}
 

	
 
/** Construct the row containing the digit keys. */
 
static NWidgetBase *MakeNumberKeys(int *biggest_index)
 
static NWidgetBase *MakeNumberKeys()
 
{
 
	NWidgetHorizontal *hor = new NWidgetHorizontalLTR();
 

	
 
	for (int widnum = WID_OSK_NUMBERS_FIRST; widnum <= WID_OSK_NUMBERS_LAST; widnum++) {
 
		AddKey(hor, KEY_PADDING, 2, WWT_PUSHBTN, widnum, 0x0, biggest_index);
 
		AddKey(hor, KEY_PADDING, 2, WWT_PUSHBTN, widnum, 0x0);
 
	}
 
	return hor;
 
}
 

	
 
/** Construct the qwerty row keys. */
 
static NWidgetBase *MakeQwertyKeys(int *biggest_index)
 
static NWidgetBase *MakeQwertyKeys()
 
{
 
	NWidgetHorizontal *hor = new NWidgetHorizontalLTR();
 

	
 
	AddKey(hor, KEY_PADDING, 3, WWT_PUSHIMGBTN, WID_OSK_SPECIAL, SPR_OSK_SPECIAL, biggest_index);
 
	AddKey(hor, KEY_PADDING, 3, WWT_PUSHIMGBTN, WID_OSK_SPECIAL, SPR_OSK_SPECIAL);
 
	for (int widnum = WID_OSK_QWERTY_FIRST; widnum <= WID_OSK_QWERTY_LAST; widnum++) {
 
		AddKey(hor, KEY_PADDING, 2, WWT_PUSHBTN, widnum, 0x0, biggest_index);
 
		AddKey(hor, KEY_PADDING, 2, WWT_PUSHBTN, widnum, 0x0);
 
	}
 
	AddKey(hor, KEY_PADDING, 1, NWID_SPACER, 0, 0, biggest_index);
 
	AddKey(hor, KEY_PADDING, 1, NWID_SPACER, 0, 0);
 
	return hor;
 
}
 

	
 
/** Construct the asdfg row keys. */
 
static NWidgetBase *MakeAsdfgKeys(int *biggest_index)
 
static NWidgetBase *MakeAsdfgKeys()
 
{
 
	NWidgetHorizontal *hor = new NWidgetHorizontalLTR();
 

	
 
	AddKey(hor, KEY_PADDING, 4, WWT_IMGBTN, WID_OSK_CAPS, SPR_OSK_CAPS, biggest_index);
 
	AddKey(hor, KEY_PADDING, 4, WWT_IMGBTN, WID_OSK_CAPS, SPR_OSK_CAPS);
 
	for (int widnum = WID_OSK_ASDFG_FIRST; widnum <= WID_OSK_ASDFG_LAST; widnum++) {
 
		AddKey(hor, KEY_PADDING, 2, WWT_PUSHBTN, widnum, 0x0, biggest_index);
 
		AddKey(hor, KEY_PADDING, 2, WWT_PUSHBTN, widnum, 0x0);
 
	}
 
	return hor;
 
}
 

	
 
/** Construct the zxcvb row keys. */
 
static NWidgetBase *MakeZxcvbKeys(int *biggest_index)
 
static NWidgetBase *MakeZxcvbKeys()
 
{
 
	NWidgetHorizontal *hor = new NWidgetHorizontalLTR();
 

	
 
	AddKey(hor, KEY_PADDING, 3, WWT_IMGBTN, WID_OSK_SHIFT, SPR_OSK_SHIFT, biggest_index);
 
	AddKey(hor, KEY_PADDING, 3, WWT_IMGBTN, WID_OSK_SHIFT, SPR_OSK_SHIFT);
 
	for (int widnum = WID_OSK_ZXCVB_FIRST; widnum <= WID_OSK_ZXCVB_LAST; widnum++) {
 
		AddKey(hor, KEY_PADDING, 2, WWT_PUSHBTN, widnum, 0x0, biggest_index);
 
		AddKey(hor, KEY_PADDING, 2, WWT_PUSHBTN, widnum, 0x0);
 
	}
 
	AddKey(hor, KEY_PADDING, 1, NWID_SPACER, 0, 0, biggest_index);
 
	AddKey(hor, KEY_PADDING, 1, NWID_SPACER, 0, 0);
 
	return hor;
 
}
 

	
 
/** Construct the spacebar row keys. */
 
static NWidgetBase *MakeSpacebarKeys(int *biggest_index)
 
static NWidgetBase *MakeSpacebarKeys()
 
{
 
	NWidgetHorizontal *hor = new NWidgetHorizontal();
 

	
 
	AddKey(hor, KEY_PADDING,  8, NWID_SPACER, 0, 0, biggest_index);
 
	AddKey(hor, KEY_PADDING, 13, WWT_PUSHTXTBTN, WID_OSK_SPACE, STR_EMPTY, biggest_index);
 
	AddKey(hor, KEY_PADDING,  3, NWID_SPACER, 0, 0, biggest_index);
 
	AddKey(hor, KEY_PADDING,  2, WWT_PUSHIMGBTN, WID_OSK_LEFT,  SPR_OSK_LEFT, biggest_index);
 
	AddKey(hor, KEY_PADDING,  2, WWT_PUSHIMGBTN, WID_OSK_RIGHT, SPR_OSK_RIGHT, biggest_index);
 
	AddKey(hor, KEY_PADDING,  8, NWID_SPACER, 0, 0);
 
	AddKey(hor, KEY_PADDING, 13, WWT_PUSHTXTBTN, WID_OSK_SPACE, STR_EMPTY);
 
	AddKey(hor, KEY_PADDING,  3, NWID_SPACER, 0, 0);
 
	AddKey(hor, KEY_PADDING,  2, WWT_PUSHIMGBTN, WID_OSK_LEFT,  SPR_OSK_LEFT);
 
	AddKey(hor, KEY_PADDING,  2, WWT_PUSHIMGBTN, WID_OSK_RIGHT, SPR_OSK_RIGHT);
 
	return hor;
 
}
 

	
src/script/script_gui.cpp
Show inline comments
 
@@ -1229,9 +1229,9 @@ struct ScriptDebugWindow : public Window
 
};
 

	
 
/** Make a number of rows with buttons for each company for the Script debug window. */
 
NWidgetBase *MakeCompanyButtonRowsScriptDebug(int *biggest_index)
 
NWidgetBase *MakeCompanyButtonRowsScriptDebug()
 
{
 
	return MakeCompanyButtonRows(biggest_index, WID_SCRD_COMPANY_BUTTON_START, WID_SCRD_COMPANY_BUTTON_END, COLOUR_GREY, 8, STR_AI_DEBUG_SELECT_AI_TOOLTIP);
 
	return MakeCompanyButtonRows(WID_SCRD_COMPANY_BUTTON_START, WID_SCRD_COMPANY_BUTTON_END, COLOUR_GREY, 8, STR_AI_DEBUG_SELECT_AI_TOOLTIP);
 
}
 

	
 
/** Widgets for the Script debug window. */
src/smallmap_gui.cpp
Show inline comments
 
@@ -1942,12 +1942,12 @@ static const NWidgetPart _nested_smallma
 
	EndContainer(),
 
};
 

	
 
static NWidgetBase *SmallMapDisplay(int *biggest_index)
 
static NWidgetBase *SmallMapDisplay()
 
{
 
	NWidgetContainer *map_display = new NWidgetSmallmapDisplay;
 

	
 
	MakeNWidgets(std::begin(_nested_smallmap_display), std::end(_nested_smallmap_display), biggest_index, map_display);
 
	MakeNWidgets(std::begin(_nested_smallmap_bar), std::end(_nested_smallmap_bar), biggest_index, map_display);
 
	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);
 
	return map_display;
 
}
 

	
src/station_gui.cpp
Show inline comments
 
@@ -714,10 +714,9 @@ const StringID CompanyStationsWindow::so
 

	
 
/**
 
 * Make a horizontal row of cargo buttons, starting at widget #WID_STL_CARGOSTART.
 
 * @param biggest_index Pointer to store biggest used widget number of the buttons.
 
 * @return Horizontal row.
 
 */
 
static NWidgetBase *CargoWidgets(int *biggest_index)
 
static NWidgetBase *CargoWidgets()
 
{
 
	NWidgetHorizontal *container = new NWidgetHorizontal();
 

	
 
@@ -730,7 +729,6 @@ static NWidgetBase *CargoWidgets(int *bi
 
		panel->SetDataTip(0, STR_STATION_LIST_USE_CTRL_TO_SELECT_MORE);
 
		container->Add(panel);
 
	}
 
	*biggest_index = WID_STL_CARGOSTART + static_cast<int>(_sorted_standard_cargo_specs.size());
 
	return container;
 
}
 

	
src/terraform_gui.cpp
Show inline comments
 
@@ -646,9 +646,9 @@ struct ScenarioEditorLandscapeGeneration
 

	
 
	void OnTimeout() override
 
	{
 
		for (uint i = WID_ETT_START; i < this->nested_array_size; i++) {
 
			if (i == WID_ETT_BUTTONS_START) i = WID_ETT_BUTTONS_END; // skip the buttons
 
			this->RaiseWidgetWhenLowered(i);
 
		for (const auto &pair : this->widget_lookup) {
 
			if (pair.first < WID_ETT_START || (pair.first >= WID_ETT_BUTTONS_START && pair.first < WID_ETT_BUTTONS_END)) continue; // skip the buttons
 
			this->RaiseWidgetWhenLowered(pair.first);
 
		}
 
	}
 

	
src/tests/test_window_desc.cpp
Show inline comments
 
@@ -89,11 +89,10 @@ TEST_CASE_METHOD(WindowDescTestsFixture,
 

	
 
	INFO(fmt::format("{}:{}", window_desc->file, window_desc->line));
 

	
 
	int biggest_index = -1;
 
	NWidgetStacked *shade_select = nullptr;
 
	NWidgetBase *root = nullptr;
 

	
 
	REQUIRE_NOTHROW(root = MakeWindowNWidgetTree(window_desc->nwid_begin, window_desc->nwid_end, &biggest_index, &shade_select));
 
	REQUIRE_NOTHROW(root = MakeWindowNWidgetTree(window_desc->nwid_begin, window_desc->nwid_end, &shade_select));
 
	CHECK((root != nullptr));
 
	delete root;
 
}
src/toolbar_gui.cpp
Show inline comments
 
@@ -2120,7 +2120,7 @@ struct MainToolbarWindow : Window {
 
	}};
 
};
 

	
 
static NWidgetBase *MakeMainToolbar(int *biggest_index)
 
static NWidgetBase *MakeMainToolbar()
 
{
 
	/** Sprites to use for the different toolbar buttons */
 
	static const SpriteID toolbar_button_sprites[] = {
 
@@ -2174,7 +2174,6 @@ static NWidgetBase *MakeMainToolbar(int 
 
		hor->Add(leaf);
 
	}
 

	
 
	*biggest_index = std::max<int>(*biggest_index, WID_TN_SWITCH_BAR);
 
	return hor;
 
}
 

	
 
@@ -2513,9 +2512,9 @@ static const NWidgetPart _nested_toolb_s
 
	NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SWITCH_BAR), SetDataTip(SPR_IMG_SWITCH_TOOLBAR, STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR),
 
};
 

	
 
static NWidgetBase *MakeScenarioToolbar(int *biggest_index)
 
static NWidgetBase *MakeScenarioToolbar()
 
{
 
	return MakeNWidgets(std::begin(_nested_toolb_scen_inner_widgets), std::end(_nested_toolb_scen_inner_widgets), biggest_index, new NWidgetScenarioToolbarContainer());
 
	return MakeNWidgets(std::begin(_nested_toolb_scen_inner_widgets), std::end(_nested_toolb_scen_inner_widgets), new NWidgetScenarioToolbarContainer());
 
}
 

	
 
static const NWidgetPart _nested_toolb_scen_widgets[] = {
src/tree_gui.cpp
Show inline comments
 
@@ -256,7 +256,7 @@ public:
 
 * get producing the correct result than dynamically building the widgets is.
 
 * @see NWidgetFunctionType
 
 */
 
static NWidgetBase *MakeTreeTypeButtons(int *biggest_index)
 
static 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];
 
@@ -278,7 +278,6 @@ static NWidgetBase *MakeTreeTypeButtons(
 
			NWidgetBackground *button = new NWidgetBackground(WWT_PANEL, COLOUR_GREY, WID_BT_TYPE_BUTTON_FIRST + cur_type);
 
			button->SetDataTip(0x0, STR_PLANT_TREE_TOOLTIP);
 
			hstack->Add(button);
 
			*biggest_index = WID_BT_TYPE_BUTTON_FIRST + cur_type;
 
			cur_type++;
 
		}
 
	}
src/widget.cpp
Show inline comments
 
@@ -877,9 +877,9 @@ void Window::DrawWidgets() const
 

	
 
	if (this->flags & WF_HIGHLIGHTED) {
 
		extern bool _window_highlight_colour;
 
		for (uint i = 0; i < this->nested_array_size; i++) {
 
			const NWidgetBase *widget = this->GetWidget<NWidgetBase>(i);
 
			if (widget == nullptr || !widget->IsHighlighted()) continue;
 
		for (const auto &pair : this->widget_lookup) {
 
			const NWidgetBase *widget = pair.second;
 
			if (!widget->IsHighlighted()) continue;
 

	
 
			Rect outer = widget->GetCurrentRect();
 
			Rect inner = outer.Shrink(WidgetDimensions::scaled.bevel).Expand(1);
 
@@ -903,7 +903,7 @@ void Window::DrawSortButtonState(int wid
 
{
 
	if (state == SBS_OFF) return;
 

	
 
	assert(this->widget_lookup != nullptr);
 
	assert(!this->widget_lookup.empty());
 
	Rect r = this->GetWidget<NWidgetBase>(widget)->GetCurrentRect();
 

	
 
	/* Sort button uses the same sprites as vertical scrollbar */
 
@@ -1023,10 +1023,9 @@ NWidgetBase::NWidgetBase(WidgetType tp) 
 
 */
 

	
 
/**
 
 * @fn void NWidgetBase::FillWidgetLookup(NWidgetBase **widget_lookup, uint length)
 
 * Fill the Window::widget_lookup array with pointers to nested widgets in the tree.
 
 * @param array Base pointer of the array.
 
 * @param length Length of the array.
 
 * @fn void NWidgetBase::FillWidgetLookup(WidgetLookup &widget_lookup)
 
 * Fill the Window::widget_lookup with pointers to nested widgets in the tree.
 
 * @param widget_lookup The WidgetLookup.
 
 */
 

	
 
/**
 
@@ -1276,9 +1275,9 @@ void NWidgetCore::SetAlignment(StringAli
 
	this->align = align;
 
}
 

	
 
void NWidgetCore::FillWidgetLookup(NWidgetBase **widget_lookup, uint length)
 
void NWidgetCore::FillWidgetLookup(WidgetLookup &widget_lookup)
 
{
 
	if (this->index >= 0 && (uint)(this->index) < length) widget_lookup[this->index] = this;
 
	if (this->index >= 0) widget_lookup[this->index] = this;
 
}
 

	
 
NWidgetCore *NWidgetCore::GetWidgetFromPos(int x, int y)
 
@@ -1345,10 +1344,10 @@ void NWidgetContainer::Add(NWidgetBase *
 
	}
 
}
 

	
 
void NWidgetContainer::FillWidgetLookup(NWidgetBase **widget_lookup, uint length)
 
void NWidgetContainer::FillWidgetLookup(WidgetLookup &widget_lookup)
 
{
 
	for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
 
		child_wid->FillWidgetLookup(widget_lookup, length);
 
		child_wid->FillWidgetLookup(widget_lookup);
 
	}
 
}
 

	
 
@@ -1452,10 +1451,10 @@ void NWidgetStacked::AssignSizePosition(
 
	}
 
}
 

	
 
void NWidgetStacked::FillWidgetLookup(NWidgetBase **widget_lookup, uint length)
 
void NWidgetStacked::FillWidgetLookup(WidgetLookup &widget_lookup)
 
{
 
	if (this->index >= 0 && (uint)(this->index) < length) widget_lookup[this->index] = this;
 
	NWidgetContainer::FillWidgetLookup(widget_lookup, length);
 
	if (this->index >= 0) widget_lookup[this->index] = this;
 
	NWidgetContainer::FillWidgetLookup(widget_lookup);
 
}
 

	
 
void NWidgetStacked::Draw(const Window *w)
 
@@ -1564,7 +1563,7 @@ void NWidgetHorizontal::SetupSmallestSiz
 
	this->resize_y = 1;   // smallest common child resize step.
 
	this->gaps = 0;
 

	
 
	/* 1a. Forward call, collect biggest nested array index, and longest/widest child length. */
 
	/* 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) {
 
@@ -1756,7 +1755,7 @@ void NWidgetVertical::SetupSmallestSize(
 
	this->resize_y = 0;   // smallest non-zero child widget resize step.
 
	this->gaps = 0;
 

	
 
	/* 1a. Forward call, collect biggest nested array index, and longest/widest child length. */
 
	/* 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) {
 
@@ -1925,7 +1924,7 @@ void NWidgetSpacer::SetupSmallestSize(Wi
 
	this->smallest_y = this->min_y;
 
}
 

	
 
void NWidgetSpacer::FillWidgetLookup(NWidgetBase **, uint)
 
void NWidgetSpacer::FillWidgetLookup(WidgetLookup &)
 
{
 
}
 

	
 
@@ -2065,10 +2064,10 @@ void NWidgetMatrix::AssignSizePosition(S
 
	this->SetCount(this->count);
 
}
 

	
 
void NWidgetMatrix::FillWidgetLookup(NWidgetBase **widget_lookup, uint length)
 
void NWidgetMatrix::FillWidgetLookup(WidgetLookup &widget_lookup)
 
{
 
	if (this->index >= 0 && (uint)(this->index) < length) widget_lookup[this->index] = this;
 
	NWidgetContainer::FillWidgetLookup(widget_lookup, length);
 
	if (this->index >= 0) widget_lookup[this->index] = this;
 
	NWidgetContainer::FillWidgetLookup(widget_lookup);
 
}
 

	
 
NWidgetCore *NWidgetMatrix::GetWidgetFromPos(int x, int y)
 
@@ -2185,7 +2184,7 @@ void NWidgetMatrix::GetScrollOffsets(int
 
 * Constructor parent nested widgets.
 
 * @param tp     Type of parent widget.
 
 * @param colour Colour of the parent widget.
 
 * @param index  Index in the widget array used by the window system.
 
 * @param index  Index of the widget.
 
 * @param child  Child container widget (if supplied). If not supplied, a
 
 *               vertical container will be inserted while adding the first
 
 *               child widget.
 
@@ -2335,10 +2334,10 @@ void NWidgetBackground::AssignSizePositi
 
	}
 
}
 

	
 
void NWidgetBackground::FillWidgetLookup(NWidgetBase **widget_lookup, uint length)
 
void NWidgetBackground::FillWidgetLookup(WidgetLookup &widget_lookup)
 
{
 
	if (this->index >= 0 && (uint)(this->index) < length) widget_lookup[this->index] = this;
 
	if (this->child != nullptr) this->child->FillWidgetLookup(widget_lookup, length);
 
	if (this->index >= 0) widget_lookup[this->index] = this;
 
	if (this->child != nullptr) this->child->FillWidgetLookup(widget_lookup);
 
}
 

	
 
void NWidgetBackground::Draw(const Window *w)
 
@@ -2556,7 +2555,7 @@ void Scrollbar::SetCapacityFromWidget(Wi
 
 * Scrollbar widget.
 
 * @param tp     Scrollbar type. (horizontal/vertical)
 
 * @param colour Colour of the scrollbar.
 
 * @param index  Index in the widget array used by the window system.
 
 * @param index  Index of the widget.
 
 */
 
NWidgetScrollbar::NWidgetScrollbar(WidgetType tp, Colours colour, int index) : NWidgetCore(tp, colour, 1, 1, 0x0, STR_NULL), Scrollbar(tp != NWID_HSCROLLBAR)
 
{
 
@@ -2680,7 +2679,7 @@ Dimension NWidgetLeaf::dropdown_dimensio
 
 * Nested leaf widget.
 
 * @param tp     Type of leaf widget.
 
 * @param colour Colour of the leaf widget.
 
 * @param index  Index in the widget array used by the window system.
 
 * @param index  Index of the widget.
 
 * @param data   Data of the widget.
 
 * @param tip    Tooltip of the widget.
 
 */
 
@@ -3110,11 +3109,9 @@ bool NWidgetLeaf::ButtonHit(const Point 
 
 * @param nwid_end Pointer to ending of nested widget parts.
 
 * @param dest  Address of pointer to use for returning the composed widget.
 
 * @param fill_dest Fill the composed widget with child widgets.
 
 * @param biggest_index Pointer to biggest nested widget index in the tree encountered so far.
 
 * @return Pointer to remaining nested widget parts.
 
 * @pre \c biggest_index != nullptr.
 
 */
 
static const NWidgetPart *MakeNWidget(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetBase **dest, bool *fill_dest, int *biggest_index)
 
static const NWidgetPart *MakeNWidget(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetBase **dest, bool *fill_dest)
 
{
 
	*dest = nullptr;
 
	*fill_dest = false;
 
@@ -3143,7 +3140,6 @@ static const NWidgetPart *MakeNWidget(co
 
			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);
 
				*biggest_index = std::max(*biggest_index, (int)nwid_begin->u.widget.index);
 
				*fill_dest = true;
 
				break;
 

	
 
@@ -3160,16 +3156,12 @@ static const NWidgetPart *MakeNWidget(co
 
				*fill_dest = true;
 
				nwm->SetIndex(nwid_begin->u.widget.index);
 
				nwm->SetColour(nwid_begin->u.widget.colour);
 
				*biggest_index = std::max(*biggest_index, (int)nwid_begin->u.widget.index);
 
				break;
 
			}
 

	
 
			case WPT_FUNCTION: {
 
				if (*dest != nullptr) return nwid_begin;
 
				/* Ensure proper functioning even when the called code simply writes its largest index. */
 
				int biggest = -1;
 
				*dest = nwid_begin->u.func_ptr(&biggest);
 
				*biggest_index = std::max(*biggest_index, biggest);
 
				*dest = nwid_begin->u.func_ptr();
 
				*fill_dest = false;
 
				break;
 
			}
 
@@ -3267,14 +3259,12 @@ static const NWidgetPart *MakeNWidget(co
 
			case NWID_VIEWPORT:
 
				if (*dest != nullptr) return nwid_begin;
 
				*dest = new NWidgetViewport(nwid_begin->u.widget.index);
 
				*biggest_index = std::max(*biggest_index, (int)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);
 
				*biggest_index = std::max(*biggest_index, (int)nwid_begin->u.widget.index);
 
				break;
 

	
 
			case NWID_SELECTION: {
 
@@ -3283,7 +3273,6 @@ static const NWidgetPart *MakeNWidget(co
 
				*dest = nws;
 
				*fill_dest = true;
 
				nws->SetIndex(nwid_begin->u.widget.index);
 
				*biggest_index = std::max(*biggest_index, (int)nwid_begin->u.widget.index);
 
				break;
 
			}
 

	
 
@@ -3291,7 +3280,6 @@ static const NWidgetPart *MakeNWidget(co
 
				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);
 
				*biggest_index = std::max(*biggest_index, (int)nwid_begin->u.widget.index);
 
				break;
 
		}
 
		nwid_begin++;
 
@@ -3316,11 +3304,9 @@ bool IsContainerWidgetType(WidgetType tp
 
 * @param nwid_begin Pointer to beginning of nested widget parts.
 
 * @param nwid_end Pointer to ending of nested widget parts.
 
 * @param parent Pointer or container to use for storing the child widgets (*parent == nullptr or *parent == container or background widget).
 
 * @param biggest_index Pointer to biggest nested widget index in the tree.
 
 * @return Pointer to remaining nested widget parts.
 
 * @post \c *biggest_index contains the largest widget index of the tree and \c -1 if no index is used.
 
 */
 
static const NWidgetPart *MakeWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetBase **parent, int *biggest_index)
 
static const NWidgetPart *MakeWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, 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. */
 
@@ -3331,7 +3317,7 @@ static const NWidgetPart *MakeWidgetTree
 
	for (;;) {
 
		NWidgetBase *sub_widget = nullptr;
 
		bool fill_sub = false;
 
		nwid_begin = MakeNWidget(nwid_begin, nwid_end, &sub_widget, &fill_sub, biggest_index);
 
		nwid_begin = MakeNWidget(nwid_begin, nwid_end, &sub_widget, &fill_sub);
 

	
 
		/* Break out of loop when end reached */
 
		if (sub_widget == nullptr) break;
 
@@ -3339,7 +3325,7 @@ static const NWidgetPart *MakeWidgetTree
 
		/* 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, biggest_index);
 
			nwid_begin = MakeWidgetTree(nwid_begin, nwid_end, &sub_ptr);
 
		}
 

	
 
		/* Add sub_widget to parent container if available, otherwise return the widget to the caller. */
 
@@ -3362,19 +3348,15 @@ static const NWidgetPart *MakeWidgetTree
 
 * Construct a nested widget tree from an array of parts.
 
 * @param nwid_begin Pointer to beginning of nested widget parts.
 
 * @param nwid_end Pointer to ending of nested widget parts.
 
 * @param biggest_index Pointer to biggest nested widget index collected in the tree.
 
 * @param container Container to add the nested widgets to. In case it is nullptr a vertical container is used.
 
 * @return Root of the nested widget tree, a vertical container containing the entire GUI.
 
 * @ingroup NestedWidgetParts
 
 * @pre \c biggest_index != nullptr
 
 * @post \c *biggest_index contains the largest widget index of the tree and \c -1 if no index is used.
 
 */
 
NWidgetContainer *MakeNWidgets(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, int *biggest_index, NWidgetContainer *container)
 
NWidgetContainer *MakeNWidgets(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetContainer *container)
 
{
 
	*biggest_index = -1;
 
	if (container == nullptr) container = new NWidgetVertical();
 
	NWidgetBase *cont_ptr = container;
 
	[[maybe_unused]] const NWidgetPart *nwid_part = MakeWidgetTree(nwid_begin, nwid_end, &cont_ptr, biggest_index);
 
	[[maybe_unused]] const NWidgetPart *nwid_part = MakeWidgetTree(nwid_begin, nwid_end, &cont_ptr);
 
#ifdef WITH_ASSERT
 
	if (unlikely(nwid_part != nwid_end)) throw std::runtime_error("Did not consume all NWidgetParts");
 
#endif
 
@@ -3387,20 +3369,15 @@ NWidgetContainer *MakeNWidgets(const NWi
 
 * container with a caption widget) and has a shade box widget.
 
 * @param nwid_begin Pointer to beginning of nested widget parts.
 
 * @param nwid_end Pointer to ending of nested widget parts.
 
 * @param biggest_index Pointer to biggest nested widget index collected in the tree.
 
 * @param[out] shade_select Pointer to the inserted shade selection widget (\c nullptr if not unserted).
 
 * @return Root of the nested widget tree, a vertical container containing the entire GUI.
 
 * @ingroup NestedWidgetParts
 
 * @pre \c biggest_index != nullptr
 
 * @post \c *biggest_index contains the largest widget index of the tree and \c -1 if no index is used.
 
 */
 
NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, int *biggest_index, NWidgetStacked **shade_select)
 
NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetStacked **shade_select)
 
{
 
	*biggest_index = -1;
 

	
 
	/* Read the first widget recursively from the array. */
 
	NWidgetBase *nwid = nullptr;
 
	nwid_begin = MakeWidgetTree(nwid_begin, nwid_end, &nwid, biggest_index);
 
	nwid_begin = MakeWidgetTree(nwid_begin, nwid_end, &nwid);
 
	assert(nwid != nullptr);
 

	
 
	NWidgetContainer *root = new NWidgetVertical;
 
@@ -3425,25 +3402,21 @@ NWidgetContainer *MakeWindowNWidgetTree(
 
	}
 

	
 
	/* Load the remaining parts into 'body'. */
 
	int biggest2 = -1;
 
	MakeNWidgets(nwid_begin, nwid_end, &biggest2, body);
 

	
 
	*biggest_index = std::max(*biggest_index, biggest2);
 
	MakeNWidgets(nwid_begin, nwid_end, body);
 

	
 
	return root;
 
}
 

	
 
/**
 
 * Make a number of rows with button-like graphics, for enabling/disabling each company.
 
 * @param biggest_index Storage for collecting the biggest index used in the returned tree.
 
 * @param widget_first The first widget index to use.
 
 * @param widget_last The last widget index to use.
 
 * @param colour The colour in which to draw the button.
 
 * @param max_length Maximal number of company buttons in one row.
 
 * @param button_tooltip The tooltip-string of every button.
 
 * @return Panel with rows of company buttons.
 
 * @post \c *biggest_index contains the largest used index in the tree.
 
 */
 
NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int widget_last, Colours button_colour, int max_length, StringID button_tooltip)
 
NWidgetBase *MakeCompanyButtonRows(int widget_first, int widget_last, Colours button_colour, int max_length, StringID button_tooltip)
 
{
 
	assert(max_length >= 1);
 
	NWidgetVertical *vert = nullptr; // Storage for all rows.
 
@@ -3475,7 +3448,6 @@ NWidgetBase *MakeCompanyButtonRows(int *
 
		hor->Add(panel);
 
		hor_length++;
 
	}
 
	*biggest_index = widget_last;
 
	if (vert == nullptr) return hor; // All buttons fit in a single row.
 

	
 
	if (hor_length > 0 && hor_length < max_length) {
src/widget_type.h
Show inline comments
 
@@ -47,7 +47,7 @@ enum ResizeWidgetValues {
 
 */
 
enum WidgetType {
 
	/* Window widget types. */
 
	WWT_EMPTY,      ///< Empty widget, place holder to reserve space in widget array
 
	WWT_EMPTY,      ///< Empty widget, place holder to reserve space in widget tree.
 

	
 
	WWT_PANEL,      ///< Simple depressed panel
 
	WWT_INSET,      ///< Pressed (inset) panel, most commonly used as combo box _text_ area
 
@@ -122,6 +122,9 @@ enum SizingType {
 
class NWidgetCore;
 
class Scrollbar;
 

	
 
/** Lookup between widget IDs and NWidget objects. */
 
using WidgetLookup = std::map<int, class NWidgetBase *>;
 

	
 
/**
 
 * Baseclass for nested widgets.
 
 * @invariant After initialization, \f$current\_x = smallest\_x + n * resize\_x, for n \geq 0\f$.
 
@@ -136,7 +139,7 @@ public:
 
	virtual void SetupSmallestSize(Window *w) = 0;
 
	virtual void AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl) = 0;
 

	
 
	virtual void FillWidgetLookup(NWidgetBase **widget_lookup, uint length) = 0;
 
	virtual void FillWidgetLookup(WidgetLookup &widget_lookup) = 0;
 

	
 
	virtual NWidgetCore *GetWidgetFromPos(int x, int y) = 0;
 
	virtual NWidgetBase *GetWidgetOfType(WidgetType tp);
 
@@ -337,7 +340,7 @@ public:
 
	inline void SetDisabled(bool disabled);
 
	inline bool IsDisabled() const;
 

	
 
	void FillWidgetLookup(NWidgetBase **widget_lookup, uint length) override;
 
	void FillWidgetLookup(WidgetLookup &widget_lookup) override;
 
	NWidgetCore *GetWidgetFromPos(int x, int y) override;
 
	bool IsHighlighted() const override;
 
	TextColour GetHighlightColour() const override;
 
@@ -345,7 +348,7 @@ public:
 

	
 
	NWidgetDisplay disp_flags; ///< Flags that affect display and interaction with the widget.
 
	Colours colour;            ///< Colour of this widget.
 
	int index;                 ///< Index of the nested widget in the widget array of the window (\c -1 means 'not used').
 
	int index;                 ///< Index of the nested widget (\c -1 means 'not used').
 
	uint32_t widget_data;        ///< Data of the widget. @see Widget::data
 
	StringID tool_tip;         ///< Tooltip of the widget. @see Widget::tootips
 
	int scrollbar_index;       ///< Index of an attached scrollbar.
 
@@ -419,7 +422,7 @@ public:
 

	
 
	void AdjustPaddingForZoom() override;
 
	void Add(NWidgetBase *wid);
 
	void FillWidgetLookup(NWidgetBase **widget_lookup, uint length) override;
 
	void FillWidgetLookup(WidgetLookup &widget_lookup) override;
 

	
 
	void Draw(const Window *w) override;
 
	NWidgetCore *GetWidgetFromPos(int x, int y) override;
 
@@ -462,7 +465,7 @@ public:
 
	void AdjustPaddingForZoom() override;
 
	void SetupSmallestSize(Window *w) override;
 
	void AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl) override;
 
	void FillWidgetLookup(NWidgetBase **widget_lookup, uint length) override;
 
	void FillWidgetLookup(WidgetLookup &widget_lookup) override;
 

	
 
	void Draw(const Window *w) override;
 
	NWidgetCore *GetWidgetFromPos(int x, int y) override;
 
@@ -564,7 +567,7 @@ public:
 

	
 
	void SetupSmallestSize(Window *w) override;
 
	void AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl) override;
 
	void FillWidgetLookup(NWidgetBase **widget_lookup, uint length) override;
 
	void FillWidgetLookup(WidgetLookup &widget_lookup) override;
 

	
 
	NWidgetCore *GetWidgetFromPos(int x, int y) override;
 
	void Draw(const Window *w) override;
 
@@ -593,7 +596,7 @@ public:
 
	NWidgetSpacer(int width, int height);
 

	
 
	void SetupSmallestSize(Window *w) override;
 
	void FillWidgetLookup(NWidgetBase **widget_lookup, uint length) override;
 
	void FillWidgetLookup(WidgetLookup &widget_lookup) override;
 

	
 
	void Draw(const Window *w) override;
 
	void SetDirty(const Window *w) const override;
 
@@ -617,7 +620,7 @@ public:
 
	void SetupSmallestSize(Window *w) override;
 
	void AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl) override;
 

	
 
	void FillWidgetLookup(NWidgetBase **widget_lookup, uint length) override;
 
	void FillWidgetLookup(WidgetLookup &widget_lookup) override;
 

	
 
	void Draw(const Window *w) override;
 
	NWidgetCore *GetWidgetFromPos(int x, int y) override;
 
@@ -955,7 +958,7 @@ struct NWidgetPartDataTip {
 
 */
 
struct NWidgetPartWidget {
 
	Colours colour; ///< Widget colour.
 
	int16_t index;    ///< Widget index in the widget array.
 
	int16_t index; ///< Index of the widget.
 
};
 

	
 
/**
 
@@ -1002,11 +1005,9 @@ struct NWidgetPartAlignment {
 

	
 
/**
 
 * Pointer to function returning a nested widget.
 
 * @param biggest_index Pointer to storage for collecting the biggest index used in the nested widget.
 
 * @return Nested widget (tree).
 
 * @post \c *biggest_index must contain the value of the biggest index in the returned tree.
 
 */
 
typedef NWidgetBase *NWidgetFunctionType(int *biggest_index);
 
typedef NWidgetBase *NWidgetFunctionType();
 

	
 
/**
 
 * Partial widget specification to allow NWidgets to be written nested.
 
@@ -1282,7 +1283,7 @@ static inline NWidgetPart SetScrollbar(i
 
 * Widget part function for starting a new 'real' widget.
 
 * @param tp  Type of the new nested widget.
 
 * @param col Colour of the new widget.
 
 * @param idx Index of the widget in the widget array.
 
 * @param idx Index of the widget.
 
 * @note with #WWT_PANEL, #WWT_FRAME, #WWT_INSET, a new container is started.
 
 *       Child widgets must have a index bigger than the parent index.
 
 * @ingroup NestedWidgetParts
 
@@ -1330,10 +1331,10 @@ static inline NWidgetPart NWidgetFunctio
 
}
 

	
 
bool IsContainerWidgetType(WidgetType tp);
 
NWidgetContainer *MakeNWidgets(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, int *biggest_index, NWidgetContainer *container);
 
NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, int *biggest_index, NWidgetStacked **shade_select);
 
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);
 

	
 
NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int widget_last, Colours button_colour, int max_length, StringID button_tooltip);
 
NWidgetBase *MakeCompanyButtonRows(int widget_first, int widget_last, Colours button_colour, int max_length, StringID button_tooltip);
 

	
 
void SetupWidgetDimensions();
 

	
src/window.cpp
Show inline comments
 
@@ -224,10 +224,8 @@ int Window::GetRowFromWidget(int clickpo
 
 */
 
void Window::DisableAllWidgetHighlight()
 
{
 
	for (uint i = 0; i < this->nested_array_size; i++) {
 
		NWidgetBase *nwid = this->GetWidget<NWidgetBase>(i);
 
		if (nwid == nullptr) continue;
 

	
 
	for (auto &pair : this->widget_lookup) {
 
		NWidgetBase *nwid = pair.second;
 
		if (nwid->IsHighlighted()) {
 
			nwid->SetHighlighted(TC_INVALID);
 
			nwid->SetDirty(this);
 
@@ -244,8 +242,6 @@ void Window::DisableAllWidgetHighlight()
 
 */
 
void Window::SetWidgetHighlight(byte widget_index, TextColour highlighted_colour)
 
{
 
	assert(widget_index < this->nested_array_size);
 

	
 
	NWidgetBase *nwid = this->GetWidget<NWidgetBase>(widget_index);
 
	if (nwid == nullptr) return;
 

	
 
@@ -258,9 +254,8 @@ void Window::SetWidgetHighlight(byte wid
 
	} else {
 
		/* If we disable a highlight, check all widgets if anyone still has a highlight */
 
		bool valid = false;
 
		for (uint i = 0; i < this->nested_array_size; i++) {
 
			nwid = this->GetWidget<NWidgetBase>(i);
 
			if (nwid == nullptr) continue;
 
		for (const auto &pair : this->widget_lookup) {
 
			nwid = pair.second;
 
			if (!nwid->IsHighlighted()) continue;
 

	
 
			valid = true;
 
@@ -277,8 +272,6 @@ void Window::SetWidgetHighlight(byte wid
 
 */
 
bool Window::IsWidgetHighlighted(byte widget_index) const
 
{
 
	assert(widget_index < this->nested_array_size);
 

	
 
	const NWidgetBase *nwid = this->GetWidget<NWidgetBase>(widget_index);
 
	if (nwid == nullptr) return false;
 

	
 
@@ -493,18 +486,19 @@ void Window::UnfocusFocusedWidget()
 
 */
 
bool Window::SetFocusedWidget(int widget_index)
 
{
 
	/* Do nothing if widget_index is already focused, or if it wasn't a valid widget. */
 
	if ((uint)widget_index >= this->nested_array_size) return false;
 

	
 
	assert(this->widget_lookup[widget_index] != nullptr); // Setting focus to a non-existing widget is a bad idea.
 
	NWidgetCore *widget = this->GetWidget<NWidgetCore>(widget_index);
 
	assert(widget != nullptr); /* Setting focus to a non-existing widget is a bad idea. */
 

	
 
	if (this->nested_focus != nullptr) {
 
		if (this->GetWidget<NWidgetCore>(widget_index) == this->nested_focus) return false;
 
		/* Do nothing if widget_index is already focused. */
 
		if (widget == this->nested_focus) return false;
 

	
 
		/* Repaint the widget that lost focus. A focused edit box may else leave the caret on the screen. */
 
		this->nested_focus->SetDirty(this);
 
		if (this->nested_focus->type == WWT_EDITBOX) VideoDriver::GetInstance()->EditBoxLostFocus();
 
	}
 
	this->nested_focus = this->GetWidget<NWidgetCore>(widget_index);
 

	
 
	this->nested_focus = widget;
 
	if (this->nested_focus->type == WWT_EDITBOX) VideoDriver::GetInstance()->EditBoxGainedFocus();
 
	return true;
 
}
 
@@ -531,21 +525,23 @@ void Window::OnFocusLost(bool)
 
 */
 
void Window::RaiseButtons(bool autoraise)
 
{
 
	for (uint i = 0; i < this->nested_array_size; i++) {
 
		if (this->widget_lookup[i] == nullptr) continue;
 
		WidgetType type = this->widget_lookup[i]->type;
 
	for (auto &pair : this->widget_lookup) {
 
		WidgetType type = pair.second->type;
 
		NWidgetCore *wid = dynamic_cast<NWidgetCore *>(pair.second);
 
		if (((type & ~WWB_PUSHBUTTON) < WWT_LAST || type == NWID_PUSHBUTTON_DROPDOWN) &&
 
				(!autoraise || (type & WWB_PUSHBUTTON) || type == WWT_EDITBOX) && this->IsWidgetLowered(i)) {
 
			this->RaiseWidget(i);
 
			this->SetWidgetDirty(i);
 
				(!autoraise || (type & WWB_PUSHBUTTON) || type == WWT_EDITBOX) && wid->IsLowered()) {
 
			wid->SetLowered(false);
 
			wid->SetDirty(this);
 
		}
 
	}
 

	
 
	/* Special widgets without widget index */
 
	NWidgetCore *wid = this->nested_root != nullptr ? (NWidgetCore*)this->nested_root->GetWidgetOfType(WWT_DEFSIZEBOX) : nullptr;
 
	if (wid != nullptr) {
 
		wid->SetLowered(false);
 
		wid->SetDirty(this);
 
	{
 
		NWidgetCore *wid = this->nested_root != nullptr ? dynamic_cast<NWidgetCore *>(this->nested_root->GetWidgetOfType(WWT_DEFSIZEBOX)) : nullptr;
 
		if (wid != nullptr) {
 
			wid->SetLowered(false);
 
			wid->SetDirty(this);
 
		}
 
	}
 
}
 

	
 
@@ -556,9 +552,10 @@ void Window::RaiseButtons(bool autoraise
 
void Window::SetWidgetDirty(byte widget_index) const
 
{
 
	/* Sometimes this function is called before the window is even fully initialized */
 
	if (this->widget_lookup == nullptr) return;
 

	
 
	this->widget_lookup[widget_index]->SetDirty(this);
 
	auto it = this->widget_lookup.find(widget_index);
 
	if (it == std::end(this->widget_lookup)) return;
 

	
 
	it->second->SetDirty(this);
 
}
 

	
 
/**
 
@@ -635,7 +632,7 @@ static void DispatchLeftClickEvent(Windo
 
	/* Clicked on a widget that is not disabled.
 
	 * So unless the clicked widget is the caption bar, change focus to this widget.
 
	 * Exception: In the OSK we always want the editbox to stay focused. */
 
	if (widget_type != WWT_CAPTION && w->window_class != WC_OSK) {
 
	if (widget_index >= 0 && widget_type != WWT_CAPTION && w->window_class != WC_OSK) {
 
		/* focused_widget_changed is 'now' only true if the window this widget
 
		 * is in gained focus. In that case it must remain true, also if the
 
		 * local widget focus did not change. As such it's the logical-or of
 
@@ -1091,8 +1088,6 @@ Window::~Window()
 
	assert(*this->z_position == nullptr);
 

	
 
	if (this->viewport != nullptr) DeleteWindowViewport(this);
 

	
 
	free(this->widget_lookup); // Contents is released through deletion of #nested_root.
 
	delete this->nested_root;
 
}
 

	
 
@@ -1729,12 +1724,8 @@ static Point LocalGetWindowPlacement(con
 
 */
 
void Window::CreateNestedTree()
 
{
 
	int biggest_index = -1;
 
	this->nested_root = MakeWindowNWidgetTree(this->window_desc->nwid_begin, this->window_desc->nwid_end, &biggest_index, &this->shade_select);
 
	this->nested_array_size = (uint)(biggest_index + 1);
 

	
 
	this->widget_lookup = CallocT<NWidgetBase *>(this->nested_array_size);
 
	this->nested_root->FillWidgetLookup(this->widget_lookup, this->nested_array_size);
 
	this->nested_root = MakeWindowNWidgetTree(this->window_desc->nwid_begin, this->window_desc->nwid_end, &this->shade_select);
 
	this->nested_root->FillWidgetLookup(this->widget_lookup);
 
}
 

	
 
/**
 
@@ -1840,9 +1831,9 @@ static void DecreaseWindowCounters()
 
	for (Window *w : Window::Iterate()) {
 
		if (_scroller_click_timeout == 0) {
 
			/* Unclick scrollbar buttons if they are pressed. */
 
			for (uint i = 0; i < w->nested_array_size; i++) {
 
				NWidgetBase *nwid = w->widget_lookup[i];
 
				if (nwid != nullptr && (nwid->type == NWID_HSCROLLBAR || nwid->type == NWID_VSCROLLBAR)) {
 
			for (auto &pair : w->widget_lookup) {
 
				NWidgetBase *nwid = pair.second;
 
				if (nwid->type == NWID_HSCROLLBAR || nwid->type == NWID_VSCROLLBAR) {
 
					NWidgetScrollbar *sb = static_cast<NWidgetScrollbar*>(nwid);
 
					if (sb->disp_flags & (ND_SCROLLBAR_UP | ND_SCROLLBAR_DOWN)) {
 
						sb->disp_flags &= ~(ND_SCROLLBAR_UP | ND_SCROLLBAR_DOWN);
 
@@ -3155,8 +3146,8 @@ void Window::ProcessHighlightedInvalidat
 
{
 
	if ((this->flags & WF_HIGHLIGHTED) == 0) return;
 

	
 
	for (uint i = 0; i < this->nested_array_size; i++) {
 
		if (this->IsWidgetHighlighted(i)) this->SetWidgetDirty(i);
 
	for (const auto &pair : this->widget_lookup) {
 
		if (pair.second->IsHighlighted()) pair.second->SetDirty(this);
 
	}
 
}
 

	
src/window_gui.h
Show inline comments
 
@@ -260,8 +260,7 @@ public:
 
	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.
 
	NWidgetBase **widget_lookup;      ///< Array of pointers into the tree. Do not access directly, use #Window::GetWidget() instead.
 
	uint nested_array_size;          ///< Size of the nested array.
 
	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).
 

	
 
@@ -328,8 +327,7 @@ public:
 
	 */
 
	inline void SetWidgetDisabledState(byte widget_index, bool disab_stat)
 
	{
 
		assert(widget_index < this->nested_array_size);
 
		if (this->widget_lookup[widget_index] != nullptr) this->GetWidget<NWidgetCore>(widget_index)->SetDisabled(disab_stat);
 
		this->GetWidget<NWidgetCore>(widget_index)->SetDisabled(disab_stat);
 
	}
 

	
 
	/**
 
@@ -357,7 +355,6 @@ public:
 
	 */
 
	inline bool IsWidgetDisabled(byte widget_index) const
 
	{
 
		assert(widget_index < this->nested_array_size);
 
		return this->GetWidget<NWidgetCore>(widget_index)->IsDisabled();
 
	}
 

	
 
@@ -389,7 +386,6 @@ public:
 
	 */
 
	inline void SetWidgetLoweredState(byte widget_index, bool lowered_stat)
 
	{
 
		assert(widget_index < this->nested_array_size);
 
		this->GetWidget<NWidgetCore>(widget_index)->SetLowered(lowered_stat);
 
	}
 

	
 
@@ -399,7 +395,6 @@ public:
 
	 */
 
	inline void ToggleWidgetLoweredState(byte widget_index)
 
	{
 
		assert(widget_index < this->nested_array_size);
 
		bool lowered_state = this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
 
		this->GetWidget<NWidgetCore>(widget_index)->SetLowered(!lowered_state);
 
	}
 
@@ -441,7 +436,6 @@ public:
 
	 */
 
	inline bool IsWidgetLowered(byte widget_index) const
 
	{
 
		assert(widget_index < this->nested_array_size);
 
		return this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
 
	}
 

	
 
@@ -894,8 +888,9 @@ inline bool AllEqual(It begin, It end, P
 
template <class NWID>
 
inline NWID *Window::GetWidget(uint widnum)
 
{
 
	if (widnum >= this->nested_array_size || this->widget_lookup[widnum] == nullptr) return nullptr;
 
	NWID *nwid = dynamic_cast<NWID *>(this->widget_lookup[widnum]);
 
	auto it = this->widget_lookup.find(widnum);
 
	if (it == std::end(this->widget_lookup)) return nullptr;
 
	NWID *nwid = dynamic_cast<NWID *>(it->second);
 
	assert(nwid != nullptr);
 
	return nwid;
 
}
 
@@ -904,8 +899,9 @@ inline NWID *Window::GetWidget(uint widn
 
template <>
 
inline const NWidgetBase *Window::GetWidget<NWidgetBase>(uint widnum) const
 
{
 
	if (widnum >= this->nested_array_size) return nullptr;
 
	return this->widget_lookup[widnum];
 
	auto it = this->widget_lookup.find(widnum);
 
	if (it == std::end(this->widget_lookup)) return nullptr;
 
	return it->second;
 
}
 

	
 
/**
0 comments (0 inline, 0 general)