Changeset - r15800:374f3518cc15
[Not reviewed]
master
0 1 0
terkhen - 14 years ago 2010-08-13 14:28:51
terkhen@openttd.org
(svn r20485) -Fix [FS#4012]: Sorting of refittable cargos was wrong for trains.
1 file changed with 76 insertions and 33 deletions:
0 comments (0 inline, 0 general)
src/vehicle_gui.cpp
Show inline comments
 
@@ -305,37 +305,46 @@ struct RefitOption {
 
	}
 
};
 

	
 
typedef SmallVector<RefitOption, 32> RefitList;
 
typedef SmallVector<RefitOption, 32> SubtypeList; ///< List of refit subtypes associated to a cargo.
 

	
 
/**
 
 * Draw the list of available refit options for a consist and highlight the selected refit option (if any).
 
 * @param *list First vehicle in consist to get the refit-options of
 
 * @param list  List of subtype options for each (sorted) cargo.
 
 * @param sel   Selected refit cargo-type in the window
 
 * @param pos   Position of the selected item in caller widow
 
 * @param rows  Number of rows(capacity) in caller window
 
 * @param delta Step height in caller window
 
 * @param r     Rectangle of the matrix widget.
 
 */
 
static void DrawVehicleRefitWindow(const RefitList &list, int sel, uint pos, uint rows, uint delta, const Rect &r)
 
static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], int sel, uint pos, uint rows, uint delta, const Rect &r)
 
{
 
	uint y = r.top + WD_MATRIX_TOP;
 
	/* Draw the list, and find the selected cargo (by its position in list) */
 
	for (uint i = pos; i < pos + rows && i < list.Length(); i++) {
 
		TextColour colour = (sel == (int)i) ? TC_WHITE : TC_BLACK;
 
		const RefitOption *refit = &list[i];
 
	uint current = 0;
 

	
 
		/* Get the cargo name */
 
		SetDParam(0, CargoSpec::Get(refit->cargo)->name);
 
	/* Draw the list of subtypes for each cargo, and find the selected refit option (by its position). */
 
	for (uint i = 0; current < pos + rows && i < NUM_CARGO; i++) {
 
		for (uint j = 0; current < pos + rows && j < list[i].Length(); j++) {
 
			/* Refit options with a position smaller than pos don't have to be drawn. */
 
			if (current < pos) {
 
				current++;
 
				continue;
 
			}
 

	
 
		/* If the callback succeeded, draw the cargo suffix */
 
		if (refit->value != CALLBACK_FAILED) {
 
			SetDParam(1, GetGRFStringID(GetEngineGRFID(refit->engine), 0xD000 + refit->value));
 
			DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y, STR_JUST_STRING_SPACE_STRING, colour);
 
		} else {
 
			DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y, STR_JUST_STRING, colour);
 
			TextColour colour = (sel == (int)current) ? TC_WHITE : TC_BLACK;
 
			const RefitOption refit = list[i][j];
 
			/* Get the cargo name. */
 
			SetDParam(0, CargoSpec::Get(refit.cargo)->name);
 
			/* If the callback succeeded, draw the cargo suffix. */
 
			if (refit.value != CALLBACK_FAILED) {
 
				SetDParam(1, GetGRFStringID(GetEngineGRFID(refit.engine), 0xD000 + refit.value));
 
				DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y, STR_JUST_STRING_SPACE_STRING, colour);
 
			} else {
 
				DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y, STR_JUST_STRING, colour);
 
			}
 

	
 
			y += delta;
 
			current++;
 
		}
 

	
 
		y += delta;
 
	}
 
}
 

	
 
@@ -351,10 +360,10 @@ enum VehicleRefitWidgets {
 

	
 
/** Refit cargo window. */
 
struct RefitWindow : public Window {
 
	int sel;              ///< Index in refit options, \c -1 if nothing is selected.
 
	RefitOption *cargo;   ///< Refit option selected by \v sel.
 
	RefitList list;       ///< List of cargo types available for refitting.
 
	VehicleOrderID order; ///< If not #INVALID_VEH_ORDER_ID, selection is part of a refit order (rather than execute directly).
 
	int sel;                     ///< Index in refit options, \c -1 if nothing is selected.
 
	RefitOption *cargo;          ///< Refit option selected by \v sel.
 
	SubtypeList list[NUM_CARGO]; ///< List of refit subtypes available for each sorted cargo.
 
	VehicleOrderID order;        ///< If not #INVALID_VEH_ORDER_ID, selection is part of a refit order (rather than execute directly).
 
	Scrollbar *vscroll;
 

	
 
	/**
 
@@ -362,7 +371,7 @@ struct RefitWindow : public Window {
 
	 */
 
	void BuildRefitList()
 
	{
 
		this->list.Clear();
 
		for (uint i = 0; i < NUM_CARGO; i++) this->list[i].Clear();
 
		Vehicle *v = Vehicle::Get(this->window_number);
 

	
 
		do {
 
@@ -374,11 +383,15 @@ struct RefitWindow : public Window {
 
			if (!e->CanCarryCargo()) continue;
 

	
 
			/* Loop through all cargos in the refit mask */
 
			int current_index = 0;
 
			const CargoSpec *cs;
 
			FOR_ALL_SORTED_CARGOSPECS(cs) {
 
				CargoID cid = cs->Index();
 
				/* Skip cargo type if it's not listed */
 
				if (!HasBit(cmask, cid)) continue;
 
				if (!HasBit(cmask, cid)) {
 
					current_index++;
 
					continue;
 
				}
 

	
 
				/* Check the vehicle's callback mask for cargo suffixes */
 
				if (HasBit(callback_mask, CBM_VEHICLE_CARGO_SUFFIX)) {
 
@@ -405,7 +418,7 @@ struct RefitWindow : public Window {
 
						option.subtype = refit_cyc;
 
						option.value   = callback;
 
						option.engine  = v->engine_type;
 
						this->list.Include(option);
 
						this->list[current_index].Include(option);
 
					}
 

	
 
					/* Reset the vehicle's cargo type */
 
@@ -422,11 +435,37 @@ struct RefitWindow : public Window {
 
					option.subtype = 0;
 
					option.value   = CALLBACK_FAILED;
 
					option.engine  = INVALID_ENGINE;
 
					this->list.Include(option);
 
					this->list[current_index].Include(option);
 
				}
 
				current_index++;
 
			}
 
		} while ((v->type == VEH_TRAIN || v->type == VEH_ROAD) && (v = v->Next()) != NULL);
 
		this->vscroll->SetCount(this->list.Length());
 

	
 
		int scroll_size = 0;
 
		for (uint i = 0; i < NUM_CARGO; i++) {
 
			scroll_size += (this->list[i].Length());
 
		}
 
		this->vscroll->SetCount(scroll_size);
 
	}
 

	
 
	/**
 
	 * Gets the #RefitOption placed in the selected index.
 
	 * @return Pointer to the #RefitOption currently in use.
 
	 */
 
	RefitOption *GetRefitOption()
 
	{
 
		if (this->sel < 0) return NULL;
 
		int subtype = 0;
 
		for (uint i = 0; subtype <= this->sel && i < NUM_CARGO; i++) {
 
			for (uint j = 0; subtype <= this->sel && j < this->list[i].Length(); j++) {
 
				if (subtype == this->sel) {
 
					return &this->list[i][j];
 
				}
 
				subtype++;
 
			}
 
		}
 

	
 
		return NULL;
 
	}
 

	
 
	RefitWindow(const WindowDesc *desc, const Vehicle *v, VehicleOrderID order) : Window()
 
@@ -457,12 +496,16 @@ struct RefitWindow : public Window {
 
			this->BuildRefitList();
 
			this->sel = -1;
 
			this->cargo = NULL;
 
			for (uint i = 0; i < this->list.Length(); i++) {
 
				if (this->list[i] == current_refit_option) {
 
					this->sel = i;
 
					this->cargo = &this->list[i];
 
					this->vscroll->ScrollTowards(i);
 
					break;
 
			int current = 0;
 
			for (uint i = 0; this->cargo == NULL && i < NUM_CARGO; i++) {
 
				for (uint j = 0; j < list[i].Length(); j++) {
 
					if (list[i][j] == current_refit_option) {
 
						this->sel = current;
 
						this->cargo = &list[i][j];
 
						this->vscroll->ScrollTowards(current);
 
						break;
 
					}
 
					current++;
 
				}
 
			}
 

	
 
@@ -526,7 +569,7 @@ struct RefitWindow : public Window {
 
			}
 

	
 
			case 1: // A new cargo has been selected.
 
				this->cargo = (this->sel >= 0 && this->sel < (int)this->list.Length()) ? &this->list[this->sel] : NULL;
 
				this->cargo = GetRefitOption();
 
				break;
 
		}
 
	}
0 comments (0 inline, 0 general)