1
0
Fork 0

Add: Draw station rating mini graphs in vehicle order lists.

pull/14410/head
Peter Nelson 2025-07-01 22:38:29 +01:00
parent 574b99305f
commit 9a68cef76a
No known key found for this signature in database
GPG Key ID: 8EF8F0A467DF75ED
4 changed files with 43 additions and 30 deletions

View File

@ -10,6 +10,7 @@
#ifndef ORDER_FUNC_H #ifndef ORDER_FUNC_H
#define ORDER_FUNC_H #define ORDER_FUNC_H
#include "core/geometry_type.hpp"
#include "order_type.h" #include "order_type.h"
#include "vehicle_type.h" #include "vehicle_type.h"
#include "company_type.h" #include "company_type.h"
@ -24,7 +25,7 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth = 0,
VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v); VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v);
uint GetOrderDistance(VehicleOrderID prev, VehicleOrderID cur, const Vehicle *v, int conditional_depth = 0); uint GetOrderDistance(VehicleOrderID prev, VehicleOrderID cur, const Vehicle *v, int conditional_depth = 0);
void DrawOrderString(const Vehicle *v, const Order *order, VehicleOrderID order_index, int y, bool selected, bool timetable, int left, int middle, int right); void DrawOrderString(const Vehicle *v, const Order *order, VehicleOrderID order_index, bool selected, bool timetable, Rect index_rect, Rect order_rect, int rating_width);
static const uint DEF_SERVINT_DAYS_TRAINS = 150; static const uint DEF_SERVINT_DAYS_TRAINS = 150;
static const uint DEF_SERVINT_DAYS_ROADVEH = 150; static const uint DEF_SERVINT_DAYS_ROADVEH = 150;

View File

@ -22,6 +22,7 @@
#include "tilehighlight_func.h" #include "tilehighlight_func.h"
#include "network/network.h" #include "network/network.h"
#include "station_base.h" #include "station_base.h"
#include "station_gui.h"
#include "industry.h" #include "industry.h"
#include "waypoint_base.h" #include "waypoint_base.h"
#include "core/geometry_func.hpp" #include "core/geometry_func.hpp"
@ -33,6 +34,7 @@
#include "vehicle_func.h" #include "vehicle_func.h"
#include "error.h" #include "error.h"
#include "order_cmd.h" #include "order_cmd.h"
#include "order_func.h"
#include "company_cmd.h" #include "company_cmd.h"
#include "core/string_consumer.hpp" #include "core/string_consumer.hpp"
@ -218,14 +220,13 @@ static StringID GetOrderGoToString(const Order &order)
* @param v Vehicle the order belongs to * @param v Vehicle the order belongs to
* @param order The order to draw * @param order The order to draw
* @param order_index Index of the order in the orders of the vehicle * @param order_index Index of the order in the orders of the vehicle
* @param y Y position for drawing
* @param selected True, if the order is selected * @param selected True, if the order is selected
* @param timetable True, when drawing in the timetable GUI * @param timetable True, when drawing in the timetable GUI
* @param left Left border for text drawing * @param index_rect Rect to draw order index, and current order marker.
* @param middle X position between order index and order text * @param order_rect Rect to draw order detail text within.
* @param right Right border for text drawing * @param rating_width Width of each station rating mini graph, or 0 to disable drawing ratings.
*/ */
void DrawOrderString(const Vehicle *v, const Order *order, VehicleOrderID order_index, int y, bool selected, bool timetable, int left, int middle, int right) void DrawOrderString(const Vehicle *v, const Order *order, VehicleOrderID order_index, bool selected, bool timetable, Rect index_rect, Rect order_rect, int rating_width)
{ {
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
@ -233,11 +234,11 @@ void DrawOrderString(const Vehicle *v, const Order *order, VehicleOrderID order_
Dimension sprite_size = GetSpriteSize(sprite); Dimension sprite_size = GetSpriteSize(sprite);
if (v->cur_real_order_index == order_index) { if (v->cur_real_order_index == order_index) {
/* Draw two arrows before the next real order. */ /* Draw two arrows before the next real order. */
DrawSprite(sprite, PAL_NONE, rtl ? right - sprite_size.width : left, y + ((int)GetCharacterHeight(FS_NORMAL) - (int)sprite_size.height) / 2); DrawSpriteIgnorePadding(sprite, PAL_NONE, index_rect.WithWidth(sprite_size.width, rtl), SA_CENTER);
DrawSprite(sprite, PAL_NONE, rtl ? right - 2 * sprite_size.width : left + sprite_size.width, y + ((int)GetCharacterHeight(FS_NORMAL) - (int)sprite_size.height) / 2); DrawSpriteIgnorePadding(sprite, PAL_NONE, index_rect.Indent(sprite_size.width, rtl).WithWidth(sprite_size.width, rtl), SA_CENTER);
} else if (v->cur_implicit_order_index == order_index) { } else if (v->cur_implicit_order_index == order_index) {
/* Draw one arrow before the next implicit order; the next real order will still get two arrows. */ /* Draw one arrow before the next implicit order; the next real order will still get two arrows. */
DrawSprite(sprite, PAL_NONE, rtl ? right - sprite_size.width : left, y + ((int)GetCharacterHeight(FS_NORMAL) - (int)sprite_size.height) / 2); DrawSpriteIgnorePadding(sprite, PAL_NONE, index_rect.WithWidth(sprite_size.width, rtl), SA_CENTER);
} }
TextColour colour = TC_BLACK; TextColour colour = TC_BLACK;
@ -247,8 +248,9 @@ void DrawOrderString(const Vehicle *v, const Order *order, VehicleOrderID order_
colour = TC_WHITE; colour = TC_WHITE;
} }
DrawString(left, rtl ? right - 2 * sprite_size.width - 3 : middle, y, GetString(STR_ORDER_INDEX, order_index + 1), colour, SA_RIGHT | SA_FORCE); DrawString(index_rect.Indent(sprite_size.width * 2, rtl), GetString(STR_ORDER_INDEX, order_index + 1), colour, SA_RIGHT | SA_FORCE);
const Station *st = nullptr;
std::string line; std::string line;
switch (order->GetType()) { switch (order->GetType()) {
@ -264,7 +266,8 @@ void DrawOrderString(const Vehicle *v, const Order *order, VehicleOrderID order_
case OT_GOTO_STATION: { case OT_GOTO_STATION: {
OrderLoadFlags load = order->GetLoadType(); OrderLoadFlags load = order->GetLoadType();
OrderUnloadFlags unload = order->GetUnloadType(); OrderUnloadFlags unload = order->GetUnloadType();
bool valid_station = CanVehicleUseStation(v, Station::Get(order->GetDestination().ToStationID())); st = Station::Get(order->GetDestination().ToStationID());
bool valid_station = CanVehicleUseStation(v, st);
line = GetString(valid_station ? STR_ORDER_GO_TO_STATION : STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION, STR_ORDER_GO_TO + (v->IsGroundVehicle() ? order->GetNonStopType() : 0), order->GetDestination()); line = GetString(valid_station ? STR_ORDER_GO_TO_STATION : STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION, STR_ORDER_GO_TO + (v->IsGroundVehicle() ? order->GetNonStopType() : 0), order->GetDestination());
if (timetable) { if (timetable) {
@ -360,7 +363,12 @@ void DrawOrderString(const Vehicle *v, const Order *order, VehicleOrderID order_
} }
} }
DrawString(rtl ? left : middle, rtl ? middle : right, y, line, colour); int w = GetStringBoundingBox(line).width;
DrawString(order_rect, line, colour);
if (st != nullptr && rating_width > 0) {
DrawStationRatingMiniGraphs(st, order_rect.Indent(w + WidgetDimensions::scaled.hsep_wide, rtl), rating_width);
}
} }
/** /**
@ -561,6 +569,7 @@ private:
DP_BOTTOM_MIDDLE_STOP_SHARING = 1, ///< Display 'stop sharing' in the middle button of the bottom row of the vehicle order window. DP_BOTTOM_MIDDLE_STOP_SHARING = 1, ///< Display 'stop sharing' in the middle button of the bottom row of the vehicle order window.
}; };
int rating_width = 0;
int selected_order = -1; int selected_order = -1;
VehicleOrderID order_over = INVALID_VEH_ORDER_ID; ///< Order over which another order is dragged, \c INVALID_VEH_ORDER_ID if none. VehicleOrderID order_over = INVALID_VEH_ORDER_ID; ///< Order over which another order is dragged, \c INVALID_VEH_ORDER_ID if none.
OrderPlaceObjectState goto_type = OPOS_NONE; OrderPlaceObjectState goto_type = OPOS_NONE;
@ -818,6 +827,11 @@ public:
this->OnInvalidateData(VIWD_MODIFY_ORDERS); this->OnInvalidateData(VIWD_MODIFY_ORDERS);
} }
void OnInit() override
{
this->rating_width = GetStationRatingMiniGraphWidth();
}
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
{ {
switch (widget) { switch (widget) {
@ -1101,10 +1115,8 @@ public:
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
uint64_t max_value = GetParamMaxValue(this->vehicle->GetNumOrders(), 2); uint64_t max_value = GetParamMaxValue(this->vehicle->GetNumOrders(), 2);
int index_column_width = GetStringBoundingBox(GetString(STR_ORDER_INDEX, max_value)).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + WidgetDimensions::scaled.hsep_normal; int index_column_width = GetStringBoundingBox(GetString(STR_ORDER_INDEX, max_value)).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + WidgetDimensions::scaled.hsep_normal;
int middle = rtl ? ir.right - index_column_width : ir.left + index_column_width;
int y = ir.top; Rect tr = ir.WithHeight(this->GetWidget<NWidgetBase>(WID_O_ORDER_LIST)->resize_y);
int line_height = this->GetWidget<NWidgetBase>(WID_O_ORDER_LIST)->resize_y;
VehicleOrderID i = this->vscroll->GetPosition(); VehicleOrderID i = this->vscroll->GetPosition();
VehicleOrderID num_orders = this->vehicle->GetNumOrders(); VehicleOrderID num_orders = this->vehicle->GetNumOrders();
@ -1117,19 +1129,18 @@ public:
if (i != this->selected_order && i == this->order_over) { if (i != this->selected_order && i == this->order_over) {
/* Highlight dragged order destination. */ /* Highlight dragged order destination. */
int top = (this->order_over < this->selected_order ? y : y + line_height) - WidgetDimensions::scaled.framerect.top; int top = (this->order_over < this->selected_order ? tr.top : tr.bottom) - WidgetDimensions::scaled.framerect.top;
int bottom = std::min(top + 2, ir.bottom); int bottom = std::min(top + 2, ir.bottom);
top = std::max(top - 3, ir.top); top = std::max(top - 3, ir.top);
GfxFillRect(ir.left, top, ir.right, bottom, GetColourGradient(COLOUR_GREY, SHADE_LIGHTEST)); GfxFillRect(ir.left, top, ir.right, bottom, GetColourGradient(COLOUR_GREY, SHADE_LIGHTEST));
break; break;
} }
y += line_height; tr = tr.Translate(0, tr.Height());
++i;
i++;
} }
/* Reset counters for drawing the orders. */ /* Reset counters for drawing the orders. */
y = ir.top; tr = ir;
i = this->vscroll->GetPosition(); i = this->vscroll->GetPosition();
} }
@ -1138,15 +1149,14 @@ public:
/* Don't draw anything if it extends past the end of the window. */ /* Don't draw anything if it extends past the end of the window. */
if (!this->vscroll->IsVisible(i)) break; if (!this->vscroll->IsVisible(i)) break;
DrawOrderString(this->vehicle, this->vehicle->GetOrder(i), i, y, i == this->selected_order, false, ir.left, middle, ir.right); DrawOrderString(this->vehicle, this->vehicle->GetOrder(i), i, i == this->selected_order, false, tr.WithWidth(index_column_width, rtl), tr.Indent(index_column_width, rtl), this->rating_width);
y += line_height; tr = tr.Translate(0, tr.Height());
++i;
i++;
} }
if (this->vscroll->IsVisible(i)) { if (this->vscroll->IsVisible(i)) {
StringID str = this->vehicle->IsOrderListShared() ? STR_ORDERS_END_OF_SHARED_ORDERS : STR_ORDERS_END_OF_ORDERS; StringID str = this->vehicle->IsOrderListShared() ? STR_ORDERS_END_OF_SHARED_ORDERS : STR_ORDERS_END_OF_ORDERS;
DrawString(rtl ? ir.left : middle, rtl ? middle : ir.right, y, str, (i == this->selected_order) ? TC_WHITE : TC_BLACK); DrawString(tr.Indent(index_column_width, rtl), str, (i == this->selected_order) ? TC_WHITE : TC_BLACK);
} }
} }

View File

@ -35,4 +35,7 @@ void ShowSelectStationIfNeeded(TileArea ta, StationPickerCmdProc proc);
void ShowSelectRailWaypointIfNeeded(TileArea ta, StationPickerCmdProc proc); void ShowSelectRailWaypointIfNeeded(TileArea ta, StationPickerCmdProc proc);
void ShowSelectRoadWaypointIfNeeded(TileArea ta, StationPickerCmdProc proc); void ShowSelectRoadWaypointIfNeeded(TileArea ta, StationPickerCmdProc proc);
uint GetStationRatingMiniGraphWidth();
void DrawStationRatingMiniGraphs(const Station *st, const Rect &row, uint rating_width);
#endif /* STATION_GUI_H */ #endif /* STATION_GUI_H */

View File

@ -427,7 +427,7 @@ struct TimetableWindow : Window {
void DrawTimetablePanel(const Rect &r) const void DrawTimetablePanel(const Rect &r) const
{ {
const Vehicle *v = this->vehicle; const Vehicle *v = this->vehicle;
Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); Rect tr = r.Shrink(WidgetDimensions::scaled.framerect).WithHeight(GetCharacterHeight(FS_NORMAL));
int i = this->vscroll->GetPosition(); int i = this->vscroll->GetPosition();
VehicleOrderID order_id = (i + 1) / 2; VehicleOrderID order_id = (i + 1) / 2;
bool final_order = false; bool final_order = false;
@ -435,7 +435,6 @@ struct TimetableWindow : Window {
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
int index_column_width = GetStringBoundingBox(GetString(STR_ORDER_INDEX, GetParamMaxValue(v->GetNumOrders(), 2))).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + WidgetDimensions::scaled.hsep_normal; int index_column_width = GetStringBoundingBox(GetString(STR_ORDER_INDEX, GetParamMaxValue(v->GetNumOrders(), 2))).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + WidgetDimensions::scaled.hsep_normal;
int middle = rtl ? tr.right - index_column_width : tr.left + index_column_width;
auto orders = v->Orders(); auto orders = v->Orders();
while (true) { while (true) {
@ -443,20 +442,20 @@ struct TimetableWindow : Window {
if (!this->vscroll->IsVisible(i)) break; if (!this->vscroll->IsVisible(i)) break;
if (i % 2 == 0) { if (i % 2 == 0) {
DrawOrderString(v, &orders[order_id], order_id, tr.top, i == selected, true, tr.left, middle, tr.right); DrawOrderString(v, &orders[order_id], order_id, i == selected, true, tr.WithWidth(index_column_width, rtl), tr.Indent(index_column_width, rtl), 0);
if (order_id > v->orders->GetNext(order_id)) final_order = true; if (order_id > v->orders->GetNext(order_id)) final_order = true;
order_id = v->orders->GetNext(order_id); order_id = v->orders->GetNext(order_id);
} else { } else {
TextColour colour; TextColour colour;
std::string string = GetTimetableTravelString(orders[order_id], i, colour); std::string string = GetTimetableTravelString(orders[order_id], i, colour);
DrawString(rtl ? tr.left : middle, rtl ? middle : tr.right, tr.top, string, colour); DrawString(tr.Indent(index_column_width, rtl), string, colour);
if (final_order) break; if (final_order) break;
} }
i++; i++;
tr.top += GetCharacterHeight(FS_NORMAL); tr = tr.Translate(0, tr.Height());
} }
} }