Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Show cargo icon on cargo filter lists. #11487

Merged
merged 5 commits into from
Dec 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/build_vehicle_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1579,8 +1579,9 @@ struct BuildVehicleWindow : Window {
}

/* Add cargos */
Dimension d = GetLargestCargoIconSize();
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
list.push_back(std::make_unique<DropDownListStringItem>(cs->name, cs->Index(), false));
list.push_back(std::make_unique<DropDownListIconItem>(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false));
}

return list;
Expand Down
16 changes: 15 additions & 1 deletion src/cargotype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "stdafx.h"
#include "cargotype.h"
#include "core/geometry_func.hpp"
#include "newgrf_cargo.h"
#include "string_func.h"
#include "strings_func.h"
Expand Down Expand Up @@ -70,6 +71,19 @@ void SetupCargoForClimate(LandscapeID l)
std::fill(insert, std::end(CargoSpec::array), CargoSpec{});
}

/**
* Get dimensions of largest cargo icon.
* @return Dimensions of largest cargo icon.
*/
Dimension GetLargestCargoIconSize()
{
Dimension size = {0, 0};
for (const CargoSpec *cs : _sorted_cargo_specs) {
size = maxdim(size, GetSpriteSize(cs->GetCargoIcon()));
}
return size;
}

/**
* Get the cargo ID of a default cargo, if present.
* @param l Landscape
Expand Down Expand Up @@ -179,7 +193,7 @@ static bool CargoSpecClassSorter(const CargoSpec * const &a, const CargoSpec * c
void InitializeSortedCargoSpecs()
{
_sorted_cargo_specs.clear();
/* Add each cargo spec to the list. */
/* Add each cargo spec to the list, and determine the largest cargo icon size. */
for (const CargoSpec *cargo : CargoSpec::Iterate()) {
_sorted_cargo_specs.push_back(cargo);
}
Expand Down
1 change: 1 addition & 0 deletions src/cargotype.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ void SetupCargoForClimate(LandscapeID l);
CargoID GetCargoIDByLabel(CargoLabel cl);
CargoID GetCargoIDByBitnum(uint8_t bitnum);
CargoID GetDefaultCargoID(LandscapeID l, CargoType ct);
Dimension GetLargestCargoIconSize();

void InitializeSortedCargoSpecs();
extern std::array<uint8_t, NUM_CARGO> _sorted_cargo_types;
Expand Down
39 changes: 9 additions & 30 deletions src/company_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,36 +575,15 @@ static const LiveryClass _livery_class[LS_END] = {
LC_ROAD, LC_ROAD,
};

class DropDownListColourItem : public DropDownListStringItem {
/**
* Colour selection list item, with icon and string components.
* @tparam TSprite Recolourable sprite to draw as icon.
*/
template <SpriteID TSprite = SPR_SQUARE>
class DropDownListColourItem : public DropDownIcon<DropDownString<DropDownListItem>> {
public:
DropDownListColourItem(int result, bool masked) : DropDownListStringItem(result >= COLOUR_END ? STR_COLOUR_DEFAULT : _colour_dropdown[result], result, masked) {}

uint Width() const override
DropDownListColourItem(int colour, bool masked) : DropDownIcon<DropDownString<DropDownListItem>>(TSprite, PALETTE_RECOLOUR_START + (colour % COLOUR_END), colour < COLOUR_END ? _colour_dropdown[colour] : STR_COLOUR_DEFAULT, colour, masked)
{
return ScaleGUITrad(28) + WidgetDimensions::scaled.hsep_normal + GetStringBoundingBox(this->String()).width + WidgetDimensions::scaled.dropdowntext.Horizontal();
}

uint Height() const override
{
return std::max(GetCharacterHeight(FS_NORMAL), ScaleGUITrad(12) + WidgetDimensions::scaled.vsep_normal);
}

bool Selectable() const override
{
return true;
}

void Draw(const Rect &r, bool sel, Colours) const override
{
bool rtl = _current_text_dir == TD_RTL;
int icon_y = CenterBounds(r.top, r.bottom, 0);
int text_y = CenterBounds(r.top, r.bottom, GetCharacterHeight(FS_NORMAL));
Rect tr = r.Shrink(WidgetDimensions::scaled.dropdowntext);
DrawSprite(SPR_VEH_BUS_SIDE_VIEW, PALETTE_RECOLOUR_START + (this->result % COLOUR_END),
rtl ? tr.right - ScaleGUITrad(14) : tr.left + ScaleGUITrad(14),
icon_y);
tr = tr.Indent(ScaleGUITrad(28) + WidgetDimensions::scaled.hsep_normal, rtl);
DrawString(tr.left, tr.right, text_y, this->String(), sel ? TC_WHITE : TC_BLACK);
}
};

Expand Down Expand Up @@ -662,10 +641,10 @@ struct SelectCompanyLiveryWindow : public Window {
if (default_livery != nullptr) {
/* Add COLOUR_END to put the colour out of range, but also allow us to show what the default is */
default_col = (primary ? default_livery->colour1 : default_livery->colour2) + COLOUR_END;
list.push_back(std::make_unique<DropDownListColourItem>(default_col, false));
list.push_back(std::make_unique<DropDownListColourItem<>>(default_col, false));
}
for (uint i = 0; i < lengthof(_colour_dropdown); i++) {
list.push_back(std::make_unique<DropDownListColourItem>(i, HasBit(used_colours, i)));
list.push_back(std::make_unique<DropDownListColourItem<>>(i, HasBit(used_colours, i)));
}

byte sel = (default_livery == nullptr || HasBit(livery->in_use, primary ? 0 : 1)) ? (primary ? livery->colour1 : livery->colour2) : default_col;
Expand Down
3 changes: 2 additions & 1 deletion src/core/geometry_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ struct Dimension {
uint width;
uint height;

Dimension(uint w = 0, uint h = 0) : width(w), height(h) {};
constexpr Dimension() : width(0), height(0) {}
constexpr Dimension(uint w, uint h) : width(w), height(h) {}

bool operator< (const Dimension &other) const
{
Expand Down
2 changes: 1 addition & 1 deletion src/genworld_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ static DropDownList BuildTownNameDropDown()
size_t newgrf_size = list.size();
/* Insert newgrf_names at the top of the list */
if (newgrf_size > 0) {
list.push_back(std::make_unique<DropDownListItem>(-1, false)); // separator line
list.push_back(std::make_unique<DropDownListDividerItem>(-1, false)); // separator line
newgrf_size++;
}

Expand Down
6 changes: 4 additions & 2 deletions src/industry_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1753,8 +1753,9 @@ class IndustryDirectoryWindow : public Window {
list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CF_NONE), CF_NONE, false));

/* Add cargos */
Dimension d = GetLargestCargoIconSize();
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
list.push_back(std::make_unique<DropDownListStringItem>(cs->name, cs->Index(), false));
list.push_back(std::make_unique<DropDownListIconItem>(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false));
}

return list;
Expand Down Expand Up @@ -3091,8 +3092,9 @@ struct IndustryCargoesWindow : public Window {

case WID_IC_CARGO_DROPDOWN: {
DropDownList lst;
Dimension d = GetLargestCargoIconSize();
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
lst.push_back(std::make_unique<DropDownListStringItem>(cs->name, cs->Index(), false));
lst.push_back(std::make_unique<DropDownListIconItem>(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false));
}
if (!lst.empty()) {
int selected = (this->ind_cargo >= NUM_INDUSTRYTYPES) ? (int)(this->ind_cargo - NUM_INDUSTRYTYPES) : -1;
Expand Down
4 changes: 1 addition & 3 deletions src/rail_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2354,9 +2354,7 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option)
list.push_back(std::make_unique<DropDownListStringItem>(rti->strings.replace_text, rt, !HasBit(avail_railtypes, rt)));
} else {
StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING;
auto iconitem = std::make_unique<DropDownListIconItem>(rti->gui_sprites.build_x_rail, PAL_NONE, str, rt, !HasBit(avail_railtypes, rt));
iconitem->SetDimension(d);
list.push_back(std::move(iconitem));
list.push_back(std::make_unique<DropDownListIconItem>(d, rti->gui_sprites.build_x_rail, PAL_NONE, str, rt, !HasBit(avail_railtypes, rt)));
}
}

Expand Down
8 changes: 2 additions & 6 deletions src/road_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1828,9 +1828,7 @@ DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement, b
list.push_back(std::make_unique<DropDownListStringItem>(rti->strings.replace_text, rt, !HasBit(avail_roadtypes, rt)));
} else {
StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING;
auto iconitem = std::make_unique<DropDownListIconItem>(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt));
iconitem->SetDimension(d);
list.push_back(std::move(iconitem));
list.push_back(std::make_unique<DropDownListIconItem>(d, rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt)));
}
}

Expand Down Expand Up @@ -1869,9 +1867,7 @@ DropDownList GetScenRoadTypeDropDownList(RoadTramTypes rtts)
SetDParam(0, rti->strings.menu_text);
SetDParam(1, rti->max_speed / 2);
StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING;
auto item = std::make_unique<DropDownListIconItem>(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt));
item->SetDimension(d);
list.push_back(std::move(item));
list.push_back(std::make_unique<DropDownListIconItem>(d, rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt)));
}

if (list.empty()) {
Expand Down
2 changes: 1 addition & 1 deletion src/settings_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ struct GameOptionsWindow : Window {
std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc);

/* Append custom currency at the end */
list.push_back(std::make_unique<DropDownListItem>(-1, false)); // separator line
list.push_back(std::make_unique<DropDownListDividerItem>(-1, false)); // separator line
list.push_back(std::make_unique<DropDownListStringItem>(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, HasBit(disabled, CURRENCY_CUSTOM)));
break;
}
Expand Down
113 changes: 16 additions & 97 deletions src/toolbar_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,97 +89,16 @@ enum CallBackFunction {

static CallBackFunction _last_started_action = CBF_NONE; ///< Last started user action.


/**
* Drop down list entry for showing a checked/unchecked toggle item.
* Company name list item, with company-colour icon, name, and lock components.
*/
class DropDownListCheckedItem : public DropDownListStringItem {
uint checkmark_width;
class DropDownListCompanyItem : public DropDownIcon<DropDownIcon<DropDownString<DropDownListItem>, true>> {
public:
bool checked;

DropDownListCheckedItem(StringID string, int result, bool masked, bool checked) : DropDownListStringItem(string, result, masked), checked(checked)
{
this->checkmark_width = GetStringBoundingBox(STR_JUST_CHECKMARK).width + WidgetDimensions::scaled.hsep_wide;
}

uint Width() const override
{
return DropDownListStringItem::Width() + this->checkmark_width;
}

void Draw(const Rect &r, bool sel, Colours) const override
{
bool rtl = _current_text_dir == TD_RTL;
Rect tr = r.Shrink(WidgetDimensions::scaled.dropdowntext, RectPadding::zero);
if (this->checked) {
DrawString(tr, STR_JUST_CHECKMARK, sel ? TC_WHITE : TC_BLACK);
}
DrawString(tr.Indent(this->checkmark_width, rtl), this->String(), sel ? TC_WHITE : TC_BLACK);
}
};

/**
* Drop down list entry for showing a company entry, with companies 'blob'.
*/
class DropDownListCompanyItem : public DropDownListItem {
Dimension icon_size;
Dimension lock_size;
public:
bool greyed;

DropDownListCompanyItem(int result, bool masked, bool greyed) : DropDownListItem(result, masked), greyed(greyed)
{
this->icon_size = GetSpriteSize(SPR_COMPANY_ICON);
this->lock_size = GetSpriteSize(SPR_LOCK);
}

bool Selectable() const override
DropDownListCompanyItem(CompanyID company, bool shaded) : DropDownIcon<DropDownIcon<DropDownString<DropDownListItem>, true>>(SPR_COMPANY_ICON, COMPANY_SPRITE_COLOUR(company), NetworkCompanyIsPassworded(company) ? SPR_LOCK : SPR_EMPTY, PAL_NONE, STR_NULL, company, false, shaded)
{
return true;
}

uint Width() const override
{
CompanyID company = (CompanyID)this->result;
SetDParam(0, company);
SetDParam(1, company);
return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_size.width + this->lock_size.width + WidgetDimensions::scaled.dropdowntext.Horizontal() + WidgetDimensions::scaled.hsep_wide;
}

uint Height() const override
{
return std::max(std::max(this->icon_size.height, this->lock_size.height) + WidgetDimensions::scaled.imgbtn.Vertical(), (uint)GetCharacterHeight(FS_NORMAL));
}

void Draw(const Rect &r, bool sel, Colours) const override
{
CompanyID company = (CompanyID)this->result;
bool rtl = _current_text_dir == TD_RTL;

/* It's possible the company is deleted while the dropdown is open */
if (!Company::IsValidID(company)) return;

Rect tr = r.Shrink(WidgetDimensions::scaled.dropdowntext, RectPadding::zero);
int icon_y = CenterBounds(r.top, r.bottom, icon_size.height);
int text_y = CenterBounds(r.top, r.bottom, GetCharacterHeight(FS_NORMAL));
int lock_y = CenterBounds(r.top, r.bottom, lock_size.height);

DrawCompanyIcon(company, tr.WithWidth(this->icon_size.width, rtl).left, icon_y);
if (NetworkCompanyIsPassworded(company)) {
DrawSprite(SPR_LOCK, PAL_NONE, tr.WithWidth(this->lock_size.width, !rtl).left, lock_y);
}

SetDParam(0, company);
SetDParam(1, company);
TextColour col;
if (this->greyed) {
col = (sel ? TC_SILVER : TC_GREY) | TC_NO_SHADE;
} else {
col = sel ? TC_WHITE : TC_BLACK;
}
tr = tr.Indent(this->icon_size.width + WidgetDimensions::scaled.hsep_normal, rtl).Indent(this->lock_size.width + WidgetDimensions::scaled.hsep_normal, !rtl);
DrawString(tr.left, tr.right, text_y, STR_COMPANY_NAME_COMPANY_NUM, col);
this->SetString(GetString(STR_COMPANY_NAME_COMPANY_NUM));
}
};

Expand Down Expand Up @@ -208,7 +127,7 @@ static void PopupMainToolbarMenu(Window *w, int widget, const std::initializer_l
int i = 0;
for (StringID string : strings) {
if (string == STR_NULL) {
list.push_back(std::make_unique<DropDownListItem>(-1, false));
list.push_back(std::make_unique<DropDownListDividerItem>(-1, false));
} else {
list.push_back(std::make_unique<DropDownListStringItem>(string, i, false));
i++;
Expand Down Expand Up @@ -254,7 +173,7 @@ static void PopupMainCompanyToolbMenu(Window *w, int widget, int grey = 0)

for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
if (!Company::IsValidID(c)) continue;
list.push_back(std::make_unique<DropDownListCompanyItem>(c, false, HasBit(grey, c)));
list.push_back(std::make_unique<DropDownListCompanyItem>(c, HasBit(grey, c)));
}

PopupMainToolbarMenu(w, widget, std::move(list), _local_company == COMPANY_SPECTATOR ? (widget == WID_TN_COMPANIES ? CTMN_CLIENT_LIST : CTMN_SPECTATOR) : (int)_local_company);
Expand Down Expand Up @@ -341,16 +260,16 @@ static CallBackFunction ToolbarOptionsClick(Window *w)
}
list.push_back(std::make_unique<DropDownListStringItem>(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS, false));
list.push_back(std::make_unique<DropDownListStringItem>(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES, false));
list.push_back(std::make_unique<DropDownListItem>(-1, false));
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES)));
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false, HasBit(_display_opt, DO_SHOW_STATION_NAMES)));
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED, OME_SHOW_WAYPOINTNAMES, false, HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES)));
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_SIGNS_DISPLAYED, OME_SHOW_SIGNS, false, HasBit(_display_opt, DO_SHOW_SIGNS)));
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS, OME_SHOW_COMPETITOR_SIGNS, false, HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS)));
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_FULL_ANIMATION, OME_FULL_ANIMATION, false, HasBit(_display_opt, DO_FULL_ANIMATION)));
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_FULL_DETAIL, OME_FULL_DETAILS, false, HasBit(_display_opt, DO_FULL_DETAIL)));
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES)));
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS)));
list.push_back(std::make_unique<DropDownListDividerItem>(-1, false));
list.push_back(std::make_unique<DropDownListCheckedItem>(HasBit(_display_opt, DO_SHOW_TOWN_NAMES), STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES, false));
list.push_back(std::make_unique<DropDownListCheckedItem>(HasBit(_display_opt, DO_SHOW_STATION_NAMES), STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false));
list.push_back(std::make_unique<DropDownListCheckedItem>(HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES), STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED, OME_SHOW_WAYPOINTNAMES, false));
list.push_back(std::make_unique<DropDownListCheckedItem>(HasBit(_display_opt, DO_SHOW_SIGNS), STR_SETTINGS_MENU_SIGNS_DISPLAYED, OME_SHOW_SIGNS, false));
list.push_back(std::make_unique<DropDownListCheckedItem>(HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS), STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS, OME_SHOW_COMPETITOR_SIGNS, false));
list.push_back(std::make_unique<DropDownListCheckedItem>(HasBit(_display_opt, DO_FULL_ANIMATION), STR_SETTINGS_MENU_FULL_ANIMATION, OME_FULL_ANIMATION, false));
list.push_back(std::make_unique<DropDownListCheckedItem>(HasBit(_display_opt, DO_FULL_DETAIL), STR_SETTINGS_MENU_FULL_DETAIL, OME_FULL_DETAILS, false));
list.push_back(std::make_unique<DropDownListCheckedItem>(IsTransparencySet(TO_HOUSES), STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS, false));
list.push_back(std::make_unique<DropDownListCheckedItem>(IsTransparencySet(TO_SIGNS), STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS, false));

ShowDropDownList(w, std::move(list), 0, WID_TN_SETTINGS, 140, true);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
Expand Down
3 changes: 2 additions & 1 deletion src/vehicle_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,8 +383,9 @@ DropDownList BaseVehicleListWindow::BuildCargoDropDownList() const
list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CF_NONE), CF_NONE, false));

/* Add cargos */
Dimension d = GetLargestCargoIconSize();
for (const CargoSpec *cs : _sorted_cargo_specs) {
list.push_back(std::make_unique<DropDownListStringItem>(cs->name, cs->Index(), false));
list.push_back(std::make_unique<DropDownListIconItem>(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false));
}

return list;
Expand Down