Merge pull request #7608 from AaronVanGeffen/vehicle_type_dropdown

Order vehicle type dropdown orthographically
This commit is contained in:
Aaron van Geffen 2018-06-01 21:29:36 +02:00 committed by GitHub
commit f03fe46b83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 130 additions and 76 deletions

View File

@ -49,6 +49,7 @@
- Improved: [#7555] Allow setting the Twitch API URL, allowing custom API servers.
- Improved: [#7567] Improve the performance of loading parks and the title sequence.
- Improved: [#7577] Allow fine-tuning the virtual floor style.
- Improved: [#7608] The vehicle selection dropdown is now sorted orthographically.
0.1.2 (2018-03-18)
------------------------------------------------------------------------

View File

@ -1236,6 +1236,19 @@ struct RideTypeLabel
static sint32 RideDropdownDataLanguage = LANGUAGE_UNDEFINED;
static std::vector<RideTypeLabel> RideDropdownData;
// Used for sorting the vehicle type dropdown.
struct VehicleTypeLabel
{
sint32 subtype_id;
rct_string_id label_id;
const char* label_string;
};
static sint32 VehicleDropdownDataLanguage = LANGUAGE_UNDEFINED;
static rct_ride_entry *VehicleDropdownRideType = nullptr;
static bool VehicleDropdownExpanded = false;
static std::vector<VehicleTypeLabel> VehicleDropdownData;
static void window_ride_draw_tab_image(rct_drawpixelinfo *dpi, rct_window *w, sint32 page, sint32 spriteIndex)
{
rct_widgetindex widgetIndex = WIDX_TAB_1 + page;
@ -2183,6 +2196,8 @@ static void populate_ride_type_dropdown()
}
std::sort(RideDropdownData.begin(), RideDropdownData.end(), [](auto& a, auto& b) { return std::strcmp(a.label_string, b.label_string) < 0; });
RideDropdownDataLanguage = ls.GetCurrentLanguage();
}
static void window_ride_show_ride_type_dropdown(rct_window *w, rct_widget *widget)
@ -2223,6 +2238,115 @@ static void window_ride_show_ride_type_dropdown(rct_window *w, rct_widget *widge
dropdown_set_checked(pos, true);
}
static void populate_vehicle_type_dropdown(Ride *ride)
{
rct_ride_entry *rideEntry = get_ride_entry_by_ride(ride);
bool selectionShouldBeExpanded;
sint32 rideTypeIterator, rideTypeIteratorMax;
if (gCheatsShowVehiclesFromOtherTrackTypes && !(ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE) || ride->type == RIDE_TYPE_MAZE || ride->type == RIDE_TYPE_MINI_GOLF))
{
selectionShouldBeExpanded = true;
rideTypeIterator = 0;
rideTypeIteratorMax = RIDE_TYPE_COUNT - 1;
}
else
{
selectionShouldBeExpanded = false;
rideTypeIterator = ride->type;
rideTypeIteratorMax = ride->type;
}
// Don't repopulate the list if we just did.
auto& ls = OpenRCT2::GetContext()->GetLocalisationService();
if (VehicleDropdownExpanded == selectionShouldBeExpanded &&
VehicleDropdownRideType == rideEntry &&
VehicleDropdownDataLanguage == ls.GetCurrentLanguage())
return;
VehicleDropdownData.clear();
for (; rideTypeIterator <= rideTypeIteratorMax; rideTypeIterator++)
{
if (selectionShouldBeExpanded && ride_type_has_flag(rideTypeIterator, RIDE_TYPE_FLAG_FLAT_RIDE))
continue;
if (selectionShouldBeExpanded && (rideTypeIterator == RIDE_TYPE_MAZE || rideTypeIterator == RIDE_TYPE_MINI_GOLF))
continue;
uint8 *rideEntryIndexPtr = get_ride_entry_indices_for_ride_type(rideTypeIterator);
for (uint8 *currentRideEntryIndex = rideEntryIndexPtr; *currentRideEntryIndex != RIDE_ENTRY_INDEX_NULL; currentRideEntryIndex++)
{
sint32 rideEntryIndex = *currentRideEntryIndex;
rct_ride_entry *currentRideEntry = get_ride_entry(rideEntryIndex);
// Skip if vehicle type has not been invented yet
if (!ride_entry_is_invented(rideEntryIndex) && !gCheatsIgnoreResearchStatus)
continue;
// Skip if vehicle does not belong to the same ride group
if (RideGroupManager::RideTypeHasRideGroups(ride->type) && !selectionShouldBeExpanded)
{
const RideGroup *rideGroup = RideGroupManager::GetRideGroup(ride->type, rideEntry);
const RideGroup *currentRideGroup = RideGroupManager::GetRideGroup(ride->type, currentRideEntry);
if (!rideGroup->Equals(currentRideGroup))
continue;
}
VehicleTypeLabel label = { rideEntryIndex, currentRideEntry->naming.name, ls.GetString(currentRideEntry->naming.name) };
VehicleDropdownData.push_back(label);
}
}
std::sort(VehicleDropdownData.begin(), VehicleDropdownData.end(), [](auto& a, auto& b) { return std::strcmp(a.label_string, b.label_string) < 0; });
VehicleDropdownExpanded = selectionShouldBeExpanded;
VehicleDropdownRideType = rideEntry;
VehicleDropdownDataLanguage = ls.GetCurrentLanguage();
}
static void window_ride_show_vehicle_type_dropdown(rct_window *w, rct_widget *widget)
{
Ride *ride = get_ride(w->number);
populate_vehicle_type_dropdown(ride);
size_t numItems = std::min<size_t>(VehicleDropdownData.size(), DROPDOWN_ITEMS_MAX_SIZE);
for (size_t i = 0; i < numItems; i++)
{
gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL;
gDropdownItemsArgs[i] = VehicleDropdownData[i].label_id;
}
rct_widget *dropdownWidget = widget - 1;
window_dropdown_show_text_custom_width(
w->x + dropdownWidget->left,
w->y + dropdownWidget->top,
dropdownWidget->bottom - dropdownWidget->top + 1,
w->colours[1],
0,
DROPDOWN_FLAG_STAY_OPEN,
numItems,
widget->right - dropdownWidget->left
);
// Find the current vehicle type in the ordered list.
uint8 pos = 0;
for (uint8 i = 0; i < VehicleDropdownData.size(); i++)
{
if (VehicleDropdownData[i].subtype_id == ride->subtype)
{
pos = i;
break;
}
}
gDropdownHighlightedIndex = pos;
gDropdownDefaultIndex = pos;
dropdown_set_checked(pos, true);
}
/**
*
* rct2: 0x006AF1BD
@ -2702,83 +2826,11 @@ static void window_ride_vehicle_resize(rct_window *w)
*/
static void window_ride_vehicle_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget)
{
rct_widget *dropdownWidget = widget - 1;
Ride *ride;
rct_ride_entry *rideEntry, *currentRideEntry;
const RideGroup * rideGroup, * currentRideGroup;
sint32 numItems, rideEntryIndex, selectedIndex, rideTypeIterator, rideTypeIteratorMax;
uint8 *rideEntryIndexPtr;
bool selectionShouldBeExpanded;
ride = get_ride(w->number);
rideEntry = get_ride_entry_by_ride(ride);
if(gCheatsShowVehiclesFromOtherTrackTypes && !(ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE) || ride->type==RIDE_TYPE_MAZE || ride->type==RIDE_TYPE_MINI_GOLF)) {
selectionShouldBeExpanded = true;
rideTypeIterator = 0;
rideTypeIteratorMax = RIDE_TYPE_COUNT - 1;
}
else {
selectionShouldBeExpanded = false;
rideTypeIterator = ride->type;
rideTypeIteratorMax = ride->type;
}
Ride *ride = get_ride(w->number);
switch (widgetIndex) {
case WIDX_VEHICLE_TYPE_DROPDOWN:
selectedIndex = -1;
numItems = 0;
// Dropdowns with more items start acting weird, so cap it.
for (; rideTypeIterator <= rideTypeIteratorMax && numItems < DROPDOWN_ITEMS_MAX_SIZE; rideTypeIterator++) {
if(selectionShouldBeExpanded && ride_type_has_flag(rideTypeIterator, RIDE_TYPE_FLAG_FLAT_RIDE))
continue;
if(selectionShouldBeExpanded && (rideTypeIterator == RIDE_TYPE_MAZE || rideTypeIterator == RIDE_TYPE_MINI_GOLF))
continue;
rideEntryIndexPtr = get_ride_entry_indices_for_ride_type(rideTypeIterator);
for (uint8 *currentRideEntryIndex = rideEntryIndexPtr; *currentRideEntryIndex != RIDE_ENTRY_INDEX_NULL && numItems < DROPDOWN_ITEMS_MAX_SIZE; currentRideEntryIndex++) {
rideEntryIndex = *currentRideEntryIndex;
currentRideEntry = get_ride_entry(rideEntryIndex);
// Skip if vehicle type is not invented yet
if (!ride_entry_is_invented(rideEntryIndex) && !gCheatsIgnoreResearchStatus)
continue;
// Skip if vehicle does not belong to the same ride group
if (RideGroupManager::RideTypeHasRideGroups(ride->type) && !selectionShouldBeExpanded)
{
rideGroup = RideGroupManager::GetRideGroup(ride->type, rideEntry);
currentRideGroup = RideGroupManager::GetRideGroup(ride->type, currentRideEntry);
if (!rideGroup->Equals(currentRideGroup))
continue;
}
if (ride->subtype == rideEntryIndex)
selectedIndex = numItems;
gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL;
gDropdownItemsArgs[numItems] = (rideEntryIndex << 16) | currentRideEntry->naming.name;
numItems++;
}
}
window_dropdown_show_text_custom_width(
w->x + dropdownWidget->left,
w->y + dropdownWidget->top,
dropdownWidget->bottom - dropdownWidget->top + 1,
w->colours[1],
0,
DROPDOWN_FLAG_STAY_OPEN,
numItems,
widget->right - dropdownWidget->left
);
dropdown_set_checked(selectedIndex, true);
window_ride_show_vehicle_type_dropdown(w, &w->widgets[widgetIndex]);
break;
case WIDX_VEHICLE_TRAINS_INCREASE:
if (ride->num_vehicles < 32)
@ -2793,6 +2845,7 @@ static void window_ride_vehicle_mousedown(rct_window *w, rct_widgetindex widgetI
ride_set_num_cars_per_vehicle(w->number, ride->num_cars_per_train + 1);
break;
case WIDX_VEHICLE_CARS_PER_TRAIN_DECREASE:
rct_ride_entry * rideEntry = get_ride_entry_by_ride(ride);
if (ride->num_cars_per_train > rideEntry->zero_cars + 1)
ride_set_num_cars_per_vehicle(w->number, ride->num_cars_per_train - 1);
break;
@ -2810,8 +2863,8 @@ static void window_ride_vehicle_dropdown(rct_window *w, rct_widgetindex widgetIn
switch (widgetIndex) {
case WIDX_VEHICLE_TYPE_DROPDOWN:
dropdownIndex = (gDropdownItemsArgs[dropdownIndex] >> 16) & 0xFFFF;
ride_set_ride_entry(w->number, dropdownIndex);
sint32 newRideType = VehicleDropdownData[dropdownIndex].subtype_id;
ride_set_ride_entry(w->number, newRideType);
break;
}
}