Changeset - r10660:e9232b868967
[Not reviewed]
master
0 1 0
rubidium - 15 years ago 2009-01-10 16:39:18
rubidium@openttd.org
(svn r14962) -Codechange: add the concept of patch entries and patch (sub) pages
1 file changed with 100 insertions and 18 deletions:
0 comments (0 inline, 0 general)
src/settings_gui.cpp
Show inline comments
 
@@ -586,19 +586,53 @@ void ShowGameDifficulty()
 

	
 
static const int SETTING_HEIGHT = 11;         ///< Height of a single patch setting in the tree view
 

	
 
/** Data structure describing a single patch in a tab */
 
struct PatchEntry {
 
/** Flags for #PatchEntry */
 
enum PatchEntryFlags {
 
	PEF_LAST_FIELD = 0x04, ///< This entry is the last one in a (sub-)page
 

	
 
	/* Entry kind */
 
	PEF_SETTING_KIND = 0x10, ///< Entry kind: Entry is a setting
 
	PEF_SUBTREE_KIND = 0x20, ///< Entry kind: Entry is a sub-tree
 
	PEF_KIND_MASK    = (PEF_SETTING_KIND | PEF_SUBTREE_KIND), ///< Bit-mask for fetching entry kind
 
};
 

	
 
struct PatchPage; // Forward declaration
 

	
 
/** Data fields for a sub-page (#PEF_SUBTREE_KIND kind)*/
 
struct PatchEntrySubtree {
 
	PatchPage *page; ///< Pointer to the sub-page
 
	bool folded;     ///< Sub-page is folded (not visible except for its title)
 
	StringID title;  ///< Title of the sub-page
 
};
 

	
 
/** Data fields for a single setting (#PEF_SETTING_KIND kind) */
 
struct PatchEntrySetting {
 
	const char *name;           ///< Name of the setting
 
	const SettingDesc *setting; ///< Setting description of the setting
 
	uint index;                 ///< Index of the setting in the settings table
 
};
 

	
 
/** Data structure describing a single patch in a tab */
 
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);
 
};
 

	
 
/** 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);
 
};
 

	
 

	
 
@@ -610,9 +644,61 @@ struct PatchPage {
 
 */
 
PatchEntry::PatchEntry(const char *nm)
 
{
 
	this->name = nm;
 
	this->setting = NULL;
 
	this->index = 0;
 
	this->flags = PEF_SETTING_KIND;
 
	this->level = 0;
 
	this->d.entry.name = nm;
 
	this->d.entry.setting = NULL;
 
	this->d.entry.index = 0;
 
}
 

	
 
/**
 
 * Constructor for a sub-page in the 'advanced settings' window
 
 * @param sub   Sub-page
 
 * @param title Title of the sub-page
 
 */
 
PatchEntry::PatchEntry(PatchPage *sub, StringID title)
 
{
 
	this->flags = PEF_SUBTREE_KIND;
 
	this->level = 0;
 
	this->d.sub.page = sub;
 
	this->d.sub.folded = true;
 
	this->d.sub.title = title;
 
}
 

	
 
/**
 
 * Initialization of a patch entry
 
 * @param level      Page nesting level of this entry
 
 * @param last_field Boolean indicating this entry is the last at the (sub-)page
 
 */
 
void PatchEntry::Init(byte level, bool last_field)
 
{
 
	this->level = level;
 
	if (last_field) this->flags |= PEF_LAST_FIELD;
 

	
 
	switch (this->flags & PEF_KIND_MASK) {
 
		case PEF_SETTING_KIND:
 
			this->d.entry.setting = GetPatchFromName(this->d.entry.name, &this->d.entry.index);
 
			assert(this->d.entry.setting != NULL);
 
			break;
 
		case PEF_SUBTREE_KIND:
 
			this->d.sub.page->Init(level + 1);
 
			break;
 
		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);
 
	}
 
}
 

	
 

	
 
@@ -795,14 +881,7 @@ 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++) {
 
				for (uint i = 0; i != page->num; i++) {
 
					uint index;
 
					const SettingDesc *sd = GetPatchFromName(page->entries[i].name, &index);
 
					assert(sd != NULL);
 

	
 
					page->entries[i].setting = sd;
 
					page->entries[i].index = index;
 
				}
 
				page->Init();
 
			}
 
			first_time = false;
 
		}
 
@@ -832,7 +911,8 @@ struct PatchesSelectionWindow : Window {
 
		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++) {
 
			const SettingDesc *sd = page->entries[i].setting;
 
			assert((page->entries[i].flags & PEF_KIND_MASK) == PEF_SETTING_KIND);
 
			const SettingDesc *sd = page->entries[i].d.entry.setting;
 
			DrawPatch(patches_ptr, sd, x, y, this->click - (i * 2));
 
			y += SETTING_HEIGHT;
 
		}
 
@@ -899,7 +979,8 @@ struct PatchesSelectionWindow : Window {
 

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

	
 
				const SettingDesc *sd = page->entries[btn].setting;
 
				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;
 
@@ -952,7 +1033,7 @@ struct PatchesSelectionWindow : Window {
 
					}
 

	
 
					if (value != oldvalue) {
 
						SetPatchValue(page->entries[btn].index, value);
 
						SetPatchValue(page->entries[btn].d.entry.index, value);
 
						this->SetDirty();
 
					}
 
				} else {
 
@@ -990,13 +1071,14 @@ struct PatchesSelectionWindow : Window {
 
	{
 
		if (!StrEmpty(str)) {
 
			const PatchEntry *pe = &_patches_page[this->page].entries[this->entry];
 
			const SettingDesc *sd = pe->setting;
 
			assert((pe->flags & PEF_KIND_MASK) == PEF_SETTING_KIND);
 
			const SettingDesc *sd = pe->d.entry.setting;
 
			int32 value = atoi(str);
 

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

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