00001
00002
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "gui.h"
00008 #include "window_gui.h"
00009 #include "textbuf_gui.h"
00010 #include "command_func.h"
00011 #include "vehicle_gui.h"
00012 #include "vehicle_gui_base.h"
00013 #include "train.h"
00014 #include "group.h"
00015 #include "debug.h"
00016 #include "strings_func.h"
00017 #include "core/alloc_func.hpp"
00018 #include "window_func.h"
00019 #include "vehicle_func.h"
00020 #include "autoreplace_gui.h"
00021 #include "string_func.h"
00022 #include "viewport_func.h"
00023 #include "gfx_func.h"
00024 #include "company_func.h"
00025 #include "widgets/dropdown_type.h"
00026 #include "widgets/dropdown_func.h"
00027 #include "tilehighlight_func.h"
00028
00029 #include "table/strings.h"
00030 #include "table/sprites.h"
00031
00032 typedef GUIList<const Group*> GUIGroupList;
00033
00034 enum GroupListWidgets {
00035 GRP_WIDGET_CLOSEBOX = 0,
00036 GRP_WIDGET_CAPTION,
00037 GRP_WIDGET_STICKY,
00038 GRP_WIDGET_SORT_BY_ORDER,
00039 GRP_WIDGET_SORT_BY_DROPDOWN,
00040 GRP_WIDGET_EMPTY_TOP_RIGHT,
00041 GRP_WIDGET_LIST_VEHICLE,
00042 GRP_WIDGET_LIST_VEHICLE_SCROLLBAR,
00043 GRP_WIDGET_EMPTY2,
00044 GRP_WIDGET_AVAILABLE_VEHICLES,
00045 GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN,
00046 GRP_WIDGET_STOP_ALL,
00047 GRP_WIDGET_START_ALL,
00048 GRP_WIDGET_EMPTY_BOTTOM_RIGHT,
00049 GRP_WIDGET_RESIZE,
00050
00051 GRP_WIDGET_EMPTY_TOP_LEFT,
00052 GRP_WIDGET_ALL_VEHICLES,
00053 GRP_WIDGET_DEFAULT_VEHICLES,
00054 GRP_WIDGET_LIST_GROUP,
00055 GRP_WIDGET_LIST_GROUP_SCROLLBAR,
00056 GRP_WIDGET_CREATE_GROUP,
00057 GRP_WIDGET_DELETE_GROUP,
00058 GRP_WIDGET_RENAME_GROUP,
00059 GRP_WIDGET_EMPTY1,
00060 GRP_WIDGET_REPLACE_PROTECTION,
00061 };
00062
00063 enum GroupActionListFunction {
00064 GALF_REPLACE,
00065 GALF_SERVICE,
00066 GALF_DEPOT,
00067 GALF_ADD_SHARED,
00068 GALF_REMOVE_ALL,
00069 };
00070
00076 static void ShowGroupActionDropdown(Window *w, GroupID gid)
00077 {
00078 DropDownList *list = new DropDownList();
00079
00080 list->push_back(new DropDownListStringItem(STR_REPLACE_VEHICLES, GALF_REPLACE, false));
00081 list->push_back(new DropDownListStringItem(STR_SEND_FOR_SERVICING, GALF_SERVICE, false));
00082 list->push_back(new DropDownListStringItem(STR_SEND_TRAIN_TO_DEPOT, GALF_DEPOT, false));
00083
00084 if (IsValidGroupID(gid)) {
00085 list->push_back(new DropDownListStringItem(STR_GROUP_ADD_SHARED_VEHICLE, GALF_ADD_SHARED, false));
00086 list->push_back(new DropDownListStringItem(STR_GROUP_REMOVE_ALL_VEHICLES, GALF_REMOVE_ALL, false));
00087 }
00088
00089 ShowDropDownList(w, list, 0, GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN);
00090 }
00091
00092
00093 static const Widget _group_widgets[] = {
00094 { WWT_CLOSEBOX, RESIZE_NONE, COLOUR_GREY, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
00095 { WWT_CAPTION, RESIZE_RIGHT, COLOUR_GREY, 11, 447, 0, 13, 0x0, STR_018C_WINDOW_TITLE_DRAG_THIS},
00096 { WWT_STICKYBOX, RESIZE_LR, COLOUR_GREY, 448, 459, 0, 13, 0x0, STR_STICKY_BUTTON},
00097 { WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_GREY, 200, 280, 14, 25, STR_SORT_BY, STR_SORT_ORDER_TIP},
00098 { WWT_DROPDOWN, RESIZE_NONE, COLOUR_GREY, 281, 447, 14, 25, 0x0, STR_SORT_CRITERIA_TIP},
00099 { WWT_PANEL, RESIZE_RIGHT, COLOUR_GREY, 448, 459, 14, 25, 0x0, STR_NULL},
00100 { WWT_MATRIX, RESIZE_RB, COLOUR_GREY, 200, 447, 26, 181, 0x701, STR_NULL},
00101 { WWT_SCROLLBAR, RESIZE_LRB, COLOUR_GREY, 448, 459, 26, 181, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
00102 { WWT_PANEL, RESIZE_TB, COLOUR_GREY, 188, 199, 169, 193, 0x0, STR_NULL},
00103 { WWT_PUSHTXTBTN, RESIZE_TB, COLOUR_GREY, 200, 305, 182, 193, 0x0, STR_AVAILABLE_ENGINES_TIP},
00104 { WWT_DROPDOWN, RESIZE_TB, COLOUR_GREY, 306, 423, 182, 193, STR_MANAGE_LIST, STR_MANAGE_LIST_TIP},
00105 { WWT_PUSHIMGBTN, RESIZE_TB, COLOUR_GREY, 424, 435, 182, 193, SPR_FLAG_VEH_STOPPED, STR_MASS_STOP_LIST_TIP},
00106 { WWT_PUSHIMGBTN, RESIZE_TB, COLOUR_GREY, 436, 447, 182, 193, SPR_FLAG_VEH_RUNNING, STR_MASS_START_LIST_TIP},
00107 { WWT_PANEL, RESIZE_RTB, COLOUR_GREY, 448, 447, 182, 193, 0x0, STR_NULL},
00108 { WWT_RESIZEBOX, RESIZE_LRTB, COLOUR_GREY, 448, 459, 182, 193, 0x0, STR_RESIZE_BUTTON},
00109
00110 { WWT_PANEL, RESIZE_NONE, COLOUR_GREY, 0, 199, 14, 25, 0x0, STR_NULL},
00111 { WWT_PANEL, RESIZE_NONE, COLOUR_GREY, 0, 199, 26, 38, 0x0, STR_NULL},
00112 { WWT_PANEL, RESIZE_NONE, COLOUR_GREY, 0, 199, 39, 51, 0x0, STR_NULL},
00113 { WWT_MATRIX, RESIZE_BOTTOM, COLOUR_GREY, 0, 187, 52, 168, 0x701, STR_GROUPS_CLICK_ON_GROUP_FOR_TIP},
00114 { WWT_SCROLL2BAR, RESIZE_BOTTOM, COLOUR_GREY, 188, 199, 52, 168, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
00115 { WWT_PUSHIMGBTN, RESIZE_TB, COLOUR_GREY, 0, 23, 169, 193, 0x0, STR_GROUP_CREATE_TIP},
00116 { WWT_PUSHIMGBTN, RESIZE_TB, COLOUR_GREY, 24, 47, 169, 193, 0x0, STR_GROUP_DELETE_TIP},
00117 { WWT_PUSHIMGBTN, RESIZE_TB, COLOUR_GREY, 48, 71, 169, 193, 0x0, STR_GROUP_RENAME_TIP},
00118 { WWT_PANEL, RESIZE_TB, COLOUR_GREY, 72, 163, 169, 193, 0x0, STR_NULL},
00119 { WWT_PUSHIMGBTN, RESIZE_TB, COLOUR_GREY, 164, 187, 169, 193, 0x0, STR_GROUP_REPLACE_PROTECTION_TIP},
00120 { WIDGETS_END},
00121 };
00122
00123
00124 class VehicleGroupWindow : public BaseVehicleListWindow {
00125 private:
00126 GroupID group_sel;
00127 VehicleID vehicle_sel;
00128 GUIGroupList groups;
00129
00135 void BuildGroupList(Owner owner)
00136 {
00137 if (!this->groups.NeedRebuild()) return;
00138
00139 this->groups.Clear();
00140
00141 const Group *g;
00142 FOR_ALL_GROUPS(g) {
00143 if (g->owner == owner && g->vehicle_type == this->vehicle_type) {
00144 *this->groups.Append() = g;
00145 }
00146 }
00147
00148 this->groups.Compact();
00149 this->groups.RebuildDone();
00150 }
00151
00153 static int CDECL GroupNameSorter(const Group* const *a, const Group* const *b)
00154 {
00155 static const Group *last_group[2] = { NULL, NULL };
00156 static char last_name[2][64] = { "", "" };
00157
00158 if (*a != last_group[0]) {
00159 last_group[0] = *a;
00160 SetDParam(0, (*a)->index);
00161 GetString(last_name[0], STR_GROUP_NAME, lastof(last_name[0]));
00162 }
00163
00164 if (*b != last_group[1]) {
00165 last_group[1] = *b;
00166 SetDParam(0, (*b)->index);
00167 GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1]));
00168 }
00169
00170 int r = strcmp(last_name[0], last_name[1]);
00171 if (r == 0) return (*a)->index - (*b)->index;
00172 return r;
00173 }
00174
00175 public:
00176 VehicleGroupWindow(const WindowDesc *desc, WindowNumber window_number) : BaseVehicleListWindow(desc, window_number)
00177 {
00178 const Owner owner = (Owner)GB(this->window_number, 0, 8);
00179 this->vehicle_type = (VehicleType)GB(this->window_number, 11, 5);
00180
00181 this->caption_color = owner;
00182 this->resize.step_width = 1;
00183
00184 switch (this->vehicle_type) {
00185 default: NOT_REACHED();
00186 case VEH_TRAIN:
00187 case VEH_ROAD:
00188 this->vscroll2.cap = 9;
00189 this->vscroll.cap = 6;
00190 this->resize.step_height = PLY_WND_PRC__SIZE_OF_ROW_SMALL;
00191 break;
00192 case VEH_SHIP:
00193 case VEH_AIRCRAFT:
00194 this->vscroll2.cap = 9;
00195 this->vscroll.cap = 4;
00196 this->resize.step_height = PLY_WND_PRC__SIZE_OF_ROW_BIG;
00197 break;
00198 }
00199
00200 this->widget[GRP_WIDGET_LIST_GROUP].data = (this->vscroll2.cap << 8) + 1;
00201 this->widget[GRP_WIDGET_LIST_VEHICLE].data = (this->vscroll.cap << 8) + 1;
00202
00203 switch (this->vehicle_type) {
00204 default: NOT_REACHED();
00205 case VEH_TRAIN: this->sorting = &_sorting.train; break;
00206 case VEH_ROAD: this->sorting = &_sorting.roadveh; break;
00207 case VEH_SHIP: this->sorting = &_sorting.ship; break;
00208 case VEH_AIRCRAFT: this->sorting = &_sorting.aircraft; break;
00209 }
00210
00211 this->vehicles.SetListing(*this->sorting);
00212 this->vehicles.ForceRebuild();
00213 this->vehicles.NeedResort();
00214
00215 this->groups.ForceRebuild();
00216 this->groups.NeedResort();
00217
00218 this->group_sel = ALL_GROUP;
00219 this->vehicle_sel = INVALID_VEHICLE;
00220
00221 switch (this->vehicle_type) {
00222 case VEH_TRAIN:
00223 this->widget[GRP_WIDGET_LIST_VEHICLE].tooltips = STR_883D_TRAINS_CLICK_ON_TRAIN_FOR;
00224 this->widget[GRP_WIDGET_AVAILABLE_VEHICLES].data = STR_AVAILABLE_TRAINS;
00225
00226 this->widget[GRP_WIDGET_CREATE_GROUP].data = SPR_GROUP_CREATE_TRAIN;
00227 this->widget[GRP_WIDGET_RENAME_GROUP].data = SPR_GROUP_RENAME_TRAIN;
00228 this->widget[GRP_WIDGET_DELETE_GROUP].data = SPR_GROUP_DELETE_TRAIN;
00229 break;
00230
00231 case VEH_ROAD:
00232 this->widget[GRP_WIDGET_LIST_VEHICLE].tooltips = STR_901A_ROAD_VEHICLES_CLICK_ON;
00233 this->widget[GRP_WIDGET_AVAILABLE_VEHICLES].data = STR_AVAILABLE_ROAD_VEHICLES;
00234
00235 this->widget[GRP_WIDGET_CREATE_GROUP].data = SPR_GROUP_CREATE_ROADVEH;
00236 this->widget[GRP_WIDGET_RENAME_GROUP].data = SPR_GROUP_RENAME_ROADVEH;
00237 this->widget[GRP_WIDGET_DELETE_GROUP].data = SPR_GROUP_DELETE_ROADVEH;
00238 break;
00239
00240 case VEH_SHIP:
00241 this->widget[GRP_WIDGET_LIST_VEHICLE].tooltips = STR_9823_SHIPS_CLICK_ON_SHIP_FOR;
00242 this->widget[GRP_WIDGET_AVAILABLE_VEHICLES].data = STR_AVAILABLE_SHIPS;
00243
00244 this->widget[GRP_WIDGET_CREATE_GROUP].data = SPR_GROUP_CREATE_SHIP;
00245 this->widget[GRP_WIDGET_RENAME_GROUP].data = SPR_GROUP_RENAME_SHIP;
00246 this->widget[GRP_WIDGET_DELETE_GROUP].data = SPR_GROUP_DELETE_SHIP;
00247 break;
00248
00249 case VEH_AIRCRAFT:
00250 this->widget[GRP_WIDGET_LIST_VEHICLE].tooltips = STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT;
00251 this->widget[GRP_WIDGET_AVAILABLE_VEHICLES].data = STR_AVAILABLE_AIRCRAFT;
00252
00253 this->widget[GRP_WIDGET_CREATE_GROUP].data = SPR_GROUP_CREATE_AIRCRAFT;
00254 this->widget[GRP_WIDGET_RENAME_GROUP].data = SPR_GROUP_RENAME_AIRCRAFT;
00255 this->widget[GRP_WIDGET_DELETE_GROUP].data = SPR_GROUP_DELETE_AIRCRAFT;
00256 break;
00257
00258 default: NOT_REACHED();
00259 }
00260
00261 this->FindWindowPlacementAndResize(desc);
00262 if (this->vehicle_type == VEH_TRAIN) ResizeWindow(this, 65, 0);
00263 }
00264
00265 ~VehicleGroupWindow()
00266 {
00267 *this->sorting = this->vehicles.GetListing();
00268 }
00269
00270 virtual void OnInvalidateData(int data)
00271 {
00272 if (data == 0) {
00273 this->vehicles.ForceRebuild();
00274 this->groups.ForceRebuild();
00275 } else {
00276 this->vehicles.ForceResort();
00277 this->groups.ForceResort();
00278 }
00279
00280 if (!(IsAllGroupID(this->group_sel) || IsDefaultGroupID(this->group_sel) || IsValidGroupID(this->group_sel))) {
00281 this->group_sel = ALL_GROUP;
00282 HideDropDownMenu(this);
00283 }
00284 this->SetDirty();
00285 }
00286
00287 virtual void OnPaint()
00288 {
00289 const Owner owner = (Owner)GB(this->window_number, 0, 8);
00290 int x = this->widget[GRP_WIDGET_LIST_VEHICLE].left + 2;
00291 int y1 = PLY_WND_PRC__OFFSET_TOP_WIDGET + 2;
00292 int max;
00293 int i;
00294
00295
00296
00297 this->BuildVehicleList(owner, this->group_sel, IsAllGroupID(this->group_sel) ? VLW_STANDARD : VLW_GROUP_LIST);
00298 this->SortVehicleList();
00299
00300 this->BuildGroupList(owner);
00301 this->groups.Sort(&GroupNameSorter);
00302
00303 SetVScroll2Count(this, this->groups.Length());
00304 SetVScrollCount(this, this->vehicles.Length());
00305
00306
00307 if (this->vehicles.Length() == 0 && this->IsWidgetLowered(GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN)) {
00308 this->RaiseWidget(GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN);
00309 HideDropDownMenu(this);
00310 }
00311
00312
00313 this->SetWidgetsDisabledState(this->vehicles.Length() == 0 || _local_company != owner,
00314 GRP_WIDGET_STOP_ALL,
00315 GRP_WIDGET_START_ALL,
00316 GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN,
00317 WIDGET_LIST_END);
00318
00319
00320 this->SetWidgetsDisabledState(IsDefaultGroupID(this->group_sel) || IsAllGroupID(this->group_sel) || _local_company != owner,
00321 GRP_WIDGET_DELETE_GROUP,
00322 GRP_WIDGET_RENAME_GROUP,
00323 GRP_WIDGET_REPLACE_PROTECTION,
00324 WIDGET_LIST_END);
00325
00326
00327
00328
00329
00330
00331
00332 this->SetWidgetsDisabledState(_local_company != owner,
00333 GRP_WIDGET_CREATE_GROUP,
00334 GRP_WIDGET_AVAILABLE_VEHICLES,
00335 WIDGET_LIST_END);
00336
00337
00338
00339
00340 if (IsDefaultGroupID(this->group_sel) || IsAllGroupID(this->group_sel)) {
00341 SetDParam(0, owner);
00342 SetDParam(1, this->vehicles.Length());
00343
00344 switch (this->vehicle_type) {
00345 case VEH_TRAIN:
00346 this->widget[GRP_WIDGET_CAPTION].data = STR_881B_TRAINS;
00347 this->widget[GRP_WIDGET_REPLACE_PROTECTION].data = SPR_GROUP_REPLACE_OFF_TRAIN;
00348 break;
00349 case VEH_ROAD:
00350 this->widget[GRP_WIDGET_CAPTION].data = STR_9001_ROAD_VEHICLES;
00351 this->widget[GRP_WIDGET_REPLACE_PROTECTION].data = SPR_GROUP_REPLACE_OFF_ROADVEH;
00352 break;
00353 case VEH_SHIP:
00354 this->widget[GRP_WIDGET_CAPTION].data = STR_9805_SHIPS;
00355 this->widget[GRP_WIDGET_REPLACE_PROTECTION].data = SPR_GROUP_REPLACE_OFF_SHIP;
00356 break;
00357 case VEH_AIRCRAFT:
00358 this->widget[GRP_WIDGET_CAPTION].data = STR_A009_AIRCRAFT;
00359 this->widget[GRP_WIDGET_REPLACE_PROTECTION].data = SPR_GROUP_REPLACE_OFF_AIRCRAFT;
00360 break;
00361 default: NOT_REACHED();
00362 }
00363 } else {
00364 const Group *g = GetGroup(this->group_sel);
00365
00366 SetDParam(0, g->index);
00367 SetDParam(1, g->num_vehicle);
00368
00369 switch (this->vehicle_type) {
00370 case VEH_TRAIN:
00371 this->widget[GRP_WIDGET_CAPTION].data = STR_GROUP_TRAINS_CAPTION;
00372 this->widget[GRP_WIDGET_REPLACE_PROTECTION].data = (g->replace_protection) ? SPR_GROUP_REPLACE_ON_TRAIN : SPR_GROUP_REPLACE_OFF_TRAIN;
00373 break;
00374 case VEH_ROAD:
00375 this->widget[GRP_WIDGET_CAPTION].data = STR_GROUP_ROADVEH_CAPTION;
00376 this->widget[GRP_WIDGET_REPLACE_PROTECTION].data = (g->replace_protection) ? SPR_GROUP_REPLACE_ON_ROADVEH : SPR_GROUP_REPLACE_OFF_ROADVEH;
00377 break;
00378 case VEH_SHIP:
00379 this->widget[GRP_WIDGET_CAPTION].data = STR_GROUP_SHIPS_CAPTION;
00380 this->widget[GRP_WIDGET_REPLACE_PROTECTION].data = (g->replace_protection) ? SPR_GROUP_REPLACE_ON_SHIP : SPR_GROUP_REPLACE_OFF_SHIP;
00381 break;
00382 case VEH_AIRCRAFT:
00383 this->widget[GRP_WIDGET_CAPTION].data = STR_GROUP_AIRCRAFTS_CAPTION;
00384 this->widget[GRP_WIDGET_REPLACE_PROTECTION].data = (g->replace_protection) ? SPR_GROUP_REPLACE_ON_AIRCRAFT : SPR_GROUP_REPLACE_OFF_AIRCRAFT;
00385 break;
00386 default: NOT_REACHED();
00387 }
00388 }
00389
00390
00391 this->widget[GRP_WIDGET_SORT_BY_DROPDOWN].data = this->vehicle_sorter_names[this->vehicles.SortType()];
00392
00393 this->DrawWidgets();
00394
00395
00396
00397 StringID str_all_veh, str_no_group_veh;
00398
00399 switch (this->vehicle_type) {
00400 case VEH_TRAIN:
00401 str_all_veh = STR_GROUP_ALL_TRAINS;
00402 str_no_group_veh = STR_GROUP_DEFAULT_TRAINS;
00403 break;
00404 case VEH_ROAD:
00405 str_all_veh = STR_GROUP_ALL_ROADS;
00406 str_no_group_veh = STR_GROUP_DEFAULT_ROADS;
00407 break;
00408 case VEH_SHIP:
00409 str_all_veh = STR_GROUP_ALL_SHIPS;
00410 str_no_group_veh = STR_GROUP_DEFAULT_SHIPS;
00411 break;
00412 case VEH_AIRCRAFT:
00413 str_all_veh = STR_GROUP_ALL_AIRCRAFTS;
00414 str_no_group_veh = STR_GROUP_DEFAULT_AIRCRAFTS;
00415 break;
00416 default: NOT_REACHED();
00417 }
00418 DrawString(10, y1, str_all_veh, IsAllGroupID(this->group_sel) ? TC_WHITE : TC_BLACK);
00419
00420 y1 += 13;
00421
00422 DrawString(10, y1, str_no_group_veh, IsDefaultGroupID(this->group_sel) ? TC_WHITE : TC_BLACK);
00423
00424 max = min(this->vscroll2.pos + this->vscroll2.cap, this->groups.Length());
00425 for (i = this->vscroll2.pos ; i < max ; ++i) {
00426 const Group *g = this->groups[i];
00427
00428 assert(g->owner == owner);
00429
00430 y1 += PLY_WND_PRC__SIZE_OF_ROW_TINY;
00431
00432
00433 SetDParam(0, g->index);
00434 DrawString(10, y1, STR_GROUP_NAME, (this->group_sel == g->index) ? TC_WHITE : TC_BLACK);
00435
00436
00437 SetDParam(0, g->num_vehicle);
00438 DrawStringRightAligned(187, y1 + 1, STR_GROUP_TINY_NUM, (this->group_sel == g->index) ? TC_WHITE : TC_BLACK);
00439 }
00440
00441 this->DrawSortButtonState(GRP_WIDGET_SORT_BY_ORDER, this->vehicles.IsDescSortOrder() ? SBS_DOWN : SBS_UP);
00442
00443 this->DrawVehicleListItems(x, this->vehicle_sel);
00444 }
00445
00446 virtual void OnClick(Point pt, int widget)
00447 {
00448 if (widget != GRP_WIDGET_SORT_BY_DROPDOWN && widget != GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN) HideDropDownMenu(this);
00449
00450 switch(widget) {
00451 case GRP_WIDGET_SORT_BY_ORDER:
00452 this->vehicles.ToggleSortOrder();
00453 this->SetDirty();
00454 break;
00455
00456 case GRP_WIDGET_SORT_BY_DROPDOWN:
00457 ShowDropDownMenu(this, this->vehicle_sorter_names, this->vehicles.SortType(), GRP_WIDGET_SORT_BY_DROPDOWN, 0, (this->vehicle_type == VEH_TRAIN || this->vehicle_type == VEH_ROAD) ? 0 : (1 << 10));
00458 return;
00459
00460 case GRP_WIDGET_ALL_VEHICLES:
00461 if (!IsAllGroupID(this->group_sel)) {
00462 this->group_sel = ALL_GROUP;
00463 this->vehicles.ForceRebuild();
00464 this->SetDirty();
00465 }
00466 break;
00467
00468 case GRP_WIDGET_DEFAULT_VEHICLES:
00469 if (!IsDefaultGroupID(this->group_sel)) {
00470 this->group_sel = DEFAULT_GROUP;
00471 this->vehicles.ForceRebuild();
00472 this->SetDirty();
00473 }
00474 break;
00475
00476 case GRP_WIDGET_LIST_GROUP: {
00477 uint16 id_g = (pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET - 26) / PLY_WND_PRC__SIZE_OF_ROW_TINY;
00478
00479 if (id_g >= this->vscroll2.cap) return;
00480
00481 id_g += this->vscroll2.pos;
00482
00483 if (id_g >= this->groups.Length()) return;
00484
00485 this->group_sel = this->groups[id_g]->index;;
00486
00487 this->vehicles.ForceRebuild();
00488 this->SetDirty();
00489 break;
00490 }
00491
00492 case GRP_WIDGET_LIST_VEHICLE: {
00493 uint32 id_v = (pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / (int)this->resize.step_height;
00494 const Vehicle *v;
00495
00496 if (id_v >= this->vscroll.cap) return;
00497
00498 id_v += this->vscroll.pos;
00499
00500 if (id_v >= this->vehicles.Length()) return;
00501
00502 v = this->vehicles[id_v];
00503
00504 this->vehicle_sel = v->index;
00505
00506 if (v->IsValid()) {
00507 SetObjectToPlaceWnd(v->GetImage(DIR_W), GetVehiclePalette(v), VHM_DRAG, this);
00508 _cursor.vehchain = true;
00509 }
00510
00511 this->SetDirty();
00512 break;
00513 }
00514
00515 case GRP_WIDGET_CREATE_GROUP:
00516 DoCommandP(0, this->vehicle_type, 0, NULL, CMD_CREATE_GROUP | CMD_MSG(STR_GROUP_CAN_T_CREATE));
00517 break;
00518
00519 case GRP_WIDGET_DELETE_GROUP: {
00520 GroupID group = this->group_sel;
00521 this->group_sel = ALL_GROUP;
00522
00523 DoCommandP(0, group, 0, NULL, CMD_DELETE_GROUP | CMD_MSG(STR_GROUP_CAN_T_DELETE));
00524 break;
00525 }
00526
00527 case GRP_WIDGET_RENAME_GROUP: {
00528 assert(IsValidGroupID(this->group_sel));
00529
00530 const Group *g = GetGroup(this->group_sel);
00531
00532 SetDParam(0, g->index);
00533 ShowQueryString(STR_GROUP_NAME, STR_GROUP_RENAME_CAPTION, MAX_LENGTH_GROUP_NAME_BYTES, MAX_LENGTH_GROUP_NAME_PIXELS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT);
00534 } break;
00535
00536
00537 case GRP_WIDGET_AVAILABLE_VEHICLES:
00538 ShowBuildVehicleWindow(0, this->vehicle_type);
00539 break;
00540
00541 case GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN:
00542 ShowGroupActionDropdown(this, this->group_sel);
00543 break;
00544
00545 case GRP_WIDGET_START_ALL:
00546 case GRP_WIDGET_STOP_ALL: {
00547 DoCommandP(0, this->group_sel, ((IsAllGroupID(this->group_sel) ? VLW_STANDARD : VLW_GROUP_LIST) & VLW_MASK)
00548 | (1 << 6)
00549 | (widget == GRP_WIDGET_START_ALL ? (1 << 5) : 0)
00550 | this->vehicle_type, NULL, CMD_MASS_START_STOP);
00551
00552 break;
00553 }
00554
00555 case GRP_WIDGET_REPLACE_PROTECTION:
00556 if (IsValidGroupID(this->group_sel)) {
00557 const Group *g = GetGroup(this->group_sel);
00558
00559 DoCommandP(0, this->group_sel, !g->replace_protection, NULL, CMD_SET_GROUP_REPLACE_PROTECTION);
00560 }
00561 break;
00562 }
00563 }
00564
00565 virtual void OnDragDrop(Point pt, int widget)
00566 {
00567 switch (widget) {
00568 case GRP_WIDGET_ALL_VEHICLES:
00569 case GRP_WIDGET_DEFAULT_VEHICLES:
00570 DoCommandP(0, DEFAULT_GROUP, this->vehicle_sel, NULL, CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_GROUP_CAN_T_ADD_VEHICLE));
00571
00572 this->vehicle_sel = INVALID_VEHICLE;
00573
00574 this->SetDirty();
00575
00576 break;
00577
00578 case GRP_WIDGET_LIST_GROUP: {
00579 uint16 id_g = (pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET - 26) / PLY_WND_PRC__SIZE_OF_ROW_TINY;
00580 const VehicleID vindex = this->vehicle_sel;
00581
00582 this->vehicle_sel = INVALID_VEHICLE;
00583
00584 this->SetDirty();
00585
00586 if (id_g >= this->vscroll2.cap) return;
00587
00588 id_g += this->vscroll2.pos;
00589
00590 if (id_g >= this->groups.Length()) return;
00591
00592 DoCommandP(0, this->groups[id_g]->index, vindex, NULL, CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_GROUP_CAN_T_ADD_VEHICLE));
00593
00594 break;
00595 }
00596
00597 case GRP_WIDGET_LIST_VEHICLE: {
00598 uint32 id_v = (pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / (int)this->resize.step_height;
00599 const Vehicle *v;
00600 const VehicleID vindex = this->vehicle_sel;
00601
00602 this->vehicle_sel = INVALID_VEHICLE;
00603
00604 this->SetDirty();
00605
00606 if (id_v >= this->vscroll.cap) return;
00607
00608 id_v += this->vscroll.pos;
00609
00610 if (id_v >= this->vehicles.Length()) return;
00611
00612 v = this->vehicles[id_v];
00613
00614 if (vindex == v->index) {
00615 ShowVehicleViewWindow(v);
00616 }
00617
00618 break;
00619 }
00620 }
00621 _cursor.vehchain = false;
00622 }
00623
00624 virtual void OnQueryTextFinished(char *str)
00625 {
00626 if (str == NULL) return;
00627
00628 _cmd_text = str;
00629 DoCommandP(0, this->group_sel, 0, NULL, CMD_RENAME_GROUP | CMD_MSG(STR_GROUP_CAN_T_RENAME));
00630 }
00631
00632 virtual void OnResize(Point new_size, Point delta)
00633 {
00634 this->vscroll2.cap += delta.y / PLY_WND_PRC__SIZE_OF_ROW_TINY;
00635 this->vscroll.cap += delta.y / (int)this->resize.step_height;
00636
00637 this->widget[GRP_WIDGET_LIST_GROUP].data = (this->vscroll2.cap << 8) + 1;
00638 this->widget[GRP_WIDGET_LIST_VEHICLE].data = (this->vscroll.cap << 8) + 1;
00639 }
00640
00641 virtual void OnDropdownSelect(int widget, int index)
00642 {
00643 switch (widget) {
00644 case GRP_WIDGET_SORT_BY_DROPDOWN:
00645 this->vehicles.SetSortType(index);
00646 break;
00647
00648 case GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN:
00649 assert(this->vehicles.Length() != 0);
00650
00651 switch (index) {
00652 case GALF_REPLACE:
00653 ShowReplaceGroupVehicleWindow(this->group_sel, this->vehicle_type);
00654 break;
00655 case GALF_SERVICE:
00656 DoCommandP(0, this->group_sel, ((IsAllGroupID(this->group_sel) ? VLW_STANDARD : VLW_GROUP_LIST) & VLW_MASK)
00657 | DEPOT_MASS_SEND
00658 | DEPOT_SERVICE, NULL, GetCmdSendToDepot(this->vehicle_type));
00659 break;
00660 case GALF_DEPOT:
00661 DoCommandP(0, this->group_sel, ((IsAllGroupID(this->group_sel) ? VLW_STANDARD : VLW_GROUP_LIST) & VLW_MASK)
00662 | DEPOT_MASS_SEND, NULL, GetCmdSendToDepot(this->vehicle_type));
00663 break;
00664 case GALF_ADD_SHARED:
00665 assert(IsValidGroupID(this->group_sel));
00666
00667 DoCommandP(0, this->group_sel, this->vehicle_type, NULL, CMD_ADD_SHARED_VEHICLE_GROUP | CMD_MSG(STR_GROUP_CAN_T_ADD_SHARED_VEHICLE));
00668 break;
00669 case GALF_REMOVE_ALL:
00670 assert(IsValidGroupID(this->group_sel));
00671
00672 DoCommandP(0, this->group_sel, this->vehicle_type, NULL, CMD_REMOVE_ALL_VEHICLES_GROUP | CMD_MSG(STR_GROUP_CAN_T_REMOVE_ALL_VEHICLES));
00673 break;
00674 default: NOT_REACHED();
00675 }
00676 break;
00677
00678 default: NOT_REACHED();
00679 }
00680
00681 this->SetDirty();
00682 }
00683
00684 virtual void OnTick()
00685 {
00686 if (_pause_game != 0) return;
00687 if (this->groups.NeedResort() || this->vehicles.NeedResort()) {
00688 this->SetDirty();
00689 }
00690 }
00691
00692 virtual void OnPlaceObjectAbort()
00693 {
00694
00695 this->vehicle_sel = INVALID_VEHICLE;
00696 this->InvalidateWidget(GRP_WIDGET_LIST_VEHICLE);
00697 }
00698 };
00699
00700
00701 static WindowDesc _group_desc = {
00702 WDP_AUTO, WDP_AUTO, 460, 194, 460, 246,
00703 WC_INVALID, WC_NONE,
00704 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
00705 _group_widgets,
00706 };
00707
00708 void ShowCompanyGroup(CompanyID company, VehicleType vehicle_type)
00709 {
00710 if (!IsValidCompanyID(company)) return;
00711
00712 _group_desc.cls = GetWindowClassForVehicleType(vehicle_type);
00713 WindowNumber num = (vehicle_type << 11) | VLW_GROUP_LIST | company;
00714 AllocateWindowDescFront<VehicleGroupWindow>(&_group_desc, num);
00715 }