summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/order_gui.cpp1220
1 files changed, 592 insertions, 628 deletions
diff --git a/src/order_gui.cpp b/src/order_gui.cpp
index 126600d27..4589080fb 100644
--- a/src/order_gui.cpp
+++ b/src/order_gui.cpp
@@ -58,60 +58,6 @@ enum OrderWindowWidgets {
ORDER_WIDGET_RESIZE,
};
-/** Under what reason are we using the PlaceObject functionality? */
-enum OrderPlaceObjectState {
- OPOS_GOTO,
- OPOS_CONDITIONAL,
-};
-
-struct order_d {
- int sel;
- OrderPlaceObjectState goto_type;
-};
-assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(order_d));
-
-/**
- * Return the memorised selected order.
- *
- * @param w current window
- * @return the memorised order if it is a vaild one
- * else return the number of orders
- */
-static int OrderGetSel(const Window *w)
-{
- const Vehicle *v = GetVehicle(w->window_number);
- int num = WP(w, order_d).sel;
-
- return (num >= 0 && num < v->num_orders) ? num : v->num_orders;
-}
-
-/**
- * Calculate the selected order.
- * The calculation is based on the relative (to the window) y click position and
- * the position of the scrollbar.
- *
- * @param w current window
- * @param y Y-value of the click relative to the window origin
- * @param v current vehicle
- * @return the new selected order if the order is valid else return that
- * an invalid one has been selected.
- */
-static int GetOrderFromOrderWndPt(Window *w, int y, const Vehicle *v)
-{
- /*
- * Calculation description:
- * 15 = 14 (w->widget[ORDER_WIDGET_ORDER_LIST].top) + 1 (frame-line)
- * 10 = order text hight
- */
- int sel = (y - w->widget[ORDER_WIDGET_ORDER_LIST].top - 1) / 10;
-
- if ((uint)sel >= w->vscroll.cap) return INVALID_ORDER;
-
- sel += w->vscroll.pos;
-
- return (sel <= v->num_orders && sel >= 0) ? sel : INVALID_ORDER;
-}
-
/** Order load types that could be given to station orders. */
static const StringID _station_load_types[][5] = {
{
@@ -312,121 +258,6 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
}
-static void DrawOrdersWindow(Window *w)
-{
- const Vehicle *v = GetVehicle(w->window_number);
- bool shared_orders = v->IsOrderListShared();
-
- SetVScrollCount(w, v->num_orders + 1);
-
- int sel = OrderGetSel(w);
- const Order *order = GetVehicleOrder(v, sel);
-
- if (v->owner == _local_player) {
- /* Set the strings for the dropdown boxes. */
- w->widget[ORDER_WIDGET_NON_STOP].data = _order_non_stop_drowdown[order == NULL ? 0 : order->GetNonStopType()];
- w->widget[ORDER_WIDGET_FULL_LOAD].data = _order_full_load_drowdown[order == NULL ? 0 : order->GetLoadType()];
- w->widget[ORDER_WIDGET_UNLOAD].data = _order_unload_drowdown[order == NULL ? 0 : order->GetUnloadType()];
- w->widget[ORDER_WIDGET_COND_VARIABLE].data = _order_conditional_variable[order == NULL ? 0 : order->GetConditionVariable()];
- w->widget[ORDER_WIDGET_COND_COMPARATOR].data = _order_conditional_condition[order == NULL ? 0 : order->GetConditionComparator()];
-
- /* skip */
- w->SetWidgetDisabledState(ORDER_WIDGET_SKIP, v->num_orders <= 1);
-
- /* delete */
- w->SetWidgetDisabledState(ORDER_WIDGET_DELETE,
- (uint)v->num_orders + ((shared_orders || v->num_orders != 0) ? 1 : 0) <= (uint)WP(w, order_d).sel);
-
- /* non-stop only for trains */
- w->SetWidgetDisabledState(ORDER_WIDGET_NON_STOP, (v->type != VEH_TRAIN && v->type != VEH_ROAD) || order == NULL);
- w->SetWidgetDisabledState(ORDER_WIDGET_FULL_LOAD, order == NULL || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) != 0); // full load
- w->SetWidgetDisabledState(ORDER_WIDGET_UNLOAD, order == NULL || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) != 0); // unload
- /* Disable list of vehicles with the same shared orders if there is no list */
- w->SetWidgetDisabledState(ORDER_WIDGET_SHARED_ORDER_LIST, !shared_orders || v->orders == NULL);
- w->SetWidgetDisabledState(ORDER_WIDGET_REFIT, order == NULL); // Refit
- w->SetWidgetDisabledState(ORDER_WIDGET_SERVICE, order == NULL); // Refit
- w->HideWidget(ORDER_WIDGET_REFIT); // Refit
- w->HideWidget(ORDER_WIDGET_SERVICE); // Service
-
- w->HideWidget(ORDER_WIDGET_COND_VARIABLE);
- w->HideWidget(ORDER_WIDGET_COND_COMPARATOR);
- w->HideWidget(ORDER_WIDGET_COND_VALUE);
- }
-
- w->ShowWidget(ORDER_WIDGET_NON_STOP);
- w->ShowWidget(ORDER_WIDGET_UNLOAD);
- w->ShowWidget(ORDER_WIDGET_FULL_LOAD);
-
- if (order != NULL) {
- switch (order->GetType()) {
- case OT_GOTO_STATION:
- if (!GetStation(order->GetDestination())->IsBuoy()) break;
- /* Fall-through */
-
- case OT_GOTO_WAYPOINT:
- w->DisableWidget(ORDER_WIDGET_FULL_LOAD);
- w->DisableWidget(ORDER_WIDGET_UNLOAD);
- break;
-
- case OT_GOTO_DEPOT:
- w->DisableWidget(ORDER_WIDGET_FULL_LOAD);
-
- /* Remove unload and replace it with refit */
- w->HideWidget(ORDER_WIDGET_UNLOAD);
- w->ShowWidget(ORDER_WIDGET_REFIT);
- w->HideWidget(ORDER_WIDGET_FULL_LOAD);
- w->ShowWidget(ORDER_WIDGET_SERVICE);
- break;
-
- case OT_CONDITIONAL: {
- w->HideWidget(ORDER_WIDGET_NON_STOP);
- w->HideWidget(ORDER_WIDGET_UNLOAD);
- w->HideWidget(ORDER_WIDGET_FULL_LOAD);
- w->ShowWidget(ORDER_WIDGET_COND_VARIABLE);
- w->ShowWidget(ORDER_WIDGET_COND_COMPARATOR);
- w->ShowWidget(ORDER_WIDGET_COND_VALUE);
-
- OrderConditionVariable ocv = order->GetConditionVariable();
- w->SetWidgetDisabledState(ORDER_WIDGET_COND_COMPARATOR, ocv == OCV_UNCONDITIONALLY);
- w->SetWidgetDisabledState(ORDER_WIDGET_COND_VALUE, ocv == OCV_REQUIRES_SERVICE || ocv == OCV_UNCONDITIONALLY);
-
- uint value = order->GetConditionValue();
- if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value);
- SetDParam(1, value);
- } break;
-
- default: // every other orders
- w->DisableWidget(ORDER_WIDGET_NON_STOP);
- w->DisableWidget(ORDER_WIDGET_FULL_LOAD);
- w->DisableWidget(ORDER_WIDGET_UNLOAD);
- }
- }
-
- SetDParam(0, v->index);
- DrawWindowWidgets(w);
-
- int y = 15;
-
- int i = w->vscroll.pos;
- order = GetVehicleOrder(v, i);
- StringID str;
- while (order != NULL) {
- /* Don't draw anything if it extends past the end of the window. */
- if (i - w->vscroll.pos >= w->vscroll.cap) break;
-
- DrawOrderString(v, order, i, y, i == WP(w, order_d).sel, false);
- y += 10;
-
- i++;
- order = order->next;
- }
-
- if (i - w->vscroll.pos < w->vscroll.cap) {
- str = shared_orders ? STR_END_OF_SHARED_ORDERS : STR_882A_END_OF_ORDERS;
- DrawString(2, y, str, (i == WP(w, order_d).sel) ? TC_WHITE : TC_BLACK);
- }
-}
-
static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile)
{
Order order;
@@ -510,548 +341,689 @@ static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile)
return order;
}
-static bool HandleOrderVehClick(const Vehicle *v, const Vehicle *u, Window *w)
-{
- if (u->type != v->type) return false;
+struct OrdersWindow : public Window {
+private:
+ /** Under what reason are we using the PlaceObject functionality? */
+ enum OrderPlaceObjectState {
+ OPOS_GOTO,
+ OPOS_CONDITIONAL,
+ };
+
+ int selected_order;
+ OrderPlaceObjectState goto_type;
+ const Vehicle *vehicle;
- if (!u->IsPrimaryVehicle()) {
- u = u->First();
- if (!u->IsPrimaryVehicle()) return false;
+ /**
+ * Return the memorised selected order.
+ * @return the memorised order if it is a vaild one
+ * else return the number of orders
+ */
+ int OrderGetSel()
+ {
+ int num = this->selected_order;
+ return (num >= 0 && num < vehicle->num_orders) ? num : vehicle->num_orders;
}
- /* v is vehicle getting orders. Only copy/clone orders if vehicle doesn't have any orders yet
- * obviously if you press CTRL on a non-empty orders vehicle you know what you are doing */
- if (v->num_orders != 0 && _ctrl_pressed == 0) return false;
+ /**
+ * Calculate the selected order.
+ * The calculation is based on the relative (to the window) y click position and
+ * the position of the scrollbar.
+ *
+ * @param y Y-value of the click relative to the window origin
+ * @param v current vehicle
+ * @return the new selected order if the order is valid else return that
+ * an invalid one has been selected.
+ */
+ int GetOrderFromPt(int y)
+ {
+ /*
+ * Calculation description:
+ * 15 = 14 (w->widget[ORDER_WIDGET_ORDER_LIST].top) + 1 (frame-line)
+ * 10 = order text hight
+ */
+ int sel = (y - this->widget[ORDER_WIDGET_ORDER_LIST].top - 1) / 10;
- if (DoCommandP(v->tile, v->index | (u->index << 16), _ctrl_pressed ? CO_SHARE : CO_COPY, NULL,
- _ctrl_pressed ? CMD_CLONE_ORDER | CMD_MSG(STR_CANT_SHARE_ORDER_LIST) : CMD_CLONE_ORDER | CMD_MSG(STR_CANT_COPY_ORDER_LIST))) {
- WP(w, order_d).sel = -1;
- ResetObjectToPlace();
+ if ((uint)sel >= this->vscroll.cap) return INVALID_ORDER;
+
+ sel += this->vscroll.pos;
+
+ return (sel <= vehicle->num_orders && sel >= 0) ? sel : INVALID_ORDER;
}
- return true;
-}
+ bool HandleOrderVehClick(const Vehicle *u)
+ {
+ if (u->type != this->vehicle->type) return false;
-static void OrdersPlaceObj(const Vehicle *v, TileIndex tile, Window *w)
-{
- /* check if we're clicking on a vehicle first.. clone orders in that case. */
- const Vehicle *u = CheckMouseOverVehicle();
- if (u != NULL && HandleOrderVehClick(v, u, w)) return;
+ if (!u->IsPrimaryVehicle()) {
+ u = u->First();
+ if (!u->IsPrimaryVehicle()) return false;
+ }
- const Order cmd = GetOrderCmdFromTile(v, tile);
- if (!cmd.IsValid()) return;
+ /* v is vehicle getting orders. Only copy/clone orders if vehicle doesn't have any orders yet
+ * obviously if you press CTRL on a non-empty orders vehicle you know what you are doing */
+ if (this->vehicle->num_orders != 0 && _ctrl_pressed == 0) return false;
- if (DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), cmd.Pack(), NULL, CMD_INSERT_ORDER | CMD_MSG(STR_8833_CAN_T_INSERT_NEW_ORDER))) {
- if (WP(w, order_d).sel != -1) WP(w, order_d).sel++;
- ResetObjectToPlace();
+ if (DoCommandP(this->vehicle->tile, this->vehicle->index | (u->index << 16), _ctrl_pressed ? CO_SHARE : CO_COPY, NULL,
+ _ctrl_pressed ? CMD_CLONE_ORDER | CMD_MSG(STR_CANT_SHARE_ORDER_LIST) : CMD_CLONE_ORDER | CMD_MSG(STR_CANT_COPY_ORDER_LIST))) {
+ this->selected_order = -1;
+ ResetObjectToPlace();
+ }
+
+ return true;
}
-}
-/**
- * Handle the click on the goto button.
- *
- * @param w current window
- * @param v current vehicle
- */
-static void OrderClick_Goto(Window *w, const Vehicle *v, int i)
-{
- w->InvalidateWidget(ORDER_WIDGET_GOTO);
- w->ToggleWidgetLoweredState(ORDER_WIDGET_GOTO);
- if (w->IsWidgetLowered(ORDER_WIDGET_GOTO)) {
- _place_clicked_vehicle = NULL;
- SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, PAL_NONE, VHM_RECT, w);
- WP(w, order_d).goto_type = OPOS_GOTO;
- } else {
- ResetObjectToPlace();
+ /**
+ * Handle the click on the goto button.
+ *
+ * @param w current window
+ */
+ static void OrderClick_Goto(OrdersWindow *w, int i)
+ {
+ w->InvalidateWidget(ORDER_WIDGET_GOTO);
+ w->ToggleWidgetLoweredState(ORDER_WIDGET_GOTO);
+ if (w->IsWidgetLowered(ORDER_WIDGET_GOTO)) {
+ _place_clicked_vehicle = NULL;
+ SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, PAL_NONE, VHM_RECT, w);
+ w->goto_type = OPOS_GOTO;
+ } else {
+ ResetObjectToPlace();
+ }
}
-}
-/**
- * Handle the click on the full load button.
- *
- * @param w current window
- * @param v current vehicle
- * @param load_type the way to load.
- */
-static void OrderClick_FullLoad(Window *w, const Vehicle *v, int load_type)
-{
- VehicleOrderID sel_ord = OrderGetSel(w);
- const Order *order = GetVehicleOrder(v, sel_ord);
-
- if (order->GetLoadType() == load_type) return;
-
- if (load_type < 0) {
- switch (order->GetLoadType()) {
- case OLF_LOAD_IF_POSSIBLE: load_type = OLFB_FULL_LOAD; break;
- case OLFB_FULL_LOAD: load_type = OLF_FULL_LOAD_ANY; break;
- case OLF_FULL_LOAD_ANY: load_type = OLFB_NO_LOAD; break;
- case OLFB_NO_LOAD: load_type = OLF_LOAD_IF_POSSIBLE; break;
- default: NOT_REACHED();
+ /**
+ * Handle the click on the full load button.
+ *
+ * @param w current window
+ * @param load_type the way to load.
+ */
+ static void OrderClick_FullLoad(OrdersWindow *w, int load_type)
+ {
+ VehicleOrderID sel_ord = w->OrderGetSel();
+ const Order *order = GetVehicleOrder(w->vehicle, sel_ord);
+
+ if (order == NULL || order->GetLoadType() == load_type) return;
+
+ if (load_type < 0) {
+ switch (order->GetLoadType()) {
+ case OLF_LOAD_IF_POSSIBLE: load_type = OLFB_FULL_LOAD; break;
+ case OLFB_FULL_LOAD: load_type = OLF_FULL_LOAD_ANY; break;
+ case OLF_FULL_LOAD_ANY: load_type = OLFB_NO_LOAD; break;
+ case OLFB_NO_LOAD: load_type = OLF_LOAD_IF_POSSIBLE; break;
+ default: NOT_REACHED();
+ }
}
+ DoCommandP(w->vehicle->tile, w->vehicle->index + (sel_ord << 16), MOF_LOAD | (load_type << 4), NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
}
- DoCommandP(v->tile, v->index + (sel_ord << 16), MOF_LOAD | (load_type << 4), NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
-}
-/**
- * Handle the click on the service.
- *
- * @param w current window
- * @param v current vehicle
- */
-static void OrderClick_Service(Window *w, const Vehicle *v, int i)
-{
- DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), MOF_DEPOT_ACTION, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
-}
+ /**
+ * Handle the click on the service.
+ *
+ * @param w current window
+ */
+ static void OrderClick_Service(OrdersWindow *w, int i)
+ {
+ DoCommandP(w->vehicle->tile, w->vehicle->index + (w->OrderGetSel() << 16), MOF_DEPOT_ACTION, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
+ }
-/**
- * Handle the click on the service in nearest depot button.
- *
- * @param w current window
- * @param v current vehicle
- */
-static void OrderClick_NearestDepot(Window *w, const Vehicle *v, int i)
-{
- Order order;
- order.next = NULL;
- order.index = 0;
- order.MakeGoToDepot(0, ODTFB_PART_OF_ORDERS);
- order.SetDepotActionType(ODATFB_NEAREST_DEPOT);
+ /**
+ * Handle the click on the service in nearest depot button.
+ *
+ * @param w current window
+ */
+ static void OrderClick_NearestDepot(OrdersWindow *w, int i)
+ {
+ Order order;
+ order.next = NULL;
+ order.index = 0;
+ order.MakeGoToDepot(0, ODTFB_PART_OF_ORDERS);
+ order.SetDepotActionType(ODATFB_NEAREST_DEPOT);
- DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), order.Pack(), NULL, CMD_INSERT_ORDER | CMD_MSG(STR_8833_CAN_T_INSERT_NEW_ORDER));
-}
+ DoCommandP(w->vehicle->tile, w->vehicle->index + (w->OrderGetSel() << 16), order.Pack(), NULL, CMD_INSERT_ORDER | CMD_MSG(STR_8833_CAN_T_INSERT_NEW_ORDER));
+ }
-/**
- * Handle the click on the conditional order button.
- *
- * @param w current window
- * @param v current vehicle
- */
-static void OrderClick_Conditional(Window *w, const Vehicle *v, int i)
-{
- w->InvalidateWidget(ORDER_WIDGET_GOTO);
- w->LowerWidget(ORDER_WIDGET_GOTO);
- SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, PAL_NONE, VHM_RECT, w);
- WP(w, order_d).goto_type = OPOS_CONDITIONAL;
-}
+ /**
+ * Handle the click on the conditional order button.
+ *
+ * @param w current window
+ */
+ static void OrderClick_Conditional(OrdersWindow *w, int i)
+ {
+ w->InvalidateWidget(ORDER_WIDGET_GOTO);
+ w->LowerWidget(ORDER_WIDGET_GOTO);
+ SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, PAL_NONE, VHM_RECT, w);
+ w->goto_type = OPOS_CONDITIONAL;
+ }
-/**
- * Handle the click on the unload button.
- *
- * @param w current window
- * @param v current vehicle
- */
-static void OrderClick_Unload(Window *w, const Vehicle *v, int unload_type)
-{
- VehicleOrderID sel_ord = OrderGetSel(w);
- const Order *order = GetVehicleOrder(v, sel_ord);
-
- if (order->GetUnloadType() == unload_type) return;
-
- if (unload_type < 0) {
- switch (order->GetUnloadType()) {
- case OUF_UNLOAD_IF_POSSIBLE: unload_type = OUFB_UNLOAD; break;
- case OUFB_UNLOAD: unload_type = OUFB_TRANSFER; break;
- case OUFB_TRANSFER: unload_type = OUFB_NO_UNLOAD; break;
- case OUFB_NO_UNLOAD: unload_type = OUF_UNLOAD_IF_POSSIBLE; break;
- default: NOT_REACHED();
+ /**
+ * Handle the click on the unload button.
+ *
+ * @param w current window
+ */
+ static void OrderClick_Unload(OrdersWindow *w, int unload_type)
+ {
+ VehicleOrderID sel_ord = w->OrderGetSel();
+ const Order *order = GetVehicleOrder(w->vehicle, sel_ord);
+
+ if (order == NULL || order->GetUnloadType() == unload_type) return;
+
+ if (unload_type < 0) {
+ switch (order->GetUnloadType()) {
+ case OUF_UNLOAD_IF_POSSIBLE: unload_type = OUFB_UNLOAD; break;
+ case OUFB_UNLOAD: unload_type = OUFB_TRANSFER; break;
+ case OUFB_TRANSFER: unload_type = OUFB_NO_UNLOAD; break;
+ case OUFB_NO_UNLOAD: unload_type = OUF_UNLOAD_IF_POSSIBLE; break;
+ default: NOT_REACHED();
+ }
}
+
+ DoCommandP(w->vehicle->tile, w->vehicle->index + (sel_ord << 16), MOF_UNLOAD | (unload_type << 4), NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
}
- DoCommandP(v->tile, v->index + (sel_ord << 16), MOF_UNLOAD | (unload_type << 4), NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
-}
+ /**
+ * Handle the click on the nonstop button.
+ *
+ * @param w current window
+ * @param non_stop what non-stop type to use; -1 to use the 'next' one.
+ */
+ static void OrderClick_Nonstop(OrdersWindow *w, int non_stop)
+ {
+ VehicleOrderID sel_ord = w->OrderGetSel();
+ const Order *order = GetVehicleOrder(w->vehicle, sel_ord);
-/**
- * Handle the click on the nonstop button.
- *
- * @param w current window
- * @param v current vehicle
- * @param non_stop what non-stop type to use; -1 to use the 'next' one.
- */
-static void OrderClick_Nonstop(Window *w, const Vehicle *v, int non_stop)
-{
- VehicleOrderID sel_ord = OrderGetSel(w);
- const Order *order = GetVehicleOrder(v, sel_ord);
+ if (order == NULL || order->GetNonStopType() == non_stop) return;
- if (order->GetNonStopType() == non_stop) return;
+ /* Keypress if negative, so 'toggle' to the next */
+ if (non_stop < 0) {
+ non_stop = (order->GetNonStopType() + 1) % ONSF_END;
+ }
- /* Keypress if negative, so 'toggle' to the next */
- if (non_stop < 0) {
- non_stop = (order->GetNonStopType() + 1) % ONSF_END;
+ DoCommandP(w->vehicle->tile, w->vehicle->index + (sel_ord << 16), MOF_NON_STOP | non_stop << 4, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
}
- DoCommandP(v->tile, v->index + (sel_ord << 16), MOF_NON_STOP | non_stop << 4, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
-}
+ /**
+ * Handle the click on the transfer button.
+ *
+ * @param w current window
+ */
+ static void OrderClick_Transfer(OrdersWindow *w, int i)
+ {
+ VehicleOrderID sel_ord = w->OrderGetSel();
+ const Order *order = GetVehicleOrder(w->vehicle, sel_ord);
-/**
- * Handle the click on the transfer button.
- *
- * @param w current window
- * @param v current vehicle
- */
-static void OrderClick_Transfer(Window *w, const Vehicle *v, int i)
-{
- VehicleOrderID sel_ord = OrderGetSel(w);
- const Order *order = GetVehicleOrder(v, sel_ord);
+ if (order == NULL) return;
- DoCommandP(v->tile, v->index + (sel_ord << 16), MOF_UNLOAD | ((order->GetUnloadType() & ~OUFB_NO_UNLOAD) ^ OUFB_TRANSFER) << 4, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
-}
+ DoCommandP(w->vehicle->tile, w->vehicle->index + (sel_ord << 16), MOF_UNLOAD | ((order->GetUnloadType() & ~OUFB_NO_UNLOAD) ^ OUFB_TRANSFER) << 4, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
+ }
-/**
- * Handle the click on the skip button.
- * If ctrl is pressed skip to selected order.
- * Else skip to current order + 1
- *
- * @param w current window
- * @param v current vehicle
- */
-static void OrderClick_Skip(Window *w, const Vehicle *v, int i)
-{
- /* Don't skip when there's nothing to skip */
- if (_ctrl_pressed && v->cur_order_index == OrderGetSel(w)) return;
+ /**
+ * Handle the click on the skip button.
+ * If ctrl is pressed skip to selected order.
+ * Else skip to current order + 1
+ *
+ * @param w current window
+ */
+ static void OrderClick_Skip(OrdersWindow *w, int i)
+ {
+ /* Don't skip when there's nothing to skip */
+ if (_ctrl_pressed && w->vehicle->cur_order_index == w->OrderGetSel()) return;
- DoCommandP(v->tile, v->index, _ctrl_pressed ? OrderGetSel(w) : ((v->cur_order_index + 1) % v->num_orders),
- NULL, CMD_SKIP_TO_ORDER | CMD_MSG(_ctrl_pressed ? STR_CAN_T_SKIP_TO_ORDER : STR_CAN_T_SKIP_ORDER));
-}
+ DoCommandP(w->vehicle->tile, w->vehicle->index, _ctrl_pressed ? w->OrderGetSel() : ((w->vehicle->cur_order_index + 1) % w->vehicle->num_orders),
+ NULL, CMD_SKIP_TO_ORDER | CMD_MSG(_ctrl_pressed ? STR_CAN_T_SKIP_TO_ORDER : STR_CAN_T_SKIP_ORDER));
+ }
-/**
- * Handle the click on the unload button.
- *
- * @param w current window
- * @param v current vehicle
- */
-static void OrderClick_Delete(Window *w, const Vehicle *v, int i)
-{
- DoCommandP(v->tile, v->index, OrderGetSel(w), NULL, CMD_DELETE_ORDER | CMD_MSG(STR_8834_CAN_T_DELETE_THIS_ORDER));
-}
+ /**
+ * Handle the click on the unload button.
+ *
+ * @param w current window
+ */
+ static void OrderClick_Delete(OrdersWindow *w, int i)
+ {
+ DoCommandP(w->vehicle->tile, w->vehicle->index, w->OrderGetSel(), NULL, CMD_DELETE_ORDER | CMD_MSG(STR_8834_CAN_T_DELETE_THIS_ORDER));
+ }
-/**
- * Handle the click on the refit button.
- * If ctrl is pressed cancel refitting.
- * Else show the refit window.
- *
- * @param w current window
- * @param v current vehicle
- */
-static void OrderClick_Refit(Window *w, const Vehicle *v, int i)
-{
- if (_ctrl_pressed) {
- /* Cancel refitting */
- DoCommandP(v->tile, v->index, (WP(w, order_d).sel << 16) | (CT_NO_REFIT << 8) | CT_NO_REFIT, NULL, CMD_ORDER_REFIT);
- } else {
- ShowVehicleRefitWindow(v, WP(w, order_d).sel);
+ /**
+ * Handle the click on the refit button.
+ * If ctrl is pressed cancel refitting.
+ * Else show the refit window.
+ *
+ * @param w current window
+ */
+ static void OrderClick_Refit(OrdersWindow *w, int i)
+ {
+ if (_ctrl_pressed) {
+ /* Cancel refitting */
+ DoCommandP(w->vehicle->tile, w->vehicle->index, (w->OrderGetSel() << 16) | (CT_NO_REFIT << 8) | CT_NO_REFIT, NULL, CMD_ORDER_REFIT);
+ } else {
+ ShowVehicleRefitWindow(w->vehicle, w->OrderGetSel());
+ }
+ }
+ typedef void Handler(OrdersWindow*, int);
+ struct KeyToEvent {
+ uint16 keycode;
+ Handler *proc;
+ };
+
+public:
+ OrdersWindow(const WindowDesc *desc, const Vehicle *v) : Window(desc, v->index)
+ {
+ this->caption_color = v->owner;
+ this->vscroll.cap = 6;
+ this->resize.step_height = 10;
+ this->selected_order = -1;
+ this->vehicle = v;
+ if (_patches.timetabling) {
+ this->widget[ORDER_WIDGET_CAPTION].right -= 61;
+ } else {
+ this->HideWidget(ORDER_WIDGET_TIMETABLE_VIEW);
+ }
+ this->FindWindowPlacementAndResize(desc);
}
-}
-typedef void OnButtonVehClick(Window *w, const Vehicle *v, int i);
+ virtual void OnPaint()
+ {
+ bool shared_orders = this->vehicle->IsOrderListShared();
+
+ SetVScrollCount(this, this->vehicle->num_orders + 1);
+
+ int sel = OrderGetSel();
+ const Order *order = GetVehicleOrder(this->vehicle, sel);
+
+ if (this->vehicle->owner == _local_player) {
+ /* Set the strings for the dropdown boxes. */
+ this->widget[ORDER_WIDGET_NON_STOP].data = _order_non_stop_drowdown[order == NULL ? 0 : order->GetNonStopType()];
+ this->widget[ORDER_WIDGET_FULL_LOAD].data = _order_full_load_drowdown[order == NULL ? 0 : order->GetLoadType()];
+ this->widget[ORDER_WIDGET_UNLOAD].data = _order_unload_drowdown[order == NULL ? 0 : order->GetUnloadType()];
+ this->widget[ORDER_WIDGET_COND_VARIABLE].data = _order_conditional_variable[order == NULL ? 0 : order->GetConditionVariable()];
+ this->widget[ORDER_WIDGET_COND_COMPARATOR].data = _order_conditional_condition[order == NULL ? 0 : order->GetConditionComparator()];
+
+ /* skip */
+ this->SetWidgetDisabledState(ORDER_WIDGET_SKIP, this->vehicle->num_orders <= 1);
+
+ /* delete */
+ this->SetWidgetDisabledState(ORDER_WIDGET_DELETE,
+ (uint)this->vehicle->num_orders + ((shared_orders || this->vehicle->num_orders != 0) ? 1 : 0) <= (uint)this->selected_order);
+
+ /* non-stop only for trains */
+ this->SetWidgetDisabledState(ORDER_WIDGET_NON_STOP, (this->vehicle->type != VEH_TRAIN && this->vehicle->type != VEH_ROAD) || order == NULL);
+ this->SetWidgetDisabledState(ORDER_WIDGET_FULL_LOAD, order == NULL || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) != 0); // full load
+ this->SetWidgetDisabledState(ORDER_WIDGET_UNLOAD, order == NULL || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) != 0); // unload
+ /* Disable list of vehicles with the same shared orders if there is no list */
+ this->SetWidgetDisabledState(ORDER_WIDGET_SHARED_ORDER_LIST, !shared_orders || this->vehicle->orders == NULL);
+ this->SetWidgetDisabledState(ORDER_WIDGET_REFIT, order == NULL); // Refit
+ this->SetWidgetDisabledState(ORDER_WIDGET_SERVICE, order == NULL); // Refit
+ this->HideWidget(ORDER_WIDGET_REFIT); // Refit
+ this->HideWidget(ORDER_WIDGET_SERVICE); // Service
+
+ this->HideWidget(ORDER_WIDGET_COND_VARIABLE);
+ this->HideWidget(ORDER_WIDGET_COND_COMPARATOR);
+ this->HideWidget(ORDER_WIDGET_COND_VALUE);
+ }
-/**
- * Keycode function mapping.
- *
- * @see _order_keycodes[]
- * @note Keep them allways in sync with _order_keycodes[]!
- */
-static OnButtonVehClick* const _order_button_proc[] = {
- OrderClick_Skip,
- OrderClick_Delete,
- OrderClick_Nonstop,
- OrderClick_Goto,
- OrderClick_FullLoad,
- OrderClick_Unload,
- OrderClick_Transfer,
- OrderClick_Service,
-};
+ this->ShowWidget(ORDER_WIDGET_NON_STOP);
+ this->ShowWidget(ORDER_WIDGET_UNLOAD);
+ this->ShowWidget(ORDER_WIDGET_FULL_LOAD);
-static const uint16 _order_keycodes[] = {
- 'D', //skip order
- 'F', //delete order
- 'G', //non-stop
- 'H', //goto order
- 'J', //full load
- 'K' //unload
-};
+ if (order != NULL) {
+ switch (order->GetType()) {
+ case OT_GOTO_STATION:
+ if (!GetStation(order->GetDestination())->IsBuoy()) break;
+ /* Fall-through */
-static void OrdersWndProc(Window *w, WindowEvent *e)
-{
- const Vehicle *v = GetVehicle(w->window_number);
+ case OT_GOTO_WAYPOINT:
+ this->DisableWidget(ORDER_WIDGET_FULL_LOAD);
+ this->DisableWidget(ORDER_WIDGET_UNLOAD);
+ break;
- switch (e->event) {
- case WE_CREATE:
- if (_patches.timetabling) {
- w->widget[ORDER_WIDGET_CAPTION].right -= 61;
- } else {
- w->HideWidget(ORDER_WIDGET_TIMETABLE_VIEW);
- }
+ case OT_GOTO_DEPOT:
+ this->DisableWidget(ORDER_WIDGET_FULL_LOAD);
- break;
+ /* Remove unload and replace it with refit */
+ this->HideWidget(ORDER_WIDGET_UNLOAD);
+ this->ShowWidget(ORDER_WIDGET_REFIT);
+ this->HideWidget(ORDER_WIDGET_FULL_LOAD);
+ this->ShowWidget(ORDER_WIDGET_SERVICE);
+ break;
- case WE_PAINT:
- DrawOrdersWindow(w);
- break;
+ case OT_CONDITIONAL: {
+ this->HideWidget(ORDER_WIDGET_NON_STOP);
+ this->HideWidget(ORDER_WIDGET_UNLOAD);
+ this->HideWidget(ORDER_WIDGET_FULL_LOAD);
+ this->ShowWidget(ORDER_WIDGET_COND_VARIABLE);
+ this->ShowWidget(ORDER_WIDGET_COND_COMPARATOR);
+ this->ShowWidget(ORDER_WIDGET_COND_VALUE);
- case WE_CLICK:
- if (w->widget[e->we.click.widget].type != WWT_DROPDOWN) HideDropDownMenu(w);
- switch (e->we.click.widget) {
- case ORDER_WIDGET_ORDER_LIST: {
- ResetObjectToPlace();
+ OrderConditionVariable ocv = order->GetConditionVariable();
+ this->SetWidgetDisabledState(ORDER_WIDGET_COND_COMPARATOR, ocv == OCV_UNCONDITIONALLY);
+ this->SetWidgetDisabledState(ORDER_WIDGET_COND_VALUE, ocv == OCV_REQUIRES_SERVICE || ocv == OCV_UNCONDITIONALLY);
- int sel = GetOrderFromOrderWndPt(w, e->we.click.pt.y, v);
+ uint value = order->GetConditionValue();
+ if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value);
+ SetDParam(1, value);
+ } break;
- if (sel == INVALID_ORDER) {
- /* This was a click on an empty part of the orders window, so
- * deselect the currently selected order. */
- WP(w, order_d).sel = -1;
- w->SetDirty();
- return;
- }
+ default: // every other orders
+ this->DisableWidget(ORDER_WIDGET_NON_STOP);
+ this->DisableWidget(ORDER_WIDGET_FULL_LOAD);
+ this->DisableWidget(ORDER_WIDGET_UNLOAD);
+ }
+ }
- if (_ctrl_pressed && sel < v->num_orders) {
- const Order *ord = GetVehicleOrder(v, sel);
- TileIndex xy;
+ SetDParam(0, this->vehicle->index);
+ DrawWindowWidgets(this);
- switch (ord->GetType()) {
- case OT_GOTO_STATION: xy = GetStation(ord->GetDestination())->xy ; break;
- case OT_GOTO_DEPOT: xy = (v->type == VEH_AIRCRAFT) ? GetStation(ord->GetDestination())->xy : GetDepot(ord->GetDestination())->xy; break;
- case OT_GOTO_WAYPOINT: xy = GetWaypoint(ord->GetDestination())->xy; break;
- default: xy = 0; break;
- }
+ int y = 15;
- if (xy != 0) ScrollMainWindowToTile(xy);
- return;
- } else {
- if (sel == WP(w, order_d).sel) {
- /* Deselect clicked order */
- WP(w, order_d).sel = -1;
- } else {
- /* Select clicked order */
- WP(w, order_d).sel = sel;
-
- if (v->owner == _local_player) {
- /* Activate drag and drop */
- SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, VHM_DRAG, w);
- }
- }
- }
+ int i = this->vscroll.pos;
+ order = GetVehicleOrder(this->vehicle, i);
+ StringID str;
+ while (order != NULL) {
+ /* Don't draw anything if it extends past the end of the window. */
+ if (i - this->vscroll.pos >= this->vscroll.cap) break;
- w->SetDirty();
- } break;
+ DrawOrderString(this->vehicle, order, i, y, i == this->selected_order, false);
+ y += 10;
- case ORDER_WIDGET_SKIP:
- OrderClick_Skip(w, v, 0);
- break;
+ i++;
+ order = order->next;
+ }
- case ORDER_WIDGET_DELETE:
- OrderClick_Delete(w, v, 0);
- break;
+ if (i - this->vscroll.pos < this->vscroll.cap) {
+ str = shared_orders ? STR_END_OF_SHARED_ORDERS : STR_882A_END_OF_ORDERS;
+ DrawString(2, y, str, (i == this->selected_order) ? TC_WHITE : TC_BLACK);
+ }
+ }
- case ORDER_WIDGET_NON_STOP: {
- const Order *o = GetVehicleOrder(v, OrderGetSel(w));
- ShowDropDownMenu(w, _order_non_stop_drowdown, o->GetNonStopType(), ORDER_WIDGET_NON_STOP, 0, o->IsType(OT_GOTO_STATION) ? 0 : (o->IsType(OT_GOTO_WAYPOINT) ? 3 : 12));
- } break;
+ virtual void OnClick(Point pt, int widget)
+ {
+ if (this->widget[widget].type != WWT_DROPDOWN) HideDropDownMenu(this);
+ switch (widget) {
+ case ORDER_WIDGET_ORDER_LIST: {
+ ResetObjectToPlace();
+
+ int sel = this->GetOrderFromPt(pt.y);
+
+ if (sel == INVALID_ORDER) {
+ /* This was a click on an empty part of the orders window, so
+ * deselect the currently selected order. */
+ this->selected_order = -1;
+ this->SetDirty();
+ return;
+ }
- case ORDER_WIDGET_GOTO:
- OrderClick_Goto(w, v, 0);
- break;
+ if (_ctrl_pressed && sel < this->vehicle->num_orders) {
+ const Order *ord = GetVehicleOrder(this->vehicle, sel);
+ TileIndex xy;
- case ORDER_WIDGET_GOTO_DROPDOWN:
- ShowDropDownMenu(w, v->type == VEH_AIRCRAFT ? _order_goto_dropdown_aircraft : _order_goto_dropdown, 0, ORDER_WIDGET_GOTO, 0, 0, w->widget[ORDER_WIDGET_GOTO_DROPDOWN].right - w->widget[ORDER_WIDGET_GOTO].left);
- break;
+ switch (ord->GetType()) {
+ case OT_GOTO_STATION: xy = GetStation(ord->GetDestination())->xy ; break;
+ case OT_GOTO_DEPOT: xy = (this->vehicle->type == VEH_AIRCRAFT) ? GetStation(ord->GetDestination())->xy : GetDepot(ord->GetDestination())->xy; break;
+ case OT_GOTO_WAYPOINT: xy = GetWaypoint(ord->GetDestination())->xy; break;
+ default: xy = 0; break;
+ }
- case ORDER_WIDGET_FULL_LOAD:
- ShowDropDownMenu(w, _order_full_load_drowdown, GetVehicleOrder(v, OrderGetSel(w))->GetLoadType(), ORDER_WIDGET_FULL_LOAD, 0, 2);
- break;
+ if (xy != 0) ScrollMainWindowToTile(xy);
+ return;
+ } else {
+ if (sel == this->selected_order) {
+ /* Deselect clicked order */
+ this->selected_order = -1;
+ } else {
+ /* Select clicked order */
+ this->selected_order = sel;
- case ORDER_WIDGET_UNLOAD:
- ShowDropDownMenu(w, _order_unload_drowdown, GetVehicleOrder(v, OrderGetSel(w))->GetUnloadType(), ORDER_WIDGET_UNLOAD, 0, 8);
- break;
+ if (this->vehicle->owner == _local_player) {
+ /* Activate drag and drop */
+ SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, VHM_DRAG, this);
+ }
+ }
+ }
- case ORDER_WIDGET_REFIT:
- OrderClick_Refit(w, v, 0);
- break;
+ this->SetDirty();
+ } break;
- case ORDER_WIDGET_SERVICE:
- OrderClick_Service(w, v, 0);
- break;
+ case ORDER_WIDGET_SKIP:
+ OrderClick_Skip(this, 0);
+ break;
- case ORDER_WIDGET_TIMETABLE_VIEW:
- ShowTimetableWindow(v);
- break;
+ case ORDER_WIDGET_DELETE:
+ OrderClick_Delete(this, 0);
+ break;
- case ORDER_WIDGET_COND_VARIABLE:
- ShowDropDownMenu(w, _order_conditional_variable, GetVehicleOrder(v, OrderGetSel(w))->GetConditionVariable(), ORDER_WIDGET_COND_VARIABLE, 0, 0);
- break;
+ case ORDER_WIDGET_NON_STOP: {
+ const Order *o = GetVehicleOrder(this->vehicle, this->OrderGetSel());
+ ShowDropDownMenu(this, _order_non_stop_drowdown, o->GetNonStopType(), ORDER_WIDGET_NON_STOP, 0, o->IsType(OT_GOTO_STATION) ? 0 : (o->IsType(OT_GOTO_WAYPOINT) ? 3 : 12));
+ } break;
- case ORDER_WIDGET_COND_COMPARATOR: {
- const Order *o = GetVehicleOrder(v, OrderGetSel(w));
- ShowDropDownMenu(w, _order_conditional_condition, o->GetConditionComparator(), ORDER_WIDGET_COND_COMPARATOR, 0, (o->GetConditionVariable() == OCV_REQUIRES_SERVICE) ? 0x3F : 0xC0);
- } break;
+ case ORDER_WIDGET_GOTO:
+ OrderClick_Goto(this, 0);
+ break;
- case ORDER_WIDGET_COND_VALUE: {
- const Order *order = GetVehicleOrder(v, OrderGetSel(w));
- uint value = order->GetConditionValue();
- if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value);
- SetDParam(0, value);
- ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_ORDER_CONDITIONAL_VALUE_CAPT, 5, 100, w, CS_NUMERAL);
- } break;
+ case ORDER_WIDGET_GOTO_DROPDOWN:
+ ShowDropDownMenu(this, this->vehicle->type == VEH_AIRCRAFT ? _order_goto_dropdown_aircraft : _order_goto_dropdown, 0, ORDER_WIDGET_GOTO, 0, 0, this->widget[ORDER_WIDGET_GOTO_DROPDOWN].right - this->widget[ORDER_WIDGET_GOTO].left);
+ break;
- case ORDER_WIDGET_SHARED_ORDER_LIST:
- ShowVehicleListWindow(v);
- break;
- }
- break;
+ case ORDER_WIDGET_FULL_LOAD:
+ ShowDropDownMenu(this, _order_full_load_drowdown, GetVehicleOrder(this->vehicle, this->OrderGetSel())->GetLoadType(), ORDER_WIDGET_FULL_LOAD, 0, 2);
+ break;
- case WE_ON_EDIT_TEXT:
- if (!StrEmpty(e->we.edittext.str)) {
- VehicleOrderID sel = OrderGetSel(w);
- uint value = atoi(e->we.edittext.str);
+ case ORDER_WIDGET_UNLOAD:
+ ShowDropDownMenu(this, _order_unload_drowdown, GetVehicleOrder(this->vehicle, this->OrderGetSel())->GetUnloadType(), ORDER_WIDGET_UNLOAD, 0, 8);
+ break;
- switch (GetVehicleOrder(v, sel)->GetConditionVariable()) {
- case OCV_MAX_SPEED:
- value = ConvertDisplaySpeedToSpeed(value);
- break;
+ case ORDER_WIDGET_REFIT:
+ OrderClick_Refit(this, 0);
+ break;
- case OCV_RELIABILITY:
- case OCV_LOAD_PERCENTAGE:
- value = Clamp(value, 0, 100);
+ case ORDER_WIDGET_SERVICE:
+ OrderClick_Service(this, 0);
+ break;
- default:
- break;
- }
- DoCommandP(v->tile, v->index + (sel << 16), MOF_COND_VALUE | Clamp(value, 0, 2047) << 4, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
- }
- break;
+ case ORDER_WIDGET_TIMETABLE_VIEW:
+ ShowTimetableWindow(this->vehicle);
+ break;
- case WE_DROPDOWN_SELECT: // we have selected a dropdown item in the list
- switch (e->we.dropdown.button) {
- case ORDER_WIDGET_NON_STOP:
- OrderClick_Nonstop(w, v, e->we.dropdown.index);
- break;
+ case ORDER_WIDGET_COND_VARIABLE:
+ ShowDropDownMenu(this, _order_conditional_variable, GetVehicleOrder(this->vehicle, this->OrderGetSel())->GetConditionVariable(), ORDER_WIDGET_COND_VARIABLE, 0, 0);
+ break;
- case ORDER_WIDGET_FULL_LOAD:
- OrderClick_FullLoad(w, v, e->we.dropdown.index);
- break;
+ case ORDER_WIDGET_COND_COMPARATOR: {
+ const Order *o = GetVehicleOrder(this->vehicle, this->OrderGetSel());
+ ShowDropDownMenu(this, _order_conditional_condition, o->GetConditionComparator(), ORDER_WIDGET_COND_COMPARATOR, 0, (o->GetConditionVariable() == OCV_REQUIRES_SERVICE) ? 0x3F : 0xC0);
+ } break;
- case ORDER_WIDGET_UNLOAD:
- OrderClick_Unload(w, v, e->we.dropdown.index);
- break;
+ case ORDER_WIDGET_COND_VALUE: {
+ const Order *order = GetVehicleOrder(this->vehicle, this->OrderGetSel());
+ uint value = order->GetConditionValue();
+ if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value);
+ SetDParam(0, value);
+ ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_ORDER_CONDITIONAL_VALUE_CAPT, 5, 100, this, CS_NUMERAL);
+ } break;
- case ORDER_WIDGET_GOTO:
- switch (e->we.dropdown.index) {
- case 0:
- w->ToggleWidgetLoweredState(ORDER_WIDGET_GOTO);
- OrderClick_Goto(w, v, 0);
- break;
+ case ORDER_WIDGET_SHARED_ORDER_LIST:
+ ShowVehicleListWindow(this->vehicle);
+ break;
+ }
+ }
- case 1: OrderClick_NearestDepot(w, v, 0); break;
- case 2: OrderClick_Conditional(w, v, 0); break;
- default: NOT_REACHED();
- }
- break;
+ virtual void OnQueryTextFinished(char *str)
+ {
+ if (!StrEmpty(str)) {
+ VehicleOrderID sel = this->OrderGetSel();
+ uint value = atoi(str);
- case ORDER_WIDGET_COND_VARIABLE:
- DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), MOF_COND_VARIABLE | e->we.dropdown.index << 4, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
+ switch (GetVehicleOrder(this->vehicle, sel)->GetConditionVariable()) {
+ case OCV_MAX_SPEED:
+ value = ConvertDisplaySpeedToSpeed(value);
break;
- case ORDER_WIDGET_COND_COMPARATOR:
- DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), MOF_COND_COMPARATOR | e->we.dropdown.index << 4, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
+ case OCV_RELIABILITY:
+ case OCV_LOAD_PERCENTAGE:
+ value = Clamp(value, 0, 100);
+
+ default:
break;
}
- break;
+ DoCommandP(this->vehicle->tile, this->vehicle->index + (sel << 16), MOF_COND_VALUE | Clamp(value, 0, 2047) << 4, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
+ }
+ }
- case WE_DRAGDROP:
- switch (e->we.click.widget) {
- case ORDER_WIDGET_ORDER_LIST: {
- int from_order = OrderGetSel(w);
- int to_order = GetOrderFromOrderWndPt(w, e->we.dragdrop.pt.y, v);
+ virtual void OnDropdownSelect(int widget, int index)
+ {
+ switch (widget) {
+ case ORDER_WIDGET_NON_STOP:
+ OrderClick_Nonstop(this, index);
+ break;
- if (!(from_order == to_order || from_order == INVALID_ORDER || from_order > v->num_orders || to_order == INVALID_ORDER || to_order > v->num_orders) &&
- DoCommandP(v->tile, v->index, from_order | (to_order << 16), NULL, CMD_MOVE_ORDER | CMD_MSG(STR_CAN_T_MOVE_THIS_ORDER))) {
- WP(w, order_d).sel = -1;
- }
+ case ORDER_WIDGET_FULL_LOAD:
+ OrderClick_FullLoad(this, index);
+ break;
- } break;
+ case ORDER_WIDGET_UNLOAD:
+ OrderClick_Unload(this, index);
+ break;
- case ORDER_WIDGET_DELETE:
- OrderClick_Delete(w, v, 0);
- break;
- }
+ case ORDER_WIDGET_GOTO:
+ switch (index) {
+ case 0:
+ this->ToggleWidgetLoweredState(ORDER_WIDGET_GOTO);
+ OrderClick_Goto(this, 0);
+ break;
- ResetObjectToPlace();
- break;
+ case 1: OrderClick_NearestDepot(this, 0); break;
+ case 2: OrderClick_Conditional(this, 0); break;
+ default: NOT_REACHED();
+ }
+ break;
- case WE_KEYPRESS:
- if (v->owner != _local_player) break;
+ case ORDER_WIDGET_COND_VARIABLE:
+ DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 16), MOF_COND_VARIABLE | index << 4, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
+ break;
- for (uint i = 0; i < lengthof(_order_keycodes); i++) {
- if (e->we.keypress.keycode == _order_keycodes[i]) {
- e->we.keypress.cont = false;
- /* see if the button is disabled */
- if (!w->IsWidgetDisabled(i + ORDER_WIDGET_SKIP)) _order_button_proc[i](w, v, -1);
- break;
+ case ORDER_WIDGET_COND_COMPARATOR:
+ DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 16), MOF_COND_COMPARATOR | index << 4, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
+ break;
+ }
+ }
+
+ virtual void OnDragDrop(Point pt, int widget)
+ {
+ switch (widget) {
+ case ORDER_WIDGET_ORDER_LIST: {
+ int from_order = this->OrderGetSel();
+ int to_order = this->GetOrderFromPt(pt.y);
+
+ if (!(from_order == to_order || from_order == INVALID_ORDER || from_order > this->vehicle->num_orders || to_order == INVALID_ORDER || to_order > this->vehicle->num_orders) &&
+ DoCommandP(this->vehicle->tile, this->vehicle->index, from_order | (to_order << 16), NULL, CMD_MOVE_ORDER | CMD_MSG(STR_CAN_T_MOVE_THIS_ORDER))) {
+ this->selected_order = -1;
}
+ } break;
+
+ case ORDER_WIDGET_DELETE:
+ OrderClick_Delete(this, 0);
+ break;
+ }
+
+ ResetObjectToPlace();
+ }
+
+ virtual bool OnKeyPress(uint16 key, uint16 keycode)
+ {
+ static const KeyToEvent keytoevent[] = {
+ {'D', OrderClick_Skip},
+ {'F', OrderClick_Delete},
+ {'G', OrderClick_Goto},
+ {'H', OrderClick_Nonstop},
+ {'J', OrderClick_FullLoad},
+ {'K', OrderClick_Unload},
+ //{'?', OrderClick_Transfer},
+ //('?', OrderClick_Service},
+ };
+
+ if (this->vehicle->owner != _local_player) return true;
+
+ for (uint i = 0; i < lengthof(keytoevent); i++) {
+ if (keycode == keytoevent[i].keycode) {
+ keytoevent[i].proc(this, -1);
+ return false;
}
- break;
+ }
+ return true;
+ }
- case WE_PLACE_OBJ:
- if (WP(w, order_d).goto_type == OPOS_GOTO) {
- OrdersPlaceObj(GetVehicle(w->window_number), e->we.place.tile, w);
+ virtual void OnPlaceObject(Point pt, TileIndex tile)
+ {
+ if (this->goto_type == OPOS_GOTO) {
+ /* check if we're clicking on a vehicle first.. clone orders in that case. */
+ const Vehicle *v = CheckMouseOverVehicle();
+ if (v != NULL && this->HandleOrderVehClick(v)) return;
+
+ const Order cmd = GetOrderCmdFromTile(this->vehicle, tile);
+ if (!cmd.IsValid()) return;
+
+ if (DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 16), cmd.Pack(), NULL, CMD_INSERT_ORDER | CMD_MSG(STR_8833_CAN_T_INSERT_NEW_ORDER))) {
+ if (this->selected_order != -1) this->selected_order++;
+ ResetObjectToPlace();
}
- break;
+ }
+ }
- case WE_ABORT_PLACE_OBJ:
- if (WP(w, order_d).goto_type == OPOS_CONDITIONAL) {
- WP(w, order_d).goto_type = OPOS_GOTO;
- if (_cursor.pos.x >= (w->left + w->widget[ORDER_WIDGET_ORDER_LIST].left) &&
- _cursor.pos.y >= (w->top + w->widget[ORDER_WIDGET_ORDER_LIST].top) &&
- _cursor.pos.x <= (w->left + w->widget[ORDER_WIDGET_ORDER_LIST].right) &&
- _cursor.pos.y <= (w->top + w->widget[ORDER_WIDGET_ORDER_LIST].bottom)) {
- int order_id = GetOrderFromOrderWndPt(w, _cursor.pos.y - w->top, v);
- if (order_id != INVALID_ORDER) {
- Order order;
- order.next = NULL;
- order.index = 0;
- order.MakeConditional(order_id);
-
- DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), order.Pack(), NULL, CMD_INSERT_ORDER | CMD_MSG(STR_8833_CAN_T_INSERT_NEW_ORDER));
- }
+ virtual void OnPlaceObjectAbort()
+ {
+ if (this->goto_type == OPOS_CONDITIONAL) {
+ this->goto_type = OPOS_GOTO;
+ if (_cursor.pos.x >= (this->left + this->widget[ORDER_WIDGET_ORDER_LIST].left) &&
+ _cursor.pos.y >= (this->top + this->widget[ORDER_WIDGET_ORDER_LIST].top) &&
+ _cursor.pos.x <= (this->left + this->widget[ORDER_WIDGET_ORDER_LIST].right) &&
+ _cursor.pos.y <= (this->top + this->widget[ORDER_WIDGET_ORDER_LIST].bottom)) {
+ int order_id = this->GetOrderFromPt(_cursor.pos.y - this->top);
+ if (order_id != INVALID_ORDER) {
+ Order order;
+ order.next = NULL;
+ order.index = 0;
+ order.MakeConditional(order_id);
+
+ DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 16), order.Pack(), NULL, CMD_INSERT_ORDER | CMD_MSG(STR_8833_CAN_T_INSERT_NEW_ORDER));
}
}
- w->RaiseWidget(ORDER_WIDGET_GOTO);
- w->InvalidateWidget(ORDER_WIDGET_GOTO);
- break;
+ }
+ this->RaiseWidget(ORDER_WIDGET_GOTO);
+ this->InvalidateWidget(ORDER_WIDGET_GOTO);
+ }
- /* check if a vehicle in a depot was clicked.. */
- case WE_MOUSELOOP:
- v = _place_clicked_vehicle;
- /*
- * Check if we clicked on a vehicle
- * and if the GOTO button of this window is pressed
- * This is because of all open order windows WE_MOUSELOOP is called
- * and if you have 3 windows open, and this check is not done
- * the order is copied to the last open window instead of the
- * one where GOTO is enabled
- */
- if (v != NULL && w->IsWidgetLowered(ORDER_WIDGET_GOTO)) {
- _place_clicked_vehicle = NULL;
- HandleOrderVehClick(GetVehicle(w->window_number), v, w);
- }
- break;
+ virtual void OnMouseLoop()
+ {
+ const Vehicle *v = _place_clicked_vehicle;
+ /*
+ * Check if we clicked on a vehicle
+ * and if the GOTO button of this window is pressed
+ * This is because of all open order windows WE_MOUSELOOP is called
+ * and if you have 3 windows open, and this check is not done
+ * the order is copied to the last open window instead of the
+ * one where GOTO is enabled
+ */
+ if (v != NULL && this->IsWidgetLowered(ORDER_WIDGET_GOTO)) {
+ _place_clicked_vehicle = NULL;
+ this->HandleOrderVehClick(v);
+ }
+ }
- case WE_RESIZE:
- /* Update the scroll + matrix */
- w->vscroll.cap = (w->widget[ORDER_WIDGET_ORDER_LIST].bottom - w->widget[ORDER_WIDGET_ORDER_LIST].top) / 10;
- break;
+ virtual void OnResize(Point new_size, Point delta)
+ {
+ /* Update the scroll + matrix */
+ this->vscroll.cap = (this->widget[ORDER_WIDGET_ORDER_LIST].bottom - this->widget[ORDER_WIDGET_ORDER_LIST].top) / 10;
+ }
- case WE_TIMEOUT: // handle button unclick ourselves...
- /* unclick all buttons except for the 'goto' button (ORDER_WIDGET_GOTO), which is 'persistent' */
- for (uint i = 0; i < w->widget_count; i++) {
- if (w->IsWidgetLowered(i) && i != ORDER_WIDGET_GOTO) {
- w->RaiseWidget(i);
- w->InvalidateWidget(i);
- }
+ virtual void OnTimeout()
+ {
+ /* unclick all buttons except for the 'goto' button (ORDER_WIDGET_GOTO), which is 'persistent' */
+ for (uint i = 0; i < this->widget_count; i++) {
+ if (this->IsWidgetLowered(i) && i != ORDER_WIDGET_GOTO) {
+ this->RaiseWidget(i);
+ this->InvalidateWidget(i);
}
- break;
+ }
}
-}
+};
/**
* Widget definition for player train orders
@@ -1091,7 +1063,7 @@ static const WindowDesc _orders_train_desc = {
WC_VEHICLE_ORDERS, WC_VEHICLE_VIEW,
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_RESIZABLE,
_orders_train_widgets,
- OrdersWndProc
+ NULL
};
/**
@@ -1132,7 +1104,7 @@ static const WindowDesc _orders_desc = {
WC_VEHICLE_ORDERS, WC_VEHICLE_VIEW,
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_RESIZABLE,
_orders_widgets,
- OrdersWndProc
+ NULL
};
/**
@@ -1173,27 +1145,19 @@ static const WindowDesc _other_orders_desc = {
WC_VEHICLE_ORDERS, WC_VEHICLE_VIEW,
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
_other_orders_widgets,
- OrdersWndProc
+ NULL
};
void ShowOrdersWindow(const Vehicle *v)
{
- Window *w;
VehicleID veh = v->index;
DeleteWindowById(WC_VEHICLE_ORDERS, veh);
DeleteWindowById(WC_VEHICLE_DETAILS, veh);
if (v->owner != _local_player) {
- w = AllocateWindowDescFront<Window>(&_other_orders_desc, veh);
+ new OrdersWindow(&_other_orders_desc, v);
} else {
- w = AllocateWindowDescFront<Window>((v->type == VEH_TRAIN || v->type == VEH_ROAD) ? &_orders_train_desc : &_orders_desc, veh);
- }
-
- if (w != NULL) {
- w->caption_color = v->owner;
- w->vscroll.cap = 6;
- w->resize.step_height = 10;
- WP(w, order_d).sel = -1;
+ new OrdersWindow((v->type == VEH_TRAIN || v->type == VEH_ROAD) ? &_orders_train_desc : &_orders_desc, v);
}
}