Changeset - r19401:96b7d1ecdefe
[Not reviewed]
master
0 3 0
frosch - 12 years ago 2012-06-01 15:20:18
frosch@openttd.org
(svn r24318) -Feature: Add dropdowns to NewGRF configurations, if all values have labels.
3 files changed with 103 insertions and 4 deletions:
0 comments (0 inline, 0 general)
src/newgrf_config.cpp
Show inline comments
 
@@ -161,12 +161,23 @@ void GRFConfig::SetSuitablePalette()
 
		case GRFP_GRF_WINDOWS: pal = PAL_WINDOWS;  break;
 
		default:               pal = _settings_client.gui.newgrf_default_palette == 1 ? PAL_WINDOWS : PAL_DOS; break;
 
	}
 
	SB(this->palette, GRFP_USE_BIT, 1, pal == PAL_WINDOWS ? GRFP_USE_WINDOWS : GRFP_USE_DOS);
 
}
 

	
 
/**
 
 * Finalize Action 14 info after file scan is finished.
 
 */
 
void GRFConfig::FinalizeParameterInfo()
 
{
 
	for (GRFParameterInfo **info = this->param_info.Begin(); info != this->param_info.End(); ++info) {
 
		if (*info == NULL) continue;
 
		(*info)->Finalize();
 
	}
 
}
 

	
 
GRFConfig *_all_grfs;
 
GRFConfig *_grfconfig;
 
GRFConfig *_grfconfig_newgame;
 
GRFConfig *_grfconfig_static;
 

	
 
/**
 
@@ -229,13 +240,14 @@ GRFParameterInfo::GRFParameterInfo(GRFPa
 
	type(info.type),
 
	min_value(info.min_value),
 
	max_value(info.max_value),
 
	def_value(info.def_value),
 
	param_nr(info.param_nr),
 
	first_bit(info.first_bit),
 
	num_bit(info.num_bit)
 
	num_bit(info.num_bit),
 
	complete_labels(info.complete_labels)
 
{
 
	for (uint i = 0; i < info.value_names.Length(); i++) {
 
		SmallPair<uint32, GRFText *> *data = info.value_names.Get(i);
 
		this->value_names.Insert(data->first, DuplicateGRFText(data->second));
 
	}
 
}
 
@@ -278,12 +290,26 @@ void GRFParameterInfo::SetValue(struct G
 
	}
 
	config->num_params = max<uint>(config->num_params, this->param_nr + 1);
 
	SetWindowDirty(WC_GAME_OPTIONS, WN_GAME_OPTIONS_NEWGRF_STATE);
 
}
 

	
 
/**
 
 * Finalize Action 14 info after file scan is finished.
 
 */
 
void GRFParameterInfo::Finalize()
 
{
 
	this->complete_labels = true;
 
	for (uint32 value = this->min_value; value <= this->max_value; value++) {
 
		if (!this->value_names.Contains(value)) {
 
			this->complete_labels = false;
 
			break;
 
		}
 
	}
 
}
 

	
 
/**
 
 * Update the palettes of the graphics from the config file.
 
 * Called when changing the default palette in advanced settings.
 
 * @param p1 Unused.
 
 * @return Always true.
 
 */
 
bool UpdateNewGRFConfigPalette(int32 p1)
 
@@ -364,12 +390,13 @@ bool FillGRFDetails(GRFConfig *config, b
 
		return false;
 
	}
 

	
 
	/* Find and load the Action 8 information */
 
	LoadNewGRFFile(config, CONFIG_SLOT, GLS_FILESCAN, subdir);
 
	config->SetSuitablePalette();
 
	config->FinalizeParameterInfo();
 

	
 
	/* Skip if the grfid is 0 (not read) or 0xFFFFFFFF (ttdp system grf) */
 
	if (config->ident.grfid == 0 || config->ident.grfid == 0xFFFFFFFF || config->IsOpenTTDBaseGRF()) return false;
 

	
 
	if (is_static) {
 
		/* Perform a 'safety scan' for static GRFs */
src/newgrf_config.h
Show inline comments
 
@@ -130,15 +130,17 @@ struct GRFParameterInfo {
 
	uint32 max_value;      ///< The maximal value of this parameter
 
	uint32 def_value;      ///< Default value of this parameter
 
	byte param_nr;         ///< GRF parameter to store content in
 
	byte first_bit;        ///< First bit to use in the GRF parameter
 
	byte num_bit;          ///< Number of bits to use for this parameter
 
	SmallMap<uint32, struct GRFText *, 8> value_names; ///< Names for each value.
 
	bool complete_labels;  ///< True if all values have a label.
 

	
 
	uint32 GetValue(struct GRFConfig *config) const;
 
	void SetValue(struct GRFConfig *config, uint32 value);
 
	void Finalize();
 
};
 

	
 
/** Reference counted wrapper around a GRFText pointer. */
 
struct GRFTextWrapper : public SimpleCountedObject {
 
	struct GRFText *text; ///< The actual text
 

	
 
@@ -180,12 +182,13 @@ struct GRFConfig : ZeroedMemoryAllocator
 
	const char *GetName() const;
 
	const char *GetDescription() const;
 
	const char *GetURL() const;
 

	
 
	void SetParameterDefaults();
 
	void SetSuitablePalette();
 
	void FinalizeParameterInfo();
 
};
 

	
 
/** Method to find GRFs using FindGRFConfig */
 
enum FindGRFConfigMode {
 
	FGCM_EXACT,       ///< Only find Grfs matching md5sum
 
	FGCM_COMPATIBLE,  ///< Find best compatible Grf wrt. desired_version
src/newgrf_gui.cpp
Show inline comments
 
@@ -16,12 +16,13 @@
 
#include "strings_func.h"
 
#include "window_func.h"
 
#include "gamelog.h"
 
#include "settings_type.h"
 
#include "settings_func.h"
 
#include "widgets/dropdown_type.h"
 
#include "widgets/dropdown_func.h"
 
#include "network/network.h"
 
#include "network/network_content.h"
 
#include "sortlist_type.h"
 
#include "querystring_gui.h"
 
#include "core/geometry_func.hpp"
 
#include "newgrf_text.h"
 
@@ -140,22 +141,26 @@ static void ShowNewGRFInfo(const GRFConf
 
 */
 
struct NewGRFParametersWindow : public Window {
 
	static GRFParameterInfo dummy_parameter_info; ///< Dummy info in case a newgrf didn't provide info about some parameter.
 
	GRFConfig *grf_config; ///< Set the parameters of this GRFConfig.
 
	uint clicked_button;   ///< The row in which a button was clicked or UINT_MAX.
 
	bool clicked_increase; ///< True if the increase button was clicked, false for the decrease button.
 
	bool clicked_dropdown; ///< Whether the dropdown is open.
 
	bool closing_dropdown; ///< True, if the dropdown list is currently closing.
 
	int timeout;           ///< How long before we unpress the last-pressed button?
 
	uint clicked_row;      ///< The selected parameter
 
	int line_height;       ///< Height of a row in the matrix widget.
 
	Scrollbar *vscroll;
 
	bool action14present;  ///< True if action14 information is present.
 
	bool editable;         ///< Allow editing parameters.
 

	
 
	NewGRFParametersWindow(const WindowDesc *desc, GRFConfig *c, bool editable) : Window(),
 
		grf_config(c),
 
		clicked_button(UINT_MAX),
 
		clicked_dropdown(false),
 
		closing_dropdown(false),
 
		timeout(0),
 
		clicked_row(UINT_MAX),
 
		editable(editable)
 
	{
 
		this->action14present = (c->num_valid_params != lengthof(c->param) || c->param_info.Length() != 0);
 

	
 
@@ -260,13 +265,17 @@ struct NewGRFParametersWindow : public W
 
			bool selected = (i == this->clicked_row);
 

	
 
			if (par_info->type == PTYPE_BOOL) {
 
				DrawBoolButton(buttons_left, y + button_y_offset, current_value != 0, this->editable);
 
				SetDParam(2, par_info->GetValue(this->grf_config) == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON);
 
			} else if (par_info->type == PTYPE_UINT_ENUM) {
 
				DrawArrowButtons(buttons_left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, this->editable && current_value > par_info->min_value, this->editable && current_value < par_info->max_value);
 
				if (par_info->complete_labels) {
 
					DrawDropDownButton(buttons_left, y + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && this->clicked_dropdown, this->editable);
 
				} else {
 
					DrawArrowButtons(buttons_left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, this->editable && current_value > par_info->min_value, this->editable && current_value < par_info->max_value);
 
				}
 
				SetDParam(2, STR_JUST_INT);
 
				SetDParam(3, current_value);
 
				if (par_info->value_names.Contains(current_value)) {
 
					const char *label = GetGRFStringFromGRFText(par_info->value_names.Find(current_value)->second);
 
					if (label != NULL) {
 
						SetDParam(2, STR_JUST_RAW_STRING);
 
@@ -286,12 +295,21 @@ struct NewGRFParametersWindow : public W
 

	
 
			DrawString(text_left, text_right, y + WD_MATRIX_TOP, STR_NEWGRF_PARAMETERS_SETTING, selected ? TC_WHITE : TC_LIGHT_BLUE);
 
			y += this->line_height;
 
		}
 
	}
 

	
 
	virtual void OnPaint()
 
	{
 
		if (this->closing_dropdown) {
 
			this->closing_dropdown = false;
 
			this->clicked_dropdown = false;
 
		}
 
		this->DrawWidgets();
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget, int click_count)
 
	{
 
		switch (widget) {
 
			case WID_NP_NUMPAR_DEC:
 
				if (this->editable && !this->action14present && this->grf_config->num_params > 0) {
 
					this->grf_config->num_params--;
 
@@ -313,26 +331,57 @@ struct NewGRFParametersWindow : public W
 
			case WID_NP_BACKGROUND: {
 
				if (!this->editable) break;
 
				uint num = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NP_BACKGROUND);
 
				if (num >= this->vscroll->GetCount()) break;
 
				if (this->clicked_row != num) {
 
					DeleteChildWindows(WC_QUERY_STRING);
 
					HideDropDownMenu(this);
 
					this->clicked_row = num;
 
					this->clicked_dropdown = false;
 
				}
 

	
 
				const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_NP_BACKGROUND);
 
				int x = pt.x - wid->pos_x;
 
				if (_current_text_dir == TD_RTL) x = wid->current_x - 1 - x;
 
				x -= 4;
 

	
 
				GRFParameterInfo *par_info = (num < this->grf_config->param_info.Length()) ? this->grf_config->param_info[num] : NULL;
 
				if (par_info == NULL) par_info = GetDummyParameterInfo(num);
 

	
 
				/* One of the arrows is clicked */
 
				uint32 old_val = par_info->GetValue(this->grf_config);
 
				if (IsInsideMM(x, 0, SETTING_BUTTON_WIDTH)) {
 
				if (par_info->type != PTYPE_BOOL && IsInsideMM(x, 0, SETTING_BUTTON_WIDTH) && par_info->complete_labels) {
 
					if (this->clicked_dropdown) {
 
						/* unclick the dropdown */
 
						HideDropDownMenu(this);
 
						this->clicked_dropdown = false;
 
						this->closing_dropdown = false;
 
					} else {
 
						const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_NP_BACKGROUND);
 
						int rel_y = (pt.y - (int)wid->pos_y) % this->line_height;
 

	
 
						Rect wi_rect;
 
						wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x);;
 
						wi_rect.right = wi_rect.left + SETTING_BUTTON_WIDTH - 1;
 
						wi_rect.top = pt.y - rel_y + (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
 
						wi_rect.bottom = wi_rect.top + SETTING_BUTTON_HEIGHT - 1;
 

	
 
						/* For dropdowns we also have to check the y position thoroughly, the mouse may not above the just opening dropdown */
 
						if (pt.y >= wi_rect.top && pt.y <= wi_rect.bottom) {
 
							this->clicked_dropdown = true;
 
							this->closing_dropdown = false;
 

	
 
							DropDownList *list = new DropDownList();
 
							for (uint32 i = par_info->min_value; i <= par_info->max_value; i++) {
 
								list->push_back(new DropDownListCharStringItem(GetGRFStringFromGRFText(par_info->value_names.Find(i)->second), i, false));
 
							}
 

	
 
							ShowDropDownListAt(this, list, old_val, -1, wi_rect, COLOUR_ORANGE, true);
 
						}
 
					}
 
				} else if (IsInsideMM(x, 0, SETTING_BUTTON_WIDTH)) {
 
					uint32 val = old_val;
 
					if (par_info->type == PTYPE_BOOL) {
 
						val = !val;
 
					} else {
 
						if (x >= SETTING_BUTTON_WIDTH / 2) {
 
							/* Increase button clicked */
 
@@ -347,13 +396,13 @@ struct NewGRFParametersWindow : public W
 
					if (val != old_val) {
 
						par_info->SetValue(this->grf_config, val);
 

	
 
						this->clicked_button = num;
 
						this->timeout = 5;
 
					}
 
				} else if (par_info->type == PTYPE_UINT_ENUM && click_count >= 2) {
 
				} else if (par_info->type == PTYPE_UINT_ENUM && !par_info->complete_labels && click_count >= 2) {
 
					/* Display a query box so users can enter a custom value. */
 
					SetDParam(0, old_val);
 
					ShowQueryString(STR_JUST_INT, STR_CONFIG_SETTING_QUERY_CAPTION, 10, this, CS_NUMERAL, QSF_NONE);
 
				}
 
				this->SetDirty();
 
				break;
 
@@ -380,12 +429,32 @@ struct NewGRFParametersWindow : public W
 
		if (par_info == NULL) par_info = GetDummyParameterInfo(this->clicked_row);
 
		uint32 val = Clamp<uint32>(value, par_info->min_value, par_info->max_value);
 
		par_info->SetValue(this->grf_config, val);
 
		this->SetDirty();
 
	}
 

	
 
	virtual void OnDropdownSelect(int widget, int index)
 
	{
 
		assert(this->clicked_dropdown);
 
		GRFParameterInfo *par_info = ((uint)this->clicked_row < this->grf_config->param_info.Length()) ? this->grf_config->param_info[this->clicked_row] : NULL;
 
		if (par_info == NULL) par_info = GetDummyParameterInfo(this->clicked_row);
 
		par_info->SetValue(this->grf_config, index);
 
		this->SetDirty();
 
	}
 

	
 
	virtual void OnDropdownClose(Point pt, int widget, int index, bool instant_close)
 
	{
 
		/* We cannot raise the dropdown button just yet. OnClick needs some hint, whether
 
		 * the same dropdown button was clicked again, and then not open the dropdown again.
 
		 * So, we only remember that it was closed, and process it on the next OnPaint, which is
 
		 * after OnClick. */
 
		assert(this->clicked_dropdown);
 
		this->closing_dropdown = true;
 
		this->SetDirty();
 
	}
 

	
 
	virtual void OnResize()
 
	{
 
		NWidgetCore *nwi = this->GetWidget<NWidgetCore>(WID_NP_BACKGROUND);
 
		this->vscroll->SetCapacity(nwi->current_y / this->line_height);
 
		nwi->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START);
 
	}
0 comments (0 inline, 0 general)