summaryrefslogtreecommitdiff
path: root/train_gui.c
diff options
context:
space:
mode:
authorbjarni <bjarni@openttd.org>2006-09-26 16:47:51 +0000
committerbjarni <bjarni@openttd.org>2006-09-26 16:47:51 +0000
commitf7769e885e1a928018a9be33553a887cb00babf7 (patch)
tree381d620a928fbc6c40266c4078ae71959a878f36 /train_gui.c
parent65a3777a403f1c3eb0f2856bf0b0073b4c83fad9 (diff)
downloadopenttd-f7769e885e1a928018a9be33553a887cb00babf7.tar.xz
(svn r6513) -Codechange: unified the code to draw depot windows
This change is intended to make it easier to make depot behaviour consistent and faster to code when adding more features in the future The user interface should hopefully not be affected by this
Diffstat (limited to 'train_gui.c')
-rw-r--r--train_gui.c412
1 files changed, 1 insertions, 411 deletions
diff --git a/train_gui.c b/train_gui.c
index c097857d2..8866bf2be 100644
--- a/train_gui.c
+++ b/train_gui.c
@@ -349,7 +349,7 @@ void ShowBuildTrainWindow(TileIndex tile)
* @param len Length measured in 1/8ths of a standard wagon.
* @return Number of pixels across.
*/
-static int WagonLengthToPixels(int len) {
+int WagonLengthToPixels(int len) {
return (len * _traininfo_vehicle_width) / 8;
}
@@ -396,416 +396,6 @@ void DrawTrainImage(const Vehicle *v, int x, int y, int count, int skip, Vehicle
_cur_dpi = old_dpi;
}
-static void DrawTrainDepotWindow(Window *w)
-{
- Vehicle **vl = WP(w, traindepot_d).vehicle_list;
- TileIndex tile;
- int x, y, i, hnum, max;
- Depot *depot;
- uint16 num;
-
- tile = w->window_number;
-
- /* setup disabled buttons */
- w->disabled_state =
- IsTileOwner(tile, _local_player) ? 0 : ((1 << 4) | (1 << 5) | (1 << 8) | (1<<9));
-
- /* determine amount of items for scroller */
- hnum = 8;
- for (num = 0; num < WP(w, traindepot_d).engine_count; num++) {
- const Vehicle *v = vl[num];
- hnum = maxu(hnum, v->u.rail.cached_total_length);
- }
-
- /* Always have 1 empty row, so people can change the setting of the train */
- SetVScrollCount(w, WP(w, traindepot_d).engine_count + WP(w, traindepot_d).wagon_count + 1);
- SetHScrollCount(w, WagonLengthToPixels(hnum));
-
- /* locate the depot struct */
- depot = GetDepotByTile(tile);
- assert(depot != NULL);
-
- SetDParam(0, depot->town_index);
- DrawWindowWidgets(w);
-
- x = 2;
- y = 15;
- num = w->vscroll.pos;
- max = min(WP(w, traindepot_d).engine_count, w->vscroll.pos + w->vscroll.cap);
-
-
- /* draw all trains */
- for (; num < max; num++) {
- const Vehicle *v = vl[num];
-
- DrawTrainImage(v, x + 21, y, w->hscroll.cap + 4, w->hscroll.pos, WP(w,traindepot_d).sel);
- /* Draw the train number */
- SetDParam(0, v->unitnumber);
- DrawString(x, y, (v->max_age - 366 < v->age) ? STR_00E3 : STR_00E2, 0);
-
- /* Number of wagons relative to a standard length wagon (rounded up) */
- SetDParam(0, (v->u.rail.cached_total_length + 7) / 8);
- DrawStringRightAligned(w->widget[6].right - 1, y + 4, STR_TINY_BLACK, 0); // Draw the counter
-
- /* Draw the pretty flag */
- DrawSprite(v->vehstatus & VS_STOPPED ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, x + 15, y);
-
- y += 14;
- }
-
- max = min(WP(w, traindepot_d).engine_count + WP(w, traindepot_d).wagon_count, w->vscroll.pos + w->vscroll.cap);
-
- /* draw all remaining vehicles */
- for (; num < max; num++) {
- const Vehicle *v = WP(w, traindepot_d).wagon_list[num - WP(w, traindepot_d).engine_count];
- const Vehicle *u;
-
- DrawTrainImage(v, x + 50, y, w->hscroll.cap - 29, 0, WP(w,traindepot_d).sel);
- DrawString(x, y + 2, STR_8816, 0);
-
- /*Draw the train counter */
- i = 0;
- u = v;
- do i++; while ( (u=u->next) != NULL); // Determine length of train
- SetDParam(0, i); // Set the counter
- DrawStringRightAligned(w->widget[6].right - 1, y + 4, STR_TINY_BLACK, 0); // Draw the counter
- y += 14;
- }
-}
-
-typedef struct GetDepotVehiclePtData {
- Vehicle *head;
- Vehicle *wagon;
-} GetDepotVehiclePtData;
-
-static int GetVehicleFromTrainDepotWndPt(const Window *w, int x, int y, GetDepotVehiclePtData *d)
-{
- Vehicle **vl = WP(w, traindepot_d).vehicle_list;
- int row;
- int skip = 0;
- Vehicle *v;
-
- x = x - 23;
-
- row = (y - 14) / 14;
- if ((uint)row >= w->vscroll.cap) return 1; /* means err */
-
- row += w->vscroll.pos;
-
- if (WP(w, traindepot_d).engine_count + WP(w, traindepot_d).wagon_count <= row) {
- /* empty row, so no vehicle is selected */
- d->head = NULL;
- d->wagon = NULL;
- return 0;
- }
-
- if (WP(w, traindepot_d).engine_count > row) {
- v = vl[row];
- skip = w->hscroll.pos;
- } else {
- vl = WP(w, traindepot_d).wagon_list;
- v = vl[row - WP(w, traindepot_d).engine_count];
- /* free wagons don't have an initial loco. */
- x -= _traininfo_vehicle_width;
- }
-
- d->head = d->wagon = v;
-
- /* either pressed the flag or the number, but only when it's a loco */
- if (x < 0 && IsFrontEngine(v)) return (x >= -10) ? -2 : -1;
-
- skip = (skip * 8) / _traininfo_vehicle_width;
- x = (x * 8) / _traininfo_vehicle_width;
-
- /* Skip vehicles that are scrolled off the list */
- x += skip;
-
- /* find the vehicle in this row that was clicked */
- while (v != NULL && (x -= v->u.rail.cached_veh_length) >= 0) v = v->next;
-
- // if an articulated part was selected, find its parent
- while (v != NULL && IsArticulatedPart(v)) v = GetPrevVehicleInChain(v);
-
- d->wagon = v;
-
- return 0;
-}
-
-static void TrainDepotMoveVehicle(Vehicle *wagon, VehicleID sel, Vehicle *head)
-{
- Vehicle *v;
-
- v = GetVehicle(sel);
-
- if (v == wagon) return;
-
- if (wagon == NULL) {
- if (head != NULL) wagon = GetLastVehicleInChain(head);
- } else {
- wagon = GetPrevVehicleInChain(wagon);
- if (wagon == NULL) return;
- }
-
- if (wagon == v) return;
-
- DoCommandP(v->tile, v->index + ((wagon == NULL ? INVALID_VEHICLE : wagon->index) << 16), _ctrl_pressed ? 1 : 0, NULL, CMD_MOVE_RAIL_VEHICLE | CMD_MSG(STR_8837_CAN_T_MOVE_VEHICLE));
-}
-
-static void TrainDepotClickTrain(Window *w, int x, int y)
-{
- GetDepotVehiclePtData gdvp;
- int mode;
- Vehicle *v;
-
- mode = GetVehicleFromTrainDepotWndPt(w, x, y, &gdvp);
-
- // share / copy orders
- if (_thd.place_mode && mode <= 0) {
- _place_clicked_vehicle = gdvp.head;
- return;
- }
-
- v = gdvp.wagon;
-
- switch (mode) {
- case 0: { // start dragging of vehicle
- VehicleID sel = WP(w, traindepot_d).sel;
-
- if (sel != INVALID_VEHICLE) {
- WP(w,traindepot_d).sel = INVALID_VEHICLE;
- TrainDepotMoveVehicle(v, sel, gdvp.head);
- } else if (v != NULL) {
- WP(w,traindepot_d).sel = v->index;
- SetObjectToPlaceWnd(GetVehiclePalette(v) | GetTrainImage(v, DIR_W), 4, w);
- SetWindowDirty(w);
- }
- break;
- }
-
- case -1: // show info window
- ShowTrainViewWindow(v);
- break;
-
- case -2: // click start/stop flag
- DoCommandP(v->tile, v->index, 0, NULL, CMD_START_STOP_TRAIN | CMD_MSG(STR_883B_CAN_T_STOP_START_TRAIN));
- break;
- }
-}
-
-/**
- * Clones a train
- * @param *v is the original vehicle to clone
- * @param *w is the window of the depot where the clone is build
- */
-static void HandleCloneVehClick(const Vehicle *v, const Window *w)
-{
- if (v == NULL || v->type != VEH_Train) return;
-
- // for train vehicles: subtype 0 for locs and not zero for others
- if (!IsFrontEngine(v)) {
- v = GetFirstVehicleInChain(v);
- // Do nothing when clicking on a train in depot with no loc attached
- if (!IsFrontEngine(v)) return;
- }
-
- DoCommandP(w->window_number, v->index, _ctrl_pressed ? 1 : 0, CcCloneTrain,
- CMD_CLONE_VEHICLE | CMD_MSG(STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE)
- );
-
- ResetObjectToPlace();
-}
-
-static void ClonePlaceObj(const Window *w)
-{
- Vehicle *v = CheckMouseOverVehicle();
-
- if (v != NULL) HandleCloneVehClick(v, w);
-}
-
-static void TrainDepotWndProc(Window *w, WindowEvent *e)
-{
- switch (e->event) {
- case WE_CREATE:
- WP(w, traindepot_d).vehicle_list = NULL;
- WP(w, traindepot_d).wagon_list = NULL;
- WP(w, traindepot_d).engine_count = 0;
- WP(w, traindepot_d).wagon_count = 0;
- break;
-
- case WE_PAINT:
- BuildDepotVehicleList(VEH_Train, w->window_number, &WP(w, traindepot_d).vehicle_list, &WP(w, traindepot_d).engine_list_length, &WP(w, traindepot_d).engine_count,
- &WP(w, traindepot_d).wagon_list, &WP(w, traindepot_d).wagon_list_length, &WP(w, traindepot_d).wagon_count);
- DrawTrainDepotWindow(w);
- break;
-
- case WE_CLICK: {
- switch (e->we.click.widget) {
- case 8:
- ResetObjectToPlace();
- ShowBuildTrainWindow(w->window_number);
- break;
-
- case 10: ScrollMainWindowToTile(w->window_number); break;
-
- case 6:
- TrainDepotClickTrain(w, e->we.click.pt.x, e->we.click.pt.y);
- break;
- case 9: /* clone button */
- InvalidateWidget(w, 9);
- TOGGLEBIT(w->click_state, 9);
-
- if (HASBIT(w->click_state, 9)) {
- _place_clicked_vehicle = NULL;
- SetObjectToPlaceWnd(SPR_CURSOR_CLONE, VHM_RECT, w);
- } else {
- ResetObjectToPlace();
- }
- break;
-
- }
- } break;
-
- case WE_PLACE_OBJ:
- ClonePlaceObj(w);
- break;
-
- case WE_ABORT_PLACE_OBJ:
- CLRBIT(w->click_state, 9);
- InvalidateWidget(w, 9);
- break;
-
- // check if a vehicle in a depot was clicked..
- case WE_MOUSELOOP: {
- const Vehicle *v = _place_clicked_vehicle;
-
- // since OTTD checks all open depot windows, we will make sure that it triggers the one with a clicked clone button
- if (v != NULL && HASBIT(w->click_state, 9)) {
- _place_clicked_vehicle = NULL;
- HandleCloneVehClick(v, w);
- }
- } break;
-
-
- case WE_DESTROY:
- DeleteWindowById(WC_BUILD_VEHICLE, w->window_number);
- free((void*)WP(w, traindepot_d).vehicle_list);
- free((void*)WP(w, traindepot_d).wagon_list);
- break;
-
- case WE_DRAGDROP: {
- switch (e->we.click.widget) {
- case 4: case 5: {
- Vehicle *v;
- int sell_cmd;
-
- /* sell vehicle */
- if (w->disabled_state & (1 << e->we.click.widget))
- return;
-
- if (WP(w,traindepot_d).sel == INVALID_VEHICLE)
- return;
-
- v = GetVehicle(WP(w,traindepot_d).sel);
-
- WP(w,traindepot_d).sel = INVALID_VEHICLE;
- SetWindowDirty(w);
-
- HandleButtonClick(w, e->we.click.widget);
-
- sell_cmd = (e->we.click.widget == 5 || _ctrl_pressed) ? 1 : 0;
-
- if (!IsFrontEngine(v)) {
- DoCommandP(v->tile, v->index, sell_cmd, NULL, CMD_SELL_RAIL_WAGON | CMD_MSG(STR_8839_CAN_T_SELL_RAILROAD_VEHICLE));
- } else {
- _backup_orders_tile = v->tile;
- BackupVehicleOrders(v, _backup_orders_data);
- if (!DoCommandP(v->tile, v->index, sell_cmd, NULL, CMD_SELL_RAIL_WAGON | CMD_MSG(STR_8839_CAN_T_SELL_RAILROAD_VEHICLE)))
- _backup_orders_tile = 0;
- }
- } break;
-
- case 6: {
- GetDepotVehiclePtData gdvp;
- VehicleID sel = WP(w,traindepot_d).sel;
-
- WP(w,traindepot_d).sel = INVALID_VEHICLE;
- SetWindowDirty(w);
-
- if (GetVehicleFromTrainDepotWndPt(w, e->we.dragdrop.pt.x, e->we.dragdrop.pt.y, &gdvp) == 0 &&
- sel != INVALID_VEHICLE) {
- if (gdvp.wagon != NULL && gdvp.wagon->index == sel && _ctrl_pressed) {
- DoCommandP(GetVehicle(sel)->tile, GetVehicle(sel)->index, true, NULL, CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG(STR_9033_CAN_T_MAKE_VEHICLE_TURN));
- } else if (gdvp.wagon == NULL || gdvp.wagon->index != sel) {
- TrainDepotMoveVehicle(gdvp.wagon, sel, gdvp.head);
- } else if (gdvp.head != NULL && IsFrontEngine(gdvp.head)) {
- ShowTrainViewWindow(gdvp.head);
- }
- }
- } break;
-
- default:
- WP(w,traindepot_d).sel = INVALID_VEHICLE;
- SetWindowDirty(w);
- break;
- }
- } break;
- case WE_RESIZE: {
- /* Update the scroll + matrix */
- w->vscroll.cap += e->we.sizing.diff.y / 14;
- w->hscroll.cap += e->we.sizing.diff.x;
- w->widget[6].data = (w->vscroll.cap << 8) + 1;
- } break;
- }
-}
-
-static const Widget _train_depot_widgets[] = {
-{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
-{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 348, 0, 13, STR_8800_TRAIN_DEPOT, STR_018C_WINDOW_TITLE_DRAG_THIS},
-{ WWT_STICKYBOX, RESIZE_LR, 14, 349, 360, 0, 13, 0x0, STR_STICKY_BUTTON},
-
-{ WWT_PANEL, RESIZE_LRB, 14, 326, 348, 14, 13, 0x0, STR_NULL},
-{ WWT_PANEL, RESIZE_LRTB, 14, 326, 348, 14, 54, 0x2A9, STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE},
-{ WWT_PANEL, RESIZE_LRTB, 14, 326, 348, 55, 109, 0x2BF, STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP},
-
-{ WWT_MATRIX, RESIZE_RB, 14, 0, 325, 14, 97, 0x601, STR_883F_TRAINS_CLICK_ON_TRAIN_FOR},
-{ WWT_SCROLLBAR, RESIZE_LRB, 14, 349, 360, 14, 109, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
-{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 116, 110, 121, STR_8815_NEW_VEHICLES, STR_8840_BUILD_NEW_TRAIN_VEHICLE},
-{WWT_NODISTXTBTN, RESIZE_TB, 14, 117, 232, 110, 121, STR_CLONE_TRAIN, STR_CLONE_TRAIN_DEPOT_INFO},
-{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 233, 348, 110, 121, STR_00E4_LOCATION, STR_8842_CENTER_MAIN_VIEW_ON_TRAIN},
-
-
-{ WWT_HSCROLLBAR, RESIZE_RTB, 14, 0, 325, 98, 109, 0x0, STR_HSCROLL_BAR_SCROLLS_LIST},
-{ WWT_PANEL, RESIZE_RTB, 14, 349, 348, 110, 121, 0x0, STR_NULL},
-
-{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 349, 360, 110, 121, 0x0, STR_RESIZE_BUTTON},
-{ WIDGETS_END},
-};
-
-static const WindowDesc _train_depot_desc = {
- -1, -1, 361, 122,
- WC_VEHICLE_DEPOT,0,
- WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
- _train_depot_widgets,
- TrainDepotWndProc
-};
-
-
-void ShowTrainDepotWindow(TileIndex tile)
-{
- Window *w;
-
- w = AllocateWindowDescFront(&_train_depot_desc, tile);
- if (w) {
- w->caption_color = GetTileOwner(w->window_number);
- w->vscroll.cap = 6;
- w->hscroll.cap = 10 * 29;
- w->resize.step_width = 1;
- w->resize.step_height = 14;
- WP(w,traindepot_d).sel = INVALID_VEHICLE;
- _backup_orders_tile = 0;
- }
-}
-
static void RailVehicleRefitWndProc(Window *w, WindowEvent *e)
{
switch (e->event) {