Changeset - r10662:78df1ba8e47f
[Not reviewed]
master
0 1 0
rubidium - 15 years ago 2009-01-10 16:44:51
rubidium@openttd.org
(svn r14964) -Codechange: hide the length of a patch page behind a function (Alberth)
1 file changed with 33 insertions and 5 deletions:
0 comments (0 inline, 0 general)
src/settings_gui.cpp
Show inline comments
 
@@ -624,32 +624,36 @@ struct PatchEntry {
 
	byte flags; ///< Flags of the patch entry. @see PatchEntryFlags
 
	byte level; ///< Nesting level of this patch entry
 
	union {
 
		PatchEntrySetting entry; ///< Data fields if entry is a setting
 
		PatchEntrySubtree sub;   ///< Data fields if entry is a sub-page
 
	} d; ///< Data fields for each kind
 

	
 
	PatchEntry(const char *nm);
 
	PatchEntry(PatchPage *sub, StringID title);
 

	
 
	void Init(byte level, bool last_field);
 
	void SetButtons(byte new_val);
 

	
 
	uint Length() const;
 
};
 

	
 
/** Data structure describing one page of patches in the patch settings window. */
 
struct PatchPage {
 
	PatchEntry *entries; ///< Array of patch entries of the page.
 
	byte num;            ///< Number of entries on the page (statically filled).
 

	
 
	void Init(byte level = 0);
 

	
 
	uint Length() const;
 
};
 

	
 

	
 
/* == PatchEntry methods == */
 

	
 
/**
 
 * Constructor for a single setting in the 'advanced settings' window
 
 * @param nm Name of the setting in the setting table
 
 */
 
PatchEntry::PatchEntry(const char *nm)
 
{
 
	this->flags = PEF_SETTING_KIND;
 
@@ -697,38 +701,62 @@ void PatchEntry::Init(byte level, bool l
 

	
 
/**
 
 * Set the button-depressed flags (#PEF_LEFT_DEPRESSED and #PEF_RIGHT_DEPRESSED) to a specified value
 
 * @param new_val New value for the button flags
 
 * @see PatchEntryFlags
 
 */
 
void PatchEntry::SetButtons(byte new_val)
 
{
 
	assert((new_val & ~PEF_BUTTONS_MASK) == 0); // Should not touch any flags outside the buttons
 
	this->flags = (this->flags & ~PEF_BUTTONS_MASK) | new_val;
 
}
 

	
 
/** Return numbers of rows needed to display the entry */
 
uint PatchEntry::Length() const
 
{
 
	switch(this->flags & PEF_KIND_MASK) {
 
		case PEF_SETTING_KIND:
 
			return 1;
 
		case PEF_SUBTREE_KIND:
 
			if (this->d.sub.folded) return 1; // Only displaying the title
 

	
 
			return 1 + this->d.sub.page->Length(); // 1 extra row for the title
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 

	
 
/* == PatchPage methods == */
 

	
 
/**
 
 * Initialization of an entire setting page
 
 * @param level Nesting level of this page (internal variable, do not provide a value for it when calling)
 
 */
 
void PatchPage::Init(byte level)
 
{
 
	for (uint field = 0; field < this->num; field++) {
 
		this->entries[field].Init(level, field + 1 == num);
 
	}
 
}
 

	
 
/** Return number of rows needed to display the whole page */
 
uint PatchPage::Length() const
 
{
 
	uint length = 0;
 
	for (uint field = 0; field < this->num; field++) {
 
		length += this->entries[field].Length();
 
	}
 
	return length;
 
}
 

	
 

	
 
static PatchEntry _patches_ui[] = {
 
	PatchEntry("gui.vehicle_speed"),
 
	PatchEntry("gui.status_long_date"),
 
	PatchEntry("gui.date_format_in_default_names"),
 
	PatchEntry("gui.show_finances"),
 
	PatchEntry("gui.autoscroll"),
 
	PatchEntry("gui.reverse_scroll"),
 
	PatchEntry("gui.smooth_scroll"),
 
	PatchEntry("gui.errmsg_duration"),
 
	PatchEntry("gui.toolbar_pos"),
 
	PatchEntry("gui.measure_tooltip"),
 
@@ -900,46 +928,46 @@ struct PatchesSelectionWindow : Window {
 
		/* Build up the dynamic settings-array only once per OpenTTD session */
 
		if (first_time) {
 
			for (PatchPage *page = &_patches_page[0]; page != endof(_patches_page); page++) {
 
				page->Init();
 
			}
 
			first_time = false;
 
		}
 

	
 
		this->page = 0;
 
		this->clicked_entry = NULL; // No numeric patch setting buttons are depressed
 
		this->vscroll.pos = 0;
 
		this->vscroll.cap = (this->widget[PATCHSEL_OPTIONSPANEL].bottom - this->widget[PATCHSEL_OPTIONSPANEL].top - 8) / SETTING_HEIGHT;
 
		SetVScrollCount(this, _patches_page[this->page].num);
 
		SetVScrollCount(this, _patches_page[this->page].Length());
 

	
 
		this->resize.step_height = SETTING_HEIGHT;
 
		this->resize.height = this->height;
 
		this->resize.step_width = 1;
 
		this->resize.width = this->width;
 

	
 
		this->LowerWidget(this->page + PATCHSEL_INTERFACE); // Depress button of currently selected page
 

	
 
		this->FindWindowPlacementAndResize(desc);
 
	}
 

	
 
	virtual void OnPaint()
 
	{
 
		const PatchPage *page = &_patches_page[this->page];
 

	
 
		/* Set up selected category */
 
		this->DrawWidgets();
 

	
 
		int x = SETTINGTREE_LEFT_OFFSET;
 
		int y = SETTINGTREE_TOP_OFFSET;
 
		for (uint i = this->vscroll.pos; i != page->num && this->vscroll.pos + this->vscroll.cap - i > 0; i++) {
 
		for (uint i = this->vscroll.pos; i != page->Length() && this->vscroll.pos + this->vscroll.cap - i > 0; i++) {
 
			assert((page->entries[i].flags & PEF_KIND_MASK) == PEF_SETTING_KIND);
 
			const SettingDesc *sd = page->entries[i].d.entry.setting;
 
			int state = page->entries[i].flags & PEF_BUTTONS_MASK;
 
			DrawPatch(patches_ptr, sd, x, y, state);
 
			y += SETTING_HEIGHT;
 
		}
 
	}
 

	
 
	void DrawPatch(GameSettings *patches_ptr, const SettingDesc *sd, int x, int y, int state)
 
	{
 
		const SettingDescBase *sdb = &sd->desc;
 
		const void *var = GetVariableAddress(patches_ptr, &sd->save);
 
@@ -989,25 +1017,25 @@ struct PatchesSelectionWindow : Window {
 
			case PATCHSEL_OPTIONSPANEL: {
 
				int y = pt.y - SETTINGTREE_TOP_OFFSET;  // Shift y coordinate
 
				if (y < 0) return;  // Clicked above first entry
 

	
 
				int x = pt.x - SETTINGTREE_LEFT_OFFSET;  // Shift x coordinate
 
				if (x < 0) return;  // Clicked left of the entry
 

	
 
				byte btn = this->vscroll.pos + y / SETTING_HEIGHT;  // Compute which setting is selected
 
				if (y % SETTING_HEIGHT > SETTING_HEIGHT - 2) return;  // Clicked too low at the setting
 

	
 
				const PatchPage *page = &_patches_page[this->page];
 

	
 
				if (btn >= page->num) return;  // Clicked below the last setting of the page
 
				if (btn >= page->Length()) return;  // Clicked below the last setting of the page
 

	
 
				assert((page->entries[btn].flags & PEF_KIND_MASK) == PEF_SETTING_KIND);
 
				const SettingDesc *sd = page->entries[btn].d.entry.setting;
 

	
 
				/* return if action is only active in network, or only settable by server */
 
				if (!(sd->save.conv & SLF_NETWORK_NO) && _networking && !_network_server) return;
 
				if ((sd->desc.flags & SGF_NETWORK_ONLY) && !_networking) return;
 
				if ((sd->desc.flags & SGF_NO_NETWORK) && _networking) return;
 

	
 
				void *var = GetVariableAddress(patches_ptr, &sd->save);
 
				int32 value = (int32)ReadValue(var, sd->save.conv);
 

	
 
@@ -1070,25 +1098,25 @@ struct PatchesSelectionWindow : Window {
 
						this->entry = btn;
 
						SetDParam(0, value);
 
						ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_CONFIG_PATCHES_QUERY_CAPT, 10, 100, this, CS_NUMERAL, QSF_NONE);
 
					}
 
				}
 
			} break;
 

	
 
			case PATCHSEL_INTERFACE: case PATCHSEL_CONSTRUCTION: case PATCHSEL_VEHICLES:
 
			case PATCHSEL_STATIONS:  case PATCHSEL_ECONOMY:      case PATCHSEL_COMPETITORS:
 
				this->RaiseWidget(this->page + PATCHSEL_INTERFACE);
 
				this->page = widget - PATCHSEL_INTERFACE;
 
				this->LowerWidget(this->page + PATCHSEL_INTERFACE);
 
				SetVScrollCount(this, _patches_page[this->page].num);
 
				SetVScrollCount(this, _patches_page[this->page].Length());
 
				DeleteWindowById(WC_QUERY_STRING, 0);
 
				this->SetDirty();
 
				break;
 
		}
 
	}
 

	
 
	virtual void OnTimeout()
 
	{
 
		if (this->clicked_entry != NULL) { // On timeout, release any depressed buttons
 
			this->clicked_entry->SetButtons(0);
 
			this->clicked_entry = NULL;
 
			this->SetDirty();
 
@@ -1105,25 +1133,25 @@ struct PatchesSelectionWindow : Window {
 

	
 
			/* Save the correct currency-translated value */
 
			if (sd->desc.flags & SGF_CURRENCY) value /= _currency->rate;
 

	
 
			SetPatchValue(pe->d.entry.index, value);
 
			this->SetDirty();
 
		}
 
	}
 

	
 
	virtual void OnResize(Point new_size, Point delta)
 
	{
 
		this->vscroll.cap += delta.y / SETTING_HEIGHT;
 
		SetVScrollCount(this, _patches_page[this->page].num);
 
		SetVScrollCount(this, _patches_page[this->page].Length());
 
	}
 
};
 

	
 
GameSettings *PatchesSelectionWindow::patches_ptr = NULL;
 
const int PatchesSelectionWindow::SETTINGTREE_LEFT_OFFSET = 5;
 
const int PatchesSelectionWindow::SETTINGTREE_TOP_OFFSET = 47;
 

	
 
static const Widget _patches_selection_widgets[] = {
 
{   WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_MAUVE,     0,    10,     0,    13, STR_00C5,                        STR_018B_CLOSE_WINDOW},
 
{    WWT_CAPTION,  RESIZE_RIGHT,  COLOUR_MAUVE,    11,   381,     0,    13, STR_CONFIG_PATCHES_CAPTION,      STR_018C_WINDOW_TITLE_DRAG_THIS},
 
{      WWT_PANEL,  RESIZE_RIGHT,  COLOUR_MAUVE,     0,   381,    14,    41, 0x0,                             STR_NULL},
 
{      WWT_PANEL,     RESIZE_RB,  COLOUR_MAUVE,     0,   369,    42,   215, 0x0,                             STR_NULL}, // PATCHSEL_OPTIONSPANEL
0 comments (0 inline, 0 general)