mirror of https://github.com/OpenTTD/OpenTTD
(svn r24421) [1.2] -Backport from trunk:
- Fix: EQUALSIZE widget containers within EQUALSIZE containers were initialised with wrong sizes (r24346) - Fix: The cursor in the company password window was not blinking due to wrong magic constants (r24335) - Fix: [NewGRF] Change the length of 8/8 roadvehicles in vehicle lists to 32 pixels; this is in fact the correct length as can be seen in corners for short articulated parts following each other [FS#2553] (r24332) - Fix: [NewGRF] Group vehicles in the purchase list properly by source GRF, but also consider engine GRFID overrides [FS#4254] (r24330, r24321)release/1.2
parent
1971a5a2fe
commit
fc11459405
|
@ -33,7 +33,7 @@ void DrawEngineList(VehicleType type, int x, int r, int y, const GUIEngineList *
|
||||||
|
|
||||||
static int CDECL EngineNumberSorter(const EngineID *a, const EngineID *b)
|
static int CDECL EngineNumberSorter(const EngineID *a, const EngineID *b)
|
||||||
{
|
{
|
||||||
int r = ListPositionOfEngine(*a) - ListPositionOfEngine(*b);
|
int r = Engine::Get(*a)->list_position - Engine::Get(*b)->list_position;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ static CargoID _last_filter_criteria[] = {CF_ANY, CF_ANY, CF_ANY, CF_ANY};
|
||||||
*/
|
*/
|
||||||
static int CDECL EngineNumberSorter(const EngineID *a, const EngineID *b)
|
static int CDECL EngineNumberSorter(const EngineID *a, const EngineID *b)
|
||||||
{
|
{
|
||||||
int r = ListPositionOfEngine(*a) - ListPositionOfEngine(*b);
|
int r = Engine::Get(*a)->list_position - Engine::Get(*b)->list_position;
|
||||||
|
|
||||||
return _internal_sort_order ? -r : r;
|
return _internal_sort_order ? -r : r;
|
||||||
}
|
}
|
||||||
|
@ -1094,7 +1094,7 @@ struct BuildVehicleWindow : Window {
|
||||||
|
|
||||||
this->sel_engine = sel_id;
|
this->sel_engine = sel_id;
|
||||||
|
|
||||||
/* make engines first, and then wagons, sorted by ListPositionOfEngine() */
|
/* make engines first, and then wagons, sorted by selected sort_criteria */
|
||||||
_internal_sort_order = false;
|
_internal_sort_order = false;
|
||||||
EngList_Sort(&this->eng_list, TrainEnginesThenWagonsSorter);
|
EngList_Sort(&this->eng_list, TrainEnginesThenWagonsSorter);
|
||||||
|
|
||||||
|
|
|
@ -2181,7 +2181,7 @@ struct NetworkCompanyPasswordWindow : public QueryStringBaseWindow {
|
||||||
|
|
||||||
virtual void OnMouseLoop()
|
virtual void OnMouseLoop()
|
||||||
{
|
{
|
||||||
this->HandleEditBox(4);
|
this->HandleEditBox(WID_NCP_PASSWORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual EventState OnKeyPress(uint16 key, uint16 keycode)
|
virtual EventState OnKeyPress(uint16 key, uint16 keycode)
|
||||||
|
|
|
@ -1175,30 +1175,22 @@ void TriggerVehicle(Vehicle *v, VehicleTrigger trigger)
|
||||||
v->InvalidateNewGRFCacheOfChain();
|
v->InvalidateNewGRFCacheOfChain();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Functions for changing the order of vehicle purchase lists
|
/* Functions for changing the order of vehicle purchase lists */
|
||||||
* This is currently only implemented for rail vehicles. */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the list position of an engine.
|
|
||||||
* Used when sorting a list of engines.
|
|
||||||
* @param engine ID of the engine.
|
|
||||||
* @return The list position of the engine.
|
|
||||||
*/
|
|
||||||
uint ListPositionOfEngine(EngineID engine)
|
|
||||||
{
|
|
||||||
const Engine *e = Engine::Get(engine);
|
|
||||||
/* Crude sorting to group by GRF ID */
|
|
||||||
return (e->GetGRFID() * 256) + e->list_position;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ListOrderChange {
|
struct ListOrderChange {
|
||||||
EngineID engine;
|
EngineID engine;
|
||||||
EngineID target;
|
uint target; ///< local ID
|
||||||
};
|
};
|
||||||
|
|
||||||
static SmallVector<ListOrderChange, 16> _list_order_changes;
|
static SmallVector<ListOrderChange, 16> _list_order_changes;
|
||||||
|
|
||||||
void AlterVehicleListOrder(EngineID engine, EngineID target)
|
/**
|
||||||
|
* Record a vehicle ListOrderChange.
|
||||||
|
* @param engine Engine to move
|
||||||
|
* @param target Local engine ID to move \a engine in front of
|
||||||
|
* @note All sorting is done later in CommitVehicleListOrderChanges
|
||||||
|
*/
|
||||||
|
void AlterVehicleListOrder(EngineID engine, uint target)
|
||||||
{
|
{
|
||||||
/* Add the list order change to a queue */
|
/* Add the list order change to a queue */
|
||||||
ListOrderChange *loc = _list_order_changes.Append();
|
ListOrderChange *loc = _list_order_changes.Append();
|
||||||
|
@ -1206,49 +1198,74 @@ void AlterVehicleListOrder(EngineID engine, EngineID target)
|
||||||
loc->target = target;
|
loc->target = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparator function to sort engines via scope-GRFID and local ID.
|
||||||
|
* @param a left side
|
||||||
|
* @param b right side
|
||||||
|
* @return comparison result
|
||||||
|
*/
|
||||||
|
static int CDECL EnginePreSort(const EngineID *a, const EngineID *b)
|
||||||
|
{
|
||||||
|
const EngineIDMapping *id_a = _engine_mngr.Get(*a);
|
||||||
|
const EngineIDMapping *id_b = _engine_mngr.Get(*b);
|
||||||
|
|
||||||
|
/* 1. Sort by engine type */
|
||||||
|
if (id_a->type != id_b->type) return (int)id_a->type - (int)id_b->type;
|
||||||
|
|
||||||
|
/* 2. Sort by scope-GRFID */
|
||||||
|
if (id_a->grfid != id_b->grfid) return id_a->grfid < id_b->grfid ? -1 : 1;
|
||||||
|
|
||||||
|
/* 3. Sort by local ID */
|
||||||
|
return (int)id_a->internal_id - (int)id_b->internal_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deternine default engine sorting and execute recorded ListOrderChanges from AlterVehicleListOrder.
|
||||||
|
*/
|
||||||
void CommitVehicleListOrderChanges()
|
void CommitVehicleListOrderChanges()
|
||||||
{
|
{
|
||||||
/* List position to Engine map */
|
/* Pre-sort engines by scope-grfid and local index */
|
||||||
typedef SmallMap<uint16, Engine *, 16> ListPositionMap;
|
SmallVector<EngineID, 16> ordering;
|
||||||
ListPositionMap lptr_map;
|
Engine *e;
|
||||||
|
FOR_ALL_ENGINES(e) {
|
||||||
|
*ordering.Append() = e->index;
|
||||||
|
}
|
||||||
|
QSortT(ordering.Begin(), ordering.Length(), EnginePreSort);
|
||||||
|
|
||||||
|
/* Apply Insertion-Sort opeations */
|
||||||
const ListOrderChange *end = _list_order_changes.End();
|
const ListOrderChange *end = _list_order_changes.End();
|
||||||
for (const ListOrderChange *it = _list_order_changes.Begin(); it != end; ++it) {
|
for (const ListOrderChange *it = _list_order_changes.Begin(); it != end; ++it) {
|
||||||
EngineID engine = it->engine;
|
EngineID source = it->engine;
|
||||||
EngineID target = it->target;
|
uint local_target = it->target;
|
||||||
|
|
||||||
if (engine == target) continue;
|
const EngineIDMapping *id_source = _engine_mngr.Get(source);
|
||||||
|
if (id_source->internal_id == local_target) continue;
|
||||||
|
|
||||||
Engine *source_e = Engine::Get(engine);
|
EngineID target = _engine_mngr.GetID(id_source->type, local_target, id_source->grfid);
|
||||||
Engine *target_e = NULL;
|
if (target == INVALID_ENGINE) continue;
|
||||||
|
|
||||||
/* Populate map with current list positions */
|
int source_index = ordering.FindIndex(source);
|
||||||
Engine *e;
|
int target_index = ordering.FindIndex(target);
|
||||||
FOR_ALL_ENGINES_OF_TYPE(e, source_e->type) {
|
|
||||||
if (!_settings_game.vehicle.dynamic_engines || e->GetGRF() == source_e->GetGRF()) {
|
assert(source_index >= 0 && target_index >= 0);
|
||||||
if (e->grf_prop.local_id == target) target_e = e;
|
assert(source_index != target_index);
|
||||||
lptr_map[e->list_position] = e;
|
|
||||||
}
|
EngineID *list = ordering.Begin();
|
||||||
|
if (source_index < target_index) {
|
||||||
|
--target_index;
|
||||||
|
for (int i = source_index; i < target_index; ++i) list[i] = list[i + 1];
|
||||||
|
list[target_index] = source;
|
||||||
|
} else {
|
||||||
|
for (int i = source_index; i > target_index; --i) list[i] = list[i - 1];
|
||||||
|
list[target_index] = source;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* std::map sorted by default, SmallMap does not */
|
/* Store final sort-order */
|
||||||
lptr_map.SortByKey();
|
const EngineID *idend = ordering.End();
|
||||||
|
uint index = 0;
|
||||||
/* Get the target position, if it exists */
|
for (const EngineID *it = ordering.Begin(); it != idend; ++it, ++index) {
|
||||||
if (target_e != NULL) {
|
Engine::Get(*it)->list_position = index;
|
||||||
uint16 target_position = target_e->list_position;
|
|
||||||
|
|
||||||
bool moving = false;
|
|
||||||
const ListPositionMap::Pair *end = lptr_map.End();
|
|
||||||
for (ListPositionMap::Pair *it = lptr_map.Begin(); it != end; ++it) {
|
|
||||||
if (it->first == target_position) moving = true;
|
|
||||||
if (moving) it->second->list_position++;
|
|
||||||
}
|
|
||||||
|
|
||||||
source_e->list_position = target_position;
|
|
||||||
}
|
|
||||||
|
|
||||||
lptr_map.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear out the queue */
|
/* Clear out the queue */
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "gfx_type.h"
|
#include "gfx_type.h"
|
||||||
|
|
||||||
static const uint TRAININFO_DEFAULT_VEHICLE_WIDTH = 29;
|
static const uint TRAININFO_DEFAULT_VEHICLE_WIDTH = 29;
|
||||||
static const uint ROADVEHINFO_DEFAULT_VEHICLE_WIDTH = 28;
|
static const uint ROADVEHINFO_DEFAULT_VEHICLE_WIDTH = 32;
|
||||||
static const uint VEHICLEINFO_FULL_VEHICLE_WIDTH = 32;
|
static const uint VEHICLEINFO_FULL_VEHICLE_WIDTH = 32;
|
||||||
|
|
||||||
void SetWagonOverrideSprites(EngineID engine, CargoID cargo, const struct SpriteGroup *group, EngineID *train_id, uint trains);
|
void SetWagonOverrideSprites(EngineID engine, CargoID cargo, const struct SpriteGroup *group, EngineID *train_id, uint trains);
|
||||||
|
@ -63,8 +63,7 @@ void TriggerVehicle(Vehicle *veh, VehicleTrigger trigger);
|
||||||
|
|
||||||
void UnloadWagonOverrides(Engine *e);
|
void UnloadWagonOverrides(Engine *e);
|
||||||
|
|
||||||
uint ListPositionOfEngine(EngineID engine);
|
void AlterVehicleListOrder(EngineID engine, uint target);
|
||||||
void AlterVehicleListOrder(EngineID engine, EngineID target);
|
|
||||||
void CommitVehicleListOrderChanges();
|
void CommitVehicleListOrderChanges();
|
||||||
|
|
||||||
EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id);
|
EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id);
|
||||||
|
|
|
@ -1153,7 +1153,17 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui
|
||||||
{
|
{
|
||||||
assert(given_width >= this->smallest_x && given_height >= this->smallest_y);
|
assert(given_width >= this->smallest_x && given_height >= this->smallest_y);
|
||||||
|
|
||||||
uint additional_length = given_width - this->smallest_x; // Additional width given to us.
|
/* Compute additional width given to us. */
|
||||||
|
uint additional_length = given_width;
|
||||||
|
if (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE)) {
|
||||||
|
/* For EQUALSIZE containers this does not sum to smallest_x during initialisation */
|
||||||
|
for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
|
||||||
|
additional_length -= child_wid->smallest_x + child_wid->padding_right + child_wid->padding_left;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
additional_length -= this->smallest_x;
|
||||||
|
}
|
||||||
|
|
||||||
this->StoreSizePosition(sizing, x, y, given_width, given_height);
|
this->StoreSizePosition(sizing, x, y, given_width, given_height);
|
||||||
|
|
||||||
/* In principle, the additional horizontal space is distributed evenly over the available resizable childs. Due to step sizes, this may not always be feasible.
|
/* In principle, the additional horizontal space is distributed evenly over the available resizable childs. Due to step sizes, this may not always be feasible.
|
||||||
|
@ -1305,7 +1315,17 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint
|
||||||
{
|
{
|
||||||
assert(given_width >= this->smallest_x && given_height >= this->smallest_y);
|
assert(given_width >= this->smallest_x && given_height >= this->smallest_y);
|
||||||
|
|
||||||
int additional_length = given_height - this->smallest_y; // Additional height given to us.
|
/* Compute additional height given to us. */
|
||||||
|
uint additional_length = given_height;
|
||||||
|
if (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE)) {
|
||||||
|
/* For EQUALSIZE containers this does not sum to smallest_y during initialisation */
|
||||||
|
for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
|
||||||
|
additional_length -= child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
additional_length -= this->smallest_y;
|
||||||
|
}
|
||||||
|
|
||||||
this->StoreSizePosition(sizing, x, y, given_width, given_height);
|
this->StoreSizePosition(sizing, x, y, given_width, given_height);
|
||||||
|
|
||||||
/* Like the horizontal container, the vertical container also distributes additional height evenly, starting with the childs with the biggest resize steps.
|
/* Like the horizontal container, the vertical container also distributes additional height evenly, starting with the childs with the biggest resize steps.
|
||||||
|
|
Loading…
Reference in New Issue