order_gui.cpp

Go to the documentation of this file.
00001 /* $Id: order_gui.cpp 14367 2008-09-20 20:34:36Z peter1138 $ */
00002 
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "road_map.h"
00008 #include "station_map.h"
00009 #include "gui.h"
00010 #include "window_gui.h"
00011 #include "station.h"
00012 #include "town.h"
00013 #include "command_func.h"
00014 #include "viewport_func.h"
00015 #include "gfx_func.h"
00016 #include "depot.h"
00017 #include "waypoint.h"
00018 #include "train.h"
00019 #include "water_map.h"
00020 #include "vehicle_gui.h"
00021 #include "timetable.h"
00022 #include "cargotype.h"
00023 #include "order.h"
00024 #include "strings_func.h"
00025 #include "window_func.h"
00026 #include "vehicle_func.h"
00027 #include "settings_type.h"
00028 #include "player_func.h"
00029 
00030 #include "table/sprites.h"
00031 #include "table/strings.h"
00032 
00033 enum OrderWindowWidgets {
00034   ORDER_WIDGET_CLOSEBOX = 0,
00035   ORDER_WIDGET_CAPTION,
00036   ORDER_WIDGET_TIMETABLE_VIEW,
00037   ORDER_WIDGET_ORDER_LIST,
00038   ORDER_WIDGET_SCROLLBAR,
00039   ORDER_WIDGET_SKIP,
00040   ORDER_WIDGET_DELETE,
00041   ORDER_WIDGET_NON_STOP,
00042   ORDER_WIDGET_GOTO,
00043   ORDER_WIDGET_FULL_LOAD,
00044   ORDER_WIDGET_UNLOAD,
00045   ORDER_WIDGET_REFIT,
00046   ORDER_WIDGET_TRANSFER,
00047   ORDER_WIDGET_SHARED_ORDER_LIST,
00048   ORDER_WIDGET_RESIZE_BAR,
00049   ORDER_WIDGET_RESIZE,
00050 };
00051 
00059 static int OrderGetSel(const Window *w)
00060 {
00061   const Vehicle *v = GetVehicle(w->window_number);
00062   int num = WP(w, order_d).sel;
00063 
00064   return (num >= 0 && num < v->num_orders) ? num : v->num_orders;
00065 }
00066 
00078 static int GetOrderFromOrderWndPt(Window *w, int y, const Vehicle *v)
00079 {
00080   /*
00081    * Calculation description:
00082    * 15 = 14 (w->widget[ORDER_WIDGET_ORDER_LIST].top) + 1 (frame-line)
00083    * 10 = order text hight
00084    */
00085   int sel = (y - 15) / 10;
00086 
00087   if ((uint)sel >= w->vscroll.cap) return INVALID_ORDER;
00088 
00089   sel += w->vscroll.pos;
00090 
00091   return (sel <= v->num_orders && sel >= 0) ? sel : INVALID_ORDER;
00092 }
00093 
00094 static StringID StationOrderStrings[] = {
00095   STR_8806_GO_TO,
00096   STR_GO_TO_TRANSFER,
00097   STR_8807_GO_TO_UNLOAD,
00098   STR_GO_TO_TRANSFER_UNLOAD,
00099   STR_8808_GO_TO_LOAD,
00100   STR_GO_TO_TRANSFER_LOAD,
00101   STR_NULL,
00102   STR_NULL,
00103   STR_880A_GO_NON_STOP_TO,
00104   STR_GO_TO_NON_STOP_TRANSFER,
00105   STR_880B_GO_NON_STOP_TO_UNLOAD,
00106   STR_GO_TO_NON_STOP_TRANSFER_UNLOAD,
00107   STR_880C_GO_NON_STOP_TO_LOAD,
00108   STR_GO_TO_NON_STOP_TRANSFER_LOAD,
00109   STR_NULL
00110 };
00111 
00112 static void DrawOrdersWindow(Window *w)
00113 {
00114   const Vehicle *v;
00115   const Order *order;
00116   StringID str;
00117   int sel;
00118   int y, i;
00119   bool shared_orders;
00120 
00121   v = GetVehicle(w->window_number);
00122 
00123   shared_orders = v->IsOrderListShared();
00124 
00125   SetVScrollCount(w, v->num_orders + 1);
00126 
00127   sel = OrderGetSel(w);
00128   SetDParam(2, STR_8827_FULL_LOAD);
00129 
00130   order = GetVehicleOrder(v, sel);
00131 
00132   if (v->owner == _local_player) {
00133     /* skip */
00134     w->SetWidgetDisabledState(ORDER_WIDGET_SKIP, v->num_orders <= 1);
00135 
00136     /* delete */
00137     w->SetWidgetDisabledState(ORDER_WIDGET_DELETE,
00138         (uint)v->num_orders + ((shared_orders || v->num_orders != 0) ? 1 : 0) <= (uint)WP(w, order_d).sel);
00139 
00140     /* non-stop only for trains */
00141     w->SetWidgetDisabledState(ORDER_WIDGET_NON_STOP,  v->type != VEH_TRAIN || order == NULL);
00142     w->SetWidgetDisabledState(ORDER_WIDGET_FULL_LOAD, order == NULL); // full load
00143     w->SetWidgetDisabledState(ORDER_WIDGET_UNLOAD,    order == NULL); // unload
00144     w->SetWidgetDisabledState(ORDER_WIDGET_TRANSFER,  order == NULL); // transfer
00145     /* Disable list of vehicles with the same shared orders if there is no list */
00146     w->SetWidgetDisabledState(ORDER_WIDGET_SHARED_ORDER_LIST, !shared_orders || v->orders == NULL);
00147     w->SetWidgetDisabledState(ORDER_WIDGET_REFIT,     order == NULL); // Refit
00148     w->HideWidget(ORDER_WIDGET_REFIT); // Refit
00149   } else {
00150     w->DisableWidget(ORDER_WIDGET_RESIZE_BAR);
00151   }
00152 
00153   w->ShowWidget(ORDER_WIDGET_UNLOAD); // Unload
00154 
00155   if (order != NULL) {
00156     switch (order->type) {
00157       case OT_GOTO_STATION:
00158         if (!GetStation(order->dest)->IsBuoy()) break;
00159         /* Fall-through */
00160 
00161       case OT_GOTO_WAYPOINT:
00162         w->DisableWidget(ORDER_WIDGET_FULL_LOAD);
00163         w->DisableWidget(ORDER_WIDGET_UNLOAD);
00164         w->DisableWidget(ORDER_WIDGET_TRANSFER);
00165         break;
00166 
00167       case OT_GOTO_DEPOT:
00168         w->DisableWidget(ORDER_WIDGET_TRANSFER);
00169 
00170         /* Remove unload and replace it with refit */
00171         w->HideWidget(ORDER_WIDGET_UNLOAD);
00172         w->ShowWidget(ORDER_WIDGET_REFIT);
00173         SetDParam(2,STR_SERVICE);
00174         break;
00175 
00176       default: // every other orders
00177         w->DisableWidget(ORDER_WIDGET_NON_STOP);
00178         w->DisableWidget(ORDER_WIDGET_FULL_LOAD);
00179         w->DisableWidget(ORDER_WIDGET_UNLOAD);
00180     }
00181   }
00182 
00183   SetDParam(0, v->index);
00184   DrawWindowWidgets(w);
00185 
00186   y = 15;
00187 
00188   i = w->vscroll.pos;
00189   order = GetVehicleOrder(v, i);
00190   while (order != NULL) {
00191     str = (v->cur_order_index == i) ? STR_8805 : STR_8804;
00192     SetDParam(3, STR_EMPTY);
00193 
00194     if (i - w->vscroll.pos < w->vscroll.cap) {
00195       SetDParam(1, 6);
00196 
00197       switch (order->type) {
00198         case OT_DUMMY:
00199           SetDParam(1, STR_INVALID_ORDER);
00200           SetDParam(2, order->dest);
00201           break;
00202 
00203         case OT_GOTO_STATION:
00204           SetDParam(1, StationOrderStrings[order->flags]);
00205           SetDParam(2, order->dest);
00206           break;
00207 
00208         case OT_GOTO_DEPOT: {
00209           StringID s = STR_NULL;
00210 
00211           if (v->type == VEH_AIRCRAFT) {
00212             s = STR_GO_TO_AIRPORT_HANGAR;
00213             SetDParam(2, order->dest);
00214           } else {
00215             SetDParam(2, GetDepot(order->dest)->town_index);
00216 
00217             switch (v->type) {
00218               case VEH_TRAIN: s = (order->flags & OFB_NON_STOP) ? STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT : STR_GO_TO_TRAIN_DEPOT; break;
00219               case VEH_ROAD:  s = STR_GO_TO_ROADVEH_DEPOT; break;
00220               case VEH_SHIP:  s = STR_GO_TO_SHIP_DEPOT; break;
00221               default: break;
00222             }
00223           }
00224 
00225           if (order->flags & OFB_FULL_LOAD) s++; /* service at */
00226 
00227           SetDParam(1, s);
00228           if (order->refit_cargo < NUM_CARGO) {
00229             SetDParam(3, STR_REFIT_ORDER);
00230             SetDParam(4, GetCargo(order->refit_cargo)->name);
00231           } else {
00232             SetDParam(3, STR_EMPTY);
00233           }
00234           break;
00235         }
00236 
00237         case OT_GOTO_WAYPOINT:
00238           SetDParam(1, (order->flags & OFB_NON_STOP) ? STR_GO_NON_STOP_TO_WAYPOINT : STR_GO_TO_WAYPOINT);
00239           SetDParam(2, order->dest);
00240           break;
00241 
00242         default: break;
00243       }
00244 
00245       SetDParam(0, i + 1);
00246       DrawString(2, y, str, (i == WP(w, order_d).sel) ? TC_WHITE : TC_BLACK);
00247 
00248       y += 10;
00249     }
00250 
00251     i++;
00252     order = order->next;
00253   }
00254 
00255   if (i - w->vscroll.pos < w->vscroll.cap) {
00256     str = shared_orders ? STR_END_OF_SHARED_ORDERS : STR_882A_END_OF_ORDERS;
00257     DrawString(2, y, str, (i == WP(w, order_d).sel) ? TC_WHITE : TC_BLACK);
00258   }
00259 }
00260 
00261 static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile)
00262 {
00263   Order order;
00264   order.next  = NULL;
00265   order.index = 0;
00266   order.refit_cargo   = CT_INVALID;
00267   order.refit_subtype = 0;
00268 
00269   // check depot first
00270   if (_patches.gotodepot) {
00271     switch (GetTileType(tile)) {
00272     case MP_RAILWAY:
00273       if (v->type == VEH_TRAIN && IsTileOwner(tile, _local_player)) {
00274         if (IsRailDepot(tile)) {
00275           order.type = OT_GOTO_DEPOT;
00276           order.flags = OFB_PART_OF_ORDERS;
00277           order.dest = GetDepotByTile(tile)->index;
00278           return order;
00279         }
00280       }
00281       break;
00282 
00283     case MP_ROAD:
00284       if (IsRoadDepot(tile) && v->type == VEH_ROAD && IsTileOwner(tile, _local_player)) {
00285         order.type = OT_GOTO_DEPOT;
00286         order.flags = OFB_PART_OF_ORDERS;
00287         order.dest = GetDepotByTile(tile)->index;
00288         return order;
00289       }
00290       break;
00291 
00292     case MP_STATION:
00293       if (v->type != VEH_AIRCRAFT) break;
00294       if (IsHangar(tile) && IsTileOwner(tile, _local_player)) {
00295         order.type = OT_GOTO_DEPOT;
00296         order.flags = OFB_PART_OF_ORDERS;
00297         order.dest = GetStationIndex(tile);
00298         return order;
00299       }
00300       break;
00301 
00302     case MP_WATER:
00303       if (v->type != VEH_SHIP) break;
00304       if (IsTileDepotType(tile, TRANSPORT_WATER) &&
00305           IsTileOwner(tile, _local_player)) {
00306         TileIndex tile2 = GetOtherShipDepotTile(tile);
00307 
00308         order.type = OT_GOTO_DEPOT;
00309         order.flags = OFB_PART_OF_ORDERS;
00310         order.dest = GetDepotByTile(tile < tile2 ? tile : tile2)->index;
00311         return order;
00312       }
00313 
00314       default:
00315         break;
00316     }
00317   }
00318 
00319   // check waypoint
00320   if (IsTileType(tile, MP_RAILWAY) &&
00321       v->type == VEH_TRAIN &&
00322       IsTileOwner(tile, _local_player) &&
00323       IsRailWaypoint(tile)) {
00324     order.type = OT_GOTO_WAYPOINT;
00325     order.flags = 0;
00326     order.dest = GetWaypointByTile(tile)->index;
00327     return order;
00328   }
00329 
00330   if (IsTileType(tile, MP_STATION)) {
00331     StationID st_index = GetStationIndex(tile);
00332     const Station *st = GetStation(st_index);
00333 
00334     if (st->owner == _current_player || st->owner == OWNER_NONE) {
00335       byte facil;
00336       (facil=FACIL_DOCK, v->type == VEH_SHIP) ||
00337       (facil=FACIL_TRAIN, v->type == VEH_TRAIN) ||
00338       (facil=FACIL_AIRPORT, v->type == VEH_AIRCRAFT) ||
00339       (facil=FACIL_BUS_STOP, v->type == VEH_ROAD && IsCargoInClass(v->cargo_type, CC_PASSENGERS)) ||
00340       (facil=FACIL_TRUCK_STOP, 1);
00341       if (st->facilities & facil) {
00342         order.type = OT_GOTO_STATION;
00343         order.flags = 0;
00344         order.dest = st_index;
00345         return order;
00346       }
00347     }
00348   }
00349 
00350   // not found
00351   order.Free();
00352   order.dest = INVALID_STATION;
00353   return order;
00354 }
00355 
00356 static bool HandleOrderVehClick(const Vehicle *v, const Vehicle *u, Window *w)
00357 {
00358   if (u->type != v->type) return false;
00359 
00360   if (!u->IsPrimaryVehicle()) {
00361     u = u->First();
00362     if (!u->IsPrimaryVehicle()) return false;
00363   }
00364 
00365   // v is vehicle getting orders. Only copy/clone orders if vehicle doesn't have any orders yet
00366   // obviously if you press CTRL on a non-empty orders vehicle you know what you are doing
00367   if (v->num_orders != 0 && _ctrl_pressed == 0) return false;
00368 
00369   if (DoCommandP(v->tile, v->index | (u->index << 16), _ctrl_pressed ? CO_SHARE : CO_COPY, NULL,
00370     _ctrl_pressed ? CMD_CLONE_ORDER | CMD_MSG(STR_CANT_SHARE_ORDER_LIST) : CMD_CLONE_ORDER | CMD_MSG(STR_CANT_COPY_ORDER_LIST))) {
00371     WP(w, order_d).sel = -1;
00372     ResetObjectToPlace();
00373   }
00374 
00375   return true;
00376 }
00377 
00378 static void OrdersPlaceObj(const Vehicle *v, TileIndex tile, Window *w)
00379 {
00380   Order cmd;
00381   const Vehicle *u;
00382 
00383   // check if we're clicking on a vehicle first.. clone orders in that case.
00384   u = CheckMouseOverVehicle();
00385   if (u != NULL && HandleOrderVehClick(v, u, w)) return;
00386 
00387   cmd = GetOrderCmdFromTile(v, tile);
00388   if (!cmd.IsValid()) return;
00389 
00390   if (DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), PackOrder(&cmd), NULL, CMD_INSERT_ORDER | CMD_MSG(STR_8833_CAN_T_INSERT_NEW_ORDER))) {
00391     if (WP(w, order_d).sel != -1) WP(w,order_d).sel++;
00392     ResetObjectToPlace();
00393   }
00394 }
00395 
00402 static void OrderClick_Goto(Window *w, const Vehicle *v)
00403 {
00404   w->InvalidateWidget(ORDER_WIDGET_GOTO);
00405   w->ToggleWidgetLoweredState(ORDER_WIDGET_GOTO);
00406   if (w->IsWidgetLowered(ORDER_WIDGET_GOTO)) {
00407     _place_clicked_vehicle = NULL;
00408     SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, PAL_NONE, VHM_RECT, w);
00409   } else {
00410     ResetObjectToPlace();
00411   }
00412 }
00413 
00420 static void OrderClick_FullLoad(Window *w, const Vehicle *v)
00421 {
00422   DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), OF_FULL_LOAD, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
00423 }
00424 
00431 static void OrderClick_Unload(Window *w, const Vehicle *v)
00432 {
00433   DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), OF_UNLOAD,    NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
00434 }
00435 
00442 static void OrderClick_Nonstop(Window *w, const Vehicle *v)
00443 {
00444   DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), OF_NON_STOP,  NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
00445 }
00446 
00453 static void OrderClick_Transfer(Window* w, const Vehicle* v)
00454 {
00455   DoCommandP(v->tile, v->index + (OrderGetSel(w) <<  16), OF_TRANSFER, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
00456 }
00457 
00466 static void OrderClick_Skip(Window *w, const Vehicle *v)
00467 {
00468   /* Don't skip when there's nothing to skip */
00469   if (_ctrl_pressed && v->cur_order_index == OrderGetSel(w)) return;
00470 
00471   DoCommandP(v->tile, v->index, _ctrl_pressed ? OrderGetSel(w) : ((v->cur_order_index + 1) % v->num_orders),
00472       NULL, CMD_SKIP_TO_ORDER | CMD_MSG(_ctrl_pressed ? STR_CAN_T_SKIP_TO_ORDER : STR_CAN_T_SKIP_ORDER));
00473 }
00474 
00481 static void OrderClick_Delete(Window *w, const Vehicle *v)
00482 {
00483   DoCommandP(v->tile, v->index, OrderGetSel(w), NULL, CMD_DELETE_ORDER | CMD_MSG(STR_8834_CAN_T_DELETE_THIS_ORDER));
00484 }
00485 
00494 static void OrderClick_Refit(Window *w, const Vehicle *v)
00495 {
00496   if (_ctrl_pressed) {
00497     /* Cancel refitting */
00498     DoCommandP(v->tile, v->index, (WP(w, order_d).sel << 16) | (CT_NO_REFIT << 8) | CT_NO_REFIT, NULL, CMD_ORDER_REFIT);
00499   } else {
00500     ShowVehicleRefitWindow(v, WP(w, order_d).sel);
00501   }
00502 }
00503 
00504 typedef void OnButtonVehClick(Window *w, const Vehicle *v);
00505 
00512 static OnButtonVehClick* const _order_button_proc[] = {
00513   OrderClick_Skip,
00514   OrderClick_Delete,
00515   OrderClick_Nonstop,
00516   OrderClick_Goto,
00517   OrderClick_FullLoad,
00518   OrderClick_Unload,
00519   OrderClick_Transfer
00520 };
00521 
00522 static const uint16 _order_keycodes[] = {
00523   'D', //skip order
00524   'F', //delete order
00525   'G', //non-stop
00526   'H', //goto order
00527   'J', //full load
00528   'K'  //unload
00529 };
00530 
00531 static void OrdersWndProc(Window *w, WindowEvent *e)
00532 {
00533   switch (e->event) {
00534     case WE_CREATE:
00535       /* Ensure that the refit and unload buttons always remain at the same location.
00536        * Only one of them can be active at any one time and takes turns on being disabled.
00537        * To ensure that they stay at the same location, we also verify that they behave the same
00538        * when resizing. */
00539       if (GetVehicle(w->window_number)->owner == _local_player) { // only the vehicle owner got these buttons
00540         assert(w->widget[ORDER_WIDGET_REFIT].left          == w->widget[ORDER_WIDGET_UNLOAD].left);
00541         assert(w->widget[ORDER_WIDGET_REFIT].right         == w->widget[ORDER_WIDGET_UNLOAD].right);
00542         assert(w->widget[ORDER_WIDGET_REFIT].top           == w->widget[ORDER_WIDGET_UNLOAD].top);
00543         assert(w->widget[ORDER_WIDGET_REFIT].bottom        == w->widget[ORDER_WIDGET_UNLOAD].bottom);
00544         assert(w->widget[ORDER_WIDGET_REFIT].display_flags == w->widget[ORDER_WIDGET_UNLOAD].display_flags);
00545       }
00546     if (GetVehicle(w->window_number)->num_orders == 0) return;
00547 
00548       if (_patches.timetabling) {
00549         w->widget[ORDER_WIDGET_CAPTION].right -= 61;
00550       } else {
00551         w->HideWidget(ORDER_WIDGET_TIMETABLE_VIEW);
00552       }
00553 
00554       break;
00555 
00556   case WE_PAINT:
00557     DrawOrdersWindow(w);
00558     break;
00559 
00560   case WE_CLICK: {
00561     const Vehicle *v = GetVehicle(w->window_number);
00562     switch (e->we.click.widget) {
00563     case ORDER_WIDGET_ORDER_LIST: {
00564       ResetObjectToPlace();
00565 
00566       int sel = GetOrderFromOrderWndPt(w, e->we.click.pt.y, v);
00567 
00568       if (sel == INVALID_ORDER) {
00569         /* This was a click on an empty part of the orders window, so
00570          * deselect the currently selected order. */
00571         WP(w, order_d).sel = -1;
00572         SetWindowDirty(w);
00573         return;
00574       }
00575 
00576       if (_ctrl_pressed && sel < v->num_orders) {
00577         const Order *ord = GetVehicleOrder(v, sel);
00578         TileIndex xy;
00579 
00580         switch (ord->type) {
00581           case OT_GOTO_STATION:  xy = GetStation(ord->dest)->xy ; break;
00582           case OT_GOTO_DEPOT:    xy = (v->type == VEH_AIRCRAFT) ?  GetStation(ord->dest)->xy : GetDepot(ord->dest)->xy;    break;
00583           case OT_GOTO_WAYPOINT: xy = GetWaypoint(ord->dest)->xy; break;
00584           default:               xy = 0; break;
00585         }
00586 
00587         if (xy != 0) ScrollMainWindowToTile(xy);
00588         return;
00589       } else {
00590         if (sel == WP(w, order_d).sel) {
00591           /* Deselect clicked order */
00592           WP(w, order_d).sel = -1;
00593         } else {
00594           /* Select clicked order */
00595           WP(w, order_d).sel = sel;
00596 
00597           if (v->owner == _local_player) {
00598             /* Activate drag and drop */
00599             SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, VHM_DRAG, w);
00600           }
00601         }
00602       }
00603 
00604       SetWindowDirty(w);
00605     } break;
00606 
00607     case ORDER_WIDGET_SKIP:
00608       OrderClick_Skip(w, v);
00609       break;
00610 
00611     case ORDER_WIDGET_DELETE:
00612       OrderClick_Delete(w, v);
00613       break;
00614 
00615     case ORDER_WIDGET_NON_STOP:
00616       OrderClick_Nonstop(w, v);
00617       break;
00618 
00619     case ORDER_WIDGET_GOTO:
00620       OrderClick_Goto(w, v);
00621       break;
00622 
00623     case ORDER_WIDGET_FULL_LOAD:
00624       OrderClick_FullLoad(w, v);
00625       break;
00626 
00627     case ORDER_WIDGET_UNLOAD:
00628       OrderClick_Unload(w, v);
00629       break;
00630     case ORDER_WIDGET_REFIT:
00631       OrderClick_Refit(w, v);
00632       break;
00633 
00634     case ORDER_WIDGET_TRANSFER:
00635       OrderClick_Transfer(w, v);
00636       break;
00637 
00638     case ORDER_WIDGET_TIMETABLE_VIEW:
00639       ShowTimetableWindow(v);
00640       break;
00641 
00642     case ORDER_WIDGET_SHARED_ORDER_LIST:
00643       ShowVehicleListWindow(v);
00644       break;
00645     }
00646   } break;
00647 
00648   case WE_DRAGDROP: {
00649     const Vehicle *v = GetVehicle(w->window_number);
00650 
00651     switch (e->we.click.widget) {
00652       case ORDER_WIDGET_ORDER_LIST: {
00653         int from_order = OrderGetSel(w);
00654         int to_order = GetOrderFromOrderWndPt(w, e->we.dragdrop.pt.y, v);
00655 
00656         if (!(from_order == to_order || from_order == INVALID_ORDER || from_order > v->num_orders || to_order == INVALID_ORDER || to_order > v->num_orders) &&
00657             DoCommandP(v->tile, v->index, from_order | (to_order << 16), NULL, CMD_MOVE_ORDER | CMD_MSG(STR_CAN_T_MOVE_THIS_ORDER))) {
00658           WP(w, order_d).sel = -1;
00659         }
00660 
00661         break;
00662       }
00663 
00664       case ORDER_WIDGET_DELETE:
00665         OrderClick_Delete(w, v);
00666         break;
00667     }
00668 
00669     ResetObjectToPlace();
00670     break;
00671   }
00672 
00673   case WE_KEYPRESS: {
00674     Vehicle *v = GetVehicle(w->window_number);
00675     uint i;
00676 
00677     if (v->owner != _local_player) break;
00678 
00679     for (i = 0; i < lengthof(_order_keycodes); i++) {
00680       if (e->we.keypress.keycode == _order_keycodes[i]) {
00681         e->we.keypress.cont = false;
00682         //see if the button is disabled
00683         if (!w->IsWidgetDisabled(i + ORDER_WIDGET_SKIP)) _order_button_proc[i](w, v);
00684         break;
00685       }
00686     }
00687     break;
00688   }
00689 
00690   case WE_RCLICK: {
00691     const Vehicle *v = GetVehicle(w->window_number);
00692     int s = OrderGetSel(w);
00693 
00694     if (e->we.click.widget != ORDER_WIDGET_FULL_LOAD) break;
00695     if (s == v->num_orders || GetVehicleOrder(v, s)->type != OT_GOTO_DEPOT) {
00696       GuiShowTooltips(STR_8857_MAKE_THE_HIGHLIGHTED_ORDER);
00697     } else {
00698       GuiShowTooltips(STR_SERVICE_HINT);
00699     }
00700   } break;
00701 
00702   case WE_PLACE_OBJ: {
00703     OrdersPlaceObj(GetVehicle(w->window_number), e->we.place.tile, w);
00704   } break;
00705 
00706   case WE_ABORT_PLACE_OBJ: {
00707     w->RaiseWidget(ORDER_WIDGET_GOTO);
00708     w->InvalidateWidget(ORDER_WIDGET_GOTO);
00709   } break;
00710 
00711   // check if a vehicle in a depot was clicked..
00712   case WE_MOUSELOOP: {
00713     const Vehicle *v = _place_clicked_vehicle;
00714     /*
00715      * Check if we clicked on a vehicle
00716      * and if the GOTO button of this window is pressed
00717      * This is because of all open order windows WE_MOUSELOOP is called
00718      * and if you have 3 windows open, and this check is not done
00719      * the order is copied to the last open window instead of the
00720      * one where GOTO is enabled
00721      */
00722     if (v != NULL && w->IsWidgetLowered(ORDER_WIDGET_GOTO)) {
00723       _place_clicked_vehicle = NULL;
00724       HandleOrderVehClick(GetVehicle(w->window_number), v, w);
00725     }
00726   } break;
00727 
00728   case WE_RESIZE:
00729     /* Update the scroll + matrix */
00730     w->vscroll.cap = (w->widget[ORDER_WIDGET_ORDER_LIST].bottom - w->widget[ORDER_WIDGET_ORDER_LIST].top) / 10;
00731     break;
00732 
00733   case WE_TIMEOUT: { // handle button unclick ourselves...
00734     // unclick all buttons except for the 'goto' button (ORDER_WIDGET_GOTO), which is 'persistent'
00735     uint i;
00736     for (i = 0; i < w->widget_count; i++) {
00737       if (w->IsWidgetLowered(i) && i != ORDER_WIDGET_GOTO) {
00738         w->RaiseWidget(i);
00739         w->InvalidateWidget(i);
00740       }
00741     }
00742   } break;
00743   }
00744 }
00745 
00749 static const Widget _orders_train_widgets[] = {
00750   {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                STR_018B_CLOSE_WINDOW},               // ORDER_WIDGET_CLOSEBOX
00751   {    WWT_CAPTION,   RESIZE_RIGHT,   14,    11,   398,     0,    13, STR_8829_ORDERS,         STR_018C_WINDOW_TITLE_DRAG_THIS},     // ORDER_WIDGET_CAPTION
00752   { WWT_PUSHTXTBTN,   RESIZE_LR,      14,   338,   398,     0,    13, STR_TIMETABLE_VIEW,      STR_TIMETABLE_VIEW_TOOLTIP},          // ORDER_WIDGET_TIMETABLE_VIEW
00753 
00754   {      WWT_PANEL,   RESIZE_RB,      14,     0,   386,    14,    75, 0x0,                     STR_8852_ORDERS_LIST_CLICK_ON_ORDER}, // ORDER_WIDGET_ORDER_LIST
00755 
00756   {  WWT_SCROLLBAR,   RESIZE_LRB,     14,   387,   398,    14,    75, 0x0,                     STR_0190_SCROLL_BAR_SCROLLS_LIST},    // ORDER_WIDGET_SCROLLBAR
00757 
00758   { WWT_PUSHTXTBTN,   RESIZE_TB,      14,     0,    52,    76,    87, STR_8823_SKIP,           STR_8853_SKIP_THE_CURRENT_ORDER},     // ORDER_WIDGET_SKIP
00759   { WWT_PUSHTXTBTN,   RESIZE_TB,      14,    53,   105,    76,    87, STR_8824_DELETE,         STR_8854_DELETE_THE_HIGHLIGHTED},     // ORDER_WIDGET_DELETE
00760   { WWT_PUSHTXTBTN,   RESIZE_TB,      14,   106,   158,    76,    87, STR_8825_NON_STOP,       STR_8855_MAKE_THE_HIGHLIGHTED_ORDER}, // ORDER_WIDGET_NON_STOP
00761   {    WWT_TEXTBTN,   RESIZE_TB,      14,   159,   211,    76,    87, STR_8826_GO_TO,          STR_8856_INSERT_A_NEW_ORDER_BEFORE},  // ORDER_WIDGET_GOTO
00762   { WWT_PUSHTXTBTN,   RESIZE_TB,      14,   212,   264,    76,    87, STR_FULLLOAD_OR_SERVICE, STR_NULL},                            // ORDER_WIDGET_FULL_LOAD
00763   { WWT_PUSHTXTBTN,   RESIZE_TB,      14,   265,   319,    76,    87, STR_8828_UNLOAD,         STR_8858_MAKE_THE_HIGHLIGHTED_ORDER}, // ORDER_WIDGET_UNLOAD
00764   { WWT_PUSHTXTBTN,   RESIZE_TB,      14,   265,   319,    76,    87, STR_REFIT,               STR_REFIT_TIP},                       // ORDER_WIDGET_REFIT
00765   { WWT_PUSHTXTBTN,   RESIZE_TB,      14,   320,   372,    76,    87, STR_TRANSFER,            STR_MAKE_THE_HIGHLIGHTED_ORDER},      // ORDER_WIDGET_TRANSFER
00766 
00767   { WWT_PUSHIMGBTN,   RESIZE_TB,      14,   373,   386,    76,    87, SPR_SHARED_ORDERS_ICON,  STR_VEH_WITH_SHARED_ORDERS_LIST_TIP}, // ORDER_WIDGET_SHARED_ORDER_LIST
00768 
00769   {      WWT_PANEL,   RESIZE_RTB,     14,   387,   386,    76,    87, 0x0,                     STR_NULL},                            // ORDER_WIDGET_RESIZE_BAR
00770 
00771   {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   387,   398,    76,    87, 0x0,                     STR_RESIZE_BUTTON},                   // ORDER_WIDGET_RESIZE
00772   {   WIDGETS_END},
00773 };
00774 
00775 static const WindowDesc _orders_train_desc = {
00776   WDP_AUTO, WDP_AUTO, 399, 88, 399, 88,
00777   WC_VEHICLE_ORDERS,WC_VEHICLE_VIEW,
00778   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_RESIZABLE,
00779   _orders_train_widgets,
00780   OrdersWndProc
00781 };
00782 
00786 static const Widget _orders_widgets[] = {
00787   {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                STR_018B_CLOSE_WINDOW},               // ORDER_WIDGET_CLOSEBOX
00788   {    WWT_CAPTION,   RESIZE_RIGHT,   14,    11,   409,     0,    13, STR_8829_ORDERS,         STR_018C_WINDOW_TITLE_DRAG_THIS},     // ORDER_WIDGET_CAPTION
00789   { WWT_PUSHTXTBTN,   RESIZE_LR,      14,   349,   409,     0,    13, STR_TIMETABLE_VIEW,      STR_TIMETABLE_VIEW_TOOLTIP},          // ORDER_WIDGET_TIMETABLE_VIEW
00790 
00791   {      WWT_PANEL,   RESIZE_RB,      14,     0,   397,    14,    75, 0x0,                     STR_8852_ORDERS_LIST_CLICK_ON_ORDER}, // ORDER_WIDGET_ORDER_LIST
00792 
00793   {  WWT_SCROLLBAR,   RESIZE_LRB,     14,   398,   409,    14,    75, 0x0,                     STR_0190_SCROLL_BAR_SCROLLS_LIST},    // ORDER_WIDGET_SCROLLBAR
00794 
00795   { WWT_PUSHTXTBTN,   RESIZE_TB,      14,     0,    63,    76,    87, STR_8823_SKIP,           STR_8853_SKIP_THE_CURRENT_ORDER},     // ORDER_WIDGET_SKIP
00796   { WWT_PUSHTXTBTN,   RESIZE_TB,      14,    64,   128,    76,    87, STR_8824_DELETE,         STR_8854_DELETE_THE_HIGHLIGHTED},     // ORDER_WIDGET_DELETE
00797   {      WWT_EMPTY,   RESIZE_TB,      14,     0,     0,    76,    87, 0x0,                     0x0},                                 // ORDER_WIDGET_NON_STOP
00798   {    WWT_TEXTBTN,   RESIZE_TB,      14,   129,   192,    76,    87, STR_8826_GO_TO,          STR_8856_INSERT_A_NEW_ORDER_BEFORE},  // ORDER_WIDGET_GOTO
00799   { WWT_PUSHTXTBTN,   RESIZE_TB,      14,   193,   256,    76,    87, STR_FULLLOAD_OR_SERVICE, STR_NULL},                            // ORDER_WIDGET_FULL_LOAD
00800   { WWT_PUSHTXTBTN,   RESIZE_TB,      14,   257,   319,    76,    87, STR_8828_UNLOAD,         STR_8858_MAKE_THE_HIGHLIGHTED_ORDER}, // ORDER_WIDGET_UNLOAD
00801   { WWT_PUSHTXTBTN,   RESIZE_TB,      14,   257,   319,    76,    87, STR_REFIT,               STR_REFIT_TIP},                       // ORDER_WIDGET_REFIT
00802   { WWT_PUSHTXTBTN,   RESIZE_TB,      14,   320,   383,    76,    87, STR_TRANSFER,            STR_MAKE_THE_HIGHLIGHTED_ORDER},      // ORDER_WIDGET_TRANSFER
00803 
00804   { WWT_PUSHIMGBTN,   RESIZE_TB,      14,   384,   397,    76,    87, SPR_SHARED_ORDERS_ICON,  STR_VEH_WITH_SHARED_ORDERS_LIST_TIP}, // ORDER_WIDGET_SHARED_ORDER_LIST
00805 
00806   {      WWT_PANEL,   RESIZE_RTB,     14,   397,   396,    76,    87, 0x0,                     STR_NULL},                            // ORDER_WIDGET_RESIZE_BAR
00807 
00808   {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   398,   409,    76,    87, 0x0,                     STR_RESIZE_BUTTON},                   // ORDER_WIDGET_RESIZE
00809   {   WIDGETS_END},
00810 };
00811 
00812 static const WindowDesc _orders_desc = {
00813   WDP_AUTO, WDP_AUTO, 410, 88, 410, 88,
00814   WC_VEHICLE_ORDERS,WC_VEHICLE_VIEW,
00815   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_RESIZABLE,
00816   _orders_widgets,
00817   OrdersWndProc
00818 };
00819 
00823 static const Widget _other_orders_widgets[] = {
00824   {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,           STR_018B_CLOSE_WINDOW},               // ORDER_WIDGET_CLOSEBOX
00825   {    WWT_CAPTION,   RESIZE_RIGHT,   14,    11,   331,     0,    13, STR_A00B_ORDERS,    STR_018C_WINDOW_TITLE_DRAG_THIS},     // ORDER_WIDGET_CAPTION
00826   { WWT_PUSHTXTBTN,   RESIZE_LR,      14,   271,   331,     0,    13, STR_TIMETABLE_VIEW, STR_TIMETABLE_VIEW_TOOLTIP},          // ORDER_WIDGET_TIMETABLE_VIEW
00827 
00828   {      WWT_PANEL,   RESIZE_RB,      14,     0,   319,    14,    75, 0x0,                STR_8852_ORDERS_LIST_CLICK_ON_ORDER}, // ORDER_WIDGET_ORDER_LIST
00829 
00830   {  WWT_SCROLLBAR,   RESIZE_LRB,     14,   320,   331,    14,    75, 0x0,                STR_0190_SCROLL_BAR_SCROLLS_LIST},    // ORDER_WIDGET_SCROLLBAR
00831 
00832   {      WWT_EMPTY,   RESIZE_NONE,    14,     0,   319,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_SKIP
00833   {      WWT_EMPTY,   RESIZE_NONE,    14,     0,   319,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_DELETE
00834   {      WWT_EMPTY,   RESIZE_NONE,    14,     0,   319,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_NON_STOP
00835   {      WWT_EMPTY,   RESIZE_NONE,    14,     0,   319,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_GOTO
00836   {      WWT_EMPTY,   RESIZE_NONE,    14,     0,   319,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_FULL_LOAD
00837   {      WWT_EMPTY,   RESIZE_NONE,    14,     0,   319,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_UNLOAD
00838   {      WWT_EMPTY,   RESIZE_NONE,    14,     0,   319,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_REFIT
00839   {      WWT_EMPTY,   RESIZE_NONE,    14,     0,   319,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_TRANSFER
00840 
00841   {      WWT_EMPTY,   RESIZE_NONE,    14,     0,   319,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_SHARED_ORDER_LIST
00842 
00843   {      WWT_PANEL,   RESIZE_RTB,     14,     0,   319,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_RESIZE_BAR
00844 
00845   {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   320,   331,    76,    87, 0x0,                STR_RESIZE_BUTTON},                   // ORDER_WIDGET_RESIZE
00846   {   WIDGETS_END},
00847 };
00848 
00849 static const WindowDesc _other_orders_desc = {
00850   WDP_AUTO, WDP_AUTO, 332, 88, 332, 88,
00851   WC_VEHICLE_ORDERS,WC_VEHICLE_VIEW,
00852   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
00853   _other_orders_widgets,
00854   OrdersWndProc
00855 };
00856 
00857 void ShowOrdersWindow(const Vehicle *v)
00858 {
00859   Window *w;
00860   VehicleID veh = v->index;
00861 
00862   DeleteWindowById(WC_VEHICLE_ORDERS, veh);
00863   DeleteWindowById(WC_VEHICLE_DETAILS, veh);
00864 
00865   if (v->owner != _local_player) {
00866     w = AllocateWindowDescFront(&_other_orders_desc, veh);
00867   } else {
00868     w = AllocateWindowDescFront((v->type == VEH_TRAIN) ? &_orders_train_desc : &_orders_desc, veh);
00869   }
00870 
00871   if (w != NULL) {
00872     w->caption_color = v->owner;
00873     w->vscroll.cap = 6;
00874     w->resize.step_height = 10;
00875     WP(w, order_d).sel = -1;
00876   }
00877 }

Generated on Wed Oct 1 17:03:22 2008 for openttd by  doxygen 1.5.6