build_vehicle_gui.c
changeset 5187 12dc9dfa6af6
parent 5070 7f5b13b7e728
child 5192 771a8421a4cc
equal deleted inserted replaced
5186:1b5e0a0eace5 5187:12dc9dfa6af6
    30 	BUILD_VEHICLE_WIDGET_SORT_TEXT,
    30 	BUILD_VEHICLE_WIDGET_SORT_TEXT,
    31 	BUILD_VEHICLE_WIDGET_SORT_DROPDOWN,
    31 	BUILD_VEHICLE_WIDGET_SORT_DROPDOWN,
    32 	BUILD_VEHICLE_WIDGET_LIST,
    32 	BUILD_VEHICLE_WIDGET_LIST,
    33 	BUILD_VEHICLE_WIDGET_SCROLLBAR,
    33 	BUILD_VEHICLE_WIDGET_SCROLLBAR,
    34 	BUILD_VEHICLE_WIDGET_PANEL,
    34 	BUILD_VEHICLE_WIDGET_PANEL,
    35 	BUILD_VEHICLE_WIDGET_PLANES,
       
    36 	BUILD_VEHICLE_WIDGET_JETS,
       
    37 	BUILD_VEHICLE_WIDGET_HELICOPTERS,
       
    38 	BUILD_VEHICLE_WIDGET_BUILD,
    35 	BUILD_VEHICLE_WIDGET_BUILD,
    39 	BUILD_VEHICLE_WIDGET_RENAME,
    36 	BUILD_VEHICLE_WIDGET_RENAME,
    40 	BUILD_VEHICLE_WIDGET_RESIZE,
    37 	BUILD_VEHICLE_WIDGET_RESIZE,
    41 } BuildVehicleWidget;
    38 } BuildVehicleWidget;
    42 
    39 
    48 	{    WWT_TEXTBTN,   RESIZE_NONE,    14,   228,   239,    14,    25, STR_0225,                STR_SORT_CRITERIA_TIP},
    45 	{    WWT_TEXTBTN,   RESIZE_NONE,    14,   228,   239,    14,    25, STR_0225,                STR_SORT_CRITERIA_TIP},
    49 	{     WWT_MATRIX, RESIZE_BOTTOM,    14,     0,   227,    26,   121, 0x401,                   STR_A025_AIRCRAFT_SELECTION_LIST },
    46 	{     WWT_MATRIX, RESIZE_BOTTOM,    14,     0,   227,    26,   121, 0x401,                   STR_A025_AIRCRAFT_SELECTION_LIST },
    50 	{  WWT_SCROLLBAR, RESIZE_BOTTOM,    14,   228,   239,    26,   121, 0x0,                     STR_0190_SCROLL_BAR_SCROLLS_LIST },
    47 	{  WWT_SCROLLBAR, RESIZE_BOTTOM,    14,   228,   239,    26,   121, 0x0,                     STR_0190_SCROLL_BAR_SCROLLS_LIST },
    51 	{      WWT_PANEL,     RESIZE_TB,    14,     0,   239,   122,   213, 0x0,                     STR_NULL },
    48 	{      WWT_PANEL,     RESIZE_TB,    14,     0,   239,   122,   213, 0x0,                     STR_NULL },
    52 
    49 
    53 	{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,    79,   214,   225, STR_BLACK_PLANES,        STR_BUILD_PLANES_TIP },
    50 	{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   114,   214,   225, STR_A006_BUILD_AIRCRAFT, STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT },
    54 	{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,    80,   159,   214,   225, STR_BLACK_JETS,          STR_BUILD_JETS_TIP },
    51 	{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,   115,   227,   214,   225, STR_A037_RENAME,         STR_A038_RENAME_AIRCRAFT_TYPE },
    55 	{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,   160,   239,   214,   225, STR_BLACK_HELICOPTERS,   STR_BUILD_HELICOPTERS_TIP },
    52 	{  WWT_RESIZEBOX,     RESIZE_TB,    14,   228,   239,   214,   225, 0x0,                     STR_RESIZE_BUTTON },
    56 
       
    57 	{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   114,   226,   237, STR_A006_BUILD_AIRCRAFT, STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT },
       
    58 	{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,   115,   227,   226,   237, STR_A037_RENAME,         STR_A038_RENAME_AIRCRAFT_TYPE },
       
    59 	{  WWT_RESIZEBOX,     RESIZE_TB,    14,   228,   239,   226,   237, 0x0,                     STR_RESIZE_BUTTON },
       
    60 	{   WIDGETS_END},
    53 	{   WIDGETS_END},
    61 };
    54 };
    62 
    55 
    63 static bool _internal_sort_order; // descending/ascending
    56 static bool _internal_sort_order; // descending/ascending
    64 static byte _last_sort_criteria = 0;
    57 static byte _last_sort_criteria = 0;
    65 static bool _last_sort_order = false;
    58 static bool _last_sort_order = false;
    66 
    59 
    67 typedef int CDECL VehicleSortListingTypeFunction(const void*, const void*);
       
    68 
       
    69 static int CDECL EngineNumberSorter(const void *a, const void *b)
    60 static int CDECL EngineNumberSorter(const void *a, const void *b)
    70 {
    61 {
    71 	const EngineID va = *(const EngineID*)a;
    62 	const EngineID va = *(const EngineID*)a;
    72 	const EngineID vb = *(const EngineID*)b;
    63 	const EngineID vb = *(const EngineID*)b;
    73 	int r = va - vb;
    64 	int r = va - vb;
   177 		return EngineNumberSorter(a, b);
   168 		return EngineNumberSorter(a, b);
   178 	}
   169 	}
   179 	return _internal_sort_order ? -r : r;
   170 	return _internal_sort_order ? -r : r;
   180 }
   171 }
   181 
   172 
   182 static VehicleSortListingTypeFunction* const _aircraft_sorter[] = {
   173 static EngList_SortTypeFunction * const _aircraft_sorter[] = {
   183 	&EngineNumberSorter,
   174 	&EngineNumberSorter,
   184 	&AircraftEngineCostSorter,
   175 	&AircraftEngineCostSorter,
   185 	&AircraftEngineSpeedSorter,
   176 	&AircraftEngineSpeedSorter,
   186 	&EngineIntroDateSorter,
   177 	&EngineIntroDateSorter,
   187 	&EngineNameSorter,
   178 	&EngineNameSorter,
   284 		}
   275 		}
   285 		ShowAircraftViewWindow(v);
   276 		ShowAircraftViewWindow(v);
   286 	}
   277 	}
   287 }
   278 }
   288 
   279 
   289 static inline void ExtendEngineListSize(EngineID **engine_list, uint16 *engine_list_length, uint16 step_size, uint16 max)
   280 static void GenerateBuildAircraftList(Window *w)
   290 {
   281 {
   291 	*engine_list_length = min(*engine_list_length + step_size, max);
       
   292 	*engine_list = realloc((void*)*engine_list, (*engine_list_length) * sizeof((*engine_list)[0]));
       
   293 }
       
   294 
       
   295 static void GenerateBuildAircraftList(EngineID **planes, uint16 *num_planes, EngineID **jets, uint16 *num_jets, EngineID **helicopters, uint16 *num_helicopters)
       
   296 {
       
   297 	uint16 plane_length      = *num_planes;
       
   298 	uint16 jet_length        = *num_jets;
       
   299 	uint16 helicopter_length = *num_helicopters;
       
   300 	EngineID eid;
   282 	EngineID eid;
   301 
   283 	buildvehicle_d *bv = &WP(w, buildvehicle_d);
   302 	(*num_planes)      = 0;
   284 
   303 	(*num_jets)        = 0;
   285 	EngList_RemoveAll(&bv->eng_list);
   304 	(*num_helicopters) = 0;
       
   305 
   286 
   306 	for (eid = AIRCRAFT_ENGINES_INDEX; eid < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES; eid++) {
   287 	for (eid = AIRCRAFT_ENGINES_INDEX; eid < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES; eid++) {
   307 
       
   308 		if (IsEngineBuildable(eid, VEH_Aircraft)) {
   288 		if (IsEngineBuildable(eid, VEH_Aircraft)) {
   309 			const AircraftVehicleInfo *avi = AircraftVehInfo(eid);
   289 			const AircraftVehicleInfo *avi = AircraftVehInfo(eid);
   310 
   290 			switch (bv->filter.acc_planes) {
   311 			switch (avi->subtype) {
   291 				case HELICOPTERS_ONLY:
   312 				case AIR_CTOL: // Propeller planes
   292 					if (avi->subtype != 0) continue; // if not helicopter
   313 					if (*num_planes == plane_length) ExtendEngineListSize(planes, &plane_length, 5, NUM_AIRCRAFT_ENGINES);
       
   314 					(*planes)[(*num_planes)++] = eid;
       
   315 					break;
   293 					break;
   316 
   294 
   317 				case (AIR_CTOL | AIR_FAST): // Jet planes
   295 				case AIRCRAFT_ONLY:
   318 					if (*num_jets == jet_length) ExtendEngineListSize(jets, &jet_length, 5, NUM_AIRCRAFT_ENGINES);
   296 					if (avi->subtype == 0) continue; // if helicopter
   319 					(*jets)[(*num_jets)++] = eid;
       
   320 					break;
   297 					break;
   321 
   298 
   322 				case 0: // Helicopters
   299 				case ALL:
   323 					if (*num_helicopters == helicopter_length) ExtendEngineListSize(helicopters, &helicopter_length, 5, NUM_AIRCRAFT_ENGINES);
       
   324 					(*helicopters)[(*num_helicopters)++] = eid;
       
   325 					break;
   300 					break;
   326 			}
   301 			}
       
   302 			EngList_Add(&bv->eng_list, eid);
   327 		}
   303 		}
   328 	}
   304 	}
   329 }
   305 }
   330 
   306 
   331 static void GenerateBuildList(Window *w)
   307 static void GenerateBuildList(Window *w)
   332 {
   308 {
   333 	switch (WP(w, buildvehicle_d).vehicle_type) {
   309 	buildvehicle_d *bv = &WP(w, buildvehicle_d);
       
   310 
       
   311 	switch (bv->vehicle_type) {
   334 		case VEH_Aircraft:
   312 		case VEH_Aircraft:
   335 			GenerateBuildAircraftList(&WP(w, buildvehicle_d).list_a, &WP(w, buildvehicle_d).list_a_length,
   313 			GenerateBuildAircraftList(w);
   336 									  &WP(w, buildvehicle_d).list_b, &WP(w, buildvehicle_d).list_b_length,
   314 			_internal_sort_order = WP(w,buildvehicle_d).descending_sort_order;
   337 									  &WP(w, buildvehicle_d).list_c, &WP(w, buildvehicle_d).list_c_length);
   315 			EngList_Sort(&WP(w, buildvehicle_d).eng_list, _aircraft_sorter[WP(w,buildvehicle_d).sort_criteria]);
   338 			break;
   316 			break;
   339 
   317 
   340 		default: NOT_REACHED();
   318 		default: NOT_REACHED();
   341 	}
   319 	}
   342 
   320 }
   343 	/* Ensure that we do not have trailing unused blocks in the arrays. We will never be able to access them anyway since we are unaware that they are there */
   321 
   344 	WP(w, buildvehicle_d).list_a = realloc((void*)WP(w, buildvehicle_d).list_a, WP(w, buildvehicle_d).list_a_length * sizeof(WP(w, buildvehicle_d).list_a[0]));
   322 static inline const EngineID *GetEngineArray(Window *w)
   345 	WP(w, buildvehicle_d).list_b = realloc((void*)WP(w, buildvehicle_d).list_b, WP(w, buildvehicle_d).list_b_length * sizeof(WP(w, buildvehicle_d).list_b[0]));
   323 {
   346 	WP(w, buildvehicle_d).list_c = realloc((void*)WP(w, buildvehicle_d).list_c, WP(w, buildvehicle_d).list_c_length * sizeof(WP(w, buildvehicle_d).list_c[0]));
   324 	return WP(w, buildvehicle_d).eng_list;
   347 
       
   348 	WP(w, buildvehicle_d).data_invalidated = false; // No need to regenerate the list anymore. We just did it
       
   349 }
       
   350 
       
   351 static inline EngineID *GetEngineArray(Window *w)
       
   352 {
       
   353 	switch (WP(w,buildvehicle_d).show_engine_button) {
       
   354 		case 1: return WP(w, buildvehicle_d).list_a;
       
   355 		case 2: return WP(w, buildvehicle_d).list_b;
       
   356 		case 3: return WP(w, buildvehicle_d).list_c;
       
   357 		default: NOT_REACHED();
       
   358 	}
       
   359 	return NULL;
       
   360 }
   325 }
   361 
   326 
   362 static inline uint16 GetEngineArrayLength(Window *w)
   327 static inline uint16 GetEngineArrayLength(Window *w)
   363 {
   328 {
   364 	switch (WP(w,buildvehicle_d).show_engine_button) {
   329 	return EngList_Count(&WP(w, buildvehicle_d).eng_list);
   365 		case 1: return WP(w, buildvehicle_d).list_a_length;
       
   366 		case 2: return WP(w, buildvehicle_d).list_b_length;
       
   367 		case 3: return WP(w, buildvehicle_d).list_c_length;
       
   368 		default: NOT_REACHED();
       
   369 	}
       
   370 	return 0;
       
   371 }
       
   372 
       
   373 static void SortAircraftBuildList(Window *w)
       
   374 {
       
   375 	_internal_sort_order = WP(w,buildvehicle_d).decenting_sort_order;
       
   376 	qsort((void*)GetEngineArray(w), GetEngineArrayLength(w), sizeof(GetEngineArray(w)[0]),
       
   377 		  _aircraft_sorter[WP(w,buildvehicle_d).sort_criteria]);
       
   378 }
   330 }
   379 
   331 
   380 static void DrawBuildAircraftWindow(Window *w)
   332 static void DrawBuildAircraftWindow(Window *w)
   381 {
   333 {
   382 	SetWindowWidgetLoweredState(w, BUILD_VEHICLE_WIDGET_PLANES,      WP(w,buildvehicle_d).show_engine_button == 1);
   334 	buildvehicle_d *bv = &WP(w, buildvehicle_d);
   383 	SetWindowWidgetLoweredState(w, BUILD_VEHICLE_WIDGET_JETS,        WP(w,buildvehicle_d).show_engine_button == 2);
       
   384 	SetWindowWidgetLoweredState(w, BUILD_VEHICLE_WIDGET_HELICOPTERS, WP(w,buildvehicle_d).show_engine_button == 3);
       
   385 
   335 
   386 	SetWindowWidgetDisabledState(w, BUILD_VEHICLE_WIDGET_BUILD, w->window_number == 0);
   336 	SetWindowWidgetDisabledState(w, BUILD_VEHICLE_WIDGET_BUILD, w->window_number == 0);
   387 
   337 
   388 	if (WP(w, buildvehicle_d).data_invalidated) {
   338 	GenerateBuildList(w);
   389 		GenerateBuildList(w);
   339 
   390 
   340 	if (bv->sel_engine != INVALID_ENGINE) {
   391 		if (WP(w,buildvehicle_d).sel_engine != INVALID_ENGINE) {
   341 		int i;
   392 			int i;
   342 		bool found = false;
   393 			bool found = false;
   343 		int num_planes = GetEngineArrayLength(w);
   394 			if (HASBIT(WP(w,buildvehicle_d).show_engine_button, 0)) {
   344 		for (i = 0; i < num_planes; i++) {
   395 				for (i = 0; i < GetEngineArrayLength(w); i++) {
   345 			if (bv->sel_engine != GetEngineArray(w)[i]) continue;
   396 					if (WP(w,buildvehicle_d).sel_engine != GetEngineArray(w)[i]) continue;
   346 			found = true;
   397 					found = true;
   347 			break;
   398 					break;
   348 		}
   399 				}
   349 		if (!found) bv->sel_engine = INVALID_ENGINE;
   400 			}
       
   401 			if (!found) WP(w,buildvehicle_d).sel_engine = INVALID_ENGINE;
       
   402 		}
       
   403 	}
   350 	}
   404 
   351 
   405 	SetVScrollCount(w, GetEngineArrayLength(w));
   352 	SetVScrollCount(w, GetEngineArrayLength(w));
   406 	DrawWindowWidgets(w);
   353 	DrawWindowWidgets(w);
   407 
       
   408 	if (WP(w,buildvehicle_d).sel_engine == INVALID_ENGINE && GetEngineArrayLength(w) != 0) {
       
   409 		WP(w,buildvehicle_d).sel_engine = GetEngineArray(w)[0];
       
   410 	}
       
   411 
   354 
   412 	{
   355 	{
   413 		int x = 2;
   356 		int x = 2;
   414 		int y = 27;
   357 		int y = 27;
   415 		EngineID selected_id = WP(w,buildvehicle_d).sel_engine;
   358 		EngineID selected_id = bv->sel_engine;
   416 		EngineID eid = w->vscroll.pos;
   359 		EngineID eid = w->vscroll.pos;
   417 		EngineID *list = GetEngineArray(w);
   360 		const EngineID *list = GetEngineArray(w);
   418 		uint16 list_length = GetEngineArrayLength(w);
   361 		uint16 list_length = GetEngineArrayLength(w);
   419 		uint16 max = min(w->vscroll.pos + w->vscroll.cap, list_length);
   362 		uint16 max = min(w->vscroll.pos + w->vscroll.cap, list_length);
   420 
   363 
   421 		for(; eid < max; eid++) {
   364 		for(; eid < max; eid++) {
   422 			const EngineID engine = list[eid];
   365 			const EngineID engine = list[eid];
   429 		if (selected_id != INVALID_ENGINE) {
   372 		if (selected_id != INVALID_ENGINE) {
   430 			const Widget *wi = &w->widget[BUILD_VEHICLE_WIDGET_PANEL];
   373 			const Widget *wi = &w->widget[BUILD_VEHICLE_WIDGET_PANEL];
   431 			DrawAircraftPurchaseInfo(x, wi->top + 1, wi->right - wi->left - 2, selected_id);
   374 			DrawAircraftPurchaseInfo(x, wi->top + 1, wi->right - wi->left - 2, selected_id);
   432 		}
   375 		}
   433 	}
   376 	}
   434 	DrawString(85, 15, _aircraft_sort_listing[WP(w,buildvehicle_d).sort_criteria], 0x10);
   377 	DrawString(85, 15, _aircraft_sort_listing[bv->sort_criteria], 0x10);
   435 	DoDrawString(WP(w,buildvehicle_d).decenting_sort_order ? DOWNARROW : UPARROW, 69, 15, 0x10);
   378 	DoDrawString(bv->descending_sort_order ? DOWNARROW : UPARROW, 69, 15, 0x10);
   436 }
   379 }
   437 
   380 
   438 static void BuildAircraftClickEvent(Window *w, WindowEvent *e)
   381 static void BuildAircraftClickEvent(Window *w, WindowEvent *e)
   439 {
   382 {
   440 	byte click_state = 0;
   383 	buildvehicle_d *bv = &WP(w, buildvehicle_d);
   441 
   384 
   442 	switch (e->we.click.widget) {
   385 	switch (e->we.click.widget) {
   443 		case BUILD_VEHICLE_WIDGET_SORT_ASSENDING_DESCENDING:
   386 		case BUILD_VEHICLE_WIDGET_SORT_ASSENDING_DESCENDING:
   444 			WP(w,buildvehicle_d).decenting_sort_order = !WP(w,buildvehicle_d).decenting_sort_order;
   387 			bv->descending_sort_order = !bv->descending_sort_order;
   445 			_last_sort_order = WP(w,buildvehicle_d).decenting_sort_order;
   388 			_last_sort_order = bv->descending_sort_order;
   446 			SortAircraftBuildList(w);
   389 			GenerateBuildList(w);
   447 			SetWindowDirty(w);
   390 			SetWindowDirty(w);
   448 			break;
   391 			break;
   449 
   392 
   450 		case BUILD_VEHICLE_WIDGET_LIST: {
   393 		case BUILD_VEHICLE_WIDGET_LIST: {
   451 			uint i = (e->we.click.pt.y - 26) / 24;
   394 			uint i = (e->we.click.pt.y - 26) / 24;
   452 			if (i < w->vscroll.cap) {
   395 			if (i < w->vscroll.cap) {
   453 				i += w->vscroll.pos;
   396 				i += w->vscroll.pos;
   454 
   397 				bv->sel_engine = (i < GetEngineArrayLength(w)) ? GetEngineArray(w)[i] : INVALID_ENGINE;
   455 				if (i < GetEngineArrayLength(w)) {
   398 				SetWindowDirty(w);
   456 					WP(w,buildvehicle_d).sel_engine = GetEngineArray(w)[i];
       
   457 					SetWindowDirty(w);
       
   458 				}
       
   459 			}
   399 			}
   460 		} break;
   400 			break;
       
   401 		}
   461 
   402 
   462 		case BUILD_VEHICLE_WIDGET_SORT_TEXT: case BUILD_VEHICLE_WIDGET_SORT_DROPDOWN:/* Select sorting criteria dropdown menu */
   403 		case BUILD_VEHICLE_WIDGET_SORT_TEXT: case BUILD_VEHICLE_WIDGET_SORT_DROPDOWN:/* Select sorting criteria dropdown menu */
   463 			ShowDropDownMenu(w, _aircraft_sort_listing, WP(w,buildvehicle_d).sort_criteria, BUILD_VEHICLE_WIDGET_SORT_DROPDOWN, 0, 0);
   404 			ShowDropDownMenu(w, _aircraft_sort_listing, bv->sort_criteria, BUILD_VEHICLE_WIDGET_SORT_DROPDOWN, 0, 0);
   464 			return;
   405 			return;
   465 
   406 
   466 		case BUILD_VEHICLE_WIDGET_HELICOPTERS: click_state++;
       
   467 		case BUILD_VEHICLE_WIDGET_JETS:        click_state++;
       
   468 		case BUILD_VEHICLE_WIDGET_PLANES:      click_state++;
       
   469 
       
   470 			if (WP(w,buildvehicle_d).show_engine_button == click_state) break; // We clicked the pressed button
       
   471 
       
   472 				WP(w,buildvehicle_d).sel_engine = INVALID_ENGINE;
       
   473 			WP(w,buildvehicle_d).show_engine_button = click_state;
       
   474 			w->vscroll.pos = 0;
       
   475 			SortAircraftBuildList(w);
       
   476 			SetWindowDirty(w);
       
   477 			break;
       
   478 
       
   479 		case BUILD_VEHICLE_WIDGET_BUILD: {
   407 		case BUILD_VEHICLE_WIDGET_BUILD: {
   480 			EngineID sel_eng = WP(w,buildvehicle_d).sel_engine;
   408 			EngineID sel_eng = bv->sel_engine;
   481 			if (sel_eng != INVALID_ENGINE)
   409 			if (sel_eng != INVALID_ENGINE)
   482 				DoCommandP(w->window_number, sel_eng, 0, CcBuildAircraft, CMD_BUILD_AIRCRAFT | CMD_MSG(STR_A008_CAN_T_BUILD_AIRCRAFT));
   410 				DoCommandP(w->window_number, sel_eng, 0, CcBuildAircraft, CMD_BUILD_AIRCRAFT | CMD_MSG(STR_A008_CAN_T_BUILD_AIRCRAFT));
   483 		} break;
   411 			break;
       
   412 		}
   484 
   413 
   485 		case BUILD_VEHICLE_WIDGET_RENAME: {
   414 		case BUILD_VEHICLE_WIDGET_RENAME: {
   486 			EngineID sel_eng = WP(w,buildvehicle_d).sel_engine;
   415 			EngineID sel_eng = bv->sel_engine;
   487 			if (sel_eng != INVALID_ENGINE) {
   416 			if (sel_eng != INVALID_ENGINE) {
   488 				WP(w,buildvehicle_d).rename_engine = sel_eng;
   417 				bv->rename_engine = sel_eng;
   489 				ShowQueryString(GetCustomEngineName(sel_eng),
   418 				ShowQueryString(GetCustomEngineName(sel_eng),
   490 								STR_A039_RENAME_AIRCRAFT_TYPE, 31, 160, w->window_class, w->window_number, CS_ALPHANUMERAL);
   419 								STR_A039_RENAME_AIRCRAFT_TYPE, 31, 160, w->window_class, w->window_number, CS_ALPHANUMERAL);
   491 			}
   420 			}
   492 		} break;
   421 			break;
       
   422 		}
   493 	}
   423 	}
   494 }
   424 }
   495 
   425 
   496 static void NewAircraftWndProc(Window *w, WindowEvent *e)
   426 static void NewAircraftWndProc(Window *w, WindowEvent *e)
   497 {
   427 {
       
   428 	buildvehicle_d *bv = &WP(w, buildvehicle_d);
       
   429 
   498 	switch (e->event) {
   430 	switch (e->event) {
   499 		case WE_INVALIDATE_DATA:
   431 		case WE_INVALIDATE_DATA:
   500 			WP(w,buildvehicle_d).data_invalidated = true;
       
   501 			SetWindowDirty(w);
   432 			SetWindowDirty(w);
   502 			break;
   433 			break;
   503 
   434 
   504 		case WE_DESTROY:
   435 		case WE_DESTROY:
   505 			free((void*)WP(w, buildvehicle_d).list_a);
   436 			EngList_Destroy(&bv->eng_list);
   506 			free((void*)WP(w, buildvehicle_d).list_b);
       
   507 			free((void*)WP(w, buildvehicle_d).list_c);
       
   508 			break;
   437 			break;
   509 
   438 
   510 		case WE_PAINT:
   439 		case WE_PAINT:
   511 			DrawBuildAircraftWindow(w);
   440 			DrawBuildAircraftWindow(w);
   512 			break;
   441 			break;
   516 			break;
   445 			break;
   517 
   446 
   518 		case WE_ON_EDIT_TEXT: {
   447 		case WE_ON_EDIT_TEXT: {
   519 			if (e->we.edittext.str[0] != '\0') {
   448 			if (e->we.edittext.str[0] != '\0') {
   520 				_cmd_text = e->we.edittext.str;
   449 				_cmd_text = e->we.edittext.str;
   521 				DoCommandP(0, WP(w, buildvehicle_d).rename_engine, 0, NULL,
   450 				DoCommandP(0, bv->rename_engine, 0, NULL,
   522 						   CMD_RENAME_ENGINE | CMD_MSG(STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE));
   451 						   CMD_RENAME_ENGINE | CMD_MSG(STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE));
   523 			}
   452 			}
   524 		} break;
   453 			break;
       
   454 		}
   525 
   455 
   526 		case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
   456 		case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
   527 			if (WP(w,buildvehicle_d).sort_criteria != e->we.dropdown.index) {
   457 			if (bv->sort_criteria != e->we.dropdown.index) {
   528 				WP(w,buildvehicle_d).sort_criteria = e->we.dropdown.index;
   458 				bv->sort_criteria = e->we.dropdown.index;
   529 				_last_sort_criteria = e->we.dropdown.index;
   459 				_last_sort_criteria = e->we.dropdown.index;
   530 				SortAircraftBuildList(w);
   460 				GenerateBuildList(w);
   531 			}
   461 			}
   532 			SetWindowDirty(w);
   462 			SetWindowDirty(w);
   533 				break;
   463 				break;
   534 
   464 
   535 			case WE_RESIZE:
   465 			case WE_RESIZE:
   538 				break;
   468 				break;
   539 	}
   469 	}
   540 }
   470 }
   541 
   471 
   542 static const WindowDesc _build_vehicle_desc = {
   472 static const WindowDesc _build_vehicle_desc = {
   543 	WDP_AUTO, WDP_AUTO, 240, 238,
   473 	WDP_AUTO, WDP_AUTO, 240, 226,
   544 	WC_BUILD_VEHICLE,0,
   474 	WC_BUILD_VEHICLE,0,
   545 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
   475 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
   546 	_build_vehicle_widgets,
   476 	_build_vehicle_widgets,
   547 	NewAircraftWndProc
   477 	NewAircraftWndProc
   548 };
   478 };
   549 
   479 
   550 /* Disable the aircraft subtype buttons for the types, that can't be build at the current airport */
       
   551 static void CreateAircraftWindow(Window *w)
       
   552 {
       
   553 	TileIndex tile = w->window_number;
       
   554 
       
   555 	if (tile == 0) {
       
   556 		WP(w, buildvehicle_d).show_engine_button = 1;
       
   557 	} else {
       
   558 		byte acc_planes = GetAirport(GetStationByTile(tile)->airport_type)->acc_planes;
       
   559 
       
   560 		WP(w, buildvehicle_d).show_engine_button = 0;
       
   561 		if (acc_planes == HELICOPTERS_ONLY || acc_planes == ALL) {
       
   562 			WP(w, buildvehicle_d).show_engine_button = 3;
       
   563 		} else {
       
   564 			DisableWindowWidget(w, BUILD_VEHICLE_WIDGET_HELICOPTERS);
       
   565 		}
       
   566 
       
   567 		if (acc_planes == AIRCRAFT_ONLY || acc_planes == ALL) {
       
   568 			/* Set the start clicked button to jets if the list isn't empty. If not, then show propeller planes */
       
   569 			WP(w, buildvehicle_d).show_engine_button = WP(w, buildvehicle_d).list_b_length == 0 ? 1 : 2;
       
   570 		} else {
       
   571 			DisableWindowWidget(w, BUILD_VEHICLE_WIDGET_JETS);
       
   572 			DisableWindowWidget(w, BUILD_VEHICLE_WIDGET_PLANES);
       
   573 		}
       
   574 
       
   575 		if (WP(w, buildvehicle_d).show_engine_button == 0) {
       
   576 			/* No plane type are buildable here */
       
   577 			NOT_REACHED();
       
   578 			WP(w, buildvehicle_d).show_engine_button = 1;
       
   579 		}
       
   580 	}
       
   581 }
       
   582 
       
   583 void ShowBuildVehicleWindow(TileIndex tile, byte type)
   480 void ShowBuildVehicleWindow(TileIndex tile, byte type)
   584 {
   481 {
       
   482 	buildvehicle_d *bv;
   585 	Window *w;
   483 	Window *w;
   586 
   484 
   587 	DeleteWindowById(WC_BUILD_VEHICLE, tile);
   485 	DeleteWindowById(WC_BUILD_VEHICLE, tile);
   588 
       
   589 	w = AllocateWindowDescFront(&_build_vehicle_desc, tile);
   486 	w = AllocateWindowDescFront(&_build_vehicle_desc, tile);
   590 
       
   591 	if (w == NULL) return;
   487 	if (w == NULL) return;
   592 
       
   593 	WP(w, buildvehicle_d).vehicle_type = type;
       
   594 
       
   595 	w->resize.step_height = GetVehicleListHeight(type);
       
   596 	w->vscroll.cap = 4;
       
   597 	w->widget[BUILD_VEHICLE_WIDGET_LIST].data = (w->vscroll.cap << 8) + 1;
       
   598 
   488 
   599 	if (tile != 0) {
   489 	if (tile != 0) {
   600 		w->caption_color = GetTileOwner(tile);
   490 		w->caption_color = GetTileOwner(tile);
   601 	} else {
   491 	} else {
   602 		w->caption_color = _local_player;
   492 		w->caption_color = _local_player;
   603 	}
   493 	}
   604 
   494 
   605 	WP(w, buildvehicle_d).list_a_length = 0;
   495 	w->resize.step_height = GetVehicleListHeight(type);
   606 	WP(w, buildvehicle_d).list_b_length = 0;
   496 	w->vscroll.cap = 4;
   607 	WP(w, buildvehicle_d).list_c_length = 0;
   497 	w->widget[BUILD_VEHICLE_WIDGET_LIST].data = (w->vscroll.cap << 8) + 1;
   608 	WP(w, buildvehicle_d).list_a        = NULL;
   498 
   609 	WP(w, buildvehicle_d).list_b        = NULL;
   499 	bv = &WP(w, buildvehicle_d);
   610 	WP(w, buildvehicle_d).list_c        = NULL;
   500 	EngList_Create(&bv->eng_list);
   611 	WP(w, buildvehicle_d).sel_engine           = INVALID_ENGINE;
   501 	bv->sel_engine           = INVALID_ENGINE;
   612 	WP(w, buildvehicle_d).sort_criteria        = _last_sort_criteria;
   502 	bv->sort_criteria        = _last_sort_criteria;
   613 	WP(w, buildvehicle_d).decenting_sort_order = _last_sort_order;
   503 	bv->descending_sort_order = _last_sort_order;
       
   504 
       
   505 	bv->vehicle_type = type;
       
   506 
       
   507 	switch (type) {
       
   508 		case VEH_Aircraft: {
       
   509 			byte acc_planes = GetAirport(GetStationByTile(tile)->airport_type)->acc_planes;
       
   510 			bv->filter.acc_planes = acc_planes;
       
   511 			break;
       
   512 		}
       
   513 		default: NOT_REACHED();
       
   514 	}
   614 
   515 
   615 	GenerateBuildList(w);
   516 	GenerateBuildList(w);
   616 	switch (type) {
   517 }
   617 		case VEH_Aircraft: CreateAircraftWindow(w); break;
       
   618 		default: NOT_REACHED();
       
   619 	}
       
   620 
       
   621 	SortAircraftBuildList(w);
       
   622 }