mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-09 07:29:44 +00:00
Feature: Option to group vehicle lists by shared orders
This applies to all kinds of vehicle lists, as well as the "vehicle groups" window.
This commit is contained in:
parent
584df548f1
commit
e59c400ca6
@ -71,6 +71,11 @@ static const NWidgetPart _nested_group_widgets[] = {
|
||||
EndContainer(),
|
||||
/* right part */
|
||||
NWidget(NWID_VERTICAL),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GL_GROUP_BY_ORDER), SetMinimalSize(81, 12), SetDataTip(STR_STATION_VIEW_GROUP, STR_TOOLTIP_GROUP_ORDER),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GL_GROUP_BY_DROPDOWN), SetMinimalSize(167, 12), SetDataTip(0x0, STR_TOOLTIP_GROUP_ORDER),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(12, 12), SetResize(1, 0), EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GL_SORT_BY_ORDER), SetMinimalSize(81, 12), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GL_SORT_BY_DROPDOWN), SetMinimalSize(167, 12), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA),
|
||||
@ -537,8 +542,11 @@ public:
|
||||
if (!IsDefaultGroupID(this->vli.index) && !IsAllGroupID(this->vli.index) && Group::Get(this->vli.index)->replace_protection) protect_sprite = SPR_GROUP_REPLACE_ON_TRAIN;
|
||||
this->GetWidget<NWidgetCore>(WID_GL_REPLACE_PROTECTION)->widget_data = protect_sprite + this->vli.vtype;
|
||||
|
||||
/* Set text of sort by dropdown */
|
||||
this->GetWidget<NWidgetCore>(WID_GL_SORT_BY_DROPDOWN)->widget_data = this->vehicle_group_none_sorter_names[this->vehgroups.SortType()];
|
||||
/* Set text of "group by" dropdown widget. */
|
||||
this->GetWidget<NWidgetCore>(WID_GL_GROUP_BY_DROPDOWN)->widget_data = this->vehicle_group_by_names[this->grouping];
|
||||
|
||||
/* Set text of "sort by" dropdown widget. */
|
||||
this->GetWidget<NWidgetCore>(WID_GL_SORT_BY_DROPDOWN)->widget_data = this->GetVehicleSorterNames()[this->vehgroups.SortType()];
|
||||
|
||||
this->DrawWidgets();
|
||||
}
|
||||
@ -650,6 +658,10 @@ public:
|
||||
this->SetDirty();
|
||||
break;
|
||||
|
||||
case WID_GL_GROUP_BY_DROPDOWN: // Select grouping option dropdown menu
|
||||
ShowDropDownMenu(this, this->vehicle_group_by_names, this->grouping, WID_GL_GROUP_BY_DROPDOWN, 0, 0);
|
||||
return;
|
||||
|
||||
case WID_GL_SORT_BY_DROPDOWN: // Select sorting criteria dropdown menu
|
||||
ShowDropDownMenu(this, this->GetVehicleSorterNames(), this->vehgroups.SortType(), WID_GL_SORT_BY_DROPDOWN, 0, (this->vli.vtype == VEH_TRAIN || this->vli.vtype == VEH_ROAD) ? 0 : (1 << 10));
|
||||
return;
|
||||
@ -715,19 +727,35 @@ public:
|
||||
if (id_v >= this->vehgroups.size()) return; // click out of list bound
|
||||
|
||||
const GUIVehicleGroup &vehgroup = this->vehgroups[id_v];
|
||||
const Vehicle * const v = vehgroup.GetSingleVehicle();
|
||||
switch (this->grouping) {
|
||||
case GB_NONE: {
|
||||
const Vehicle *v = vehgroup.GetSingleVehicle();
|
||||
if (VehicleClicked(v)) break;
|
||||
|
||||
this->vehicle_sel = v->index;
|
||||
this->vehicle_sel = v->index;
|
||||
|
||||
if (_ctrl_pressed) {
|
||||
this->SelectGroup(v->group_id);
|
||||
if (_ctrl_pressed) {
|
||||
this->SelectGroup(v->group_id);
|
||||
}
|
||||
|
||||
SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
|
||||
SetMouseCursorVehicle(v, EIT_IN_LIST);
|
||||
_cursor.vehchain = true;
|
||||
|
||||
this->SetDirty();
|
||||
break;
|
||||
}
|
||||
|
||||
case GB_SHARED_ORDERS:
|
||||
assert(vehgroup.NumVehicles() > 0);
|
||||
/* No drag-and-drop support for shared order grouping; we immediately open the shared orders window */
|
||||
ShowVehicleListWindow(vehgroup.vehicles_begin[0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
||||
SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
|
||||
SetMouseCursorVehicle(v, EIT_IN_LIST);
|
||||
_cursor.vehchain = true;
|
||||
|
||||
this->SetDirty();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -842,10 +870,21 @@ public:
|
||||
if (id_v >= this->vehgroups.size()) return; // click out of list bound
|
||||
|
||||
const GUIVehicleGroup &vehgroup = this->vehgroups[id_v];
|
||||
const Vehicle *v = vehgroup.GetSingleVehicle();
|
||||
if (!VehicleClicked(v) && vindex == v->index) {
|
||||
ShowVehicleViewWindow(v);
|
||||
switch (this->grouping) {
|
||||
case GB_NONE: {
|
||||
const Vehicle *v = vehgroup.GetSingleVehicle();
|
||||
if (!VehicleClicked(v) && vindex == v->index) {
|
||||
ShowVehicleViewWindow(v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GB_SHARED_ORDERS:
|
||||
/* Currently no drag-and-drop support when grouped by shared orders. Modify this if we want to support some drag-drop behaviour for shared order list items. */
|
||||
NOT_REACHED();
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -873,6 +912,10 @@ public:
|
||||
void OnDropdownSelect(int widget, int index) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_GL_GROUP_BY_DROPDOWN:
|
||||
this->UpdateVehicleGroupBy(static_cast<GroupBy>(index));
|
||||
break;
|
||||
|
||||
case WID_GL_SORT_BY_DROPDOWN:
|
||||
this->vehgroups.SetSortType(index);
|
||||
break;
|
||||
|
@ -315,6 +315,15 @@ STR_SORT_BY_CARGO_CAPACITY :Cargo capacity
|
||||
STR_SORT_BY_RANGE :Range
|
||||
STR_SORT_BY_POPULATION :Population
|
||||
STR_SORT_BY_RATING :Rating
|
||||
STR_SORT_BY_NUM_VEHICLES :Number of vehicles
|
||||
STR_SORT_BY_TOTAL_PROFIT_LAST_YEAR :Total profit last year
|
||||
STR_SORT_BY_TOTAL_PROFIT_THIS_YEAR :Total profit this year
|
||||
STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR :Average profit last year
|
||||
STR_SORT_BY_AVERAGE_PROFIT_THIS_YEAR :Average profit this year
|
||||
|
||||
# Group by options for vehicle list
|
||||
STR_GROUP_BY_NONE :None
|
||||
STR_GROUP_BY_SHARED_ORDERS :Shared orders
|
||||
|
||||
# Tooltips for the main toolbar
|
||||
STR_TOOLBAR_TOOLTIP_PAUSE_GAME :{BLACK}Pause game
|
||||
|
@ -58,6 +58,11 @@ static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleValueSorter;
|
||||
static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleLengthSorter;
|
||||
static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleTimeToLiveSorter;
|
||||
static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleTimetableDelaySorter;
|
||||
static BaseVehicleListWindow::VehicleGroupSortFunction VehicleGroupLengthSorter;
|
||||
static BaseVehicleListWindow::VehicleGroupSortFunction VehicleGroupTotalProfitThisYearSorter;
|
||||
static BaseVehicleListWindow::VehicleGroupSortFunction VehicleGroupTotalProfitLastYearSorter;
|
||||
static BaseVehicleListWindow::VehicleGroupSortFunction VehicleGroupAverageProfitThisYearSorter;
|
||||
static BaseVehicleListWindow::VehicleGroupSortFunction VehicleGroupAverageProfitLastYearSorter;
|
||||
|
||||
/** Wrapper to convert a VehicleIndividualSortFunction to a VehicleGroupSortFunction */
|
||||
template <BaseVehicleListWindow::VehicleIndividualSortFunction func>
|
||||
@ -99,6 +104,29 @@ const StringID BaseVehicleListWindow::vehicle_group_none_sorter_names[] = {
|
||||
INVALID_STRING_ID
|
||||
};
|
||||
|
||||
BaseVehicleListWindow::VehicleGroupSortFunction * const BaseVehicleListWindow::vehicle_group_shared_orders_sorter_funcs[] = {
|
||||
&VehicleGroupLengthSorter,
|
||||
&VehicleGroupTotalProfitThisYearSorter,
|
||||
&VehicleGroupTotalProfitLastYearSorter,
|
||||
&VehicleGroupAverageProfitThisYearSorter,
|
||||
&VehicleGroupAverageProfitLastYearSorter,
|
||||
};
|
||||
|
||||
const StringID BaseVehicleListWindow::vehicle_group_shared_orders_sorter_names[] = {
|
||||
STR_SORT_BY_NUM_VEHICLES,
|
||||
STR_SORT_BY_TOTAL_PROFIT_THIS_YEAR,
|
||||
STR_SORT_BY_TOTAL_PROFIT_LAST_YEAR,
|
||||
STR_SORT_BY_AVERAGE_PROFIT_THIS_YEAR,
|
||||
STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR,
|
||||
INVALID_STRING_ID
|
||||
};
|
||||
|
||||
const StringID BaseVehicleListWindow::vehicle_group_by_names[] = {
|
||||
STR_GROUP_BY_NONE,
|
||||
STR_GROUP_BY_SHARED_ORDERS,
|
||||
INVALID_STRING_ID
|
||||
};
|
||||
|
||||
const StringID BaseVehicleListWindow::vehicle_depot_name[] = {
|
||||
STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT,
|
||||
STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT,
|
||||
@ -156,16 +184,50 @@ void BaseVehicleListWindow::BuildVehicleList()
|
||||
|
||||
GenerateVehicleSortList(&this->vehicles, this->vli);
|
||||
|
||||
uint max_unitnumber = 0;
|
||||
for (auto it = this->vehicles.begin(); it != this->vehicles.end(); ++it) {
|
||||
this->vehgroups.emplace_back(it, it + 1, (*it)->GetDisplayProfitThisYear(), (*it)->GetDisplayProfitLastYear(), (*it)->age);
|
||||
if (this->grouping == GB_NONE) {
|
||||
uint max_unitnumber = 0;
|
||||
for (auto it = this->vehicles.begin(); it != this->vehicles.end(); ++it) {
|
||||
this->vehgroups.emplace_back(it, it + 1, (*it)->GetDisplayProfitThisYear(), (*it)->GetDisplayProfitLastYear(), (*it)->age);
|
||||
|
||||
max_unitnumber = max<uint>(max_unitnumber, (*it)->unitnumber);
|
||||
max_unitnumber = max<uint>(max_unitnumber, (*it)->unitnumber);
|
||||
}
|
||||
this->unitnumber_digits = CountDigitsForAllocatingSpace(max_unitnumber);
|
||||
} else {
|
||||
/* Sort by the primary vehicle; we just want all vehicles that share the same orders to form a contiguous range. */
|
||||
std::stable_sort(this->vehicles.begin(), this->vehicles.end(), [](const Vehicle * const &u, const Vehicle * const &v) {
|
||||
return u->FirstShared() < v->FirstShared();
|
||||
});
|
||||
|
||||
uint max_num_vehicles = 0;
|
||||
|
||||
VehicleList::const_iterator begin = this->vehicles.begin();
|
||||
while (begin != this->vehicles.end()) {
|
||||
VehicleList::const_iterator end = std::find_if_not(begin, this->vehicles.cend(), [first_shared = (*begin)->FirstShared()](const Vehicle * const &v) {
|
||||
return v->FirstShared() == first_shared;
|
||||
});
|
||||
|
||||
Money display_profit_this_year = 0;
|
||||
Money display_profit_last_year = 0;
|
||||
Date age = 0;
|
||||
for (auto it = begin; it != end; ++it) {
|
||||
const Vehicle * const v = (*it);
|
||||
display_profit_this_year += v->GetDisplayProfitThisYear();
|
||||
display_profit_last_year += v->GetDisplayProfitLastYear();
|
||||
age = max<Date>(age, v->age);
|
||||
}
|
||||
|
||||
this->vehgroups.emplace_back(begin, end, display_profit_this_year, display_profit_last_year, age);
|
||||
|
||||
max_num_vehicles = max<uint>(max_num_vehicles, static_cast<uint>(end - begin));
|
||||
|
||||
begin = end;
|
||||
}
|
||||
|
||||
this->unitnumber_digits = CountDigitsForAllocatingSpace(max_num_vehicles);
|
||||
}
|
||||
this->unitnumber_digits = CountDigitsForAllocatingSpace(max_unitnumber);
|
||||
|
||||
this->vehgroups.RebuildDone();
|
||||
this->vscroll->SetCount(this->vehgroups.size());
|
||||
this->vscroll->SetCount(static_cast<int>(this->vehgroups.size()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1114,6 +1176,36 @@ StringID GetCargoSubtypeText(const Vehicle *v)
|
||||
return STR_EMPTY;
|
||||
}
|
||||
|
||||
/** Sort vehicle groups by the number of vehicles in the group */
|
||||
static bool VehicleGroupLengthSorter(const GUIVehicleGroup &a, const GUIVehicleGroup &b)
|
||||
{
|
||||
return a.NumVehicles() < b.NumVehicles();
|
||||
}
|
||||
|
||||
/** Sort vehicle groups by the total profit this year */
|
||||
static bool VehicleGroupTotalProfitThisYearSorter(const GUIVehicleGroup &a, const GUIVehicleGroup &b)
|
||||
{
|
||||
return a.display_profit_this_year < b.display_profit_this_year;
|
||||
}
|
||||
|
||||
/** Sort vehicle groups by the total profit last year */
|
||||
static bool VehicleGroupTotalProfitLastYearSorter(const GUIVehicleGroup &a, const GUIVehicleGroup &b)
|
||||
{
|
||||
return a.display_profit_last_year < b.display_profit_last_year;
|
||||
}
|
||||
|
||||
/** Sort vehicle groups by the average profit this year */
|
||||
static bool VehicleGroupAverageProfitThisYearSorter(const GUIVehicleGroup &a, const GUIVehicleGroup &b)
|
||||
{
|
||||
return a.display_profit_this_year * static_cast<uint>(b.NumVehicles()) < b.display_profit_this_year * static_cast<uint>(a.NumVehicles());
|
||||
}
|
||||
|
||||
/** Sort vehicle groups by the average profit last year */
|
||||
static bool VehicleGroupAverageProfitLastYearSorter(const GUIVehicleGroup &a, const GUIVehicleGroup &b)
|
||||
{
|
||||
return a.display_profit_last_year * static_cast<uint>(b.NumVehicles()) < b.display_profit_last_year * static_cast<uint>(a.NumVehicles());
|
||||
}
|
||||
|
||||
/** Sort vehicles by their number */
|
||||
static bool VehicleNumberSorter(const Vehicle * const &a, const Vehicle * const &b)
|
||||
{
|
||||
@ -1289,6 +1381,12 @@ static const NWidgetPart _nested_vehicle_list[] = {
|
||||
NWidget(WWT_STICKYBOX, COLOUR_GREY),
|
||||
EndContainer(),
|
||||
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_VL_GROUP_ORDER), SetMinimalSize(81, 12), SetFill(0, 1), SetDataTip(STR_STATION_VIEW_GROUP, STR_TOOLTIP_GROUP_ORDER),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_GROUP_BY_PULLDOWN), SetMinimalSize(167, 12), SetFill(0, 1), SetDataTip(0x0, STR_TOOLTIP_GROUP_ORDER),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(12, 12), SetFill(1, 1), SetResize(1, 0), EndContainer(),
|
||||
EndContainer(),
|
||||
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VL_SORT_ORDER), SetMinimalSize(81, 12), SetFill(0, 1), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_SORT_BY_PULLDOWN), SetMinimalSize(167, 12), SetFill(0, 1), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA),
|
||||
@ -1352,6 +1450,25 @@ static void DrawSmallOrderList(const Vehicle *v, int left, int right, int y, Veh
|
||||
} while (oid != start);
|
||||
}
|
||||
|
||||
/** Draw small order list in the vehicle GUI, but without the little black arrow. This is used for shared order groups. */
|
||||
static void DrawSmallOrderList(const Order *order, int left, int right, int y)
|
||||
{
|
||||
bool rtl = _current_text_dir == TD_RTL;
|
||||
int l_offset = rtl ? 0 : ScaleGUITrad(6);
|
||||
int r_offset = rtl ? ScaleGUITrad(6) : 0;
|
||||
int i = 0;
|
||||
while (order != nullptr) {
|
||||
if (order->IsType(OT_GOTO_STATION)) {
|
||||
SetDParam(0, order->GetDestination());
|
||||
DrawString(left + l_offset, right - r_offset, y, STR_TINY_BLACK_STATION);
|
||||
|
||||
y += FONT_HEIGHT_SMALL;
|
||||
if (++i == 4) break;
|
||||
}
|
||||
order = order->next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws an image of a vehicle chain
|
||||
* @param v Front vehicle
|
||||
@ -1419,7 +1536,7 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int
|
||||
int vehicle_button_x = rtl ? right - GetSpriteSize(SPR_PROFIT_LOT).width : left;
|
||||
|
||||
int y = r.top;
|
||||
uint max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehgroups.size());
|
||||
uint max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), static_cast<uint>(this->vehgroups.size()));
|
||||
for (uint i = this->vscroll->GetPosition(); i < max; ++i) {
|
||||
|
||||
const GUIVehicleGroup &vehgroup = this->vehgroups[i];
|
||||
@ -1430,32 +1547,55 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int
|
||||
|
||||
DrawVehicleProfitButton(vehgroup.age, vehgroup.display_profit_last_year, vehgroup.NumVehicles(), vehicle_button_x, y + FONT_HEIGHT_NORMAL + 3);
|
||||
|
||||
const Vehicle *v = vehgroup.GetSingleVehicle();
|
||||
switch (this->grouping) {
|
||||
case GB_NONE: {
|
||||
const Vehicle *v = vehgroup.GetSingleVehicle();
|
||||
|
||||
DrawVehicleImage(v, image_left, image_right, y + FONT_HEIGHT_SMALL - 1, selected_vehicle, EIT_IN_LIST, 0);
|
||||
DrawVehicleImage(v, image_left, image_right, y + FONT_HEIGHT_SMALL - 1, selected_vehicle, EIT_IN_LIST, 0);
|
||||
|
||||
if (!v->name.empty()) {
|
||||
/* The vehicle got a name so we will print it */
|
||||
SetDParam(0, v->index);
|
||||
DrawString(text_left, text_right, y, STR_TINY_BLACK_VEHICLE);
|
||||
} else if (v->group_id != DEFAULT_GROUP) {
|
||||
/* The vehicle has no name, but is member of a group, so print group name */
|
||||
SetDParam(0, v->group_id);
|
||||
DrawString(text_left, text_right, y, STR_TINY_GROUP, TC_BLACK);
|
||||
if (!v->name.empty()) {
|
||||
/* The vehicle got a name so we will print it */
|
||||
SetDParam(0, v->index);
|
||||
DrawString(text_left, text_right, y, STR_TINY_BLACK_VEHICLE);
|
||||
} else if (v->group_id != DEFAULT_GROUP) {
|
||||
/* The vehicle has no name, but is member of a group, so print group name */
|
||||
SetDParam(0, v->group_id);
|
||||
DrawString(text_left, text_right, y, STR_TINY_GROUP, TC_BLACK);
|
||||
}
|
||||
|
||||
if (show_orderlist) DrawSmallOrderList(v, orderlist_left, orderlist_right, y, v->cur_real_order_index);
|
||||
|
||||
StringID str;
|
||||
if (v->IsChainInDepot()) {
|
||||
str = STR_BLUE_COMMA;
|
||||
} else {
|
||||
str = (v->age > v->max_age - DAYS_IN_LEAP_YEAR) ? STR_RED_COMMA : STR_BLACK_COMMA;
|
||||
}
|
||||
|
||||
SetDParam(0, v->unitnumber);
|
||||
DrawString(left, right, y + 2, str);
|
||||
break;
|
||||
}
|
||||
|
||||
case GB_SHARED_ORDERS:
|
||||
|
||||
assert(vehgroup.NumVehicles() > 0);
|
||||
|
||||
for (int i = 0; i < static_cast<int>(vehgroup.NumVehicles()); ++i) {
|
||||
if (image_left + 8 * i >= image_right) break; // Break if there is no more space to draw any more vehicles anyway.
|
||||
DrawVehicleImage(vehgroup.vehicles_begin[i], image_left + 8 * i, image_right, y + FONT_HEIGHT_SMALL - 1, selected_vehicle, EIT_IN_LIST, 0);
|
||||
}
|
||||
|
||||
if (show_orderlist) DrawSmallOrderList((vehgroup.vehicles_begin[0])->GetFirstOrder(), orderlist_left, orderlist_right, y);
|
||||
|
||||
SetDParam(0, vehgroup.NumVehicles());
|
||||
DrawString(left, right, y + 2, STR_BLACK_COMMA);
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
||||
if (show_orderlist) DrawSmallOrderList(v, orderlist_left, orderlist_right, y, v->cur_real_order_index);
|
||||
|
||||
StringID str;
|
||||
if (v->IsChainInDepot()) {
|
||||
str = STR_BLUE_COMMA;
|
||||
} else {
|
||||
str = (v->age > v->max_age - DAYS_IN_LEAP_YEAR) ? STR_RED_COMMA : STR_BLACK_COMMA;
|
||||
}
|
||||
|
||||
SetDParam(0, v->unitnumber);
|
||||
DrawString(left, right, y + 2, str);
|
||||
|
||||
y += line_height;
|
||||
}
|
||||
}
|
||||
@ -1472,7 +1612,7 @@ void BaseVehicleListWindow::UpdateSortingFromGrouping()
|
||||
case VEH_AIRCRAFT: this->sorting = &_sorting[this->grouping].aircraft; break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
this->vehgroups.SetSortFuncs(this->vehicle_group_none_sorter_funcs);
|
||||
this->vehgroups.SetSortFuncs(this->GetVehicleSorterFuncs());
|
||||
this->vehgroups.SetListing(*this->sorting);
|
||||
this->vehgroups.ForceRebuild();
|
||||
this->vehgroups.NeedResort();
|
||||
@ -1523,6 +1663,10 @@ public:
|
||||
|
||||
if (this->vli.type == VL_SHARED_ORDERS) {
|
||||
this->GetWidget<NWidgetCore>(WID_VL_CAPTION)->widget_data = STR_VEHICLE_LIST_SHARED_ORDERS_LIST_CAPTION;
|
||||
/* If we are in the shared orders window, then disable the group-by dropdown menu.
|
||||
* Remove this when the group-by dropdown menu has another option apart from grouping by shared orders. */
|
||||
this->SetWidgetDisabledState(WID_VL_GROUP_ORDER, true);
|
||||
this->SetWidgetDisabledState(WID_VL_GROUP_BY_PULLDOWN, true);
|
||||
} else {
|
||||
this->GetWidget<NWidgetCore>(WID_VL_CAPTION)->widget_data = STR_VEHICLE_LIST_TRAIN_CAPTION + this->vli.vtype;
|
||||
}
|
||||
@ -1656,8 +1800,11 @@ public:
|
||||
WIDGET_LIST_END);
|
||||
}
|
||||
|
||||
/* Set text of group by dropdown widget. */
|
||||
this->GetWidget<NWidgetCore>(WID_VL_GROUP_BY_PULLDOWN)->widget_data = this->vehicle_group_by_names[this->grouping];
|
||||
|
||||
/* Set text of sort by dropdown widget. */
|
||||
this->GetWidget<NWidgetCore>(WID_VL_SORT_BY_PULLDOWN)->widget_data = this->vehicle_group_none_sorter_names[this->vehgroups.SortType()];
|
||||
this->GetWidget<NWidgetCore>(WID_VL_SORT_BY_PULLDOWN)->widget_data = this->GetVehicleSorterNames()[this->vehgroups.SortType()];
|
||||
|
||||
this->DrawWidgets();
|
||||
}
|
||||
@ -1670,8 +1817,12 @@ public:
|
||||
this->SetDirty();
|
||||
break;
|
||||
|
||||
case WID_VL_SORT_BY_PULLDOWN:// Select sorting criteria dropdown menu
|
||||
ShowDropDownMenu(this, this->vehicle_group_none_sorter_names, this->vehgroups.SortType(), WID_VL_SORT_BY_PULLDOWN, 0,
|
||||
case WID_VL_GROUP_BY_PULLDOWN: // Select sorting criteria dropdown menu
|
||||
ShowDropDownMenu(this, this->vehicle_group_by_names, this->grouping, WID_VL_GROUP_BY_PULLDOWN, 0, 0);
|
||||
return;
|
||||
|
||||
case WID_VL_SORT_BY_PULLDOWN: // Select sorting criteria dropdown menu
|
||||
ShowDropDownMenu(this, this->GetVehicleSorterNames(), this->vehgroups.SortType(), WID_VL_SORT_BY_PULLDOWN, 0,
|
||||
(this->vli.vtype == VEH_TRAIN || this->vli.vtype == VEH_ROAD) ? 0 : (1 << 10));
|
||||
return;
|
||||
|
||||
@ -1680,15 +1831,29 @@ public:
|
||||
if (id_v >= this->vehgroups.size()) return; // click out of list bound
|
||||
|
||||
const GUIVehicleGroup &vehgroup = this->vehgroups[id_v];
|
||||
const Vehicle *v = vehgroup.GetSingleVehicle();
|
||||
|
||||
if (!VehicleClicked(v)) {
|
||||
if (_ctrl_pressed) {
|
||||
ShowCompanyGroupForVehicle(v);
|
||||
} else {
|
||||
ShowVehicleViewWindow(v);
|
||||
switch (this->grouping) {
|
||||
case GB_NONE: {
|
||||
const Vehicle *v = vehgroup.GetSingleVehicle();
|
||||
if (!VehicleClicked(v)) {
|
||||
if (_ctrl_pressed) {
|
||||
ShowCompanyGroupForVehicle(v);
|
||||
} else {
|
||||
ShowVehicleViewWindow(v);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GB_SHARED_ORDERS:
|
||||
assert(vehgroup.NumVehicles() > 0);
|
||||
/* We do not support VehicleClicked() here since the contextual action may only make sense for individual vehicles */
|
||||
|
||||
ShowVehicleListWindow(vehgroup.vehicles_begin[0]);
|
||||
break;
|
||||
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1711,9 +1876,14 @@ public:
|
||||
void OnDropdownSelect(int widget, int index) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_VL_GROUP_BY_PULLDOWN:
|
||||
this->UpdateVehicleGroupBy(static_cast<GroupBy>(index));
|
||||
break;
|
||||
|
||||
case WID_VL_SORT_BY_PULLDOWN:
|
||||
this->vehgroups.SetSortType(index);
|
||||
break;
|
||||
|
||||
case WID_VL_MANAGE_VEHICLES_DROPDOWN:
|
||||
assert(this->vehicles.size() != 0);
|
||||
|
||||
@ -1729,6 +1899,7 @@ public:
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
break;
|
||||
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
this->SetDirty();
|
||||
|
@ -49,6 +49,7 @@ struct BaseVehicleListWindow : public Window {
|
||||
|
||||
enum GroupBy : byte {
|
||||
GB_NONE,
|
||||
GB_SHARED_ORDERS,
|
||||
|
||||
GB_END,
|
||||
};
|
||||
@ -92,12 +93,26 @@ struct BaseVehicleListWindow : public Window {
|
||||
|
||||
const StringID *GetVehicleSorterNames()
|
||||
{
|
||||
return vehicle_group_none_sorter_names;
|
||||
switch (this->grouping) {
|
||||
case GB_NONE:
|
||||
return vehicle_group_none_sorter_names;
|
||||
case GB_SHARED_ORDERS:
|
||||
return vehicle_group_shared_orders_sorter_names;
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
VehicleGroupSortFunction * const *GetVehicleSorterFuncs()
|
||||
{
|
||||
return vehicle_group_none_sorter_funcs;
|
||||
switch (this->grouping) {
|
||||
case GB_NONE:
|
||||
return vehicle_group_none_sorter_funcs;
|
||||
case GB_SHARED_ORDERS:
|
||||
return vehicle_group_shared_orders_sorter_funcs;
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -13,6 +13,8 @@
|
||||
/** Widgets of the #VehicleGroupWindow class. */
|
||||
enum GroupListWidgets {
|
||||
WID_GL_CAPTION, ///< Caption of the window.
|
||||
WID_GL_GROUP_BY_ORDER, ///< Group order.
|
||||
WID_GL_GROUP_BY_DROPDOWN, ///< Group by dropdown list.
|
||||
WID_GL_SORT_BY_ORDER, ///< Sort order.
|
||||
WID_GL_SORT_BY_DROPDOWN, ///< Sort by dropdown list.
|
||||
WID_GL_LIST_VEHICLE, ///< List of the vehicles.
|
||||
|
@ -61,6 +61,8 @@ enum VehicleDetailsWidgets {
|
||||
/** Widgets of the #VehicleListWindow class. */
|
||||
enum VehicleListWidgets {
|
||||
WID_VL_CAPTION, ///< Caption of window.
|
||||
WID_VL_GROUP_ORDER, ///< Group order.
|
||||
WID_VL_GROUP_BY_PULLDOWN, ///< Group by dropdown list.
|
||||
WID_VL_SORT_ORDER, ///< Sort order.
|
||||
WID_VL_SORT_BY_PULLDOWN, ///< Sort by dropdown list.
|
||||
WID_VL_LIST, ///< List of the vehicles.
|
||||
|
Loading…
Reference in New Issue
Block a user