(svn r24318) -Feature: Add dropdowns to NewGRF configurations, if all values have labels.

pull/155/head
frosch 12 years ago
parent deda762b8f
commit 69f836e57b

@ -164,6 +164,17 @@ void GRFConfig::SetSuitablePalette()
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;
@ -232,7 +243,8 @@ GRFParameterInfo::GRFParameterInfo(GRFParameterInfo &info) :
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);
@ -280,6 +292,20 @@ void GRFParameterInfo::SetValue(struct GRFConfig *config, uint32 value)
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.
@ -367,6 +393,7 @@ bool FillGRFDetails(GRFConfig *config, bool is_static, Subdirectory subdir)
/* 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;

@ -133,9 +133,11 @@ struct GRFParameterInfo {
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. */
@ -183,6 +185,7 @@ struct GRFConfig : ZeroedMemoryAllocator {
void SetParameterDefaults();
void SetSuitablePalette();
void FinalizeParameterInfo();
};
/** Method to find GRFs using FindGRFConfig */

@ -19,6 +19,7 @@
#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"
@ -143,6 +144,8 @@ struct NewGRFParametersWindow : public Window {
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.
@ -153,6 +156,8 @@ struct NewGRFParametersWindow : public Window {
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)
@ -263,7 +268,11 @@ struct NewGRFParametersWindow : public Window {
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)) {
@ -289,6 +298,15 @@ struct NewGRFParametersWindow : public Window {
}
}
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) {
@ -316,7 +334,9 @@ struct NewGRFParametersWindow : public Window {
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);
@ -329,7 +349,36 @@ struct NewGRFParametersWindow : public Window {
/* 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;
@ -350,7 +399,7 @@ struct NewGRFParametersWindow : public Window {
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);
@ -383,6 +432,26 @@ struct NewGRFParametersWindow : public Window {
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);

Loading…
Cancel
Save