Index: binaries/data/mods/public/gui/civinfo/civinfo.js
===================================================================
--- binaries/data/mods/public/gui/civinfo/civinfo.js
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * Display selectable civs only.
- */
-const g_CivData = loadCivData(true, false);
-
-var g_SelectedCiv = "";
-
-/**
- * Initialize the dropdown containing all the available civs.
- */
-function init(data = {})
-{
- var civList = Object.keys(g_CivData).map(civ => ({ "name": g_CivData[civ].Name, "code": civ })).sort(sortNameIgnoreCase);
- var civSelection = Engine.GetGUIObjectByName("civSelection");
-
- civSelection.list = civList.map(civ => civ.name);
- civSelection.list_data = civList.map(civ => civ.code);
- civSelection.selected = data.civ ? civSelection.list_data.indexOf(data.civ) : 0;
-
- Engine.GetGUIObjectByName("structreeButton").tooltip = colorizeHotkey(translate("%(hotkey)s: Switch to Structure Tree."), "structree");
- Engine.GetGUIObjectByName("close").tooltip = colorizeHotkey(translate("%(hotkey)s: Close Civilization Overview."), "cancel");
-}
-
-/**
- * Give the first character a larger font.
- */
-function bigFirstLetter(str, size)
-{
- return '[font="sans-bold-' + (size + 6) + '"]' + str[0] + '[/font]' + '[font="sans-bold-' + size + '"]' + str.substring(1) + '[/font]';
-}
-
-/**
- * Set heading font - bold and mixed caps
- *
- * @param string {string}
- * @param size {number} - Font size
- * @returns {string}
- */
-function heading(string, size)
-{
- var textArray = string.split(" ");
-
- for (let i in textArray)
- {
- var word = textArray[i];
- var wordCaps = word.toUpperCase();
-
- // Check if word is capitalized, if so assume it needs a big first letter
- // Check if toLowerCase changes the character to avoid false positives from special signs
- if (word.length && word[0].toLowerCase() != word[0])
- textArray[i] = bigFirstLetter(wordCaps, size);
- else
- textArray[i] = '[font="sans-bold-' + size + '"]' + wordCaps + '[/font]'; // TODO: Would not be necessary if we could do nested tags
- }
-
- return textArray.join(" ");
-}
-
-/**
- * Prepends a backslash to all quotation marks.
- * @param str {string}
- * @returns {string}
- */
-function escapeQuotation(str)
-{
- return str.replace(/"/g, "\\\"");
-}
-
-/**
- * Returns a styled concatenation of Name, History and Description of the given object.
- *
- * @param obj {Object}
- * @returns {string}
- */
-function subHeading(obj)
-{
- if (!obj.Name)
- return "";
- let string = '[font="sans-bold-14"]' + obj.Name + '[/font] ';
- if (obj.History)
- string += '[icon="iconInfo" tooltip="' + escapeQuotation(obj.History) + '" tooltip_style="civInfoTooltip"]';
- if (obj.Description)
- string += '\n ' + obj.Description;
- // Translation: insert an itemization symbol for each entry.
- return sprintf(translate("• %(string)s"), { "string": string }) + "\n";
-}
-
-function switchToStrucTreePage()
-{
- Engine.PopGuiPage({ "civ": g_SelectedCiv, "nextPage": "page_structree.xml" });
-}
-
-function closePage()
-{
- Engine.PopGuiPage({ "civ": g_SelectedCiv, "page": "page_civinfo.xml" });
-}
-
-/**
- * Updates the GUI after the user selected a civ from dropdown.
- *
- * @param code {string}
- */
-function selectCiv(code)
-{
- var civInfo = g_CivData[code];
-
- g_SelectedCiv = code;
-
- if(!civInfo)
- error(sprintf("Error loading civ data for \"%(code)s\"", { "code": code }));
-
- // Update civ gameplay display
- Engine.GetGUIObjectByName("civGameplayHeading").caption = heading(sprintf(translate("%(civilization)s Gameplay"), { "civilization": civInfo.Name }), 16);
-
- // Bonuses
- var bonusCaption = heading(translatePlural("Civilization Bonus", "Civilization Bonuses", civInfo.CivBonuses.length), 12) + '\n';
- for (let bonus of civInfo.CivBonuses)
- bonusCaption += subHeading(bonus);
-
- // Team bonuses
- bonusCaption += heading(translatePlural("Team Bonus", "Team Bonuses", civInfo.TeamBonuses.length), 12) + '\n';
- for (let bonus of civInfo.TeamBonuses)
- bonusCaption += subHeading(bonus);
-
- Engine.GetGUIObjectByName("civBonuses").caption = bonusCaption;
-
- // Special technologies
- var techCaption = heading(translate("Special Technologies"), 12) + '\n';
- for (let faction of civInfo.Factions)
- for (let technology of faction.Technologies)
- techCaption += subHeading(technology);
-
- // Special structures
- techCaption += heading(translatePlural("Special Structure", "Special Structures", civInfo.Structures.length), 12) + '\n';
- for (let structure of civInfo.Structures)
- techCaption += subHeading(structure);
-
- Engine.GetGUIObjectByName("civTechs").caption = techCaption;
-
- // Heroes
- var heroCaption = heading(translate("Heroes"), 12) + '\n';
- for (let faction of civInfo.Factions)
- {
- for (let hero of faction.Heroes)
- heroCaption += subHeading(hero);
- heroCaption += '\n';
- }
- Engine.GetGUIObjectByName("civHeroes").caption = heroCaption;
-
- // Update civ history display
- Engine.GetGUIObjectByName("civHistoryHeading").caption = heading(sprintf(translate("History of the %(civilization)s"), { "civilization": civInfo.Name }), 16);
- Engine.GetGUIObjectByName("civHistoryText").caption = civInfo.History;
-}
Index: binaries/data/mods/public/gui/civinfo/civinfo.xml
===================================================================
--- binaries/data/mods/public/gui/civinfo/civinfo.xml
+++ /dev/null
@@ -1,141 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Index: binaries/data/mods/public/gui/civinfo/setup.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/civinfo/setup.xml
@@ -1,14 +0,0 @@
-
-
-
-
-
Index: binaries/data/mods/public/gui/civinfo/sprites.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/civinfo/sprites.xml
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Index: binaries/data/mods/public/gui/common/functions_utility.js
===================================================================
--- binaries/data/mods/public/gui/common/functions_utility.js
+++ binaries/data/mods/public/gui/common/functions_utility.js
@@ -70,6 +70,14 @@
return text.replace(/\\\\/g, "\\").replace(/\\\[/g, "\[");
}
+/**
+ * Prepends a backslash to all quotation marks.
+ */
+function escapeQuotation(text)
+{
+ return text.replace(/"/g, "\\\"");
+}
+
/**
* Merge players by team to remove duplicate Team entries, thus reducing the packet size of the lobby report.
*/
Index: binaries/data/mods/public/gui/page_civinfo.xml
===================================================================
--- binaries/data/mods/public/gui/page_civinfo.xml
+++ binaries/data/mods/public/gui/page_civinfo.xml
@@ -8,7 +8,13 @@
common/sprites.xml
common/styles.xml
- civinfo/civinfo.xml
- civinfo/setup.xml
- civinfo/sprites.xml
+ reference/common/sprites.xml
+ reference/common/styles.xml
+
+ reference/civinfo/sprites.xml
+ reference/civinfo/styles.xml
+ reference/civinfo/civinfo.xml
+ reference/civinfo/setup.xml
+
+ reference/common/setup.xml
Index: binaries/data/mods/public/gui/reference/civinfo/CivInfoPage.js
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/CivInfoPage.js
@@ -0,0 +1,122 @@
+class CivInfoPage extends ReferencePage
+{
+ constructor(data)
+ {
+ super();
+
+ this.civSelection = new CivSelectDropdown(this.civData);
+ this.civSelection.registerHandler(this.selectCiv.bind(this));
+
+ this.gameplaySection = new GameplaySection(this);
+ this.historySection = new HistorySection(this);
+
+ let structreeButton = new StructreeButton(this);
+ let closeButton = new CloseButton(this);
+ Engine.SetGlobalHotkey("civinfo", "Press", this.closePage.bind(this));
+ }
+
+ switchToStructreePage()
+ {
+ Engine.PopGuiPage({ "civ": this.activeCiv, "nextPage": "page_structree.xml" });
+ }
+
+ closePage()
+ {
+ Engine.PopGuiPage({ "civ": this.activeCiv, "page": "page_civinfo.xml" });
+ }
+
+ /**
+ * Updates the GUI after the user selected a civ from dropdown.
+ *
+ * @param code {string}
+ */
+ selectCiv(civCode)
+ {
+ this.setActiveCiv(civCode);
+
+ let civInfo = this.civData[civCode];
+
+ if(!civInfo)
+ error(sprintf("Error loading civ data for \"%(code)s\"", { "code": civCode }));
+
+ // Update civ gameplay display
+ this.gameplaySection.update(civInfo);
+
+ // Update civ history display
+ this.historySection.update(civInfo);
+ }
+
+ /**
+ * Give the first character a larger font.
+ */
+ bigFirstLetter(text, size)
+ {
+ return setStringTags(text[0], { "font": "sans-bold-" + (size + 6) }) + text.substring(1);
+ }
+
+ /**
+ * Set heading font - bold and mixed caps
+ *
+ * @param text {string}
+ * @param size {number} - Font size
+ * @returns {string}
+ */
+ formatHeading(text, size)
+ {
+ let textArray = [];
+
+ for (let word of text.split(" "))
+ {
+ let wordCaps = word.toUpperCase();
+
+ // Usually we wish a big first letter, however this isn't always desirable.
+ // Check if toLowerCase changes the character to avoid false positives from special characters
+ if (word.length && word[0].toLowerCase() != word[0])
+ word = this.bigFirstLetter(wordCaps, size);
+
+ textArray.push(setStringTags(word, { "font": "sans-bold-" + size }));
+ }
+
+ return textArray.join(" ");
+ }
+
+ /**
+ * Returns a styled concatenation of the Name, History, and Description of the given object.
+ *
+ * @param obj {Object}
+ * @returns {string}
+ */
+ formatEntry(obj)
+ {
+ if (!obj.Name)
+ return "";
+
+ let history_icon = "";
+ if (obj.History)
+ history_icon = '[icon="iconInfo" tooltip="' + escapeQuotation(obj.History) + '" tooltip_style="civInfoTooltip"]';
+
+ let description = "";
+ if (obj.Description)
+ // Translation: Description of an item in the CivInfo page, on a new line and indented.
+ description = sprintf(translate('\n %(description)s'), { "description": obj.Description, });
+
+ return sprintf(
+ // Translation: An entry in the CivInfo Page. The newline and indentation of the description is handled elsewhere.
+ // Example:
+ // > • Name of a Special Something (i)
+ // > A brief description of the aforementioned something.
+ translate("• %(name)s %(info_icon)s%(description)s"),
+ {
+ "name": setStringTags(obj.Name, { "font": "sans-bold-14" }),
+ "info_icon": history_icon,
+ "description": description,
+ }
+ );
+ }
+}
+
+CivInfoPage.prototype.CloseButtonTooltip =
+ translate("%(hotkey)s: Close Civilization Overview.");
+
+CivInfoPage.prototype.SectionHeaderSize = 16;
+CivInfoPage.prototype.SubsectionHeaderSize = 12;
Index: binaries/data/mods/public/gui/reference/civinfo/Sections/GameplaySection.js
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/Sections/GameplaySection.js
@@ -0,0 +1,30 @@
+class GameplaySection
+{
+ constructor(page)
+ {
+ this.page = page;
+ this.CivGameplayHeading = Engine.GetGUIObjectByName('civGameplayHeading');
+
+ this.BonusesSubsection = new BonusesSubsection(this.page);
+ this.HeroesSubsection = new HeroesSubsection(this.page);
+ this.StructuresSubsection = new StructuresSubsection(this.page);
+ this.TechnologiesSubsection = new TechnologiesSubsection(this.page);
+ }
+
+ update(civInfo)
+ {
+ this.CivGameplayHeading.caption =
+ this.page.formatHeading(
+ sprintf(this.headingCaption, { "civilization": civInfo.Name }),
+ this.page.SectionHeaderSize
+ );
+
+ this.BonusesSubsection.update(civInfo);
+ this.TechnologiesSubsection.update(civInfo);
+ this.StructuresSubsection.update(civInfo);
+ this.HeroesSubsection.update(civInfo);
+ }
+}
+
+GameplaySection.prototype.headingCaption =
+ translate("%(civilization)s Gameplay");
Index: binaries/data/mods/public/gui/reference/civinfo/Sections/GameplaySection.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/Sections/GameplaySection.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: binaries/data/mods/public/gui/reference/civinfo/Sections/HistorySection.js
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/Sections/HistorySection.js
@@ -0,0 +1,23 @@
+class HistorySection
+{
+ constructor(page)
+ {
+ this.page = page;
+ this.CivHistoryHeading = Engine.GetGUIObjectByName('civHistoryHeading');
+ this.CivHistoryText = Engine.GetGUIObjectByName('civHistoryText');
+ }
+
+ update(civInfo)
+ {
+ this.CivHistoryHeading.caption =
+ this.page.formatHeading(
+ sprintf(this.headingCaption, { "civilization": civInfo.Name }),
+ this.page.SectionHeaderSize
+ );
+
+ this.CivHistoryText.caption = civInfo.History;
+ }
+}
+
+HistorySection.prototype.headingCaption =
+ translate("History of the %(civilization)s");
Index: binaries/data/mods/public/gui/reference/civinfo/Sections/HistorySection.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/Sections/HistorySection.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
Index: binaries/data/mods/public/gui/reference/civinfo/Sections/Subsection.js
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/Sections/Subsection.js
@@ -0,0 +1,7 @@
+class Subsection
+{
+ constructor(page)
+ {
+ this.page = page;
+ }
+}
Index: binaries/data/mods/public/gui/reference/civinfo/Sections/Subsections/BonusesSubsection.js
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/Sections/Subsections/BonusesSubsection.js
@@ -0,0 +1,35 @@
+class BonusesSubsection extends Subsection
+{
+ constructor(page)
+ {
+ super(page);
+ this.CivBonuses = Engine.GetGUIObjectByName("civBonuses");
+ }
+
+ update(civInfo)
+ {
+ let civBonuses = civInfo.CivBonuses.map(bonus => this.page.formatEntry(bonus));
+ civBonuses.unshift(
+ this.page.formatHeading(
+ this.HeadingCivBonusCaption(civBonuses.length),
+ this.page.SubsectionHeaderSize
+ )
+ );
+
+ let teamBonuses = civInfo.TeamBonuses.map(bonus => this.page.formatEntry(bonus));
+ teamBonuses.unshift(
+ this.page.formatHeading(
+ this.HeadingTeamBonusCaption(teamBonuses.length),
+ this.page.SubsectionHeaderSize
+ )
+ );
+
+ this.CivBonuses.caption = civBonuses.join("\n") + "\n\n" + teamBonuses.join("\n");
+ }
+}
+
+BonusesSubsection.prototype.HeadingCivBonusCaption =
+ count => translatePlural("Civilization Bonus", "Civilization Bonuses", count);
+
+BonusesSubsection.prototype.HeadingTeamBonusCaption =
+ count => translatePlural("Team Bonus", "Team Bonuses", count);
Index: binaries/data/mods/public/gui/reference/civinfo/Sections/Subsections/BonusesSubsection.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/Sections/Subsections/BonusesSubsection.xml
@@ -0,0 +1,9 @@
+
+
+
+
Index: binaries/data/mods/public/gui/reference/civinfo/Sections/Subsections/HeroesSubsection.js
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/Sections/Subsections/HeroesSubsection.js
@@ -0,0 +1,30 @@
+class HeroesSubsection extends Subsection
+{
+ constructor(page)
+ {
+ super(page);
+ this.CivHeroes = Engine.GetGUIObjectByName("civHeroes");
+ }
+
+ update(civInfo)
+ {
+ let heroes = [];
+ for (let faction of civInfo.Factions)
+ Array.prototype.push.apply(
+ heroes,
+ faction.Heroes.map(hero => this.page.formatEntry(hero))
+ );
+
+ heroes.unshift(
+ this.page.formatHeading(
+ this.HeadingCaption(heroes.length),
+ this.page.SubsectionHeaderSize
+ )
+ );
+
+ this.CivHeroes.caption = heroes.join("\n");
+ }
+}
+
+HeroesSubsection.prototype.HeadingCaption =
+ count => translatePlural("Hero", "Heroes", count);
Index: binaries/data/mods/public/gui/reference/civinfo/Sections/Subsections/HeroesSubsection.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/Sections/Subsections/HeroesSubsection.xml
@@ -0,0 +1,9 @@
+
+
+
+
Index: binaries/data/mods/public/gui/reference/civinfo/Sections/Subsections/StructuresSubsection.js
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/Sections/Subsections/StructuresSubsection.js
@@ -0,0 +1,24 @@
+class StructuresSubsection extends Subsection
+{
+ constructor(page)
+ {
+ super(page);
+ this.CivStructures = Engine.GetGUIObjectByName("civStructures");
+ }
+
+ update(civInfo)
+ {
+ let structures = civInfo.Structures.map(bonus => this.page.formatEntry(bonus));
+ structures.unshift(
+ this.page.formatHeading(
+ this.HeadingCaption(structures.length),
+ this.page.SubsectionHeaderSize
+ )
+ );
+
+ this.CivStructures.caption = structures.join("\n");
+ }
+}
+
+StructuresSubsection.prototype.HeadingCaption =
+ count => translatePlural("Special Structure", "Special Structures", count);
Index: binaries/data/mods/public/gui/reference/civinfo/Sections/Subsections/StructuresSubsection.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/Sections/Subsections/StructuresSubsection.xml
@@ -0,0 +1,9 @@
+
+
+
+
Index: binaries/data/mods/public/gui/reference/civinfo/Sections/Subsections/TechnologiesSubsection.js
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/Sections/Subsections/TechnologiesSubsection.js
@@ -0,0 +1,30 @@
+class TechnologiesSubsection extends Subsection
+{
+ constructor(page)
+ {
+ super(page);
+ this.CivTechs = Engine.GetGUIObjectByName("civTechs");
+ }
+
+ update(civInfo)
+ {
+ let techs = [];
+ for (let faction of civInfo.Factions)
+ Array.prototype.push.apply(
+ techs,
+ faction.Technologies.map(tech => this.page.formatEntry(tech))
+ );
+
+ techs.unshift(
+ this.page.formatHeading(
+ this.HeadingCaption(techs.length),
+ this.page.SubsectionHeaderSize
+ )
+ );
+
+ this.CivTechs.caption = techs.join("\n");
+ }
+}
+
+TechnologiesSubsection.prototype.HeadingCaption =
+ count => translatePlural("Special Technology", "Special Technologies", count);
Index: binaries/data/mods/public/gui/reference/civinfo/Sections/Subsections/TechnologiesSubsection.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/Sections/Subsections/TechnologiesSubsection.xml
@@ -0,0 +1,9 @@
+
+
+
+
Index: binaries/data/mods/public/gui/reference/civinfo/civinfo.js
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/civinfo.js
@@ -0,0 +1,12 @@
+/**
+ * Initialize the dropdown containing all the available civs.
+ */
+function init(data = {})
+{
+ g_Page = new CivInfoPage(data);
+
+ if (data.civ)
+ g_Page.civSelection.selectCiv(data.civ);
+ else
+ g_Page.civSelection.selectFirstCiv();
+}
Index: binaries/data/mods/public/gui/reference/civinfo/civinfo.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/civinfo.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Civilization Overview
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: binaries/data/mods/public/gui/reference/civinfo/styles.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/civinfo/styles.xml
@@ -0,0 +1,10 @@
+
+
+
+
Index: binaries/data/mods/public/gui/reference/common/Buttons/StructreeButton.js
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/common/Buttons/StructreeButton.js
@@ -0,0 +1,27 @@
+class StructreeButton
+{
+ constructor(parentPage)
+ {
+ this.parentPage = parentPage;
+
+ this.civInfoButton = Engine.GetGUIObjectByName("structreeButton");
+ this.civInfoButton.onPress = this.onPress.bind(this);
+ this.civInfoButton.caption = this.Caption;
+ this.civInfoButton.tooltip = colorizeHotkey(this.Tooltip, this.Hotkey);
+ }
+
+ onPress()
+ {
+ Engine.PopGuiPage({ "civ": this.parentPage.activeCiv, "nextPage": "page_structree.xml" });
+ }
+
+}
+
+StructreeButton.prototype.Caption =
+ translate("Structure Tree");
+
+StructreeButton.prototype.Hotkey =
+ "structree";
+
+StructreeButton.prototype.Tooltip =
+ translate("%(hotkey)s: Switch to Structure Tree.");
Index: binaries/data/mods/public/gui/reference/common/Buttons/StructreeButton.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/reference/common/Buttons/StructreeButton.xml
@@ -0,0 +1,8 @@
+
+
Index: binaries/data/mods/public/l10n/messages.json
===================================================================
--- binaries/data/mods/public/l10n/messages.json
+++ binaries/data/mods/public/l10n/messages.json
@@ -250,13 +250,13 @@
"extractor": "javascript",
"filemasks": [
"globalscripts/**.js",
- "gui/civinfo/**.js",
"gui/common/**.js",
"gui/credits/**.js",
"gui/loadgame/**.js",
"gui/locale/**.js",
"gui/options/**.js",
"gui/pregame/**.js",
+ "gui/reference/civinfo/**.js",
"gui/reference/common/**.js",
"gui/reference/structree/**.js",
"gui/reference/viewer/**.js",
@@ -285,13 +285,13 @@
"extractor": "xml",
"filemasks": [
"globalscripts/**.xml",
- "gui/civinfo/**.xml",
"gui/common/**.xml",
"gui/credits/**.xml",
"gui/loadgame/**.xml",
"gui/locale/**.xml",
"gui/options/**.xml",
"gui/pregame/**.xml",
+ "gui/reference/civinfo/**.xml",
"gui/reference/structree/**.xml",
"gui/reference/viewer/**.xml",
"gui/replaymenu/**.xml",