diff options
author | Bernard Teo <bernard.14916@gmail.com> | 2019-01-11 16:50:38 +0800 |
---|---|---|
committer | Patric Stout <github@truebrain.nl> | 2020-12-21 23:15:53 +0100 |
commit | e59c400ca6e56605dd8660630246982f23a16b0a (patch) | |
tree | 43ba3c93dfa79fc5ed0e1719862c4ba773b58a9d /src | |
parent | 584df548f1bdfa27482aa995d151542abe4f0bca (diff) | |
download | openttd-e59c400ca6e56605dd8660630246982f23a16b0a.tar.xz |
Feature: Option to group vehicle lists by shared orders
This applies to all kinds of vehicle lists, as well as the "vehicle groups" window.
Diffstat (limited to 'src')
-rw-r--r-- | src/group_gui.cpp | 71 | ||||
-rw-r--r-- | src/lang/english.txt | 9 | ||||
-rw-r--r-- | src/vehicle_gui.cpp | 247 | ||||
-rw-r--r-- | src/vehicle_gui_base.h | 19 | ||||
-rw-r--r-- | src/widgets/group_widget.h | 2 | ||||
-rw-r--r-- | src/widgets/vehicle_widget.h | 2 |
6 files changed, 296 insertions, 54 deletions
diff --git a/src/group_gui.cpp b/src/group_gui.cpp index 5323b65f2..c5d9ac599 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -72,6 +72,11 @@ static const NWidgetPart _nested_group_widgets[] = { /* 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), NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(12, 12), SetResize(1, 0), EndContainer(), @@ -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; + 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(); + } - 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; diff --git a/src/lang/english.txt b/src/lang/english.txt index 6d11d2d76..2b96f1931 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -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 diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 135da393a..a1b40ba92 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -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); + } + 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); + } - max_unitnumber = max<uint>(max_unitnumber, (*it)->unitnumber); + 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) { @@ -1290,6 +1382,12 @@ static const NWidgetPart _nested_vehicle_list[] = { 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), NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(12, 12), SetFill(1, 1), SetResize(1, 0), @@ -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,31 +1547,54 @@ 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); + 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; - } + 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); + 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(); + } 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(); diff --git a/src/vehicle_gui_base.h b/src/vehicle_gui_base.h index c63d5ec18..f89b81ffb 100644 --- a/src/vehicle_gui_base.h +++ b/src/vehicle_gui_base.h @@ -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(); + } } }; diff --git a/src/widgets/group_widget.h b/src/widgets/group_widget.h index beca5a3a6..03ac61a48 100644 --- a/src/widgets/group_widget.h +++ b/src/widgets/group_widget.h @@ -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. diff --git a/src/widgets/vehicle_widget.h b/src/widgets/vehicle_widget.h index 5ecb8dffe..0ee1b2624 100644 --- a/src/widgets/vehicle_widget.h +++ b/src/widgets/vehicle_widget.h @@ -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. |