mirror of https://github.com/OpenTTD/OpenTTD.git
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.
This commit is contained in:
parent
a12f426d69
commit
b86182ab84
|
@ -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 *MakeNWidgetCompanyLines(int *biggest_index)
|
|||
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::company = INVALID_COMPANY;
|
|||
|
||||
/**
|
||||
* 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 *MakePerformanceDetailPanels(int *biggest_index)
|
|||
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[] = {
|
||||
|
|
|
@ -454,12 +454,12 @@ void LinkGraphOverlay::SetCompanyMask(CompanyMask company_mask)
|
|||
}
|
||||
|
||||
/** 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 *MakeSaturationLegendLinkGraphGUI(int *biggest_index)
|
|||
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 *MakeCargoesLegendLinkGraphGUI(int *biggest_index)
|
|||
}
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -855,9 +855,8 @@ GUIGameServerList::FilterFunction * const NetworkGameWindow::filter_funcs[] = {
|
|||
&NGameSearchFilter
|
||||
};
|
||||
|
||||
static NWidgetBase *MakeResizableHeader(int *biggest_index)
|
||||
static NWidgetBase *MakeResizableHeader()
|
||||
{
|
||||
*biggest_index = std::max<int>(*biggest_index, WID_NG_INFO);
|
||||
return new NWidgetServerListHeader();
|
||||
}
|
||||
|
||||
|
|
|
@ -1937,16 +1937,11 @@ 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(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);
|
||||
}
|
||||
|
|
|
@ -220,10 +220,9 @@ static const int KEY_PADDING = 6; // Vertical padding for remaining key rows
|
|||
* @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 *hor, int pad_y, int num_half, WidgetType w
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -1942,12 +1942,12 @@ static const NWidgetPart _nested_smallmap_bar[] = {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -714,10 +714,9 @@ const StringID CompanyStationsWindow::sorter_names[] = {
|
|||
|
||||
/**
|
||||
* 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 *biggest_index)
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -646,9 +646,9 @@ struct ScenarioEditorLandscapeGenerationWindow : Window {
|
|||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -89,11 +89,10 @@ TEST_CASE_METHOD(WindowDescTestsFixture, "WindowDesc - NWidgetPart validity")
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 *biggest_index)
|
|||
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_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(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[] = {
|
||||
|
|
|
@ -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(int *biggest_index)
|
|||
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++;
|
||||
}
|
||||
}
|
||||
|
|
102
src/widget.cpp
102
src/widget.cpp
|
@ -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 widget, SortButtonState state) const
|
|||
{
|
||||
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) : ZeroedMemoryAllocator()
|
|||
*/
|
||||
|
||||
/**
|
||||
* @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(StringAlignment align)
|
|||
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 *wid)
|
|||
}
|
||||
}
|
||||
|
||||
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(SizingType sizing, int x, int y, uint gi
|
|||
}
|
||||
}
|
||||
|
||||
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::SetupSmallestSize(Window *w)
|
|||
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(Window *w)
|
|||
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(Window *)
|
|||
this->smallest_y = this->min_y;
|
||||
}
|
||||
|
||||
void NWidgetSpacer::FillWidgetLookup(NWidgetBase **, uint)
|
||||
void NWidgetSpacer::FillWidgetLookup(WidgetLookup &)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -2065,10 +2064,10 @@ void NWidgetMatrix::AssignSizePosition(SizingType, int x, int y, uint given_widt
|
|||
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 &start_x, int &start_y, int &base_offs_
|
|||
* 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::AssignSizePosition(SizingType sizing, int x, int y, uint
|
|||
}
|
||||
}
|
||||
|
||||
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(Window *w, int widget, int padding)
|
|||
* 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_dimension = {0, 0};
|
|||
* 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 &pt)
|
|||
* @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(const NWidgetPart *nwid_begin, const NWidg
|
|||
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(const NWidgetPart *nwid_begin, const NWidg
|
|||
*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(const NWidgetPart *nwid_begin, const NWidg
|
|||
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(const NWidgetPart *nwid_begin, const NWidg
|
|||
*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(const NWidgetPart *nwid_begin, const NWidg
|
|||
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(const NWidgetPart *nwid_begin, const NW
|
|||
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(const NWidgetPart *nwid_begin, const NW
|
|||
/* 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(const NWidgetPart *nwid_begin, const NW
|
|||
* 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 NWidgetPart *nwid_begin, const NWidgetPart
|
|||
* 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(const NWidgetPart *nwid_begin, const NWi
|
|||
}
|
||||
|
||||
/* Load the remaining parts into 'body'. */
|
||||
int biggest2 = -1;
|
||||
MakeNWidgets(nwid_begin, nwid_end, &biggest2, body);
|
||||
MakeNWidgets(nwid_begin, nwid_end, body);
|
||||
|
||||
*biggest_index = std::max(*biggest_index, biggest2);
|
||||
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 *biggest_index, int widget_first, int wid
|
|||
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) {
|
||||
|
|
|
@ -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(int index)
|
|||
* 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 NWidgetFunction(NWidgetFunctionType *func_ptr)
|
|||
}
|
||||
|
||||
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();
|
||||
|
||||
|
|
|
@ -224,10 +224,8 @@ int Window::GetRowFromWidget(int clickpos, int widget, int padding, int line_hei
|
|||
*/
|
||||
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 widget_index, TextColour highlighted_colour
|
|||
} 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 widget_index, TextColour highlighted_colour
|
|||
*/
|
||||
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;
|
||||
NWidgetCore *widget = this->GetWidget<NWidgetCore>(widget_index);
|
||||
assert(widget != nullptr); /* Setting focus to a non-existing widget is a bad idea. */
|
||||
|
||||
assert(this->widget_lookup[widget_index] != 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;
|
||||
auto it = this->widget_lookup.find(widget_index);
|
||||
if (it == std::end(this->widget_lookup)) return;
|
||||
|
||||
this->widget_lookup[widget_index]->SetDirty(this);
|
||||
it->second->SetDirty(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -635,7 +632,7 @@ static void DispatchLeftClickEvent(Window *w, int x, int y, int click_count)
|
|||
/* 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(const WindowDesc *desc, int16_t sm_width, i
|
|||
*/
|
||||
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::ProcessHighlightedInvalidations()
|
|||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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, Pred pred)
|
|||
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 widnum)
|
|||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue