src/group_gui.cpp
changeset 9369 1c3d22cfdeb5
parent 9368 613ecee3302e
child 9376 afdc4beedc99
equal deleted inserted replaced
9368:613ecee3302e 9369:1c3d22cfdeb5
    27 
    27 
    28 #include "table/strings.h"
    28 #include "table/strings.h"
    29 #include "table/sprites.h"
    29 #include "table/sprites.h"
    30 
    30 
    31 typedef GUIList<const Group*> GUIGroupList;
    31 typedef GUIList<const Group*> GUIGroupList;
    32 
       
    33 static void BuildGroupList(GUIGroupList *gl, PlayerID owner, VehicleType vehicle_type)
       
    34 {
       
    35 	if (!(gl->flags & VL_REBUILD)) return;
       
    36 
       
    37 	gl->Clear();
       
    38 
       
    39 	const Group *g;
       
    40 	FOR_ALL_GROUPS(g) {
       
    41 		if (g->owner == owner && g->vehicle_type != vehicle_type) *gl->Append() = g;
       
    42 	}
       
    43 
       
    44 	gl->Compact();
       
    45 
       
    46 	gl->flags &= ~VL_REBUILD;
       
    47 	gl->flags |= VL_RESORT;
       
    48 }
       
    49 
       
    50 
       
    51 static int CDECL GroupNameSorter(const void *a, const void *b)
       
    52 {
       
    53 	static const Group *last_group[2] = { NULL, NULL };
       
    54 	static char         last_name[2][64] = { "", "" };
       
    55 
       
    56 	const Group *ga = *(const Group**)a;
       
    57 	const Group *gb = *(const Group**)b;
       
    58 	int r;
       
    59 
       
    60 	if (ga != last_group[0]) {
       
    61 		last_group[0] = ga;
       
    62 		SetDParam(0, ga->index);
       
    63 		GetString(last_name[0], STR_GROUP_NAME, lastof(last_name[0]));
       
    64 	}
       
    65 
       
    66 	if (gb != last_group[1]) {
       
    67 		last_group[1] = gb;
       
    68 		SetDParam(0, gb->index);
       
    69 		GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1]));
       
    70 	}
       
    71 
       
    72 	r = strcmp(last_name[0], last_name[1]); // sort by name
       
    73 
       
    74 	if (r == 0) return ga->index - gb->index;
       
    75 
       
    76 	return r;
       
    77 }
       
    78 
       
    79 
       
    80 static void SortGroupList(GUIGroupList *gl)
       
    81 {
       
    82 	if (!(gl->flags & VL_RESORT)) return;
       
    83 
       
    84 	qsort((void*)gl->Begin(), gl->Length(), sizeof(gl->Begin()), GroupNameSorter);
       
    85 
       
    86 	gl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
       
    87 	gl->flags &= ~VL_RESORT;
       
    88 }
       
    89 
       
    90 
    32 
    91 enum GroupListWidgets {
    33 enum GroupListWidgets {
    92 	GRP_WIDGET_CLOSEBOX = 0,
    34 	GRP_WIDGET_CLOSEBOX = 0,
    93 	GRP_WIDGET_CAPTION,
    35 	GRP_WIDGET_CAPTION,
    94 	GRP_WIDGET_STICKY,
    36 	GRP_WIDGET_STICKY,
   174 {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   448,   459,   182,   193, 0x0,                  STR_RESIZE_BUTTON},
   116 {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   448,   459,   182,   193, 0x0,                  STR_RESIZE_BUTTON},
   175 {   WIDGETS_END},
   117 {   WIDGETS_END},
   176 };
   118 };
   177 
   119 
   178 
   120 
   179 struct VehicleGroupWindow : public Window, public VehicleListBase {
   121 class VehicleGroupWindow : public Window, public VehicleListBase {
       
   122 private:
   180 	GroupID group_sel;
   123 	GroupID group_sel;
   181 	VehicleID vehicle_sel;
   124 	VehicleID vehicle_sel;
   182 	GUIGroupList groups;
   125 	GUIGroupList groups;
   183 
   126 
       
   127 	/**
       
   128 	 * (Re)Build the group list.
       
   129 	 *
       
   130 	 * @param owner The owner of the window
       
   131 	 */
       
   132 	void BuildGroupList(PlayerID owner)
       
   133 	{
       
   134 		if (!this->groups.NeedRebuild()) return;
       
   135 
       
   136 		this->groups.Clear();
       
   137 
       
   138 		const Group *g;
       
   139 		FOR_ALL_GROUPS(g) {
       
   140 			if (g->owner == owner && g->vehicle_type == this->vehicle_type) {
       
   141 				*this->groups.Append() = g;
       
   142 			}
       
   143 		}
       
   144 
       
   145 		this->groups.Compact();
       
   146 		this->groups.RebuildDone();
       
   147 	}
       
   148 
       
   149 	/** Sort the groups by their name */
       
   150 	static int GroupNameSorter(const Group* const *a, const Group* const *b)
       
   151 	{
       
   152 		static const Group *last_group[2] = { NULL, NULL };
       
   153 		static char         last_name[2][64] = { "", "" };
       
   154 
       
   155 		if (*a != last_group[0]) {
       
   156 			last_group[0] = *a;
       
   157 			SetDParam(0, (*a)->index);
       
   158 			GetString(last_name[0], STR_GROUP_NAME, lastof(last_name[0]));
       
   159 		}
       
   160 
       
   161 		if (*b != last_group[1]) {
       
   162 			last_group[1] = *b;
       
   163 			SetDParam(0, (*b)->index);
       
   164 			GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1]));
       
   165 		}
       
   166 
       
   167 		int r = strcmp(last_name[0], last_name[1]); // sort by name
       
   168 		if (r == 0) return (*a)->index - (*b)->index;
       
   169 		return r;
       
   170 	}
       
   171 
       
   172 public:
   184 	VehicleGroupWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
   173 	VehicleGroupWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
   185 	{
   174 	{
   186 		const PlayerID owner = (PlayerID)GB(this->window_number, 0, 8);
   175 		const PlayerID owner = (PlayerID)GB(this->window_number, 0, 8);
   187 		this->vehicle_type = (VehicleType)GB(this->window_number, 11, 5);
   176 		this->vehicle_type = (VehicleType)GB(this->window_number, 11, 5);
   188 
   177 
   219 
   208 
   220 		this->vehicles.sort_type = this->sorting->criteria;
   209 		this->vehicles.sort_type = this->sorting->criteria;
   221 		this->vehicles.flags = VL_REBUILD | (this->sorting->order ? VL_DESC : VL_NONE);
   210 		this->vehicles.flags = VL_REBUILD | (this->sorting->order ? VL_DESC : VL_NONE);
   222 		this->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; // Set up resort timer
   211 		this->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; // Set up resort timer
   223 
   212 
   224 		this->groups.flags = VL_REBUILD | VL_NONE;
   213 		this->groups.ForceRebuild();
   225 		this->groups.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; // Set up resort timer
   214 		this->groups.NeedResort();
   226 
   215 
   227 		this->group_sel = ALL_GROUP;
   216 		this->group_sel = ALL_GROUP;
   228 		this->vehicle_sel = INVALID_VEHICLE;
   217 		this->vehicle_sel = INVALID_VEHICLE;
   229 
   218 
   230 		switch (this->vehicle_type) {
   219 		switch (this->vehicle_type) {
   275 	}
   264 	}
   276 
   265 
   277 	virtual void OnInvalidateData(int data)
   266 	virtual void OnInvalidateData(int data)
   278 	{
   267 	{
   279 		this->vehicles.flags |= (data == 0 ? VL_REBUILD : VL_RESORT);
   268 		this->vehicles.flags |= (data == 0 ? VL_REBUILD : VL_RESORT);
   280 		this->groups.flags |= (data == 0 ? VL_REBUILD : VL_RESORT);
   269 
       
   270 		if (data == 0) {
       
   271 			this->groups.ForceRebuild();
       
   272 		} else {
       
   273 			this->groups.ForceResort();
       
   274 		}
       
   275 
   281 		if (!(IsAllGroupID(this->group_sel) || IsDefaultGroupID(this->group_sel) || IsValidGroupID(this->group_sel))) {
   276 		if (!(IsAllGroupID(this->group_sel) || IsDefaultGroupID(this->group_sel) || IsValidGroupID(this->group_sel))) {
   282 			this->group_sel = ALL_GROUP;
   277 			this->group_sel = ALL_GROUP;
   283 			HideDropDownMenu(this);
   278 			HideDropDownMenu(this);
   284 		}
   279 		}
   285 		this->SetDirty();
   280 		this->SetDirty();
   297 		/* If we select the all vehicles, this->list will contain all vehicles of the player
   292 		/* If we select the all vehicles, this->list will contain all vehicles of the player
   298 			* else this->list will contain all vehicles which belong to the selected group */
   293 			* else this->list will contain all vehicles which belong to the selected group */
   299 		BuildVehicleList(this, owner, this->group_sel, IsAllGroupID(this->group_sel) ? VLW_STANDARD : VLW_GROUP_LIST);
   294 		BuildVehicleList(this, owner, this->group_sel, IsAllGroupID(this->group_sel) ? VLW_STANDARD : VLW_GROUP_LIST);
   300 		SortVehicleList(this);
   295 		SortVehicleList(this);
   301 
   296 
   302 
   297 		this->BuildGroupList(owner);
   303 		BuildGroupList(&this->groups, owner, this->vehicle_type);
   298 		this->groups.Sort(GroupNameSorter);
   304 		SortGroupList(&this->groups);
       
   305 
   299 
   306 		SetVScrollCount(this, this->groups.Length());
   300 		SetVScrollCount(this, this->groups.Length());
   307 		SetVScroll2Count(this, this->vehicles.Length());
   301 		SetVScroll2Count(this, this->vehicles.Length());
   308 
   302 
   309 		/* The drop down menu is out, *but* it may not be used, retract it. */
   303 		/* The drop down menu is out, *but* it may not be used, retract it. */
   724 		if (--this->vehicles.resort_timer == 0) {
   718 		if (--this->vehicles.resort_timer == 0) {
   725 			this->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
   719 			this->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
   726 			this->vehicles.flags |= VL_RESORT;
   720 			this->vehicles.flags |= VL_RESORT;
   727 			this->SetDirty();
   721 			this->SetDirty();
   728 		}
   722 		}
   729 		if (--this->groups.resort_timer == 0) {
   723 		if (this->groups.NeedResort()) {
   730 			this->groups.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
       
   731 			this->groups.flags |= VL_RESORT;
       
   732 			this->SetDirty();
   724 			this->SetDirty();
   733 		}
   725 		}
   734 	}
   726 	}
   735 
   727 
   736 	virtual void OnPlaceObjectAbort()
   728 	virtual void OnPlaceObjectAbort()