Feature: Group liveries, and livery window usability enhancements. (#7108)
* Change: Replace checkbox in livery selection window with Default option in drop down selection. This reduces clutter in the UI and allows for primary/secondary colours to independently follow the default scheme if desired. * Feature: Add vehicle group liveries.
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
#include "water.h"
|
||||
#include "station_func.h"
|
||||
#include "zoom_func.h"
|
||||
#include "sortlist_type.h"
|
||||
|
||||
#include "widgets/company_widget.h"
|
||||
|
||||
@@ -522,7 +523,7 @@ public:
|
||||
|
||||
StringID String() const
|
||||
{
|
||||
return _colour_dropdown[this->result];
|
||||
return this->result >= COLOUR_END ? STR_COLOUR_DEFAULT : _colour_dropdown[this->result];
|
||||
}
|
||||
|
||||
uint Height(uint width) const
|
||||
@@ -541,7 +542,7 @@ public:
|
||||
int height = bottom - top;
|
||||
int icon_y_offset = height / 2;
|
||||
int text_y_offset = (height - FONT_HEIGHT_NORMAL) / 2 + 1;
|
||||
DrawSprite(SPR_VEH_BUS_SIDE_VIEW, PALETTE_RECOLOUR_START + this->result,
|
||||
DrawSprite(SPR_VEH_BUS_SIDE_VIEW, PALETTE_RECOLOUR_START + (this->result % COLOUR_END),
|
||||
rtl ? right - 2 - ScaleGUITrad(14) : left + ScaleGUITrad(14) + 2,
|
||||
top + icon_y_offset);
|
||||
DrawString(rtl ? left + 2 : left + ScaleGUITrad(28) + 4,
|
||||
@@ -550,60 +551,200 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static const int LEVEL_WIDTH = 10; ///< Indenting width of a sub-group in pixels
|
||||
|
||||
typedef GUIList<const Group*> GUIGroupList;
|
||||
|
||||
/** Company livery colour scheme window. */
|
||||
struct SelectCompanyLiveryWindow : public Window {
|
||||
private:
|
||||
uint32 sel;
|
||||
LiveryClass livery_class;
|
||||
Dimension square;
|
||||
Dimension box;
|
||||
uint livery_height;
|
||||
uint line_height;
|
||||
GUIGroupList groups;
|
||||
SmallVector<int, 32> indents;
|
||||
Scrollbar *vscroll;
|
||||
|
||||
void ShowColourDropDownMenu(uint32 widget)
|
||||
{
|
||||
uint32 used_colours = 0;
|
||||
const Livery *livery;
|
||||
LiveryScheme scheme;
|
||||
const Company *c;
|
||||
const Livery *livery, *default_livery = NULL;
|
||||
bool primary = widget == WID_SCL_PRI_COL_DROPDOWN;
|
||||
byte default_col;
|
||||
|
||||
/* Disallow other company colours for the primary colour */
|
||||
if (HasBit(this->sel, LS_DEFAULT) && widget == WID_SCL_PRI_COL_DROPDOWN) {
|
||||
const Company *c;
|
||||
if (this->livery_class < LC_GROUP_RAIL && HasBit(this->sel, LS_DEFAULT) && primary) {
|
||||
FOR_ALL_COMPANIES(c) {
|
||||
if (c->index != _local_company) SetBit(used_colours, c->colour);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the first selected livery to use as the default dropdown item */
|
||||
for (scheme = LS_BEGIN; scheme < LS_END; scheme++) {
|
||||
if (HasBit(this->sel, scheme)) break;
|
||||
c = Company::Get((CompanyID)this->window_number);
|
||||
|
||||
if (this->livery_class < LC_GROUP_RAIL) {
|
||||
/* Get the first selected livery to use as the default dropdown item */
|
||||
LiveryScheme scheme;
|
||||
for (scheme = LS_BEGIN; scheme < LS_END; scheme++) {
|
||||
if (HasBit(this->sel, scheme)) break;
|
||||
}
|
||||
if (scheme == LS_END) scheme = LS_DEFAULT;
|
||||
livery = &c->livery[scheme];
|
||||
if (scheme != LS_DEFAULT) default_livery = &c->livery[LS_DEFAULT];
|
||||
} else {
|
||||
const Group *g = Group::Get(this->sel);
|
||||
livery = &g->livery;
|
||||
if (g->parent == INVALID_GROUP) {
|
||||
default_livery = &c->livery[LS_DEFAULT];
|
||||
} else {
|
||||
const Group *pg = Group::Get(g->parent);
|
||||
default_livery = &pg->livery;
|
||||
}
|
||||
}
|
||||
if (scheme == LS_END) scheme = LS_DEFAULT;
|
||||
livery = &Company::Get((CompanyID)this->window_number)->livery[scheme];
|
||||
|
||||
DropDownList *list = new DropDownList();
|
||||
if (default_livery != NULL) {
|
||||
/* 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->Append() = new DropDownListColourItem(default_col, false);
|
||||
}
|
||||
for (uint i = 0; i < lengthof(_colour_dropdown); i++) {
|
||||
*list->Append() = new DropDownListColourItem(i, HasBit(used_colours, i));
|
||||
}
|
||||
|
||||
ShowDropDownList(this, list, widget == WID_SCL_PRI_COL_DROPDOWN ? livery->colour1 : livery->colour2, widget);
|
||||
byte sel = (default_livery == NULL || HasBit(livery->in_use, primary ? 0 : 1)) ? (primary ? livery->colour1 : livery->colour2) : default_col;
|
||||
ShowDropDownList(this, list, sel, widget);
|
||||
}
|
||||
|
||||
static int CDECL GroupNameSorter(const Group * const *a, const Group * const *b)
|
||||
{
|
||||
static const Group *last_group[2] = { NULL, NULL };
|
||||
static char last_name[2][64] = { "", "" };
|
||||
|
||||
if (*a != last_group[0]) {
|
||||
last_group[0] = *a;
|
||||
SetDParam(0, (*a)->index);
|
||||
GetString(last_name[0], STR_GROUP_NAME, lastof(last_name[0]));
|
||||
}
|
||||
|
||||
if (*b != last_group[1]) {
|
||||
last_group[1] = *b;
|
||||
SetDParam(0, (*b)->index);
|
||||
GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1]));
|
||||
}
|
||||
|
||||
int r = strnatcmp(last_name[0], last_name[1]); // Sort by name (natural sorting).
|
||||
if (r == 0) return (*a)->index - (*b)->index;
|
||||
return r;
|
||||
}
|
||||
|
||||
void AddChildren(GUIGroupList *source, GroupID parent, int indent)
|
||||
{
|
||||
for (const Group **g = source->Begin(); g != source->End(); g++) {
|
||||
if ((*g)->parent != parent) continue;
|
||||
*this->groups.Append() = *g;
|
||||
*this->indents.Append() = indent;
|
||||
AddChildren(source, (*g)->index, indent + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void BuildGroupList(CompanyID owner)
|
||||
{
|
||||
if (!this->groups.NeedRebuild()) return;
|
||||
|
||||
this->groups.Clear();
|
||||
this->indents.Clear();
|
||||
|
||||
if (this->livery_class >= LC_GROUP_RAIL) {
|
||||
GUIGroupList list;
|
||||
VehicleType vtype = (VehicleType)(this->livery_class - LC_GROUP_RAIL);
|
||||
|
||||
const Group *g;
|
||||
FOR_ALL_GROUPS(g) {
|
||||
if (g->owner == owner && g->vehicle_type == vtype) {
|
||||
*list.Append() = g;
|
||||
}
|
||||
}
|
||||
|
||||
list.ForceResort();
|
||||
list.Sort(&GroupNameSorter);
|
||||
|
||||
AddChildren(&list, INVALID_GROUP, 0);
|
||||
}
|
||||
|
||||
this->groups.Compact();
|
||||
this->groups.RebuildDone();
|
||||
}
|
||||
|
||||
void SetLiveryHeight()
|
||||
{
|
||||
if (this->livery_class < LC_GROUP_RAIL) {
|
||||
this->livery_height = 0;
|
||||
for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
|
||||
if (_livery_class[scheme] == this->livery_class && HasBit(_loaded_newgrf_features.used_liveries, scheme)) {
|
||||
this->livery_height++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this->livery_height = this->groups.Length();
|
||||
}
|
||||
|
||||
this->vscroll->SetCount(this->livery_height);
|
||||
}
|
||||
|
||||
public:
|
||||
SelectCompanyLiveryWindow(WindowDesc *desc, CompanyID company) : Window(desc)
|
||||
SelectCompanyLiveryWindow(WindowDesc *desc, CompanyID company, GroupID group) : Window(desc)
|
||||
{
|
||||
this->livery_class = LC_OTHER;
|
||||
this->sel = 1;
|
||||
this->CreateNestedTree();
|
||||
this->vscroll = this->GetScrollbar(WID_SCL_MATRIX_SCROLLBAR);
|
||||
|
||||
this->square = GetSpriteSize(SPR_SQUARE);
|
||||
this->box = maxdim(GetSpriteSize(SPR_BOX_CHECKED), GetSpriteSize(SPR_BOX_EMPTY));
|
||||
this->line_height = max(max(this->square.height, this->box.height), (uint)FONT_HEIGHT_NORMAL) + 4;
|
||||
this->line_height = max(this->square.height, (uint)FONT_HEIGHT_NORMAL) + 4;
|
||||
|
||||
this->InitNested(company);
|
||||
if (group == INVALID_GROUP) {
|
||||
this->livery_class = LC_OTHER;
|
||||
this->sel = 1;
|
||||
this->LowerWidget(WID_SCL_CLASS_GENERAL);
|
||||
this->BuildGroupList(company);
|
||||
this->SetLiveryHeight();
|
||||
} else {
|
||||
this->SetSelectedGroup(group);
|
||||
}
|
||||
|
||||
this->FinishInitNested(company);
|
||||
this->owner = company;
|
||||
this->LowerWidget(WID_SCL_CLASS_GENERAL);
|
||||
this->InvalidateData(1);
|
||||
}
|
||||
|
||||
void SetSelectedGroup(GroupID group)
|
||||
{
|
||||
this->RaiseWidget(this->livery_class + WID_SCL_CLASS_GENERAL);
|
||||
const Group *g = Group::Get(group);
|
||||
switch (g->vehicle_type) {
|
||||
case VEH_TRAIN: this->livery_class = LC_GROUP_RAIL; break;
|
||||
case VEH_ROAD: this->livery_class = LC_GROUP_ROAD; break;
|
||||
case VEH_SHIP: this->livery_class = LC_GROUP_SHIP; break;
|
||||
case VEH_AIRCRAFT: this->livery_class = LC_GROUP_AIRCRAFT; break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
this->sel = group;
|
||||
this->LowerWidget(this->livery_class + WID_SCL_CLASS_GENERAL);
|
||||
|
||||
this->groups.ForceRebuild();
|
||||
this->BuildGroupList((CompanyID)this->window_number);
|
||||
this->SetLiveryHeight();
|
||||
|
||||
/* Position scrollbar to selected group */
|
||||
for (uint i = 0; i < this->livery_height; i++) {
|
||||
if (this->groups[i]->index == sel) {
|
||||
this->vscroll->SetPosition(Clamp(i - this->vscroll->GetCapacity() / 2, 0, max(this->vscroll->GetCount() - this->vscroll->GetCapacity(), 0)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
{
|
||||
switch (widget) {
|
||||
@@ -613,19 +754,25 @@ public:
|
||||
for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
|
||||
d = maxdim(d, GetStringBoundingBox(STR_LIVERY_DEFAULT + scheme));
|
||||
}
|
||||
size->width = max(size->width, 5 + this->box.width + d.width + WD_FRAMERECT_RIGHT);
|
||||
|
||||
/* And group names */
|
||||
const Group *g;
|
||||
FOR_ALL_GROUPS(g) {
|
||||
if (g->owner == (CompanyID)this->window_number) {
|
||||
SetDParam(0, g->index);
|
||||
d = maxdim(d, GetStringBoundingBox(STR_GROUP_NAME));
|
||||
}
|
||||
}
|
||||
|
||||
size->width = max(size->width, 5 + d.width + WD_FRAMERECT_RIGHT);
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_SCL_MATRIX: {
|
||||
uint livery_height = 0;
|
||||
for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
|
||||
if (_livery_class[scheme] == this->livery_class && HasBit(_loaded_newgrf_features.used_liveries, scheme)) {
|
||||
livery_height++;
|
||||
}
|
||||
}
|
||||
size->height = livery_height * this->line_height;
|
||||
this->GetWidget<NWidgetCore>(WID_SCL_MATRIX)->widget_data = (livery_height << MAT_ROW_START) | (1 << MAT_COL_START);
|
||||
/* 11 items in the default rail class */
|
||||
size->height = 11 * this->line_height;
|
||||
resize->width = 1;
|
||||
resize->height = this->line_height;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -641,6 +788,7 @@ public:
|
||||
for (const StringID *id = _colour_dropdown; id != endof(_colour_dropdown); id++) {
|
||||
size->width = max(size->width, GetStringBoundingBox(*id).width + padding);
|
||||
}
|
||||
size->width = max(size->width, GetStringBoundingBox(STR_COLOUR_DEFAULT).width + padding);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -651,8 +799,11 @@ public:
|
||||
bool local = (CompanyID)this->window_number == _local_company;
|
||||
|
||||
/* Disable dropdown controls if no scheme is selected */
|
||||
this->SetWidgetDisabledState(WID_SCL_PRI_COL_DROPDOWN, !local || this->sel == 0);
|
||||
this->SetWidgetDisabledState(WID_SCL_SEC_COL_DROPDOWN, !local || this->sel == 0);
|
||||
bool disabled = this->livery_class < LC_GROUP_RAIL ? (this->sel == 0) : (this->sel == INVALID_GROUP);
|
||||
this->SetWidgetDisabledState(WID_SCL_PRI_COL_DROPDOWN, !local || disabled);
|
||||
this->SetWidgetDisabledState(WID_SCL_SEC_COL_DROPDOWN, !local || disabled);
|
||||
|
||||
this->BuildGroupList((CompanyID)this->window_number);
|
||||
|
||||
this->DrawWidgets();
|
||||
}
|
||||
@@ -667,15 +818,31 @@ public:
|
||||
case WID_SCL_PRI_COL_DROPDOWN:
|
||||
case WID_SCL_SEC_COL_DROPDOWN: {
|
||||
const Company *c = Company::Get((CompanyID)this->window_number);
|
||||
LiveryScheme scheme = LS_DEFAULT;
|
||||
bool primary = widget == WID_SCL_PRI_COL_DROPDOWN;
|
||||
StringID colour = STR_COLOUR_DEFAULT;
|
||||
|
||||
if (this->sel != 0) {
|
||||
for (scheme = LS_BEGIN; scheme < LS_END; scheme++) {
|
||||
if (HasBit(this->sel, scheme)) break;
|
||||
if (this->livery_class < LC_GROUP_RAIL) {
|
||||
if (this->sel != 0) {
|
||||
LiveryScheme scheme = LS_DEFAULT;
|
||||
for (scheme = LS_BEGIN; scheme < LS_END; scheme++) {
|
||||
if (HasBit(this->sel, scheme)) break;
|
||||
}
|
||||
if (scheme == LS_END) scheme = LS_DEFAULT;
|
||||
const Livery *livery = &c->livery[scheme];
|
||||
if (scheme == LS_DEFAULT || HasBit(livery->in_use, primary ? 0 : 1)) {
|
||||
colour = STR_COLOUR_DARK_BLUE + (primary ? livery->colour1 : livery->colour2);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this->sel != INVALID_GROUP) {
|
||||
const Group *g = Group::Get(this->sel);
|
||||
const Livery *livery = &g->livery;
|
||||
if (HasBit(livery->in_use, primary ? 0 : 1)) {
|
||||
colour = STR_COLOUR_DARK_BLUE + (primary ? livery->colour1 : livery->colour2);
|
||||
}
|
||||
}
|
||||
if (scheme == LS_END) scheme = LS_DEFAULT;
|
||||
}
|
||||
SetDParam(0, STR_COLOUR_DARK_BLUE + ((widget == WID_SCL_PRI_COL_DROPDOWN) ? c->livery[scheme].colour1 : c->livery[scheme].colour2));
|
||||
SetDParam(0, colour);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -700,36 +867,45 @@ public:
|
||||
int sec_left = nwi->pos_x;
|
||||
int sec_right = sec_left + nwi->current_x - 1;
|
||||
|
||||
int text_left = (rtl ? (uint)WD_FRAMERECT_LEFT : (this->box.width + 5));
|
||||
int text_right = (rtl ? (this->box.width + 5) : (uint)WD_FRAMERECT_RIGHT);
|
||||
int text_left = (rtl ? (uint)WD_FRAMERECT_LEFT : (this->square.width + 5));
|
||||
int text_right = (rtl ? (this->square.width + 5) : (uint)WD_FRAMERECT_RIGHT);
|
||||
|
||||
int box_offs = (this->line_height - this->box.height) / 2;
|
||||
int square_offs = (this->line_height - this->square.height) / 2 + 1;
|
||||
int text_offs = (this->line_height - FONT_HEIGHT_NORMAL) / 2 + 1;
|
||||
|
||||
int y = r.top;
|
||||
const Company *c = Company::Get((CompanyID)this->window_number);
|
||||
for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
|
||||
if (_livery_class[scheme] == this->livery_class && HasBit(_loaded_newgrf_features.used_liveries, scheme)) {
|
||||
bool sel = HasBit(this->sel, scheme) != 0;
|
||||
|
||||
/* Optional check box + scheme name. */
|
||||
if (scheme != LS_DEFAULT) {
|
||||
DrawSprite(c->livery[scheme].in_use ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, (rtl ? sch_right - (this->box.width + 5) + WD_FRAMERECT_RIGHT : sch_left) + WD_FRAMERECT_LEFT, y + box_offs);
|
||||
/* Helper function to draw livery info. */
|
||||
auto draw_livery = [&](StringID str, const Livery &liv, bool sel, bool def, int indent) {
|
||||
/* Livery Label. */
|
||||
DrawString(sch_left + WD_FRAMERECT_LEFT + (rtl ? 0 : indent), sch_right - WD_FRAMERECT_RIGHT - (rtl ? indent : 0), y + text_offs, str, sel ? TC_WHITE : TC_BLACK);
|
||||
|
||||
/* Text below the first dropdown. */
|
||||
DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour1), (rtl ? pri_right - (this->square.width + 5) + WD_FRAMERECT_RIGHT : pri_left) + WD_FRAMERECT_LEFT, y + square_offs);
|
||||
DrawString(pri_left + text_left, pri_right - text_right, y + text_offs, (def || HasBit(liv.in_use, 0)) ? STR_COLOUR_DARK_BLUE + liv.colour1 : STR_COLOUR_DEFAULT, sel ? TC_WHITE : TC_GOLD);
|
||||
|
||||
/* Text below the second dropdown. */
|
||||
if (sec_right > sec_left) { // Second dropdown has non-zero size.
|
||||
DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour2), (rtl ? sec_right - (this->square.width + 5) + WD_FRAMERECT_RIGHT : sec_left) + WD_FRAMERECT_LEFT, y + square_offs);
|
||||
DrawString(sec_left + text_left, sec_right - text_right, y + text_offs, (def || HasBit(liv.in_use, 1)) ? STR_COLOUR_DARK_BLUE + liv.colour2 : STR_COLOUR_DEFAULT, sel ? TC_WHITE : TC_GOLD);
|
||||
}
|
||||
|
||||
y += this->line_height;
|
||||
};
|
||||
|
||||
if (livery_class < LC_GROUP_RAIL) {
|
||||
const Company *c = Company::Get((CompanyID)this->window_number);
|
||||
for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
|
||||
if (_livery_class[scheme] == this->livery_class && HasBit(_loaded_newgrf_features.used_liveries, scheme)) {
|
||||
draw_livery(STR_LIVERY_DEFAULT + scheme, c->livery[scheme], HasBit(this->sel, scheme), scheme == LS_DEFAULT, 0);
|
||||
}
|
||||
DrawString(sch_left + text_left, sch_right - text_right, y + text_offs, STR_LIVERY_DEFAULT + scheme, sel ? TC_WHITE : TC_BLACK);
|
||||
|
||||
/* Text below the first dropdown. */
|
||||
DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(c->livery[scheme].colour1), (rtl ? pri_right - (this->box.width + 5) + WD_FRAMERECT_RIGHT : pri_left) + WD_FRAMERECT_LEFT, y + square_offs);
|
||||
DrawString(pri_left + text_left, pri_right - text_right, y + text_offs, STR_COLOUR_DARK_BLUE + c->livery[scheme].colour1, sel ? TC_WHITE : TC_GOLD);
|
||||
|
||||
/* Text below the second dropdown. */
|
||||
if (sec_right > sec_left) { // Second dropdown has non-zero size.
|
||||
DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(c->livery[scheme].colour2), (rtl ? sec_right - (this->box.width + 5) + WD_FRAMERECT_RIGHT : sec_left) + WD_FRAMERECT_LEFT, y + square_offs);
|
||||
DrawString(sec_left + text_left, sec_right - text_right, y + text_offs, STR_COLOUR_DARK_BLUE + c->livery[scheme].colour2, sel ? TC_WHITE : TC_GOLD);
|
||||
}
|
||||
|
||||
y += this->line_height;
|
||||
}
|
||||
} else {
|
||||
uint max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->groups.Length());
|
||||
for (uint i = this->vscroll->GetPosition(); i < max; ++i) {
|
||||
const Group *g = this->groups[i];
|
||||
SetDParam(0, g->index);
|
||||
draw_livery(STR_GROUP_NAME, g->livery, this->sel == g->index, false, this->indents[i] * LEVEL_WIDTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -743,20 +919,35 @@ public:
|
||||
case WID_SCL_CLASS_ROAD:
|
||||
case WID_SCL_CLASS_SHIP:
|
||||
case WID_SCL_CLASS_AIRCRAFT:
|
||||
case WID_SCL_GROUPS_RAIL:
|
||||
case WID_SCL_GROUPS_ROAD:
|
||||
case WID_SCL_GROUPS_SHIP:
|
||||
case WID_SCL_GROUPS_AIRCRAFT:
|
||||
this->RaiseWidget(this->livery_class + WID_SCL_CLASS_GENERAL);
|
||||
this->livery_class = (LiveryClass)(widget - WID_SCL_CLASS_GENERAL);
|
||||
this->LowerWidget(this->livery_class + WID_SCL_CLASS_GENERAL);
|
||||
|
||||
/* Select the first item in the list */
|
||||
this->sel = 0;
|
||||
for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
|
||||
if (_livery_class[scheme] == this->livery_class && HasBit(_loaded_newgrf_features.used_liveries, scheme)) {
|
||||
this->sel = 1 << scheme;
|
||||
break;
|
||||
if (this->livery_class < LC_GROUP_RAIL) {
|
||||
this->sel = 0;
|
||||
for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
|
||||
if (_livery_class[scheme] == this->livery_class && HasBit(_loaded_newgrf_features.used_liveries, scheme)) {
|
||||
this->sel = 1 << scheme;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this->sel = INVALID_GROUP;
|
||||
this->groups.ForceRebuild();
|
||||
this->BuildGroupList((CompanyID)this->window_number);
|
||||
|
||||
if (this->groups.Length() > 0) {
|
||||
this->sel = this->groups[0]->index;
|
||||
}
|
||||
}
|
||||
|
||||
this->ReInit();
|
||||
this->SetLiveryHeight();
|
||||
this->SetDirty();
|
||||
break;
|
||||
|
||||
case WID_SCL_PRI_COL_DROPDOWN: // First colour dropdown
|
||||
@@ -769,23 +960,27 @@ public:
|
||||
|
||||
case WID_SCL_MATRIX: {
|
||||
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_SCL_MATRIX);
|
||||
LiveryScheme j = (LiveryScheme)((pt.y - wid->pos_y) / this->line_height);
|
||||
if (this->livery_class < LC_GROUP_RAIL) {
|
||||
LiveryScheme j = (LiveryScheme)((pt.y - wid->pos_y) / this->line_height);
|
||||
|
||||
for (LiveryScheme scheme = LS_BEGIN; scheme <= j; scheme++) {
|
||||
if (_livery_class[scheme] != this->livery_class || !HasBit(_loaded_newgrf_features.used_liveries, scheme)) j++;
|
||||
if (scheme >= LS_END) return;
|
||||
}
|
||||
if (j >= LS_END) return;
|
||||
if (j >= this->livery_height) return;
|
||||
|
||||
/* If clicking on the left edge, toggle using the livery */
|
||||
if (_current_text_dir == TD_RTL ? pt.x - wid->pos_x > wid->current_x - (this->box.width + 5) : pt.x - wid->pos_x < (this->box.width + 5)) {
|
||||
DoCommandP(0, j | (2 << 8), !Company::Get((CompanyID)this->window_number)->livery[j].in_use, CMD_SET_COMPANY_COLOUR);
|
||||
}
|
||||
for (LiveryScheme scheme = LS_BEGIN; scheme <= j; scheme++) {
|
||||
if (_livery_class[scheme] != this->livery_class || !HasBit(_loaded_newgrf_features.used_liveries, scheme)) j++;
|
||||
if (scheme >= LS_END) return;
|
||||
}
|
||||
if (j >= LS_END) return;
|
||||
|
||||
if (_ctrl_pressed) {
|
||||
ToggleBit(this->sel, j);
|
||||
if (_ctrl_pressed) {
|
||||
ToggleBit(this->sel, j);
|
||||
} else {
|
||||
this->sel = 1 << j;
|
||||
}
|
||||
} else {
|
||||
this->sel = 1 << j;
|
||||
uint id_g = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SCL_MATRIX, 0, this->line_height);
|
||||
if (id_g >= this->groups.Length()) return;
|
||||
|
||||
this->sel = this->groups[id_g]->index;
|
||||
}
|
||||
this->SetDirty();
|
||||
break;
|
||||
@@ -793,16 +988,29 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnResize()
|
||||
{
|
||||
this->vscroll->SetCapacityFromWidget(this, WID_SCL_MATRIX);
|
||||
}
|
||||
|
||||
virtual void OnDropdownSelect(int widget, int index)
|
||||
{
|
||||
bool local = (CompanyID)this->window_number == _local_company;
|
||||
if (!local) return;
|
||||
|
||||
for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
|
||||
/* Changed colour for the selected scheme, or all visible schemes if CTRL is pressed. */
|
||||
if (HasBit(this->sel, scheme) || (_ctrl_pressed && _livery_class[scheme] == this->livery_class && HasBit(_loaded_newgrf_features.used_liveries, scheme))) {
|
||||
DoCommandP(0, scheme | (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256), index, CMD_SET_COMPANY_COLOUR);
|
||||
if (index >= COLOUR_END) index = INVALID_COLOUR;
|
||||
|
||||
if (this->livery_class < LC_GROUP_RAIL) {
|
||||
/* Set company colour livery */
|
||||
for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
|
||||
/* Changed colour for the selected scheme, or all visible schemes if CTRL is pressed. */
|
||||
if (HasBit(this->sel, scheme) || (_ctrl_pressed && _livery_class[scheme] == this->livery_class && HasBit(_loaded_newgrf_features.used_liveries, scheme))) {
|
||||
DoCommandP(0, scheme | (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256), index, CMD_SET_COMPANY_COLOUR);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Setting group livery */
|
||||
DoCommandP(0, this->sel, (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256) | (index << 16), CMD_SET_GROUP_LIVERY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -814,15 +1022,27 @@ public:
|
||||
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
|
||||
{
|
||||
if (!gui_scope) return;
|
||||
|
||||
if (data != -1) {
|
||||
/* data contains a VehicleType, rebuild list if it displayed */
|
||||
if (this->livery_class == data + LC_GROUP_RAIL) {
|
||||
if (!Group::IsValidID(this->sel)) this->sel = INVALID_GROUP;
|
||||
this->groups.ForceRebuild();
|
||||
this->BuildGroupList((CompanyID)this->window_number);
|
||||
this->SetDirty();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this->SetWidgetsDisabledState(true, WID_SCL_CLASS_RAIL, WID_SCL_CLASS_ROAD, WID_SCL_CLASS_SHIP, WID_SCL_CLASS_AIRCRAFT, WIDGET_LIST_END);
|
||||
|
||||
bool current_class_valid = this->livery_class == LC_OTHER;
|
||||
bool current_class_valid = this->livery_class == LC_OTHER || this->livery_class >= LC_GROUP_RAIL;
|
||||
if (_settings_client.gui.liveries == LIT_ALL || (_settings_client.gui.liveries == LIT_COMPANY && this->window_number == _local_company)) {
|
||||
for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
|
||||
if (HasBit(_loaded_newgrf_features.used_liveries, scheme)) {
|
||||
if (_livery_class[scheme] == this->livery_class) current_class_valid = true;
|
||||
this->EnableWidget(WID_SCL_CLASS_GENERAL + _livery_class[scheme]);
|
||||
} else {
|
||||
} else if (this->livery_class < LC_GROUP_RAIL) {
|
||||
ClrBit(this->sel, scheme);
|
||||
}
|
||||
}
|
||||
@@ -831,8 +1051,6 @@ public:
|
||||
if (!current_class_valid) {
|
||||
Point pt = {0, 0};
|
||||
this->OnClick(pt, WID_SCL_CLASS_GENERAL, 1);
|
||||
} else if (data == 0) {
|
||||
this->ReInit();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -848,6 +1066,10 @@ static const NWidgetPart _nested_select_company_livery_widgets [] = {
|
||||
NWidget(WWT_IMGBTN, COLOUR_GREY, WID_SCL_CLASS_ROAD), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_IMG_TRUCKLIST, STR_LIVERY_ROAD_VEHICLE_TOOLTIP),
|
||||
NWidget(WWT_IMGBTN, COLOUR_GREY, WID_SCL_CLASS_SHIP), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_IMG_SHIPLIST, STR_LIVERY_SHIP_TOOLTIP),
|
||||
NWidget(WWT_IMGBTN, COLOUR_GREY, WID_SCL_CLASS_AIRCRAFT), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_IMG_AIRPLANESLIST, STR_LIVERY_AIRCRAFT_TOOLTIP),
|
||||
NWidget(WWT_IMGBTN, COLOUR_GREY, WID_SCL_GROUPS_RAIL), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_GROUP_LIVERY_TRAIN, STR_LIVERY_TRAIN_TOOLTIP),
|
||||
NWidget(WWT_IMGBTN, COLOUR_GREY, WID_SCL_GROUPS_ROAD), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_GROUP_LIVERY_ROADVEH, STR_LIVERY_ROAD_VEHICLE_TOOLTIP),
|
||||
NWidget(WWT_IMGBTN, COLOUR_GREY, WID_SCL_GROUPS_SHIP), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_GROUP_LIVERY_SHIP, STR_LIVERY_SHIP_TOOLTIP),
|
||||
NWidget(WWT_IMGBTN, COLOUR_GREY, WID_SCL_GROUPS_AIRCRAFT), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_GROUP_LIVERY_AIRCRAFT, STR_LIVERY_AIRCRAFT_TOOLTIP),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(90, 22), SetFill(1, 1), EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
@@ -856,7 +1078,13 @@ static const NWidgetPart _nested_select_company_livery_widgets [] = {
|
||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_SCL_SEC_COL_DROPDOWN), SetMinimalSize(125, 12), SetFill(0, 1),
|
||||
SetDataTip(STR_BLACK_STRING, STR_LIVERY_SECONDARY_TOOLTIP),
|
||||
EndContainer(),
|
||||
NWidget(WWT_MATRIX, COLOUR_GREY, WID_SCL_MATRIX), SetMinimalSize(275, 15), SetFill(1, 0), SetMatrixDataTip(1, 1, STR_LIVERY_PANEL_TOOLTIP),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_MATRIX, COLOUR_GREY, WID_SCL_MATRIX), SetMinimalSize(275, 0), SetResize(1, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_LIVERY_PANEL_TOOLTIP), SetScrollbar(WID_SCL_MATRIX_SCROLLBAR),
|
||||
NWidget(NWID_VERTICAL),
|
||||
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SCL_MATRIX_SCROLLBAR),
|
||||
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
static WindowDesc _select_company_livery_desc(
|
||||
@@ -866,6 +1094,16 @@ static WindowDesc _select_company_livery_desc(
|
||||
_nested_select_company_livery_widgets, lengthof(_nested_select_company_livery_widgets)
|
||||
);
|
||||
|
||||
void ShowCompanyLiveryWindow(CompanyID company, GroupID group)
|
||||
{
|
||||
SelectCompanyLiveryWindow *w = (SelectCompanyLiveryWindow *)BringWindowToFrontById(WC_COMPANY_COLOUR, company);
|
||||
if (w == NULL) {
|
||||
new SelectCompanyLiveryWindow(&_select_company_livery_desc, company, group);
|
||||
} else if (group != INVALID_GROUP) {
|
||||
w->SetSelectedGroup(group);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the face of a company manager's face.
|
||||
* @param cmf the company manager's face
|
||||
@@ -2291,8 +2529,7 @@ struct CompanyWindow : Window
|
||||
case WID_C_NEW_FACE: DoSelectCompanyManagerFace(this); break;
|
||||
|
||||
case WID_C_COLOUR_SCHEME:
|
||||
if (BringWindowToFrontById(WC_COMPANY_COLOUR, this->window_number)) break;
|
||||
new SelectCompanyLiveryWindow(&_select_company_livery_desc, (CompanyID)this->window_number);
|
||||
ShowCompanyLiveryWindow((CompanyID)this->window_number, INVALID_GROUP);
|
||||
break;
|
||||
|
||||
case WID_C_PRESIDENT_NAME:
|
||||
|
Reference in New Issue
Block a user