diff --git a/binaries/data/mods/public/gui/common/tab_buttons.js b/binaries/data/mods/public/gui/common/tab_buttons.js
new file mode 100644
index 0000000000..e8f07c8b81
--- /dev/null
+++ b/binaries/data/mods/public/gui/common/tab_buttons.js
@@ -0,0 +1,71 @@
+/**
+ * Number of categories.
+ */
+var g_TabCategoryCount;
+
+/**
+ * Index of the currently visible tab, set first tab as default.
+ */
+var g_TabCategorySelected = 0;
+
+/**
+ * Function to be executed when selecting a tab. The new category index is passed.
+ */
+var g_OnSelectTab;
+
+/**
+ * Create tab buttons.
+ *
+ * @param {Array} categoriesData - Arrays of objects containing for every tab a (translated) label and tooltip.
+ * @param {number} buttonHeight - Vertical distance between the top and bottom of a button.
+ * @param {number} spacing - Vertical distance between two buttons.
+ * @param {function} onPress - Function to be executed when a button is pressed, it gets the new category index passed.
+ * @param {function} onSelect - Function to be executed whenever the selection changes (so also for scrolling), it gets the new category index passed.
+ */
+function placeTabButtons(categoriesData, buttonHeight, spacing, onPress, onSelect)
+{
+ g_OnSelectTab = onSelect;
+ g_TabCategoryCount = categoriesData.length;
+
+ for (let category in categoriesData)
+ {
+ let button = Engine.GetGUIObjectByName("tabButton[" + category + "]");
+ if (!button)
+ {
+ warn("Too few tab-buttons!");
+ break;
+ }
+
+ button.hidden = false;
+
+ let size = button.size;
+ size.top = category * (buttonHeight + spacing) + spacing / 2;
+ size.bottom = size.top + buttonHeight;
+ button.size = size;
+ button.tooltip = categoriesData[category].tooltip || "";
+ button.onPress = (category => function() { onPress(category); })(+category);
+
+ Engine.GetGUIObjectByName("tabButtonText[" + category + "]").caption = categoriesData[category].label;
+ }
+
+ selectPanel(g_TabCategorySelected);
+}
+
+/*
+ * Show next/previous panel.
+ * @param direction - +1/-1 for forward/backward.
+ */
+function selectNextTab(direction)
+{
+ selectPanel((g_TabCategorySelected + direction + g_TabCategoryCount) % g_TabCategoryCount);
+}
+
+function selectPanel(category)
+{
+ g_TabCategorySelected = category;
+ Engine.GetGUIObjectByName("tabButtons").children.forEach((button, j) => {
+ button.sprite = category == j ? "ModernTabVerticalForeground" : "ModernTabVerticalBackground";
+ });
+
+ g_OnSelectTab(category);
+}
diff --git a/binaries/data/mods/public/gui/common/tab_buttons.xml b/binaries/data/mods/public/gui/common/tab_buttons.xml
new file mode 100644
index 0000000000..413220eb75
--- /dev/null
+++ b/binaries/data/mods/public/gui/common/tab_buttons.xml
@@ -0,0 +1,20 @@
+
+
diff --git a/binaries/data/mods/public/gui/credits/credits.js b/binaries/data/mods/public/gui/credits/credits.js
index c32bfaa68b..8536f371c6 100644
--- a/binaries/data/mods/public/gui/credits/credits.js
+++ b/binaries/data/mods/public/gui/credits/credits.js
@@ -1,58 +1,48 @@
-var g_PanelNames = ["special", "programming", "art", "translators", "misc", "donators"];
-var g_ButtonNames = {};
-var g_PanelTexts = {};
-var g_SelectedPanel = 0;
+/**
+ * Order in which the tabs should show up.
+ */
+var g_OrderTabNames = ["special", "programming", "art", "translators", "misc", "donators"];
+
+/**
+ * Array of Objects containg all relevant data per tab.
+ */
+var g_PanelData = [];
+
+/**
+ * Vertical size of a tab button.
+ */
+var g_TabButtonHeight = 30;
+
+/**
+ * Vertical space between two tab buttons.
+ */
+var g_TabButtonDist = 5;
function init()
{
// Load credits list from the disk and parse them
- for (let name of g_PanelNames)
+ for (let category of g_OrderTabNames)
{
- let json = Engine.ReadJSONFile("gui/credits/texts/" + name + ".json");
+ let json = Engine.ReadJSONFile("gui/credits/texts/" + category + ".json");
if (!json || !json.Content)
{
- error("Could not load credits for " + name + "!");
+ error("Could not load credits for " + category + "!");
continue;
}
- g_ButtonNames[name] = json.Title || name;
- g_PanelTexts[name] = parseHelper(json.Content);
+ g_PanelData.push({
+ "label": json.Title || category,
+ "content": parseHelper(json.Content)
+ });
}
- placeButtons();
- selectPanel(0);
-}
-
-/*
- * Show next/previous panel.
- * @param direction - 1/-1 forward, backward panel.
- */
-function selectNextTab(direction)
-{
- selectPanel((g_SelectedPanel + direction + g_PanelNames.length) % g_PanelNames.length);
-}
-
-function placeButtons()
-{
- for (let i = 0; i < g_PanelNames.length; ++i)
- {
- let button = Engine.GetGUIObjectByName("creditsPanelButton[" + i + "]");
- if (!button)
- {
- warn("Could not display some credits.");
- break;
- }
- button.onMouseWheelUp = () => selectNextTab(1);
- button.onMouseWheelDown = () => selectNextTab(-1);
- button.hidden = false;
- let size = button.size;
- size.top = i * 35;
- size.bottom = size.top + 30;
- button.size = size;
-
- button.onPress = (i => function() {selectPanel(i);})(i);
- let buttonText = Engine.GetGUIObjectByName("creditsPanelButtonText[" + i + "]");
- buttonText.caption = translate(g_ButtonNames[g_PanelNames[i]]);
- }
+ placeTabButtons(
+ g_PanelData,
+ g_TabButtonHeight,
+ g_TabButtonDist,
+ selectPanel,
+ category => {
+ Engine.GetGUIObjectByName("creditsText").caption = g_PanelData[category].content;
+ });
}
// Run through a "Content" list and parse elements for formatting and translation
@@ -92,13 +82,3 @@ function parseHelper(list)
return result;
}
-
-function selectPanel(i)
-{
- g_SelectedPanel = i;
- Engine.GetGUIObjectByName("creditsPanelButtons").children.forEach((button, j) => {
- button.sprite = i == j ? "ModernTabVerticalForeground" : "ModernTabVerticalBackground";
- });
-
- Engine.GetGUIObjectByName("creditsText").caption = g_PanelTexts[g_PanelNames[i]];
-}
diff --git a/binaries/data/mods/public/gui/credits/credits.xml b/binaries/data/mods/public/gui/credits/credits.xml
index bee1257d8c..e7a723e491 100644
--- a/binaries/data/mods/public/gui/credits/credits.xml
+++ b/binaries/data/mods/public/gui/credits/credits.xml
@@ -14,32 +14,19 @@
-
- selectNextTab(1);
-
-
-
- selectNextTab(-1);
-
-
0 A.D. Credits
-
-
-
-
-
-
-
-
-
+
+
+
+
Close
diff --git a/binaries/data/mods/public/gui/options/options.js b/binaries/data/mods/public/gui/options/options.js
index 0fbb5f353c..38f1e1a78f 100644
--- a/binaries/data/mods/public/gui/options/options.js
+++ b/binaries/data/mods/public/gui/options/options.js
@@ -3,11 +3,6 @@
*/
var g_Options;
-/**
- * Numerical index of the chosen category.
- */
-var g_SelectedCategory;
-
/**
* Remember whether to unpause running singleplayer games.
*/
@@ -142,75 +137,33 @@ var g_OptionType = {
function init(data, hotloadData)
{
g_HasCallback = hotloadData && hotloadData.callback || data && data.callback;
- g_SelectedCategory = hotloadData ? hotloadData.selectedCategory : 0;
+ g_TabCategorySelected = hotloadData ? hotloadData.tabCategorySelected : 0;
g_Options = Engine.ReadJSONFile("gui/options/options.json");
translateObjectKeys(g_Options, ["label", "tooltip"]);
deepfreeze(g_Options);
- placeTabButtons();
- displayOptions();
+ placeTabButtons(
+ g_Options,
+ g_TabButtonHeight,
+ g_TabButtonDist,
+ selectPanel,
+ displayOptions);
}
function getHotloadData()
{
return {
- "selectedCategory": g_SelectedCategory,
+ "tabCategorySelected": g_TabCategorySelected,
"callback": g_HasCallback
};
}
-/*
- * Show next/previous panel.
- * @param direction - 1/-1 forward, backward panel.
- */
-function selectNextTab(direction)
-{
- g_SelectedCategory = (g_SelectedCategory + direction + Object.keys(g_Options).length) %
- Object.keys(g_Options).length;
- displayOptions();
-}
-
-function placeTabButtons()
-{
- for (let category in g_Options)
- {
- let button = Engine.GetGUIObjectByName("tabButton[" + category + "]");
- if (!button)
- {
- warn("Too few tab-buttons!");
- break;
- }
-
- button.onMouseWheelUp = () => selectNextTab(1);
- button.onMouseWheelDown = () => selectNextTab(-1);
- button.hidden = false;
-
- let size = button.size;
- size.top = category * (g_TabButtonHeight + g_TabButtonDist);
- size.bottom = size.top + g_TabButtonHeight;
- button.size = size;
- button.tooltip = g_Options[category].tooltip || "";
-
- button.onPress = (category => function() {
- g_SelectedCategory = category;
- displayOptions();
- })(category);
-
- Engine.GetGUIObjectByName("tabButtonText[" + category + "]").caption = g_Options[category].label;
- }
-}
-
/**
* Sets up labels and controls of all options of the currently selected category.
*/
function displayOptions()
{
- // Highlight the selected tab
- Engine.GetGUIObjectByName("tabButtons").children.forEach((button, i) => {
- button.sprite = i == g_SelectedCategory ? "ModernTabVerticalForeground" : "ModernTabVerticalBackground";
- });
-
// Hide all controls
for (let body of Engine.GetGUIObjectByName("option_controls").children)
{
@@ -220,7 +173,7 @@ function displayOptions()
}
// Initialize label and control of each option for this category
- for (let i = 0; i < g_Options[g_SelectedCategory].options.length; ++i)
+ for (let i = 0; i < g_Options[g_TabCategorySelected].options.length; ++i)
{
// Position vertically
let body = Engine.GetGUIObjectByName("option_control[" + i + "]");
@@ -231,7 +184,7 @@ function displayOptions()
body.hidden = false;
// Load option data
- let option = g_Options[g_SelectedCategory].options[i];
+ let option = g_Options[g_TabCategorySelected].options[i];
let optionType = g_OptionType[option.type];
let value = optionType.configToValue(Engine.ConfigDB_GetValue("user", option.config));
@@ -286,7 +239,7 @@ function displayOptions()
*/
function enableButtons()
{
- g_Options[g_SelectedCategory].options.forEach((option, i) => {
+ g_Options[g_TabCategorySelected].options.forEach((option, i) => {
let enabled =
!option.dependencies ||
@@ -353,7 +306,7 @@ function saveChanges()
if (value == optionType.sanitizeValue(value, control, option))
continue;
- g_SelectedCategory = category;
+ g_TabCategorySelected = category;
displayOptions();
messageBox(
diff --git a/binaries/data/mods/public/gui/options/options.xml b/binaries/data/mods/public/gui/options/options.xml
index 7d7bb3ea5d..2650eb3518 100644
--- a/binaries/data/mods/public/gui/options/options.xml
+++ b/binaries/data/mods/public/gui/options/options.xml
@@ -8,14 +8,6 @@
-
- selectNextTab(1);
-
-
-
- selectNextTab(-1);
-
-
@@ -24,12 +16,8 @@
-
-
-
-
-
-
+
+