src/station_gui.cpp
changeset 9190 31a03ef45575
parent 9185 6753f417e92e
child 9191 471b623a46b8
equal deleted inserted replaced
9189:128a1809a977 9190:31a03ef45575
   163 	}
   163 	}
   164 
   164 
   165 	return (_internal_sort_order & 1) ? maxr2 - maxr1 : maxr1 - maxr2;
   165 	return (_internal_sort_order & 1) ? maxr2 - maxr1 : maxr1 - maxr2;
   166 }
   166 }
   167 
   167 
   168 /** Flags for station list */
   168 typedef GUIList<const Station*> plstations_d;
   169 enum StationListFlags {
       
   170 	SL_ORDER   = 1 << 0, ///< Order - ascending (=0), descending (=1)
       
   171 	SL_RESORT  = 1 << 1, ///< Resort the list
       
   172 	SL_REBUILD = 1 << 2, ///< Rebuild the list
       
   173 };
       
   174 
       
   175 DECLARE_ENUM_AS_BIT_SET(StationListFlags);
       
   176 
       
   177 /** Information about station list */
       
   178 struct plstations_d {
       
   179 	const Station **sort_list; ///< Pointer to list of stations
       
   180 	uint16 list_length;        ///< Number of stations in list
       
   181 	uint16 resort_timer;       ///< Tick counter to resort the list
       
   182 	byte sort_type;            ///< Sort type - name, waiting, ...
       
   183 	byte flags;                ///< Flags - SL_ORDER, SL_RESORT, SL_REBUILD
       
   184 };
       
   185 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(plstations_d));
   169 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(plstations_d));
   186 
   170 
   187 /**
   171 /**
   188  * Set the station sort flag for all station-list windows.
   172  * Set the station sort flag for all station-list windows.
   189  * @param sl_flag Sort list flag to set for all station-list windows
   173  * @param sl_flag Sort list flag to set for all station-list windows
   190  */
   174  */
   191 static void SetStationListsFlag(StationListFlags sl_flag)
   175 static void SetStationListsFlag(SortListFlags sl_flag)
   192 {
   176 {
   193 	Window *const *wz;
   177 	Window *const *wz;
   194 
   178 
   195 	FOR_ALL_WINDOWS(wz) {
   179 	FOR_ALL_WINDOWS(wz) {
   196 		Window *w = *wz;
   180 		Window *w = *wz;
   200 		}
   184 		}
   201 	}
   185 	}
   202 }
   186 }
   203 
   187 
   204 /**
   188 /**
   205  * Set the 'SL_REBUILD' flag for all station lists
   189  * Set the 'VL_REBUILD' flag for all station lists
   206  */
   190  */
   207 void RebuildStationLists()
   191 void RebuildStationLists()
   208 {
   192 {
   209 	SetStationListsFlag(SL_REBUILD);
   193 	SetStationListsFlag(VL_REBUILD);
   210 }
   194 }
   211 
   195 
   212 /**
   196 /**
   213  * Set the 'SL_RESORT' flag for all station lists
   197  * Set the 'VL_RESORT' flag for all station lists
   214  */
   198  */
   215 void ResortStationLists()
   199 void ResortStationLists()
   216 {
   200 {
   217 	SetStationListsFlag(SL_RESORT);
   201 	SetStationListsFlag(VL_RESORT);
   218 }
   202 }
   219 
   203 
   220 /**
   204 /**
   221  * Rebuild station list if the SL_REBUILD flag is set
   205  * Rebuild station list if the VL_REBUILD flag is set
   222  *
   206  *
   223  * @param sl pointer to plstations_d (station list and flags)
   207  * @param sl pointer to plstations_d (station list and flags)
   224  * @param owner player whose stations are to be in list
   208  * @param owner player whose stations are to be in list
   225  * @param facilities types of stations of interest
   209  * @param facilities types of stations of interest
   226  * @param cargo_filter bitmap of cargo types to include
   210  * @param cargo_filter bitmap of cargo types to include
   229 static void BuildStationsList(plstations_d *sl, PlayerID owner, byte facilities, uint32 cargo_filter, bool include_empty)
   213 static void BuildStationsList(plstations_d *sl, PlayerID owner, byte facilities, uint32 cargo_filter, bool include_empty)
   230 {
   214 {
   231 	uint n = 0;
   215 	uint n = 0;
   232 	const Station *st;
   216 	const Station *st;
   233 
   217 
   234 	if (!(sl->flags & SL_REBUILD)) return;
   218 	if (!(sl->flags & VL_REBUILD)) return;
   235 
   219 
   236 	/* Create array for sorting */
   220 	/* Create array for sorting */
   237 	const Station **station_sort = MallocT<const Station*>(GetMaxStationIndex() + 1);
   221 	const Station **station_sort = MallocT<const Station*>(GetMaxStationIndex() + 1);
   238 
   222 
   239 	DEBUG(misc, 3, "Building station list for player %d", owner);
   223 	DEBUG(misc, 3, "Building station list for player %d", owner);
   263 	sl->sort_list = MallocT<const Station*>(n);
   247 	sl->sort_list = MallocT<const Station*>(n);
   264 	sl->list_length = n;
   248 	sl->list_length = n;
   265 
   249 
   266 	for (uint i = 0; i < n; ++i) sl->sort_list[i] = station_sort[i];
   250 	for (uint i = 0; i < n; ++i) sl->sort_list[i] = station_sort[i];
   267 
   251 
   268 	sl->flags &= ~SL_REBUILD;
   252 	sl->flags &= ~VL_REBUILD;
   269 	sl->flags |= SL_RESORT;
   253 	sl->flags |= VL_RESORT;
   270 	free((void*)station_sort);
   254 	free((void*)station_sort);
   271 }
   255 }
   272 
   256 
   273 
   257 
   274 /**
   258 /**
   275  * Sort station list if the SL_RESORT flag is set
   259  * Sort station list if the VL_RESORT flag is set
   276  *
   260  *
   277  * @param sl pointer to plstations_d (station list and flags)
   261  * @param sl pointer to plstations_d (station list and flags)
   278  */
   262  */
   279 static void SortStationsList(plstations_d *sl)
   263 static void SortStationsList(plstations_d *sl)
   280 {
   264 {
   283 		&StationTypeSorter,
   267 		&StationTypeSorter,
   284 		&StationWaitingSorter,
   268 		&StationWaitingSorter,
   285 		&StationRatingMaxSorter
   269 		&StationRatingMaxSorter
   286 	};
   270 	};
   287 
   271 
   288 	if (!(sl->flags & SL_RESORT)) return;
   272 	if (!(sl->flags & VL_RESORT)) return;
   289 
   273 
   290 	_internal_sort_order = sl->flags & SL_ORDER;
   274 	_internal_sort_order = sl->flags & VL_DESC;
   291 	_last_station = NULL; // used for "cache" in namesorting
   275 	_last_station = NULL; // used for "cache" in namesorting
   292 	qsort((void*)sl->sort_list, sl->list_length, sizeof(sl->sort_list[0]), _station_sorter[sl->sort_type]);
   276 	qsort((void*)sl->sort_list, sl->list_length, sizeof(sl->sort_list[0]), _station_sorter[sl->sort_type]);
   293 
   277 
   294 	sl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
   278 	sl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
   295 	sl->flags &= ~SL_RESORT;
   279 	sl->flags &= ~VL_RESORT;
   296 }
   280 }
   297 
   281 
   298 /**
   282 /**
   299  * Fuction called when any WindowEvent occurs for PlayerStations window
   283  * Fuction called when any WindowEvent occurs for PlayerStations window
   300  *
   284  *
   320 			w->SetWidgetLoweredState(SLW_FACILALL, facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
   304 			w->SetWidgetLoweredState(SLW_FACILALL, facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
   321 			w->SetWidgetLoweredState(SLW_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
   305 			w->SetWidgetLoweredState(SLW_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
   322 			w->SetWidgetLoweredState(SLW_NOCARGOWAITING, include_empty);
   306 			w->SetWidgetLoweredState(SLW_NOCARGOWAITING, include_empty);
   323 
   307 
   324 			sl->sort_list = NULL;
   308 			sl->sort_list = NULL;
   325 			sl->flags = SL_REBUILD;
   309 			sl->flags = VL_REBUILD;
   326 			sl->sort_type = station_sort.criteria;
   310 			sl->sort_type = station_sort.criteria;
   327 			if (station_sort.order) sl->flags |= SL_ORDER;
   311 			if (station_sort.order) sl->flags |= VL_DESC;
   328 
   312 
   329 			/* set up resort timer */
   313 			/* set up resort timer */
   330 			sl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
   314 			sl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
   331 			break;
   315 			break;
   332 
   316 
   344 			w->widget[SLW_SORTDROPBTN].data = _station_sort_listing[sl->sort_type];
   328 			w->widget[SLW_SORTDROPBTN].data = _station_sort_listing[sl->sort_type];
   345 
   329 
   346 			DrawWindowWidgets(w);
   330 			DrawWindowWidgets(w);
   347 
   331 
   348 			/* draw arrow pointing up/down for ascending/descending sorting */
   332 			/* draw arrow pointing up/down for ascending/descending sorting */
   349 			DrawSortButtonState(w, SLW_SORTBY, sl->flags & SL_ORDER ? SBS_DOWN : SBS_UP);
   333 			DrawSortButtonState(w, SLW_SORTBY, sl->flags & VL_DESC ? SBS_DOWN : SBS_UP);
   350 
   334 
   351 			int cg_ofst;
   335 			int cg_ofst;
   352 			int x = 89;
   336 			int x = 89;
   353 			int y = 14;
   337 			int y = 14;
   354 			int xb = 2; ///< offset from left of widget
   338 			int xb = 2; ///< offset from left of widget
   447 						}
   431 						}
   448 						SetBit(facilities, e->we.click.widget - SLW_TRAIN);
   432 						SetBit(facilities, e->we.click.widget - SLW_TRAIN);
   449 						w->LowerWidget(e->we.click.widget);
   433 						w->LowerWidget(e->we.click.widget);
   450 					}
   434 					}
   451 					w->SetWidgetLoweredState(SLW_FACILALL, facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
   435 					w->SetWidgetLoweredState(SLW_FACILALL, facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
   452 					sl->flags |= SL_REBUILD;
   436 					sl->flags |= VL_REBUILD;
   453 					w->SetDirty();
   437 					w->SetDirty();
   454 					break;
   438 					break;
   455 
   439 
   456 				case SLW_FACILALL:
   440 				case SLW_FACILALL:
   457 					for (uint i = 0; i < 5; i++) {
   441 					for (uint i = 0; i < 5; i++) {
   458 						w->LowerWidget(i + SLW_TRAIN);
   442 						w->LowerWidget(i + SLW_TRAIN);
   459 					}
   443 					}
   460 					w->LowerWidget(SLW_FACILALL);
   444 					w->LowerWidget(SLW_FACILALL);
   461 
   445 
   462 					facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
   446 					facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
   463 					sl->flags |= SL_REBUILD;
   447 					sl->flags |= VL_REBUILD;
   464 					w->SetDirty();
   448 					w->SetDirty();
   465 					break;
   449 					break;
   466 
   450 
   467 				case SLW_CARGOALL: {
   451 				case SLW_CARGOALL: {
   468 					uint i = 0;
   452 					uint i = 0;
   474 					w->LowerWidget(SLW_NOCARGOWAITING);
   458 					w->LowerWidget(SLW_NOCARGOWAITING);
   475 					w->LowerWidget(SLW_CARGOALL);
   459 					w->LowerWidget(SLW_CARGOALL);
   476 
   460 
   477 					_cargo_filter = _cargo_mask;
   461 					_cargo_filter = _cargo_mask;
   478 					include_empty = true;
   462 					include_empty = true;
   479 					sl->flags |= SL_REBUILD;
   463 					sl->flags |= VL_REBUILD;
   480 					w->SetDirty();
   464 					w->SetDirty();
   481 					break;
   465 					break;
   482 				}
   466 				}
   483 
   467 
   484 				case SLW_SORTBY: // flip sorting method asc/desc
   468 				case SLW_SORTBY: // flip sorting method asc/desc
   485 					sl->flags ^= SL_ORDER; //DESC-flag
   469 					sl->flags ^= VL_DESC; //DESC-flag
   486 					station_sort.order = HasBit(sl->flags, 0);
   470 					station_sort.order = HasBit(sl->flags, 0);
   487 					sl->flags |= SL_RESORT;
   471 					sl->flags |= VL_RESORT;
   488 					w->flags4 |= 5 << WF_TIMEOUT_SHL;
   472 					w->flags4 |= 5 << WF_TIMEOUT_SHL;
   489 					w->LowerWidget(SLW_SORTBY);
   473 					w->LowerWidget(SLW_SORTBY);
   490 					w->SetDirty();
   474 					w->SetDirty();
   491 					break;
   475 					break;
   492 
   476 
   506 						_cargo_filter = 0;
   490 						_cargo_filter = 0;
   507 						include_empty = true;
   491 						include_empty = true;
   508 
   492 
   509 						w->LowerWidget(SLW_NOCARGOWAITING);
   493 						w->LowerWidget(SLW_NOCARGOWAITING);
   510 					}
   494 					}
   511 					sl->flags |= SL_REBUILD;
   495 					sl->flags |= VL_REBUILD;
   512 					w->SetWidgetLoweredState(SLW_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
   496 					w->SetWidgetLoweredState(SLW_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
   513 					w->SetDirty();
   497 					w->SetDirty();
   514 					break;
   498 					break;
   515 
   499 
   516 				default:
   500 				default:
   537 							include_empty = false;
   521 							include_empty = false;
   538 
   522 
   539 							SetBit(_cargo_filter, c);
   523 							SetBit(_cargo_filter, c);
   540 							w->LowerWidget(e->we.click.widget);
   524 							w->LowerWidget(e->we.click.widget);
   541 						}
   525 						}
   542 						sl->flags |= SL_REBUILD;
   526 						sl->flags |= VL_REBUILD;
   543 						w->SetWidgetLoweredState(SLW_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
   527 						w->SetWidgetLoweredState(SLW_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
   544 						w->SetDirty();
   528 						w->SetDirty();
   545 					}
   529 					}
   546 					break;
   530 					break;
   547 			}
   531 			}
   550 		case WE_DROPDOWN_SELECT: // we have selected a dropdown item in the list
   534 		case WE_DROPDOWN_SELECT: // we have selected a dropdown item in the list
   551 			if (sl->sort_type != e->we.dropdown.index) {
   535 			if (sl->sort_type != e->we.dropdown.index) {
   552 				/* value has changed -> resort */
   536 				/* value has changed -> resort */
   553 				sl->sort_type = e->we.dropdown.index;
   537 				sl->sort_type = e->we.dropdown.index;
   554 				station_sort.criteria = sl->sort_type;
   538 				station_sort.criteria = sl->sort_type;
   555 				sl->flags |= SL_RESORT;
   539 				sl->flags |= VL_RESORT;
   556 			}
   540 			}
   557 			w->SetDirty();
   541 			w->SetDirty();
   558 			break;
   542 			break;
   559 
   543 
   560 		case WE_TICK:
   544 		case WE_TICK:
   561 			if (_pause_game != 0) break;
   545 			if (_pause_game != 0) break;
   562 			if (--sl->resort_timer == 0) {
   546 			if (--sl->resort_timer == 0) {
   563 				DEBUG(misc, 3, "Periodic rebuild station list player %d", owner);
   547 				DEBUG(misc, 3, "Periodic rebuild station list player %d", owner);
   564 				sl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
   548 				sl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
   565 				sl->flags |= SL_REBUILD;
   549 				sl->flags |= VL_REBUILD;
   566 				w->SetDirty();
   550 				w->SetDirty();
   567 			}
   551 			}
   568 			break;
   552 			break;
   569 
   553 
   570 		case WE_TIMEOUT:
   554 		case WE_TIMEOUT: