1
0
Fork 0

Compare commits

..

No commits in common. "badce415ea7b58921129fdb57d25dcd6d1b5290c" and "ef385499c7833feafafbd3a197ba014aa062255b" have entirely different histories.

24 changed files with 148 additions and 464 deletions

View File

@ -398,7 +398,6 @@ add_files(
sprite.h
spritecache.cpp
spritecache.h
spritecache_internal.h
station.cpp
station_base.h
station_cmd.cpp

View File

@ -581,9 +581,13 @@ static const NWidgetPart _nested_build_docks_depot_widgets[] = {
NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_DEPOT_BUILD_SHIP_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BDD_BACKGROUND),
NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 1), SetPadding(WidgetDimensions::unscaled.picker),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BDD_X), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BDD_Y), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP),
NWidget(NWID_HORIZONTAL), SetPadding(3),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, 2, 0),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_X), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_Y), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP), EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
EndContainer(),
};

View File

@ -19,8 +19,9 @@ static const GlyphID SPRITE_GLYPH = 1U << 30;
/** Font cache for basic fonts. */
class FontCache {
protected:
private:
static FontCache *caches[FS_END]; ///< All the font caches.
protected:
FontCache *parent; ///< The parent of this font cache.
const FontSize fs; ///< The size of the font.
int height; ///< The height of the font.

View File

@ -1224,24 +1224,24 @@ static const NWidgetPart _nested_industry_directory_widgets[] = {
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_ID_DROPDOWN_ORDER), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_DROPDOWN_CRITERIA), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA),
NWidget(WWT_EDITBOX, COLOUR_BROWN, WID_ID_FILTER), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_FILTER_BY_ACC_CARGO), SetMinimalSize(225, 12), SetFill(0, 1), SetDataTip(STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER, STR_TOOLTIP_FILTER_CRITERIA),
NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_FILTER_BY_PROD_CARGO), SetMinimalSize(225, 12), SetFill(0, 1), SetDataTip(STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER, STR_TOOLTIP_FILTER_CRITERIA),
NWidget(WWT_PANEL, COLOUR_BROWN), SetResize(1, 0), EndContainer(),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_BROWN, WID_ID_INDUSTRY_LIST), SetDataTip(0x0, STR_INDUSTRY_DIRECTORY_LIST_CAPTION), SetResize(1, 1), SetScrollbar(WID_ID_VSCROLLBAR),
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_ID_DROPDOWN_ORDER), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_DROPDOWN_CRITERIA), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA),
NWidget(WWT_EDITBOX, COLOUR_BROWN, WID_ID_FILTER), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_FILTER_BY_ACC_CARGO), SetMinimalSize(225, 12), SetFill(0, 1), SetDataTip(STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER, STR_TOOLTIP_FILTER_CRITERIA),
NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_FILTER_BY_PROD_CARGO), SetMinimalSize(225, 12), SetFill(0, 1), SetDataTip(STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER, STR_TOOLTIP_FILTER_CRITERIA),
NWidget(WWT_PANEL, COLOUR_BROWN), SetResize(1, 0), EndContainer(),
EndContainer(),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_BROWN, WID_ID_INDUSTRY_LIST), SetDataTip(0x0, STR_INDUSTRY_DIRECTORY_LIST_CAPTION), SetResize(1, 1), SetScrollbar(WID_ID_SCROLLBAR), EndContainer(),
EndContainer(),
NWidget(NWID_VERTICAL),
NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_ID_SCROLLBAR),
NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
EndContainer(),
NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_ID_VSCROLLBAR),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_HSCROLLBAR, COLOUR_BROWN, WID_ID_HSCROLLBAR),
NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
EndContainer(),
};
@ -1317,7 +1317,6 @@ protected:
GUIIndustryList industries;
Scrollbar *vscroll;
Scrollbar *hscroll;
CargoID cargo_filter[NUM_CARGO + 2]; ///< Available cargo filters; CargoID or CF_ANY or CF_NONE
StringID cargo_filter_texts[NUM_CARGO + 3]; ///< Texts for filter_cargo, terminated by INVALID_STRING_ID
@ -1406,19 +1405,6 @@ protected:
this->industries.SetFilterState(is_filtering_necessary);
}
/**
* Get the width needed to draw the longest industry line.
* @return Returns width of the longest industry line, including padding.
*/
uint GetIndustryListWidth() const
{
uint width = 0;
for (const Industry *i : this->industries) {
width = std::max(width, GetStringBoundingBox(this->GetIndustryString(i)).width);
}
return width + WidgetDimensions::scaled.framerect.Horizontal();
}
/** (Re)Build industries list */
void BuildSortIndustriesList()
{
@ -1437,19 +1423,18 @@ protected:
this->industries.shrink_to_fit();
this->industries.RebuildDone();
auto filter = std::make_pair(this->cargo_filter[this->accepted_cargo_filter_criteria],
this->cargo_filter[this->produced_cargo_filter_criteria]);
this->industries.Filter(filter);
this->hscroll->SetCount(this->GetIndustryListWidth());
this->vscroll->SetCount(this->industries.size()); // Update scrollbar as well.
}
auto filter = std::make_pair(this->cargo_filter[this->accepted_cargo_filter_criteria],
this->cargo_filter[this->produced_cargo_filter_criteria]);
this->industries.Filter(filter);
IndustryDirectoryWindow::produced_cargo_filter = this->cargo_filter[this->produced_cargo_filter_criteria];
this->industries.Sort();
this->vscroll->SetCount(this->industries.size()); // Update scrollbar as well.
this->SetDirty();
}
@ -1636,8 +1621,7 @@ public:
IndustryDirectoryWindow(WindowDesc *desc, WindowNumber) : Window(desc), industry_editbox(MAX_FILTER_LENGTH * MAX_CHAR_LENGTH, MAX_FILTER_LENGTH)
{
this->CreateNestedTree();
this->vscroll = this->GetScrollbar(WID_ID_VSCROLLBAR);
this->hscroll = this->GetScrollbar(WID_ID_HSCROLLBAR);
this->vscroll = this->GetScrollbar(WID_ID_SCROLLBAR);
this->industries.SetListing(this->last_sorting);
this->industries.SetSortFuncs(IndustryDirectoryWindow::sorter_funcs);
@ -1686,28 +1670,16 @@ public:
break;
case WID_ID_INDUSTRY_LIST: {
int n = 0;
Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
/* Setup a clipping rectangle... */
DrawPixelInfo tmp_dpi;
if (!FillDrawPixelInfo(&tmp_dpi, ir.left, ir.top, ir.Width(), ir.Height())) return;
/* ...but keep coordinates relative to the window. */
tmp_dpi.left += ir.left;
tmp_dpi.top += ir.top;
AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
ir.left -= this->hscroll->GetPosition();
ir.right += this->hscroll->GetCapacity() - this->hscroll->GetPosition();
if (this->industries.empty()) {
DrawString(ir, STR_INDUSTRY_DIRECTORY_NONE);
break;
}
int n = 0;
TextColour tc;
const CargoID acf_cid = this->cargo_filter[this->accepted_cargo_filter_criteria];
for (uint i = this->vscroll->GetPosition(); i < this->industries.size(); i++) {
TextColour tc = TC_FROMSTRING;
tc = TC_FROMSTRING;
if (acf_cid != CF_ANY && acf_cid != CF_NONE) {
Industry *ind = const_cast<Industry *>(this->industries[i]);
if (IndustryTemporarilyRefusesCargo(ind, acf_cid)) {
@ -1748,6 +1720,9 @@ public:
case WID_ID_INDUSTRY_LIST: {
Dimension d = GetStringBoundingBox(STR_INDUSTRY_DIRECTORY_NONE);
for (uint i = 0; i < this->industries.size(); i++) {
d = maxdim(d, GetStringBoundingBox(this->GetIndustryString(this->industries[i])));
}
resize->height = d.height;
d.height *= 5;
d.width += padding.width;
@ -1821,7 +1796,6 @@ public:
void OnResize() override
{
this->vscroll->SetCapacityFromWidget(this, WID_ID_INDUSTRY_LIST);
this->hscroll->SetCapacityFromWidget(this, WID_ID_INDUSTRY_LIST);
}
void OnEditboxChanged(int wid) override

View File

@ -5190,7 +5190,6 @@ STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Impossí
STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Veículos só podem aguardar em estações
STR_ERROR_TIMETABLE_NOT_STOPPING_HERE :{WHITE}Esse veículo não pára nesta estação
STR_ERROR_TIMETABLE_INCOMPLETE :{WHITE}... horário incompleto
STR_ERROR_TIMETABLE_NOT_STARTED :{WHITE}... o plano de horário ainda não começou
# Sign related errors
STR_ERROR_TOO_MANY_SIGNS :{WHITE}... existem placas demais

View File

@ -5189,7 +5189,6 @@ STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Ei voi a
STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Kulkuneuvo voi odottaa vain asemalla
STR_ERROR_TIMETABLE_NOT_STOPPING_HERE :{WHITE}Tämä kulkuneuvo ei pysähdy tällä asemalla
STR_ERROR_TIMETABLE_INCOMPLETE :{WHITE}… aikataulu on puutteellinen
STR_ERROR_TIMETABLE_NOT_STARTED :{WHITE}… aikataulu ei ole vielä alkanut
# Sign related errors
STR_ERROR_TOO_MANY_SIGNS :{WHITE}... liian monta kylttiä.

View File

@ -5190,7 +5190,6 @@ STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}차량
STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}차량은 정거장에서만 기다릴 수 있습니다
STR_ERROR_TIMETABLE_NOT_STOPPING_HERE :{WHITE}이 차량은 이 정거장에 서지 않습니다
STR_ERROR_TIMETABLE_INCOMPLETE :{WHITE}... 시간표가 모두 작성되지 않았습니다
STR_ERROR_TIMETABLE_NOT_STARTED :{WHITE}... 시간표가 아직 시작되지 않았습니다
# Sign related errors
STR_ERROR_TOO_MANY_SIGNS :{WHITE}... 팻말 수가 너무 많습니다

View File

@ -1954,16 +1954,27 @@ static const NWidgetPart _nested_build_depot_widgets[] = {
NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_BUILD_DEPOT_TRAIN_ORIENTATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 1), SetPadding(WidgetDimensions::unscaled.picker),
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAD_DEPOT_NW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAD_DEPOT_SW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
NWidget(NWID_SPACER), SetMinimalSize(0, 3),
NWidget(NWID_HORIZONTAL_LTR),
NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
NWidget(NWID_VERTICAL),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_NW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_SW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
EndContainer(),
EndContainer(),
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAD_DEPOT_NE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAD_DEPOT_SE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
NWidget(NWID_SPACER), SetMinimalSize(2, 0),
NWidget(NWID_VERTICAL),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_NE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_SE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 3),
EndContainer(),
};

View File

@ -1063,15 +1063,19 @@ static const NWidgetPart _nested_build_road_depot_widgets[] = {
NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROD_CAPTION), SetDataTip(STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 1), SetPadding(WidgetDimensions::unscaled.picker),
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROD_DEPOT_NW), SetMinimalSize(66, 50), SetFill(0, 0), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROD_DEPOT_SW), SetMinimalSize(66, 50), SetFill(0, 0), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
EndContainer(),
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROD_DEPOT_NE), SetMinimalSize(66, 50), SetFill(0, 0), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROD_DEPOT_SE), SetMinimalSize(66, 50), SetFill(0, 0), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
NWidget(NWID_HORIZONTAL), SetPadding(3),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(NWID_VERTICAL), SetPIP(0, 2, 0),
NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, 2, 0),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_NW), SetMinimalSize(66, 50), SetFill(0, 0), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_NE), SetMinimalSize(66, 50), SetFill(0, 0), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, 2, 0),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_SW), SetMinimalSize(66, 50), SetFill(0, 0), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_SE), SetMinimalSize(66, 50), SetFill(0, 0), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), EndContainer(),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
EndContainer(),
};

View File

@ -19,8 +19,6 @@
#include "core/math_func.hpp"
#include "core/mem_func.hpp"
#include "video/video_driver.hpp"
#include "spritecache.h"
#include "spritecache_internal.h"
#include "table/sprites.h"
#include "table/strings.h"
@ -31,6 +29,17 @@
/* Default of 4MB spritecache */
uint _sprite_cache_size = 4;
struct SpriteCache {
void *ptr;
size_t file_pos;
SpriteFile *file; ///< The file the sprite in this entry can be found in.
uint32_t id;
int16_t lru;
SpriteType type; ///< In some cases a single sprite is misused by two NewGRFs. Once as real sprite and once as recolour sprite. If the recolour sprite gets into the cache it might be drawn as real sprite which causes enormous trouble.
bool warned; ///< True iff the user has been warned about incorrect use of this sprite
byte control_flags; ///< Control flags, see SpriteCacheCtrlFlags
};
static uint _spritecache_items = 0;
static SpriteCache *_spritecache = nullptr;
@ -41,7 +50,12 @@ static inline SpriteCache *GetSpriteCache(uint index)
return &_spritecache[index];
}
SpriteCache *AllocateSpriteCache(uint index)
static inline bool IsMapgenSpriteID(SpriteID sprite)
{
return IsInsideMM(sprite, SPR_MAPGEN_BEGIN, SPR_MAPGEN_END);
}
static SpriteCache *AllocateSpriteCache(uint index)
{
if (index >= _spritecache_items) {
/* Add another 1024 items to the 'pool' */
@ -102,6 +116,7 @@ static uint _allocated_sprite_cache_size = 0;
static int _compact_cache_counter;
static void CompactSpriteCache();
static void *AllocSprite(size_t mem_req);
/**
* Skip the given amount of sprite graphics data.
@ -830,7 +845,7 @@ static void DeleteEntryFromSpriteCache()
DeleteEntryFromSpriteCache(best);
}
void *AllocSprite(size_t mem_req)
static void *AllocSprite(size_t mem_req)
{
mem_req += sizeof(MemBlock);

View File

@ -1,42 +0,0 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file spritecache_internal.h Internal functions to cache sprites in memory. */
#ifndef SPRITECACHE_INTERNAL_H
#define SPRITECACHE_INTERNAL_H
#include "stdafx.h"
#include "core/math_func.hpp"
#include "gfx_type.h"
#include "spriteloader/spriteloader.hpp"
#include "table/sprites.h"
/* These declarations are internal to spritecache but need to be exposed for unit-tests. */
struct SpriteCache {
void *ptr;
size_t file_pos;
SpriteFile *file; ///< The file the sprite in this entry can be found in.
uint32_t id;
int16_t lru;
SpriteType type; ///< In some cases a single sprite is misused by two NewGRFs. Once as real sprite and once as recolour sprite. If the recolour sprite gets into the cache it might be drawn as real sprite which causes enormous trouble.
bool warned; ///< True iff the user has been warned about incorrect use of this sprite
byte control_flags; ///< Control flags, see SpriteCacheCtrlFlags
};
static inline bool IsMapgenSpriteID(SpriteID sprite)
{
return IsInsideMM(sprite, SPR_MAPGEN_BEGIN, SPR_MAPGEN_END);
}
void *AllocSprite(size_t mem_req);
SpriteCache *AllocateSpriteCache(uint index);
#endif /* SPRITECACHE_INTERNAL_H */

View File

@ -82,7 +82,7 @@ static const RoadTypeInfo _original_roadtypes[] = {
0x01,
/* introduction date */
CalendarTime::MIN_DATE,
static_cast<int32_t>(CalendarTime::MIN_YEAR),
/* roadtypes required for this to be introduced */
ROADTYPES_NONE,

View File

@ -1,10 +1,6 @@
add_test_files(
landscape_partial_pixel_z.cpp
math_func.cpp
mock_environment.h
mock_fontcache.h
mock_spritecache.cpp
mock_spritecache.h
string_func.cpp
strings_func.cpp
test_main.cpp

View File

@ -1,39 +0,0 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file mock_environment.h Singleton instance to create a mock FontCache/SpriteCache environment. */
#ifndef MOCK_ENVIRONMENT_H
#define MOCK_ENVIRONMENT_H
#include "mock_fontcache.h"
#include "mock_spritecache.h"
/** Singleton class to set up the mock environemnt once. */
class MockEnvironment {
public:
static MockEnvironment &Instance()
{
static MockEnvironment instance;
return instance;
}
MockEnvironment(MockEnvironment const &) = delete;
void operator=(MockEnvironment const &) = delete;
private:
MockEnvironment()
{
/* Mock SpriteCache initialization is needed for some widget generators. */
MockGfxLoadSprites();
/* Mock FontCache initialization is needed for some NWidgetParts. */
MockFontCache::InitializeFontCaches();
}
};
#endif /* MOCK_ENVIRONMENT_H */

View File

@ -1,45 +0,0 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file mock_fontcache.h Mock font cache implementation definition. */
#ifndef MOCK_FONTCACHE_H
#define MOCK_FONTCACHE_H
#include "../stdafx.h"
#include "../fontcache.h"
#include "../string_func.h"
/** Font cache for mocking basic use of fonts. */
class MockFontCache : public FontCache {
public:
MockFontCache(FontSize fs) : FontCache(fs)
{
this->height = FontCache::GetDefaultFontHeight(this->fs);
}
void SetUnicodeGlyph(char32_t, SpriteID) override {}
void InitializeUnicodeGlyphMap() override {}
void ClearFontCache() override {}
const Sprite *GetGlyph(GlyphID) override { return nullptr; }
uint GetGlyphWidth(GlyphID) override { return this->height / 2; }
bool GetDrawGlyphShadow() override { return false; }
GlyphID MapCharToGlyph(char32_t key) override { return key; }
const void *GetFontTable(uint32_t, size_t &length) override { length = 0; return nullptr; }
std::string GetFontName() override { return "mock"; }
bool IsBuiltInFont() override { return true; }
static void InitializeFontCaches()
{
for (FontSize fs = FS_BEGIN; fs != FS_END; fs++) {
if (FontCache::caches[fs] == nullptr) new MockFontCache(fs); /* FontCache inserts itself into to the cache. */
}
}
};
#endif /* MOCK_FONTCACHE_H */

View File

@ -1,49 +0,0 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file mock_spritecache.cpp Mock sprite cache implementation. */
#include "../stdafx.h"
#include "../blitter/factory.hpp"
#include "../core/math_func.hpp"
#include "../spritecache.h"
#include "../spritecache_internal.h"
#include "../table/sprites.h"
static bool MockLoadNextSprite(int load_index)
{
static Sprite *sprite = (Sprite *)AllocSprite(sizeof(*sprite));
bool is_mapgen = IsMapgenSpriteID(load_index);
SpriteCache *sc = AllocateSpriteCache(load_index);
sc->file = nullptr;
sc->file_pos = 0;
sc->ptr = sprite;
sc->lru = 0;
sc->id = 0;
sc->type = is_mapgen ? SpriteType::MapGen : SpriteType::Normal;
sc->warned = false;
sc->control_flags = 0;
/* Fill with empty sprites up until the default sprite count. */
return (uint)load_index < SPR_OPENTTD_BASE + OPENTTD_SPRITE_COUNT;
}
void MockGfxLoadSprites()
{
/* Force blitter 'null'. This is necessary for GfxInitSpriteMem() to function. */
BlitterFactory::SelectBlitter("null");
GfxInitSpriteMem();
int load_index = 0;
while (MockLoadNextSprite(load_index)) {
load_index++;
}
}

View File

@ -1,15 +0,0 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file mock_spritecache.h Mock sprite cache definition. */
#ifndef MOCK_SPRITECACHE_H
#define MOCK_SPRITECACHE_H
void MockGfxLoadSprites();
#endif /* MOCK_SPRITECACHE_H */

View File

@ -11,8 +11,6 @@
#include "../3rdparty/catch2/catch.hpp"
#include "mock_environment.h"
#include "../window_gui.h"
/**
@ -21,13 +19,6 @@
*/
extern std::vector<WindowDesc*> *_window_descs;
class WindowDescTestsFixture {
private:
MockEnvironment &mock = MockEnvironment::Instance();
};
TEST_CASE("WindowDesc - ini_key uniqueness")
{
std::set<std::string> seen;
@ -82,17 +73,3 @@ TEST_CASE("WindowDesc - NWidgetParts properly closed")
CHECK(IsNWidgetTreeClosed(window_desc->nwid_begin, window_desc->nwid_end));
}
TEST_CASE_METHOD(WindowDescTestsFixture, "WindowDesc - NWidgetPart validity")
{
const WindowDesc *window_desc = GENERATE(from_range(std::begin(*_window_descs), std::end(*_window_descs)));
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));
CHECK((root != nullptr));
}

View File

@ -178,9 +178,6 @@ public:
/** The date of the first day of the original base year. */
static constexpr TimerGameCalendar::Date DAYS_TILL_ORIGINAL_BASE_YEAR = TimerGameCalendar::DateAtStartOfYear(ORIGINAL_BASE_YEAR);
/** The absolute minimum date. */
static constexpr TimerGameCalendar::Date MIN_DATE = 0;
/** The date of the last day of the max year. */
static constexpr TimerGameCalendar::Date MAX_DATE = TimerGameCalendar::DateAtStartOfYear(CalendarTime::MAX_YEAR + 1) - 1;

View File

@ -469,7 +469,7 @@ int Train::GetDisplayImageWidth(Point *offset) const
if (offset != nullptr) {
if (HasBit(this->flags, VRF_REVERSE_DIRECTION) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_RAIL_FLIPS)) {
offset->x = ScaleSpriteTrad(((int)this->gcache.cached_veh_length - (int)VEHICLE_LENGTH / 2) * reference_width / (int)VEHICLE_LENGTH);
offset->x = ScaleSpriteTrad((this->gcache.cached_veh_length - VEHICLE_LENGTH / 2) * reference_width / VEHICLE_LENGTH);
} else {
offset->x = ScaleSpriteTrad(reference_width) / 2;
}

View File

@ -151,9 +151,7 @@ const WidgetDimensions WidgetDimensions::unscaled = {
{WD_CAPTIONTEXT_LEFT, WD_CAPTIONTEXT_TOP, WD_CAPTIONTEXT_RIGHT, WD_CAPTIONTEXT_BOTTOM}, ///< captiontext
{WD_DROPDOWNTEXT_LEFT, WD_DROPDOWNTEXT_TOP, WD_DROPDOWNTEXT_RIGHT, WD_DROPDOWNTEXT_BOTTOM}, ///< dropdowntext
{20, 10, 20, 10}, ///< modalpopup
{3, 3, 3, 3}, ///< picker
1, ///< pressed
1, ///< vsep_picker
WD_PAR_VSEP_NORMAL, ///< vsep_normal
WD_PAR_VSEP_WIDE, ///< vsep_wide
2, ///< hsep_normal
@ -1500,22 +1498,6 @@ void NWidgetPIPContainer::SetPIP(uint8_t pip_pre, uint8_t pip_inter, uint8_t pip
this->pip_post = ScaleGUITrad(this->uz_pip_post);
}
/**
* Set additional pre/inter/post space for the container.
*
* @param pip_ratio_pre Ratio of additional space in front of the first child widget (above
* for the vertical container, at the left for the horizontal container).
* @param pip_ratio_inter Ratio of additional space between two child widgets.
* @param pip_ratio_post Ratio of additional space after the last child widget (below for the
* vertical container, at the right for the horizontal container).
*/
void NWidgetPIPContainer::SetPIPRatio(uint8_t pip_ratio_pre, uint8_t pip_ratio_inter, uint8_t pip_ratio_post)
{
this->pip_ratio_pre = pip_ratio_pre;
this->pip_ratio_inter = pip_ratio_inter;
this->pip_ratio_post = pip_ratio_post;
}
/** Horizontal container widget. */
NWidgetHorizontal::NWidgetHorizontal(NWidContainerFlags flags) : NWidgetPIPContainer(NWID_HORIZONTAL, flags)
{
@ -1529,7 +1511,6 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array)
this->fill_y = 1; // smallest common child fill step.
this->resize_x = 0; // smallest non-zero child widget resize step.
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. */
uint longest = 0; // Longest child found.
@ -1539,9 +1520,7 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array)
longest = std::max(longest, child_wid->smallest_x);
max_vert_fill = std::max(max_vert_fill, child_wid->GetVerticalStepSize(ST_SMALLEST));
this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.Vertical());
if (child_wid->smallest_x != 0 || child_wid->fill_x != 0) this->gaps++;
}
if (this->gaps > 0) this->gaps--; // Number of gaps is number of widgets less one.
/* 1b. Make the container higher if needed to accommodate all children nicely. */
[[maybe_unused]] uint max_smallest = this->smallest_y + 3 * max_vert_fill; // Upper limit to computing smallest height.
uint cur_height = this->smallest_y;
@ -1567,8 +1546,15 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array)
if (child_wid->fill_x == 1) child_wid->smallest_x = longest;
}
}
/* 3. Compute smallest, fill, and resize values of the container. */
/* 3. Move PIP space to the children, compute smallest, fill, and resize values of the container. */
if (this->head != nullptr) this->head->padding.left += this->pip_pre;
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
if (child_wid->next != nullptr) {
child_wid->padding.right += this->pip_inter;
} else {
child_wid->padding.right += this->pip_post;
}
this->smallest_x += child_wid->smallest_x + child_wid->padding.Horizontal();
if (child_wid->fill_x > 0) {
if (this->fill_x == 0 || this->fill_x > child_wid->fill_x) this->fill_x = child_wid->fill_x;
@ -1580,9 +1566,8 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array)
}
this->resize_y = LeastCommonMultiple(this->resize_y, child_wid->resize_y);
}
if (this->fill_x == 0 && this->pip_ratio_pre + this->pip_ratio_inter + this->pip_ratio_post > 0) this->fill_x = 1;
/* 4. Increase by required PIP space. */
this->smallest_x += this->pip_pre + this->gaps * this->pip_inter + this->pip_post;
/* We need to zero the PIP settings so we can re-initialize the tree. */
this->pip_pre = this->pip_inter = this->pip_post = 0;
}
void NWidgetHorizontal::AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl)
@ -1591,11 +1576,10 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, int x, int y, uint
/* Compute additional width given to us. */
uint additional_length = given_width;
if (this->pip_ratio_pre + this->pip_ratio_inter + this->pip_ratio_post != 0 || (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE))) {
if (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE)) {
/* For EQUALSIZE containers this does not sum to smallest_x during initialisation */
additional_length -= this->pip_pre + this->gaps * this->pip_inter + this->pip_post;
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
if (child_wid->smallest_x != 0 || child_wid->fill_x != 0) additional_length -= child_wid->smallest_x + child_wid->padding.Horizontal();
additional_length -= child_wid->smallest_x + child_wid->padding.Horizontal();
}
} else {
additional_length -= this->smallest_x;
@ -1672,21 +1656,8 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, int x, int y, uint
}
assert(num_changing_childs == 0);
uint pre = this->pip_pre;
uint inter = this->pip_inter;
if (additional_length > 0) {
/* Allocate remaining space by pip ratios. If this doesn't round exactly, the unused space will fall into pip_post
* which is never explicitly needed. */
int r = this->pip_ratio_pre + this->gaps * this->pip_ratio_inter + this->pip_ratio_post;
if (r > 0) {
pre += this->pip_ratio_pre * additional_length / r;
if (this->gaps > 0) inter += this->pip_ratio_inter * additional_length / r;
}
}
/* Third loop: Compute position and call the child. */
uint position = rtl ? this->current_x - pre : pre; // Place to put next child relative to origin of the container.
uint position = rtl ? this->current_x : 0; // Place to put next child relative to origin of the container.
NWidgetBase *child_wid = this->head;
while (child_wid != nullptr) {
uint child_width = child_wid->current_x;
@ -1694,10 +1665,8 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, int x, int y, uint
uint child_y = y + child_wid->padding.top;
child_wid->AssignSizePosition(sizing, child_x, child_y, child_width, child_wid->current_y, rtl);
if (child_wid->current_x != 0) {
uint padded_child_width = child_width + child_wid->padding.Horizontal() + inter;
position = rtl ? position - padded_child_width : position + padded_child_width;
}
uint padded_child_width = child_width + child_wid->padding.Horizontal();
position = rtl ? position - padded_child_width : position + padded_child_width;
child_wid = child_wid->next;
}
@ -1727,7 +1696,6 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array)
this->fill_y = 0; // smallest non-zero child widget fill step.
this->resize_x = 1; // smallest common child resize step.
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. */
uint highest = 0; // Highest child found.
@ -1737,9 +1705,7 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array)
highest = std::max(highest, child_wid->smallest_y);
max_hor_fill = std::max(max_hor_fill, child_wid->GetHorizontalStepSize(ST_SMALLEST));
this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.Horizontal());
if (child_wid->smallest_y != 0 || child_wid->fill_y != 0) this->gaps++;
}
if (this->gaps > 0) this->gaps--; // Number of gaps is number of widgets less one.
/* 1b. Make the container wider if needed to accommodate all children nicely. */
[[maybe_unused]] uint max_smallest = this->smallest_x + 3 * max_hor_fill; // Upper limit to computing smallest height.
uint cur_width = this->smallest_x;
@ -1765,8 +1731,15 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array)
if (child_wid->fill_y == 1) child_wid->smallest_y = highest;
}
}
/* 3. Compute smallest, fill, and resize values of the container. */
/* 3. Move PIP space to the child, compute smallest, fill, and resize values of the container. */
if (this->head != nullptr) this->head->padding.top += this->pip_pre;
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
if (child_wid->next != nullptr) {
child_wid->padding.bottom += this->pip_inter;
} else {
child_wid->padding.bottom += this->pip_post;
}
this->smallest_y += child_wid->smallest_y + child_wid->padding.Vertical();
if (child_wid->fill_y > 0) {
if (this->fill_y == 0 || this->fill_y > child_wid->fill_y) this->fill_y = child_wid->fill_y;
@ -1778,9 +1751,8 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array)
}
this->resize_x = LeastCommonMultiple(this->resize_x, child_wid->resize_x);
}
if (this->fill_y == 0 && this->pip_ratio_pre + this->pip_ratio_inter + this->pip_ratio_post > 0) this->fill_y = 1;
/* 4. Increase by required PIP space. */
this->smallest_y += this->pip_pre + this->gaps * this->pip_inter + this->pip_post;
/* We need to zero the PIP settings so we can re-initialize the tree. */
this->pip_pre = this->pip_inter = this->pip_post = 0;
}
void NWidgetVertical::AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl)
@ -1789,11 +1761,10 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, int x, int y, uint g
/* Compute additional height given to us. */
uint additional_length = given_height;
if (this->pip_ratio_pre + this->pip_ratio_inter + this->pip_ratio_post != 0 || (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE))) {
if (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE)) {
/* For EQUALSIZE containers this does not sum to smallest_y during initialisation */
additional_length -= this->pip_pre + this->gaps * this->pip_inter + this->pip_post;
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
if (child_wid->smallest_y != 0 || child_wid->fill_y != 0) additional_length -= child_wid->smallest_y + child_wid->padding.Vertical();
additional_length -= child_wid->smallest_y + child_wid->padding.Vertical();
}
} else {
additional_length -= this->smallest_y;
@ -1861,29 +1832,14 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, int x, int y, uint g
}
assert(num_changing_childs == 0);
uint pre = this->pip_pre;
uint inter = this->pip_inter;
if (additional_length > 0) {
/* Allocate remaining space by pip ratios. If this doesn't round exactly, the unused space will fall into pip_post
* which is never explicitly needed. */
int r = this->pip_ratio_pre + this->gaps * this->pip_ratio_inter + this->pip_ratio_post;
if (r > 0) {
pre += this->pip_ratio_pre * additional_length / r;
if (this->gaps > 0) inter += this->pip_ratio_inter * additional_length / r;
}
}
/* Third loop: Compute position and call the child. */
uint position = pre; // Place to put next child relative to origin of the container.
uint position = 0; // Place to put next child relative to origin of the container.
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
uint child_x = x + (rtl ? child_wid->padding.right : child_wid->padding.left);
uint child_height = child_wid->current_y;
child_wid->AssignSizePosition(sizing, child_x, y + position + child_wid->padding.top, child_wid->current_x, child_height, rtl);
if (child_wid->current_y != 0) {
position += child_height + child_wid->padding.Vertical() + inter;
}
position += child_height + child_wid->padding.Vertical();
}
}
@ -2220,24 +2176,6 @@ void NWidgetBackground::SetPIP(uint8_t pip_pre, uint8_t pip_inter, uint8_t pip_p
this->child->SetPIP(pip_pre, pip_inter, pip_post);
}
/**
* Set additional pre/inter/post space ratios for the background widget.
*
* @param pip_ratio_pre Ratio of additional space in front of the first child widget (above
* for the vertical container, at the left for the horizontal container).
* @param pip_ratio_inter Ratio of additional space between two child widgets.
* @param pip_ratio_post Ratio of additional space after the last child widget (below for the
* vertical container, at the right for the horizontal container).
* @note Using this function implies that the widget has (or will have) child widgets.
*/
void NWidgetBackground::SetPIPRatio(uint8_t pip_ratio_pre, uint8_t pip_ratio_inter, uint8_t pip_ratio_post)
{
if (this->child == nullptr) {
this->child = new NWidgetVertical();
}
this->child->SetPIPRatio(pip_ratio_pre, pip_ratio_inter, pip_ratio_post);
}
void NWidgetBackground::AdjustPaddingForZoom()
{
if (child != nullptr) child->AdjustPaddingForZoom();
@ -3179,60 +3117,64 @@ static const NWidgetPart *MakeNWidget(const NWidgetPart *nwid_begin, const NWidg
case WPT_RESIZE: {
NWidgetResizeBase *nwrb = dynamic_cast<NWidgetResizeBase *>(*dest);
if (unlikely(nwrb == nullptr)) throw std::runtime_error("WPT_RESIZE requires NWidgetResizeBase");
assert(nwid_begin->u.xy.x >= 0 && nwid_begin->u.xy.y >= 0);
nwrb->SetResize(nwid_begin->u.xy.x, nwid_begin->u.xy.y);
if (nwrb != nullptr) {
assert(nwid_begin->u.xy.x >= 0 && nwid_begin->u.xy.y >= 0);
nwrb->SetResize(nwid_begin->u.xy.x, nwid_begin->u.xy.y);
}
break;
}
case WPT_MINSIZE: {
NWidgetResizeBase *nwrb = dynamic_cast<NWidgetResizeBase *>(*dest);
if (unlikely(nwrb == nullptr)) throw std::runtime_error("WPT_MINSIZE requires NWidgetResizeBase");
assert(nwid_begin->u.xy.x >= 0 && nwid_begin->u.xy.y >= 0);
nwrb->SetMinimalSize(nwid_begin->u.xy.x, nwid_begin->u.xy.y);
if (nwrb != nullptr) {
assert(nwid_begin->u.xy.x >= 0 && nwid_begin->u.xy.y >= 0);
nwrb->SetMinimalSize(nwid_begin->u.xy.x, nwid_begin->u.xy.y);
}
break;
}
case WPT_MINTEXTLINES: {
NWidgetResizeBase *nwrb = dynamic_cast<NWidgetResizeBase *>(*dest);
if (unlikely(nwrb == nullptr)) throw std::runtime_error("WPT_MINTEXTLINES requires NWidgetResizeBase");
assert(nwid_begin->u.text_lines.size >= FS_BEGIN && nwid_begin->u.text_lines.size < FS_END);
nwrb->SetMinimalTextLines(nwid_begin->u.text_lines.lines, nwid_begin->u.text_lines.spacing, nwid_begin->u.text_lines.size);
if (nwrb != nullptr) {
assert(nwid_begin->u.text_lines.size >= FS_BEGIN && nwid_begin->u.text_lines.size < FS_END);
nwrb->SetMinimalTextLines(nwid_begin->u.text_lines.lines, nwid_begin->u.text_lines.spacing, nwid_begin->u.text_lines.size);
}
break;
}
case WPT_TEXTSTYLE: {
NWidgetCore *nwc = dynamic_cast<NWidgetCore *>(*dest);
if (unlikely(nwc == nullptr)) throw std::runtime_error("WPT_TEXTSTYLE requires NWidgetCore");
nwc->SetTextStyle(nwid_begin->u.text_style.colour, nwid_begin->u.text_style.size);
if (nwc != nullptr) {
nwc->SetTextStyle(nwid_begin->u.text_style.colour, nwid_begin->u.text_style.size);
}
break;
}
case WPT_ALIGNMENT: {
NWidgetCore *nwc = dynamic_cast<NWidgetCore *>(*dest);
if (unlikely(nwc == nullptr)) throw std::runtime_error("WPT_ALIGNMENT requires NWidgetCore");
nwc->SetAlignment(nwid_begin->u.align.align);
if (nwc != nullptr) {
nwc->SetAlignment(nwid_begin->u.align.align);
}
break;
}
case WPT_FILL: {
NWidgetResizeBase *nwrb = dynamic_cast<NWidgetResizeBase *>(*dest);
if (unlikely(nwrb == nullptr)) throw std::runtime_error("WPT_FILL requires NWidgetResizeBase");
nwrb->SetFill(nwid_begin->u.xy.x, nwid_begin->u.xy.y);
if (nwrb != nullptr) nwrb->SetFill(nwid_begin->u.xy.x, nwid_begin->u.xy.y);
break;
}
case WPT_DATATIP: {
NWidgetCore *nwc = dynamic_cast<NWidgetCore *>(*dest);
if (unlikely(nwc == nullptr)) throw std::runtime_error("WPT_DATATIP requires NWidgetCore");
nwc->widget_data = nwid_begin->u.data_tip.data;
nwc->tool_tip = nwid_begin->u.data_tip.tooltip;
if (nwc != nullptr) {
nwc->widget_data = nwid_begin->u.data_tip.data;
nwc->tool_tip = nwid_begin->u.data_tip.tooltip;
}
break;
}
case WPT_PADDING:
if (unlikely(*dest == nullptr)) throw std::runtime_error("WPT_PADDING requires NWidgetBase");
(*dest)->SetPadding(nwid_begin->u.padding);
if (*dest != nullptr) (*dest)->SetPadding(nwid_begin->u.padding);
break;
case WPT_PIPSPACE: {
@ -3241,24 +3183,14 @@ static const NWidgetPart *MakeNWidget(const NWidgetPart *nwid_begin, const NWidg
NWidgetBackground *nwb = dynamic_cast<NWidgetBackground *>(*dest);
if (nwb != nullptr) nwb->SetPIP(nwid_begin->u.pip.pre, nwid_begin->u.pip.inter, nwid_begin->u.pip.post);
if (unlikely(nwc == nullptr && nwb == nullptr)) throw std::runtime_error("WPT_PIPSPACE requires NWidgetPIPContainer or NWidgetBackground");
break;
}
case WPT_PIPRATIO: {
NWidgetPIPContainer *nwc = dynamic_cast<NWidgetPIPContainer *>(*dest);
if (nwc != nullptr) nwc->SetPIPRatio(nwid_begin->u.pip.pre, nwid_begin->u.pip.inter, nwid_begin->u.pip.post);
NWidgetBackground *nwb = dynamic_cast<NWidgetBackground *>(*dest);
if (nwb != nullptr) nwb->SetPIPRatio(nwid_begin->u.pip.pre, nwid_begin->u.pip.inter, nwid_begin->u.pip.post);
break;
}
case WPT_SCROLLBAR: {
NWidgetCore *nwc = dynamic_cast<NWidgetCore *>(*dest);
if (unlikely(nwc == nullptr)) throw std::runtime_error("WPT_SCROLLBAR requires NWidgetCore");
nwc->scrollbar_index = nwid_begin->u.widget.index;
if (nwc != nullptr) {
nwc->scrollbar_index = nwid_begin->u.widget.index;
}
break;
}
@ -3375,10 +3307,7 @@ NWidgetContainer *MakeNWidgets(const NWidgetPart *nwid_begin, const NWidgetPart
*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);
#ifdef WITH_ASSERT
if (unlikely(nwid_part != nwid_end)) throw std::runtime_error("Did not consume all NWidgetParts");
#endif
MakeWidgetTree(nwid_begin, nwid_end, &cont_ptr, biggest_index);
return container;
}

View File

@ -87,7 +87,6 @@ enum WidgetType {
WPT_DATATIP, ///< Widget part for specifying data and tooltip.
WPT_PADDING, ///< Widget part for specifying a padding.
WPT_PIPSPACE, ///< Widget part for specifying pre/inter/post space for containers.
WPT_PIPRATIO, ///< Widget part for specifying pre/inter/post ratio for containers.
WPT_TEXTSTYLE, ///< Widget part for specifying text colour.
WPT_ALIGNMENT, ///< Widget part for specifying text/image alignment.
WPT_ENDCONTAINER, ///< Widget part to denote end of a container.
@ -483,22 +482,16 @@ public:
void AdjustPaddingForZoom() override;
void SetPIP(uint8_t pip_pre, uint8_t pip_inter, uint8_t pip_post);
void SetPIPRatio(uint8_t pip_ratio_pre, uint8_t pip_ratio_inter, uint8_t pip_rato_post);
protected:
NWidContainerFlags flags; ///< Flags of the container.
uint8_t pip_pre; ///< Amount of space before first widget.
uint8_t pip_inter; ///< Amount of space between widgets.
uint8_t pip_post; ///< Amount of space after last widget.
uint8_t pip_ratio_pre; ///< Ratio of remaining space before first widget.
uint8_t pip_ratio_inter; ///< Ratio of remaining space between widgets.
uint8_t pip_ratio_post; ///< Ratio of remaining space after last widget.
uint8_t uz_pip_pre; ///< Unscaled space before first widget.
uint8_t uz_pip_inter; ///< Unscaled space between widgets.
uint8_t uz_pip_post; ///< Unscaled space after last widget.
uint8_t gaps; ///< Number of gaps between widgets.
};
/**
@ -603,7 +596,6 @@ public:
void Add(NWidgetBase *nwid);
void SetPIP(uint8_t pip_pre, uint8_t pip_inter, uint8_t pip_post);
void SetPIPRatio(uint8_t pip_ratio_pre, uint8_t pip_ratio_inter, uint8_t pip_ratio_post);
void AdjustPaddingForZoom() override;
void SetupSmallestSize(Window *w, bool init_array) override;
@ -1234,25 +1226,6 @@ static inline NWidgetPart SetPIP(uint8_t pre, uint8_t inter, uint8_t post)
return part;
}
/**
* Widget part function for setting a pre/inter/post ratio.
* @param pre The ratio of space before the first widget.
* @param inter The ratio of space between widgets.
* @param post The ratio of space after the last widget.
* @ingroup NestedWidgetParts
*/
static inline NWidgetPart SetPIPRatio(uint8_t ratio_pre, uint8_t ratio_inter, uint8_t ratio_post)
{
NWidgetPart part;
part.type = WPT_PIPRATIO;
part.u.pip.pre = ratio_pre;
part.u.pip.inter = ratio_inter;
part.u.pip.post = ratio_post;
return part;
}
/**
* Attach a scrollbar to a widget.
* The scrollbar is controlled when using the mousewheel on the widget.

View File

@ -39,8 +39,7 @@ enum IndustryDirectoryWidgets {
WID_ID_FILTER_BY_PROD_CARGO, ///< Produced cargo filter dropdown list.
WID_ID_FILTER, ///< Textbox to filter industry name.
WID_ID_INDUSTRY_LIST, ///< Industry list.
WID_ID_HSCROLLBAR, ///< Horizontal scrollbar of the list.
WID_ID_VSCROLLBAR, ///< Vertical scrollbar of the list.
WID_ID_SCROLLBAR, ///< Scrollbar of the list.
};
/** Widgets of the #IndustryCargoesWindow class */

View File

@ -50,10 +50,8 @@ struct WidgetDimensions {
RectPadding captiontext; ///< Offsets of text within a caption.
RectPadding dropdowntext; ///< Offsets of text within a dropdown widget.
RectPadding modalpopup; ///< Padding for a modal popup.
RectPadding picker; ///< Padding for a picker (dock, station, etc) window.
int pressed; ///< Offset for contents of depressed widget.
int vsep_picker; ///< Vertical spacing of picker-window widgets.
int vsep_normal; ///< Normal vertical spacing.
int vsep_wide; ///< Wide vertical spacing.
int hsep_normal; ///< Normal horizontal spacing.