group_gui.cpp

Go to the documentation of this file.
00001 /* $Id: group_gui.cpp 14422 2008-09-30 20:51:04Z rubidium $ */
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]); // sort by name
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     /* If we select the all vehicles, this->list will contain all vehicles of the owner
00296      * else this->list will contain all vehicles which belong to the selected group */
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     /* The drop down menu is out, *but* it may not be used, retract it. */
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     /* Disable all lists management button when the list is empty */
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     /* Disable the group specific function when we select the default group or all vehicles */
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     /* Disable remaining buttons for non-local companies
00327      * Needed while changing _local_company, eg. by cheats
00328      * All procedures (eg. move vehicle to another group)
00329      *  verify, whether you are the owner of the vehicle,
00330      *  so it doesn't have to be disabled
00331      */
00332     this->SetWidgetsDisabledState(_local_company != owner,
00333         GRP_WIDGET_CREATE_GROUP,
00334         GRP_WIDGET_AVAILABLE_VEHICLES,
00335         WIDGET_LIST_END);
00336 
00337 
00338     /* If selected_group == DEFAULT_GROUP || ALL_GROUP, draw the standard caption
00339         We list all vehicles or ungrouped vehicles */
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     /* Set text of sort by dropdown */
00391     this->widget[GRP_WIDGET_SORT_BY_DROPDOWN].data = this->vehicle_sorter_names[this->vehicles.SortType()];
00392 
00393     this->DrawWidgets();
00394 
00395     /* Draw Matrix Group
00396       * The selected group is drawn in white */
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       /* draw the selected group in white, else we draw it in black */
00433       SetDParam(0, g->index);
00434       DrawString(10, y1, STR_GROUP_NAME, (this->group_sel == g->index) ? TC_WHITE : TC_BLACK);
00435 
00436       /* draw the number of vehicles of the group */
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: // Flip sorting method ascending/descending
00452         this->vehicles.ToggleSortOrder();
00453         this->SetDirty();
00454         break;
00455 
00456       case GRP_WIDGET_SORT_BY_DROPDOWN: // Select sorting criteria dropdown menu
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: // All vehicles button
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: // Ungrouped vehicles button
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: { // Matrix 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: { // Matrix 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; // click out of bounds
00497 
00498         id_v += this->vscroll.pos;
00499 
00500         if (id_v >= this->vehicles.Length()) return; // click out of list bound
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: // Create a new 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: { // Delete the selected 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: { // Rename the selected roup
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: { // Start/stop all vehicles of the list
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: // All vehicles
00569       case GRP_WIDGET_DEFAULT_VEHICLES: // Ungrouped 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: { // Maxtrix 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: { // Maxtrix 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; // click out of bounds
00607 
00608         id_v += this->vscroll.pos;
00609 
00610         if (id_v >= this->vehicles.Length()) return; // click out of list bound
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: // Replace window
00653             ShowReplaceGroupVehicleWindow(this->group_sel, this->vehicle_type);
00654             break;
00655           case GALF_SERVICE: // Send for servicing
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: // Send to Depots
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: // Add shared Vehicles
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: // Remove all Vehicles from the selected group
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     /* abort drag & drop */
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 }

Generated on Fri Nov 21 19:01:32 2008 for openttd by  doxygen 1.5.6