Index: ps/trunk/binaries/data/mods/public/gui/common/tab_buttons.js
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/common/tab_buttons.js (revision 23788)
+++ ps/trunk/binaries/data/mods/public/gui/common/tab_buttons.js (revision 23789)
@@ -1,79 +1,103 @@
/**
* Number of categories.
*/
var g_TabCategoryCount;
/**
+ * Align the buttons horizontally or vertically.
+ */
+var g_TabHorizontal;
+
+/**
* 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 {boolean} horizontal - Have the tabs horizontally or vertically aligned.
+ * @param {number} buttonSize - Size of a button in the specified direction.
+ * @param {number} spacing - Distance between two buttons in the specified direction.
* @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)
+function placeTabButtons(categoriesData, horizontal, buttonSize, spacing, onPress, onSelect)
{
- g_OnSelectTab = onSelect;
g_TabCategoryCount = categoriesData.length;
+ g_TabHorizontal = horizontal;
+ g_OnSelectTab = onSelect;
for (let category in categoriesData)
{
let button = Engine.GetGUIObjectByName("tabButton[" + category + "]");
if (!button)
{
warn("Too few tab-buttons!");
break;
}
+ button.style = "ModernTabButton" + (horizontal ? "Horizontal" : "Vertical");
button.hidden = false;
let size = button.size;
- size.top = category * (buttonHeight + spacing) + spacing / 2;
- size.bottom = size.top + buttonHeight;
+ if (horizontal)
+ {
+ size.left = category * (buttonSize + spacing) + spacing / 2;
+ size.right = size.left + buttonSize;
+ size.rright = 0;
+ }
+ else
+ {
+ size.top = category * (buttonSize + spacing) + spacing / 2;
+ size.bottom = size.top + buttonSize;
+ size.rbottom = 0;
+ }
button.size = size;
button.tooltip = categoriesData[category].tooltip || "";
let categoryNum = +category;
button.onPress = () => { onPress(categoryNum); };
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)
{
if (g_TabCategoryCount)
selectPanel(g_TabCategorySelected === undefined ?
direction > 0 ?
0 :
g_TabCategoryCount - 1 :
(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";
+ button.sprite = g_TabHorizontal ?
+ category == j ?
+ "ModernTabHorizontalForeground" :
+ "ModernTabHorizontalBackground" :
+ category == j ?
+ "ModernTabVerticalForeground" :
+ "ModernTabVerticalBackground";
});
if (g_OnSelectTab)
g_OnSelectTab(category);
}
Index: ps/trunk/binaries/data/mods/public/gui/common/tab_buttons.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/common/tab_buttons.xml (revision 23788)
+++ ps/trunk/binaries/data/mods/public/gui/common/tab_buttons.xml (revision 23789)
@@ -1,20 +1,20 @@
Index: ps/trunk/binaries/data/mods/public/gui/credits/credits.js
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/credits/credits.js (revision 23788)
+++ ps/trunk/binaries/data/mods/public/gui/credits/credits.js (revision 23789)
@@ -1,98 +1,99 @@
/**
* Order in which the tabs should show up.
*/
var g_OrderTabNames = [
"special",
"programming",
"art",
"history",
"balancing",
"community",
"translators",
"donators"
];
/**
* Array of Objects containg all relevant data per tab.
*/
var g_PanelData = [];
/**
* Vertical size of a tab button.
*/
var g_TabButtonHeight = 35;
/**
* Vertical space between two tab buttons.
*/
var g_TabButtonDist = 5;
function init()
{
// Load credits list from the disk and parse them
for (let category of g_OrderTabNames)
{
let json = Engine.ReadJSONFile("gui/credits/texts/" + category + ".json");
if (!json || !json.Content)
{
error("Could not load credits for " + category + "!");
continue;
}
translateObjectKeys(json, ["Title", "Subtitle"]);
g_PanelData.push({
"label": json.Title || category,
"content": parseHelper(json.Content)
});
}
placeTabButtons(
g_PanelData,
+ false,
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
function parseHelper(list)
{
let result = "";
for (let object of list)
{
if (object.LangName)
result += setStringTags(object.LangName + "\n", { "font": "sans-bold-stroke-14" });
if (object.Title)
result += setStringTags(object.Title + "\n", { "font": "sans-bold-stroke-14" });
if (object.Subtitle)
result += setStringTags(object.Subtitle + "\n", { "font": "sans-bold-14" });
if (object.List)
{
for (let element of object.List)
{
let credit;
if (element.nick && element.name)
credit = sprintf(translate("%(nick)s - %(name)s"), { "nick": element.nick, "name": element.name });
else if (element.nick)
credit = element.nick;
else if (element.name)
credit = element.name;
if (credit)
result += setStringTags(credit + "\n", { "font": "sans-14" });
}
result += "\n";
}
if (object.Content)
result += "\n" + parseHelper(object.Content) + "\n";
}
return result;
}
Index: ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/Panels/GameSettingsTabs.js
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/Panels/GameSettingsTabs.js (revision 23788)
+++ ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/Panels/GameSettingsTabs.js (revision 23789)
@@ -1,97 +1,98 @@
class GameSettingTabs
{
constructor(setupWindow, lobbyButton)
{
this.lobbyButton = lobbyButton;
this.tabSelectHandlers = new Set();
this.tabsResizeHandlers = new Set();
this.settingsTabButtonsFrame = Engine.GetGUIObjectByName("settingTabButtonsFrame");
for (let tab in g_GameSettingsLayout)
g_GameSettingsLayout[tab].tooltip =
sprintf(this.ToggleTooltip, { "name": g_GameSettingsLayout[tab].label }) +
colorizeHotkey("\n" + this.HotkeyNextTooltip, this.ConfigNameHotkeyNext) +
colorizeHotkey("\n" + this.HotkeyPreviousTooltip, this.ConfigNameHotkeyPrevious);
setupWindow.registerLoadHandler(this.onLoad.bind(this));
Engine.SetGlobalHotkey("cancel", "Press", selectPanel);
}
registerTabsResizeHandler(handler)
{
this.tabsResizeHandlers.add(handler);
}
registerTabSelectHandler(handler)
{
this.tabSelectHandlers.add(handler);
}
onLoad()
{
placeTabButtons(
g_GameSettingsLayout,
+ false,
this.TabButtonHeight,
this.TabButtonMargin,
this.onTabPress.bind(this),
this.onTabSelect.bind(this));
this.resize();
if (!g_IsController)
selectPanel();
}
resize()
{
let size = this.settingsTabButtonsFrame.size;
size.bottom = size.top + g_GameSettingsLayout.length * (this.TabButtonHeight + this.TabButtonMargin);
if (!this.lobbyButton.lobbyButton.hidden)
{
let lobbyButtonSize = this.lobbyButton.lobbyButton.parent.size;
size.right -= lobbyButtonSize.right - lobbyButtonSize.left + this.LobbyButtonMargin;
}
this.settingsTabButtonsFrame.size = size;
for (let handler of this.tabsResizeHandlers)
handler(this.settingsTabButtonsFrame);
}
onTabPress(category)
{
selectPanel(category == g_TabCategorySelected ? undefined : category);
}
onTabSelect()
{
for (let handler of this.tabSelectHandlers)
handler();
}
}
GameSettingTabs.prototype.ToggleTooltip =
translate("Click to toggle the %(name)s settings tab.");
GameSettingTabs.prototype.HotkeyNextTooltip =
translate("Press %(hotkey)s to move to the next settings tab.");
GameSettingTabs.prototype.HotkeyPreviousTooltip =
translate("Press %(hotkey)s to move to the previous settings tab.");
GameSettingTabs.prototype.ConfigNameHotkeyNext =
"tab.next";
GameSettingTabs.prototype.ConfigNameHotkeyPrevious =
"tab.prev";
GameSettingTabs.prototype.TabButtonHeight = 30;
GameSettingTabs.prototype.TabButtonMargin = 4;
/**
* Horizontal space between tab buttons and lobby button.
*/
GameSettingTabs.prototype.LobbyButtonMargin = 8;
Index: ps/trunk/binaries/data/mods/public/gui/options/options.js
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/options/options.js (revision 23788)
+++ ps/trunk/binaries/data/mods/public/gui/options/options.js (revision 23789)
@@ -1,387 +1,388 @@
/**
* Translated JSON file contents.
*/
var g_Options;
/**
* Names of config keys that have changed, value returned when closing the page.
*/
var g_ChangedKeys;
/**
* Vertical size of a tab button.
*/
var g_TabButtonHeight = 30;
/**
* Vertical space between two tab buttons.
*/
var g_TabButtonDist = 5;
/**
* Vertical distance between the top of the page and the first option.
*/
var g_OptionControlOffset = 5;
/**
* Vertical size of each option control.
*/
var g_OptionControlHeight = 26;
/**
* Vertical distance between two consecutive options.
*/
var g_OptionControlDist = 2;
/**
* Horizontal indentation to distinguish options that depend on another option.
*/
var g_DependentLabelIndentation = 25;
/**
* Color used to indicate that the string entered by the player isn't a sane color.
*/
var g_InsaneColor = "255 0 255";
/**
* Defines the parsing of config strings and GUI control interaction for the different option types.
*
* @property configToValue - parses a string from the user config to a value of the declared type.
* @property valueToGui - sets the GUI control to display the given value.
* @property guiToValue - returns the value of the GUI control.
* @property guiSetter - event name that should be considered a value change of the GUI control.
* @property initGUI - sets properties of the GUI control that are independent of the current value.
* @property sanitizeValue - Displays a visual clue if the entered value is invalid and returns a sane value.
* @property tooltip - appends a custom tooltip to the given option description depending on the current value.
*/
var g_OptionType = {
"boolean":
{
"configToValue": config => config == "true",
"valueToGui": (value, control) => {
control.checked = value;
},
"guiToValue": control => control.checked,
"guiSetter": "onPress"
},
"string":
{
"configToValue": value => value,
"valueToGui": (value, control) => {
control.caption = value;
},
"guiToValue": control => control.caption,
"guiSetter": "onTextEdit"
},
"color":
{
"configToValue": value => value,
"valueToGui": (value, control) => {
control.caption = value;
},
"guiToValue": control => control.caption,
"guiSetter": "onTextEdit",
"sanitizeValue": (value, control, option) => {
let color = guiToRgbColor(value);
let sanitized = rgbToGuiColor(color);
if (control)
{
control.sprite = sanitized == value ? "ModernDarkBoxWhite" : "ModernDarkBoxWhiteInvalid";
control.children[1].sprite = sanitized == value ? "color:" + value : "color:" + g_InsaneColor;
}
return sanitized;
},
"tooltip": (value, option) =>
sprintf(translate("Default: %(value)s"), {
"value": Engine.ConfigDB_GetValue("default", option.config)
})
},
"number":
{
"configToValue": value => value,
"valueToGui": (value, control) => {
control.caption = value;
},
"guiToValue": control => control.caption,
"guiSetter": "onTextEdit",
"sanitizeValue": (value, control, option) => {
let sanitized =
Math.min(option.max !== undefined ? option.max : +Infinity,
Math.max(option.min !== undefined ? option.min : -Infinity,
isNaN(+value) ? 0 : value));
if (control)
control.sprite = sanitized == value ? "ModernDarkBoxWhite" : "ModernDarkBoxWhiteInvalid";
return sanitized;
},
"tooltip": (value, option) =>
sprintf(
option.min !== undefined && option.max !== undefined ?
translateWithContext("option number", "Min: %(min)s, Max: %(max)s") :
option.min !== undefined && option.max === undefined ?
translateWithContext("option number", "Min: %(min)s") :
option.min === undefined && option.max !== undefined ?
translateWithContext("option number", "Max: %(max)s") :
"",
{
"min": option.min,
"max": option.max
})
},
"dropdown":
{
"configToValue": value => value,
"valueToGui": (value, control) => {
control.selected = control.list_data.indexOf(value);
},
"guiToValue": control => control.list_data[control.selected],
"guiSetter": "onSelectionChange",
"initGUI": (option, control) => {
control.list = option.list.map(e => e.label);
control.list_data = option.list.map(e => e.value);
control.onHoverChange = () => {
let item = option.list[control.hovered];
control.tooltip = item && item.tooltip || option.tooltip;
};
}
},
"slider":
{
"configToValue": value => +value,
"valueToGui": (value, control) => {
control.value = +value;
},
"guiToValue": control => control.value,
"guiSetter": "onValueChange",
"initGUI": (option, control) => {
control.max_value = option.max;
control.min_value = option.min;
},
"tooltip": (value, option) =>
sprintf(translateWithContext("slider number", "Value: %(val)s (min: %(min)s, max: %(max)s)"), {
"val": value.toFixed(2),
"min": option.min.toFixed(2),
"max": option.max.toFixed(2)
})
}
};
function init(data, hotloadData)
{
g_ChangedKeys = hotloadData ? hotloadData.changedKeys : new Set();
g_TabCategorySelected = hotloadData ? hotloadData.tabCategorySelected : 0;
g_Options = Engine.ReadJSONFile("gui/options/options.json");
translateObjectKeys(g_Options, ["label", "tooltip"]);
deepfreeze(g_Options);
placeTabButtons(
g_Options,
+ false,
g_TabButtonHeight,
g_TabButtonDist,
selectPanel,
displayOptions);
}
function getHotloadData()
{
return {
"tabCategorySelected": g_TabCategorySelected,
"changedKeys": g_ChangedKeys
};
}
/**
* Sets up labels and controls of all options of the currently selected category.
*/
function displayOptions()
{
// Hide all controls
for (let body of Engine.GetGUIObjectByName("option_controls").children)
{
body.hidden = true;
for (let control of body.children)
control.hidden = true;
}
// Initialize label and control of each option for this category
for (let i = 0; i < g_Options[g_TabCategorySelected].options.length; ++i)
{
// Position vertically
let body = Engine.GetGUIObjectByName("option_control[" + i + "]");
let bodySize = body.size;
bodySize.top = g_OptionControlOffset + i * (g_OptionControlHeight + g_OptionControlDist);
bodySize.bottom = bodySize.top + g_OptionControlHeight;
body.size = bodySize;
body.hidden = false;
// Load option data
let option = g_Options[g_TabCategorySelected].options[i];
let optionType = g_OptionType[option.type];
let value = optionType.configToValue(Engine.ConfigDB_GetValue("user", option.config));
// Setup control
let control = Engine.GetGUIObjectByName("option_control_" + option.type + "[" + i + "]");
control.tooltip = option.tooltip + (optionType.tooltip ? "\n" + optionType.tooltip(value, option) : "");
control.hidden = false;
if (optionType.initGUI)
optionType.initGUI(option, control);
control[optionType.guiSetter] = function() {};
optionType.valueToGui(value, control);
if (optionType.sanitizeValue)
optionType.sanitizeValue(value, control, option);
control[optionType.guiSetter] = function() {
let value = optionType.guiToValue(control);
if (optionType.sanitizeValue)
optionType.sanitizeValue(value, control, option);
control.tooltip = option.tooltip + (optionType.tooltip ? "\n" + optionType.tooltip(value, option) : "");
Engine.ConfigDB_CreateValue("user", option.config, String(value));
Engine.ConfigDB_SetChanges("user", true);
g_ChangedKeys.add(option.config);
fireConfigChangeHandlers(new Set([option.config]));
if (option.function)
Engine[option.function](value);
enableButtons();
};
// Setup label
let label = Engine.GetGUIObjectByName("option_label[" + i + "]");
label.caption = option.label;
label.tooltip = option.tooltip;
label.hidden = false;
let labelSize = label.size;
labelSize.left = option.dependencies ? g_DependentLabelIndentation : 0;
labelSize.rright = control.size.rleft;
label.size = labelSize;
}
enableButtons();
}
/**
* Enable exactly the buttons whose dependencies are met.
*/
function enableButtons()
{
g_Options[g_TabCategorySelected].options.forEach((option, i) => {
let enabled =
!option.dependencies ||
option.dependencies.every(config => Engine.ConfigDB_GetValue("user", config) == "true");
Engine.GetGUIObjectByName("option_label[" + i + "]").enabled = enabled;
Engine.GetGUIObjectByName("option_control_" + option.type + "[" + i + "]").enabled = enabled;
});
let hasChanges = Engine.ConfigDB_HasChanges("user");
Engine.GetGUIObjectByName("revertChanges").enabled = hasChanges;
Engine.GetGUIObjectByName("saveChanges").enabled = hasChanges;
}
function setDefaults()
{
messageBox(
500, 200,
translate("Resetting the options will erase your saved settings. Do you want to continue?"),
translate("Warning"),
[translate("No"), translate("Yes")],
[null, reallySetDefaults]
);
}
function reallySetDefaults()
{
for (let category in g_Options)
for (let option of g_Options[category].options)
{
Engine.ConfigDB_RemoveValue("user", option.config);
g_ChangedKeys.add(option.config);
}
Engine.ConfigDB_WriteFile("user", "config/user.cfg");
revertChanges();
}
function revertChanges()
{
Engine.ConfigDB_Reload("user");
Engine.ConfigDB_SetChanges("user", false);
for (let category in g_Options)
for (let option of g_Options[category].options)
if (option.function)
Engine[option.function](
g_OptionType[option.type].configToValue(
Engine.ConfigDB_GetValue("user", option.config)));
displayOptions();
}
function saveChanges()
{
for (let category in g_Options)
for (let i = 0; i < g_Options[category].options.length; ++i)
{
let option = g_Options[category].options[i];
let optionType = g_OptionType[option.type];
if (!optionType.sanitizeValue)
continue;
let value = optionType.configToValue(Engine.ConfigDB_GetValue("user", option.config));
if (value == optionType.sanitizeValue(value, undefined, option))
continue;
selectPanel(category);
messageBox(
500, 200,
translate("Some setting values are invalid! Are you sure to save them?"),
translate("Warning"),
[translate("No"), translate("Yes")],
[null, reallySaveChanges]
);
return;
}
reallySaveChanges();
}
function reallySaveChanges()
{
Engine.ConfigDB_WriteFile("user", "config/user.cfg");
Engine.ConfigDB_SetChanges("user", false);
enableButtons();
}
/**
* Close GUI page and inform the parent GUI page which options changed.
**/
function closePage()
{
if (Engine.ConfigDB_HasChanges("user"))
messageBox(
500, 200,
translate("You have unsaved changes, do you want to close this window?"),
translate("Warning"),
[translate("No"), translate("Yes")],
[null, closePageWithoutConfirmation]);
else
closePageWithoutConfirmation();
}
function closePageWithoutConfirmation()
{
Engine.PopGuiPage(g_ChangedKeys);
}
Index: ps/trunk/binaries/data/mods/public/gui/summary/layout.js
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/summary/layout.js (revision 23788)
+++ ps/trunk/binaries/data/mods/public/gui/summary/layout.js (revision 23789)
@@ -1,384 +1,400 @@
-var getScorePanelsData = () => ({
- "score": {
- "caption": translate("Score"),
+/**
+ * Horizontal size of a tab button.
+ */
+var g_TabButtonWidth = 118;
+
+/**
+ * Horizontal space between two tab buttons.
+ */
+var g_TabButtonDist = 6;
+
+var getScorePanelsData = () => [
+ {
+ "label": translate("Score"),
"headings": [
{ "identifier": "playername", "caption": translate("Player name"), "yStart": 26, "width": 200 },
{ "identifier": "totalScore", "caption": translate("Total score"), "yStart": 16, "width": 100 },
{ "identifier": "economyScore", "caption": translate("Economy score"), "yStart": 16, "width": 100 },
{ "identifier": "militaryScore", "caption": translate("Military score"), "yStart": 16, "width": 100 },
{ "identifier": "explorationScore", "caption": translate("Exploration score"), "yStart": 16, "width": 100 }
],
"titleHeadings": [],
"counters": [
{ "width": 100, "fn": calculateScoreTotal, "verticalOffset": 12 },
{ "width": 100, "fn": calculateEconomyScore, "verticalOffset": 12 },
{ "width": 100, "fn": calculateMilitaryScore, "verticalOffset": 12 },
{ "width": 100, "fn": calculateExplorationScore, "verticalOffset": 12 }
],
"teamCounterFn": calculateScoreTeam
},
- "buildings": {
- "caption": translate("Structures"),
+ {
+ "label": translate("Structures"),
"headings": [
{ "identifier": "playername", "caption": translate("Player name"), "yStart": 26, "width": 200 },
{ "identifier": "total", "caption": translate("Total"), "yStart": 34, "width": 105 },
{ "identifier": "House", "caption": translate("Houses"), "yStart": 34, "width": 85 },
{ "identifier": "Economic", "caption": translate("Economic"), "yStart": 34, "width": 85 },
{ "identifier": "Outpost", "caption": translate("Outposts"), "yStart": 34, "width": 85 },
{ "identifier": "Military", "caption": translate("Military"), "yStart": 34, "width": 85 },
{ "identifier": "Fortress", "caption": translate("Fortresses"), "yStart": 34, "width": 85 },
{ "identifier": "CivCentre", "caption": translate("Civ centers"), "yStart": 34, "width": 85 },
{ "identifier": "Wonder", "caption": translate("Wonders"), "yStart": 34, "width": 85 }
],
"titleHeadings": [
{
"caption": sprintf(translate("Structure Statistics (%(constructed)s / %(destroyed)s / %(captured)s / %(lost)s)"),
{
"constructed": getColoredTypeTranslation("constructed"),
"destroyed": getColoredTypeTranslation("destroyed"),
"captured": getColoredTypeTranslation("captured"),
"lost": getColoredTypeTranslation("lost")
}),
"yStart": 16,
"width": 85 * 7 + 105
}, // width = 700
],
"counters": [
{ "width": 105, "fn": calculateBuildings, "verticalOffset": 3 },
{ "width": 85, "fn": calculateBuildings, "verticalOffset": 3 },
{ "width": 85, "fn": calculateBuildings, "verticalOffset": 3 },
{ "width": 85, "fn": calculateBuildings, "verticalOffset": 3 },
{ "width": 85, "fn": calculateBuildings, "verticalOffset": 3 },
{ "width": 85, "fn": calculateBuildings, "verticalOffset": 3 },
{ "width": 85, "fn": calculateBuildings, "verticalOffset": 3 },
{ "width": 85, "fn": calculateBuildings, "verticalOffset": 3 }
],
"teamCounterFn": calculateBuildingsTeam
},
- "units": {
- "caption": translate("Units"),
+ {
+ "label": translate("Units"),
"headings": [
{ "identifier": "playername", "caption": translate("Player name"), "yStart": 26, "width": 200 },
{ "identifier": "total", "caption": translate("Total"), "yStart": 34, "width": 105 },
{ "identifier": "Infantry", "caption": translate("Infantry"), "yStart": 34, "width": 85 },
{ "identifier": "Worker", "caption": translate("Worker"), "yStart": 34, "width": 85 },
{ "identifier": "Cavalry", "caption": translate("Cavalry"), "yStart": 34, "width": 85 },
{ "identifier": "Champion", "caption": translate("Champion"), "yStart": 34, "width": 85 },
{ "identifier": "Hero", "caption": translate("Heroes"), "yStart": 34, "width": 85 },
{ "identifier": "Siege", "caption": translate("Siege"), "yStart": 34, "width": 85 },
{ "identifier": "Ship", "caption": translate("Navy"), "yStart": 34, "width": 85 },
{ "identifier": "Trader", "caption": translate("Traders"), "yStart": 34, "width": 85 }
],
"titleHeadings": [
{
"caption": sprintf(translate("Unit Statistics (%(trained)s / %(killed)s / %(captured)s / %(lost)s)"),
{
"trained": getColoredTypeTranslation("trained"),
"killed": getColoredTypeTranslation("killed"),
"captured": getColoredTypeTranslation("captured"),
"lost": getColoredTypeTranslation("lost")
}),
"yStart": 16,
"width": 85 * 8 + 105
}, // width = 785
],
"counters": [
{ "width": 105, "fn": calculateUnitsWithCaptured, "verticalOffset": 3 },
{ "width": 85, "fn": calculateUnits, "verticalOffset": 3 },
{ "width": 85, "fn": calculateUnits, "verticalOffset": 3 },
{ "width": 85, "fn": calculateUnits, "verticalOffset": 3 },
{ "width": 85, "fn": calculateUnits, "verticalOffset": 3 },
{ "width": 85, "fn": calculateUnits, "verticalOffset": 3 },
{ "width": 85, "fn": calculateUnitsWithCaptured, "verticalOffset": 3 },
{ "width": 85, "fn": calculateUnits, "verticalOffset": 3 },
{ "width": 85, "fn": calculateUnits, "verticalOffset": 3 }
],
"teamCounterFn": calculateUnitsTeam
},
- "resources": {
- "caption": translate("Resources"),
+ {
+ "label": translate("Resources"),
"headings": [
{ "identifier": "playername", "caption": translate("Player name"), "yStart": 26, "width": 200 },
{ "identifier": "total", "caption": translate("Total"), "yStart": 34, "width": 110 },
...g_ResourceData.GetResources().map(res => ({
"identifier": res.code,
"caption": resourceNameFirstWord(res.code),
"yStart": 34,
"width": 100
})),
{
"identifier": "tributes",
"caption": translate("Tributes"),
"headerCaption": sprintf(translate("Tributes \n(%(sent)s / %(received)s)"),
{
"sent": getColoredTypeTranslation("sent"),
"received": getColoredTypeTranslation("received")
}),
"yStart": 16,
"width": 121
},
{ "identifier": "treasuresCollected", "caption": translate("Treasures collected"), "yStart": 16, "width": 85 },
{ "identifier": "loot", "caption": translate("Loot"), "yStart": 16, "width": 85 },
{ "identifier": "livestock", "caption": translate("Livestock bred"), "yStart": 16, "width": 85 }
],
"titleHeadings": [
{
"caption": sprintf(translate("Resource Statistics (%(gathered)s / %(used)s)"),
{
"gathered": getColoredTypeTranslation("gathered"),
"used": getColoredTypeTranslation("used")
}),
"yStart": 16,
"width": 100 * g_ResourceData.GetCodes().length + 110
},
],
"counters": [
{ "width": 110, "fn": calculateTotalResources, "verticalOffset": 12 },
...g_ResourceData.GetCodes().map(code => ({
"fn": calculateResources,
"verticalOffset": 12,
"width": 100
})),
{ "width": 121, "fn": calculateTributeSent, "verticalOffset": 12 },
{ "width": 85, "fn": calculateTreasureCollected, "verticalOffset": 12 },
{ "width": 85, "fn": calculateLootCollected, "verticalOffset": 12 },
{ "width": 85, "fn": calculateLivestockTrained, "verticalOffset": 12 }
],
"teamCounterFn": calculateResourcesTeam
},
- "market": {
- "caption": translate("Market"),
+ {
+ "label": translate("Market"),
"headings": [
{ "identifier": "playername", "caption": translate("Player name"), "yStart": 26, "width": 200 },
{ "identifier": "tradeIncome", "caption": translate("Trade income"), "yStart": 16, "width": 100 },
{ "identifier": "barterEfficency", "caption": translate("Barter efficiency"), "yStart": 16, "width": 100, "format": "PERCENTAGE" },
...g_ResourceData.GetResources().map(res => {
return {
"identifier": res.code,
"caption":
// Translation: use %(resourceWithinSentence)s if needed
sprintf(translate("%(resourceFirstWord)s exchanged"), {
"resourceFirstWord": resourceNameFirstWord(res.code),
"resourceWithinSentence": resourceNameWithinSentence(res.code)
}),
"yStart": 16,
"width": 100
};
})
],
"titleHeadings": [],
"counters": [
{ "width": 100, "fn": calculateTradeIncome, "verticalOffset": 12 },
{ "width": 100, "fn": calculateBarterEfficiency, "verticalOffset": 12 },
...g_ResourceData.GetCodes().map(code => ({
"width": 100,
"fn": calculateResourceExchanged,
"verticalOffset": 12
}))
],
"teamCounterFn": calculateMarketTeam
},
- "misc": {
- "caption": translate("Miscellaneous"),
+ {
+ "label": translate("Miscellaneous"),
"headings": [
{ "identifier": "playername", "caption": translate("Player name"), "yStart": 26, "width": 200 },
{ "identifier": "killDeath", "caption": translate("Kill / Death ratio"), "yStart": 16, "width": 100, "format": "DECIMAL2" },
{ "identifier": "mapControlPeak", "caption": translate("Map control (peak)"), "yStart": 16, "width": 100, "format": "PERCENTAGE" },
{ "identifier": "mapControl", "caption": translate("Map control (finish)"), "yStart": 16, "width": 100, "format": "PERCENTAGE" },
{ "identifier": "mapExploration", "caption": translate("Map exploration"), "yStart": 16, "width": 100, "format": "PERCENTAGE" },
{ "identifier": "vegetarianRatio", "caption": translate("Vegetarian ratio"), "yStart": 16, "width": 100, "format": "PERCENTAGE" },
{ "identifier": "feminization", "caption": translate("Feminization"), "yStart": 16, "width": 100, "format": "PERCENTAGE" },
{
"identifier": "bribes",
"caption": translate("Bribes"),
"headerCaption": sprintf(translate("Bribes\n(%(succeeded)s / %(failed)s)"),
{
"succeeded": getColoredTypeTranslation("succeeded"),
"failed": getColoredTypeTranslation("failed")
}),
"yStart": 16,
"width": 139
}
],
"titleHeadings": [],
"counters": [
{ "width": 100, "fn": calculateKillDeathRatio, "verticalOffset": 12 },
{ "width": 100, "fn": calculateMapPeakControl, "verticalOffset": 12 },
{ "width": 100, "fn": calculateMapFinalControl, "verticalOffset": 12 },
{ "width": 100, "fn": calculateMapExploration, "verticalOffset": 12 },
{ "width": 100, "fn": calculateVegetarianRatio, "verticalOffset": 12 },
{ "width": 100, "fn": calculateFeminization, "verticalOffset": 12 },
{ "width": 139, "fn": calculateBribes, "verticalOffset": 12 }
],
"teamCounterFn": calculateMiscellaneousTeam
}
-});
+];
+
+var g_ChartPanelsData = [
+ {
+ "label": translate("Charts")
+ }
+];
function getColoredTypeTranslation(type)
{
return g_SummaryTypes[type].color ?
coloredText(g_SummaryTypes[type].caption, g_SummaryTypes[type].color) :
g_SummaryTypes[type].caption;
}
function resetGeneralPanel()
{
for (let h = 0; h < g_MaxHeadingTitle; ++h)
{
Engine.GetGUIObjectByName("titleHeading[" + h + "]").hidden = true;
Engine.GetGUIObjectByName("Heading[" + h + "]").hidden = true;
for (let p = 0; p < g_MaxPlayers; ++p)
{
Engine.GetGUIObjectByName("valueData[" + p + "][" + h + "]").hidden = true;
for (let t = 0; t < g_MaxTeams; ++t)
{
Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + p + "][" + h + "]").hidden = true;
Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + h + "]").hidden = true;
}
}
}
}
function updateGeneralPanelHeadings(headings)
{
let left = 50;
for (let h in headings)
{
let headerGUIName = "playerNameHeading";
if (h > 0)
headerGUIName = "Heading[" + (h - 1) + "]";
let headerGUI = Engine.GetGUIObjectByName(headerGUIName);
headerGUI.caption = headings[h].headerCaption || headings[h].caption;
headerGUI.size = left + " " + headings[h].yStart + " " + (left + headings[h].width) + " 100%";
headerGUI.hidden = false;
if (headings[h].width < g_LongHeadingWidth)
left += headings[h].width;
}
}
function updateGeneralPanelTitles(titleHeadings)
{
let left = 250;
for (let th in titleHeadings)
{
if (th >= g_MaxHeadingTitle)
break;
if (titleHeadings[th].xOffset)
left += titleHeadings[th].xOffset;
let headerGUI = Engine.GetGUIObjectByName("titleHeading[" + th + "]");
headerGUI.caption = titleHeadings[th].caption;
headerGUI.size = left + " " + titleHeadings[th].yStart + " " + (left + titleHeadings[th].width) + " 100%";
headerGUI.hidden = false;
if (titleHeadings[th].width < g_LongHeadingWidth)
left += titleHeadings[th].width;
}
}
function updateGeneralPanelCounter(counters)
{
let rowPlayerObjectWidth = 0;
let left = 0;
for (let p = 0; p < g_MaxPlayers; ++p)
{
left = 240;
let counterObject;
for (let w in counters)
{
counterObject = Engine.GetGUIObjectByName("valueData[" + p + "][" + w + "]");
counterObject.size = left + " " + counters[w].verticalOffset + " " + (left + counters[w].width) + " 100%";
counterObject.hidden = false;
left += counters[w].width;
}
if (rowPlayerObjectWidth == 0)
rowPlayerObjectWidth = left;
let counterTotalObject;
for (let t = 0; t < g_MaxTeams; ++t)
{
left = 240;
for (let w in counters)
{
counterObject = Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + p + "][" + w + "]");
counterObject.size = left + " " + counters[w].verticalOffset + " " + (left + counters[w].width) + " 100%";
counterObject.hidden = false;
if (g_Teams[t])
{
let yStart = 25 + g_Teams[t].length * (g_PlayerBoxYSize + g_PlayerBoxGap) + 3 + counters[w].verticalOffset;
counterTotalObject = Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + w + "]");
counterTotalObject.size = (left + 20) + " " + yStart + " " + (left + counters[w].width) + " 100%";
counterTotalObject.hidden = false;
}
left += counters[w].width;
}
}
}
return rowPlayerObjectWidth;
}
function updateGeneralPanelTeams()
{
let withoutTeam = !g_Teams[-1] ? 0 : g_Teams[-1].length;
if (!g_Teams || withoutTeam > 0)
Engine.GetGUIObjectByName("noTeamsBox").hidden = false;
if (!g_Teams)
return;
let yStart = g_TeamsBoxYStart + withoutTeam * (g_PlayerBoxYSize + g_PlayerBoxGap) + (withoutTeam ? 30 : 0);
for (let i in g_Teams)
{
if (i == -1)
continue;
let teamBox = Engine.GetGUIObjectByName("teamBoxt["+i+"]");
teamBox.hidden = false;
let teamBoxSize = teamBox.size;
teamBoxSize.top = yStart;
teamBox.size = teamBoxSize;
yStart += 30 + g_Teams[i].length * (g_PlayerBoxYSize + g_PlayerBoxGap) + 32;
Engine.GetGUIObjectByName("teamNameHeadingt[" + i + "]").caption = "Team " + (+i + 1);
let teamHeading = Engine.GetGUIObjectByName("teamHeadingt[" + i + "]");
let yStartTotal = 30 + g_Teams[i].length * (g_PlayerBoxYSize + g_PlayerBoxGap) + 10;
teamHeading.size = "50 " + yStartTotal + " 100% " + (yStartTotal + 20);
teamHeading.caption = translate("Team total");
}
// If there are no players without team, hide "player name" heading
if (!withoutTeam)
Engine.GetGUIObjectByName("playerNameHeading").caption = "";
}
function initPlayerBoxPositions()
{
for (let h = 0; h < g_MaxPlayers; ++h)
{
let playerBox = Engine.GetGUIObjectByName("playerBox[" + h + "]");
let boxSize = playerBox.size;
boxSize.top += h * (g_PlayerBoxYSize + g_PlayerBoxGap);
boxSize.bottom = boxSize.top + g_PlayerBoxYSize;
playerBox.size = boxSize;
for (let i = 0; i < g_MaxTeams; ++i)
{
let playerBoxt = Engine.GetGUIObjectByName("playerBoxt[" + i + "][" + h + "]");
boxSize = playerBoxt.size;
boxSize.top += h * (g_PlayerBoxYSize + g_PlayerBoxGap);
boxSize.bottom = boxSize.top + g_PlayerBoxYSize;
playerBoxt.size = boxSize;
}
}
}
Index: ps/trunk/binaries/data/mods/public/gui/summary/summary.js
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/summary/summary.js (revision 23788)
+++ ps/trunk/binaries/data/mods/public/gui/summary/summary.js (revision 23789)
@@ -1,567 +1,539 @@
const g_CivData = loadCivData(false, false);
var g_ScorePanelsData;
var g_MaxHeadingTitle = 9;
var g_LongHeadingWidth = 250;
var g_PlayerBoxYSize = 40;
var g_PlayerBoxGap = 2;
var g_PlayerBoxAlpha = 50;
var g_TeamsBoxYStart = 40;
var g_TypeColors = {
"blue": "196 198 255",
"green": "201 255 200",
"red": "255 213 213",
"yellow": "255 255 157"
};
/**
* Colors, captions and format used for units, structures, etc. types
*/
var g_SummaryTypes = {
"percent": {
"color": "",
"caption": "%",
"postfix": "%"
},
"trained": {
"color": g_TypeColors.green,
"caption": translate("Trained"),
"postfix": " / "
},
"constructed": {
"color": g_TypeColors.green,
"caption": translate("Constructed"),
"postfix": " / "
},
"gathered": {
"color": g_TypeColors.green,
"caption": translate("Gathered"),
"postfix": " / "
},
"sent": {
"color": g_TypeColors.green,
"caption": translate("Sent"),
"postfix": " / "
},
"bought": {
"color": g_TypeColors.green,
"caption": translate("Bought"),
"postfix": " / "
},
"income": {
"color": g_TypeColors.green,
"caption": translate("Income"),
"postfix": " / "
},
"captured": {
"color": g_TypeColors.yellow,
"caption": translate("Captured"),
"postfix": " / "
},
"succeeded": {
"color": g_TypeColors.green,
"caption": translate("Succeeded"),
"postfix": " / "
},
"destroyed": {
"color": g_TypeColors.blue,
"caption": translate("Destroyed"),
"postfix": "\n"
},
"killed": {
"color": g_TypeColors.blue,
"caption": translate("Killed"),
"postfix": "\n"
},
"lost": {
"color": g_TypeColors.red,
"caption": translate("Lost"),
"postfix": ""
},
"used": {
"color": g_TypeColors.red,
"caption": translate("Used"),
"postfix": ""
},
"received": {
"color": g_TypeColors.red,
"caption": translate("Received"),
"postfix": ""
},
"sold": {
"color": g_TypeColors.red,
"caption": translate("Sold"),
"postfix": ""
},
"outcome": {
"color": g_TypeColors.red,
"caption": translate("Outcome"),
"postfix": ""
},
"failed": {
"color": g_TypeColors.red,
"caption": translate("Failed"),
"postfix": ""
}
};
// Translation: Unicode encoded infinity symbol indicating a division by zero in the summary screen.
var g_InfinitySymbol = translate("\u221E");
var g_Teams = [];
var g_PlayerCount;
var g_GameData;
var g_ResourceData = new Resources();
/**
* Selected chart indexes.
*/
var g_SelectedChart = {
"category": [0, 0],
"value": [0, 1],
"type": [0, 0]
};
-/**
- * Array of the panel button names.
- */
-var g_PanelButtons = [];
-
-/**
- * Remember the name of the currently opened view panel.
- */
-var g_SelectedPanel;
-
function init(data)
{
initSummaryData(data);
initGUISummary();
}
function initSummaryData(data)
{
g_GameData = data;
g_ScorePanelsData = getScorePanelsData();
- g_PanelButtons = Object.keys(g_ScorePanelsData).concat(["charts"]).map(panel => panel + "PanelButton");
- g_SelectedPanel = g_PanelButtons[0];
if (data && data.gui && data.gui.summarySelection)
{
- g_SelectedPanel = data.gui.summarySelection.panel;
+ g_TabCategorySelected = data.gui.summarySelection.panel;
g_SelectedChart = data.gui.summarySelection.charts;
}
initTeamData();
calculateTeamCounterDataHelper();
}
function initGUISummary()
{
initGUIWindow();
initPlayerBoxPositions();
initGUICharts();
initGUILabels();
initGUIButtons();
-
- selectPanel(Engine.GetGUIObjectByName(g_SelectedPanel));
- for (let button of g_PanelButtons)
- {
- let tab = Engine.GetGUIObjectByName(button);
- tab.onMouseWheelUp = () => selectNextTab(1);
- tab.onMouseWheelDown = () => selectNextTab(-1);
- }
}
/**
* Sets the style and title of the page.
*/
function initGUIWindow()
{
let summaryWindow = Engine.GetGUIObjectByName("summaryWindow");
summaryWindow.sprite = g_GameData.gui.dialog ? "ModernDialog" : "ModernWindow";
summaryWindow.size = g_GameData.gui.dialog ? "16 24 100%-16 100%-24" : "0 0 100% 100%";
Engine.GetGUIObjectByName("summaryWindowTitle").size = g_GameData.gui.dialog ? "50%-128 -16 50%+128 16" : "50%-128 4 50%+128 36";
}
-/**
- * Show next/previous panel.
- * @param direction - 1/-1 forward, backward panel.
- */
-function selectNextTab(direction)
+function selectPanelGUI(panel)
{
- selectPanel(Engine.GetGUIObjectByName(g_PanelButtons[
- (g_PanelButtons.indexOf(g_SelectedPanel) + direction + g_PanelButtons.length) % g_PanelButtons.length]));
-}
-
-function selectPanel(panel)
-{
- // TODO: move panel buttons to a custom parent object
-
- for (let button of Engine.GetGUIObjectByName("summaryWindow").children)
- if (button.name.endsWith("PanelButton"))
- button.sprite = "ModernTabHorizontalBackground";
-
- panel.sprite = "ModernTabHorizontalForeground";
-
- adjustTabDividers(panel.size);
+ adjustTabDividers(Engine.GetGUIObjectByName("tabButton[" + panel + "]").size);
let generalPanel = Engine.GetGUIObjectByName("generalPanel");
let chartsPanel = Engine.GetGUIObjectByName("chartsPanel");
- let chartsHidden = panel.name != "chartsPanelButton";
+
+ // We assume all scorePanels come before the charts.
+ let chartsHidden = panel < g_ScorePanelsData.length;
generalPanel.hidden = !chartsHidden;
chartsPanel.hidden = chartsHidden;
if (chartsHidden)
- updatePanelData(g_ScorePanelsData[panel.name.substr(0, panel.name.length - "PanelButton".length)]);
+ updatePanelData(g_ScorePanelsData[panel]);
else
[0, 1].forEach(updateCategoryDropdown);
-
- g_SelectedPanel = panel.name;
}
function initGUICharts()
{
let player_colors = [];
for (let i = 1; i <= g_PlayerCount; ++i)
{
let playerState = g_GameData.sim.playerStates[i];
player_colors.push(
Math.floor(playerState.color.r * 255) + " " +
Math.floor(playerState.color.g * 255) + " " +
Math.floor(playerState.color.b * 255)
);
}
for (let i = 0; i < 2; ++i)
Engine.GetGUIObjectByName("chart[" + i + "]").series_color = player_colors;
let chartLegend = Engine.GetGUIObjectByName("chartLegend");
chartLegend.caption = g_GameData.sim.playerStates.slice(1).map(
(state, index) => coloredText("â– ", player_colors[index]) + " " + state.name
).join(" ");
let chart1Part = Engine.GetGUIObjectByName("chart[1]Part");
let chart1PartSize = chart1Part.size;
chart1PartSize.rright += 50;
chart1PartSize.rleft += 50;
chart1PartSize.right -= 5;
chart1PartSize.left -= 5;
chart1Part.size = chart1PartSize;
}
function resizeDropdown(dropdown)
{
let size = dropdown.size;
size.bottom = dropdown.size.top +
(Engine.GetTextWidth(dropdown.font, dropdown.list[dropdown.selected]) >
dropdown.size.right - dropdown.size.left - 32 ? 42 : 27);
dropdown.size = size;
}
function updateCategoryDropdown(number)
{
let chartCategory = Engine.GetGUIObjectByName("chart[" + number + "]CategorySelection");
- chartCategory.list_data = Object.keys(g_ScorePanelsData);
- chartCategory.list = Object.keys(g_ScorePanelsData).map(panel => g_ScorePanelsData[panel].caption);
+ chartCategory.list_data = g_ScorePanelsData.map((panel, idx) => idx);
+ chartCategory.list = g_ScorePanelsData.map(panel => panel.label);
chartCategory.onSelectionChange = function() {
if (!this.list_data[this.selected])
return;
if (g_SelectedChart.category[number] != this.selected)
{
g_SelectedChart.category[number] = this.selected;
g_SelectedChart.value[number] = 0;
g_SelectedChart.type[number] = 0;
}
resizeDropdown(this);
updateValueDropdown(number, this.list_data[this.selected]);
};
chartCategory.selected = g_SelectedChart.category[number];
}
function updateValueDropdown(number, category)
{
let chartValue = Engine.GetGUIObjectByName("chart[" + number + "]ValueSelection");
let list = g_ScorePanelsData[category].headings.map(heading => heading.caption);
list.shift();
chartValue.list = list;
let list_data = g_ScorePanelsData[category].headings.map(heading => heading.identifier);
list_data.shift();
chartValue.list_data = list_data;
chartValue.onSelectionChange = function() {
if (!this.list_data[this.selected])
return;
if (g_SelectedChart.value[number] != this.selected)
{
g_SelectedChart.value[number] = this.selected;
g_SelectedChart.type[number] = 0;
}
resizeDropdown(this);
updateTypeDropdown(number, category, this.list_data[this.selected], this.selected);
};
chartValue.selected = g_SelectedChart.value[number];
}
function updateTypeDropdown(number, category, item, itemNumber)
{
let testValue = g_ScorePanelsData[category].counters[itemNumber].fn(g_GameData.sim.playerStates[1], 0, item);
let hide = !g_ScorePanelsData[category].counters[itemNumber].fn ||
typeof testValue != "object" || Object.keys(testValue).length < 2;
Engine.GetGUIObjectByName("chart[" + number + "]TypeLabel").hidden = hide;
let chartType = Engine.GetGUIObjectByName("chart[" + number + "]TypeSelection");
chartType.hidden = hide;
if (hide)
{
updateChart(number, category, item, itemNumber, Object.keys(testValue)[0] || undefined);
return;
}
chartType.list = Object.keys(testValue).map(type => g_SummaryTypes[type].caption);
chartType.list_data = Object.keys(testValue);
chartType.onSelectionChange = function() {
if (!this.list_data[this.selected])
return;
g_SelectedChart.type[number] = this.selected;
resizeDropdown(this);
updateChart(number, category, item, itemNumber, this.list_data[this.selected]);
};
chartType.selected = g_SelectedChart.type[number];
}
function updateChart(number, category, item, itemNumber, type)
{
if (!g_ScorePanelsData[category].counters[itemNumber].fn)
return;
let chart = Engine.GetGUIObjectByName("chart[" + number + "]");
chart.format_y = g_ScorePanelsData[category].headings[itemNumber + 1].format || "INTEGER";
Engine.GetGUIObjectByName("chart[" + number + "]XAxisLabel").caption = translate("Time elapsed");
let series = [];
for (let j = 1; j <= g_PlayerCount; ++j)
{
let playerState = g_GameData.sim.playerStates[j];
let data = [];
for (let index in playerState.sequences.time)
{
let value = g_ScorePanelsData[category].counters[itemNumber].fn(playerState, index, item);
if (type)
value = value[type];
data.push([playerState.sequences.time[index], value]);
}
series.push(data);
}
chart.series = series;
}
function adjustTabDividers(tabSize)
{
+ let tabButtonsLeft = Engine.GetGUIObjectByName("tabButtonsFrame").size.left;
+
let leftSpacer = Engine.GetGUIObjectByName("tabDividerLeft");
- let rightSpacer = Engine.GetGUIObjectByName("tabDividerRight");
+ let leftSpacerSize = leftSpacer.size;
+ leftSpacerSize.right = tabSize.left + tabButtonsLeft + 2;
+ leftSpacer.size = leftSpacerSize;
- leftSpacer.size = [
- 20,
- leftSpacer.size.top,
- tabSize.left + 2,
- leftSpacer.size.bottom
- ].join(" ");
-
- rightSpacer.size = [
- tabSize.right - 2,
- rightSpacer.size.top,
- "100%-20",
- rightSpacer.size.bottom
- ].join(" ");
+ let rightSpacer = Engine.GetGUIObjectByName("tabDividerRight");
+ let rightSpacerSize = rightSpacer.size;
+ rightSpacerSize.left = tabSize.right + tabButtonsLeft - 2;
+ rightSpacer.size = rightSpacerSize;
}
function updatePanelData(panelInfo)
{
resetGeneralPanel();
updateGeneralPanelHeadings(panelInfo.headings);
updateGeneralPanelTitles(panelInfo.titleHeadings);
let rowPlayerObjectWidth = updateGeneralPanelCounter(panelInfo.counters);
updateGeneralPanelTeams();
let index = g_GameData.sim.playerStates[1].sequences.time.length - 1;
let playerBoxesCounts = [];
for (let i = 0; i < g_PlayerCount; ++i)
{
let playerState = g_GameData.sim.playerStates[i + 1];
if (!playerBoxesCounts[playerState.team + 1])
playerBoxesCounts[playerState.team + 1] = 1;
else
playerBoxesCounts[playerState.team + 1] += 1;
let positionObject = playerBoxesCounts[playerState.team + 1] - 1;
let rowPlayer = "playerBox[" + positionObject + "]";
let playerOutcome = "playerOutcome[" + positionObject + "]";
let playerNameColumn = "playerName[" + positionObject + "]";
let playerCivicBoxColumn = "civIcon[" + positionObject + "]";
let playerCounterValue = "valueData[" + positionObject + "]";
if (playerState.team != -1)
{
rowPlayer = "playerBoxt[" + playerState.team + "][" + positionObject + "]";
playerOutcome = "playerOutcomet[" + playerState.team + "][" + positionObject + "]";
playerNameColumn = "playerNamet[" + playerState.team + "][" + positionObject + "]";
playerCivicBoxColumn = "civIcont[" + playerState.team + "][" + positionObject + "]";
playerCounterValue = "valueDataTeam[" + playerState.team + "][" + positionObject + "]";
}
let colorString = "color: " +
Math.floor(playerState.color.r * 255) + " " +
Math.floor(playerState.color.g * 255) + " " +
Math.floor(playerState.color.b * 255);
let rowPlayerObject = Engine.GetGUIObjectByName(rowPlayer);
rowPlayerObject.hidden = false;
rowPlayerObject.sprite = colorString + " " + g_PlayerBoxAlpha;
let boxSize = rowPlayerObject.size;
boxSize.right = rowPlayerObjectWidth;
rowPlayerObject.size = boxSize;
setOutcomeIcon(playerState.state, Engine.GetGUIObjectByName(playerOutcome));
playerNameColumn = Engine.GetGUIObjectByName(playerNameColumn);
playerNameColumn.caption = g_GameData.sim.playerStates[i + 1].name;
playerNameColumn.tooltip = translateAISettings(g_GameData.sim.mapSettings.PlayerData[i + 1]);
let civIcon = Engine.GetGUIObjectByName(playerCivicBoxColumn);
civIcon.sprite = "stretched:" + g_CivData[playerState.civ].Emblem;
civIcon.tooltip = g_CivData[playerState.civ].Name;
updateCountersPlayer(playerState, panelInfo.counters, panelInfo.headings, playerCounterValue, index);
}
let teamCounterFn = panelInfo.teamCounterFn;
if (g_Teams && teamCounterFn)
updateCountersTeam(teamCounterFn, panelInfo.counters, panelInfo.headings, index);
}
function continueButton()
{
let summarySelection = {
- "panel": g_SelectedPanel,
+ "panel": g_TabCategorySelected,
"charts": g_SelectedChart
};
if (g_GameData.gui.isInGame)
Engine.PopGuiPage({
"summarySelection": summarySelection
});
else if (g_GameData.gui.dialog)
Engine.PopGuiPage();
else if (Engine.HasXmppClient())
Engine.SwitchGuiPage("page_lobby.xml", { "dialog": false });
else if (g_GameData.gui.isReplay)
Engine.SwitchGuiPage("page_replaymenu.xml", {
"replaySelectionData": g_GameData.gui.replaySelectionData,
"summarySelection": summarySelection
});
else
Engine.SwitchGuiPage("page_pregame.xml");
}
function startReplay()
{
if (!Engine.StartVisualReplay(g_GameData.gui.replayDirectory))
{
warn("Replay file not found!");
return;
}
Engine.SwitchGuiPage("page_loading.xml", {
"attribs": Engine.GetReplayAttributes(g_GameData.gui.replayDirectory),
"playerAssignments": {
"local": {
"name": singleplayerName(),
"player": -1
}
},
"savedGUIData": "",
"isReplay": true,
"replaySelectionData": g_GameData.gui.replaySelectionData
});
}
function initGUILabels()
{
let assignedState = g_GameData.sim.playerStates[g_GameData.gui.assignedPlayer || -1];
Engine.GetGUIObjectByName("summaryText").caption =
g_GameData.gui.isInGame ?
translate("Current Scores") :
g_GameData.gui.isReplay ?
translate("Scores at the end of the game.") :
g_GameData.gui.disconnected ?
translate("You have been disconnected.") :
!assignedState ?
translate("You have left the game.") :
assignedState.state == "won" ?
translate("You have won the battle!") :
assignedState.state == "defeated" ?
translate("You have been defeated…") :
translate("You have abandoned the game.");
Engine.GetGUIObjectByName("timeElapsed").caption = sprintf(
translate("Game time elapsed: %(time)s"), {
"time": timeToString(g_GameData.sim.timeElapsed)
});
let mapType = g_Settings.MapTypes.find(type => type.Name == g_GameData.sim.mapSettings.mapType);
let mapSize = g_Settings.MapSizes.find(size => size.Tiles == g_GameData.sim.mapSettings.Size || 0);
Engine.GetGUIObjectByName("mapName").caption = sprintf(
translate("%(mapName)s - %(mapType)s"), {
"mapName": translate(g_GameData.sim.mapSettings.Name),
"mapType": mapSize ? mapSize.Name : (mapType ? mapType.Title : "")
});
}
function initGUIButtons()
{
let replayButton = Engine.GetGUIObjectByName("replayButton");
replayButton.hidden = g_GameData.gui.isInGame || !g_GameData.gui.replayDirectory;
let lobbyButton = Engine.GetGUIObjectByName("lobbyButton");
lobbyButton.tooltip = colorizeHotkey(translate("%(hotkey)s: Toggle the multiplayer lobby in a dialog window."), "lobby");
lobbyButton.hidden = g_GameData.gui.isInGame || !Engine.HasXmppClient();
// Right-align lobby button
let lobbyButtonSize = lobbyButton.size;
let lobbyButtonWidth = lobbyButtonSize.right - lobbyButtonSize.left;
lobbyButtonSize.right = (replayButton.hidden ? Engine.GetGUIObjectByName("continueButton").size.left : replayButton.size.left) - 10;
lobbyButtonSize.left = lobbyButtonSize.right - lobbyButtonWidth;
lobbyButton.size = lobbyButtonSize;
+
+ let allPanelsData = g_ScorePanelsData.concat(g_ChartPanelsData);
+ for (let tab in allPanelsData)
+ allPanelsData[tab].tooltip =
+ sprintf(translate("Toggle the %(name)s summary tab."), { "name": allPanelsData[tab].label }) +
+ colorizeHotkey("\n" + translate("Use %(hotkey)s to move a summary tab right."), "tab.next") +
+ colorizeHotkey("\n" + translate("Use %(hotkey)s to move a summary tab left."), "tab.prev");
+
+ placeTabButtons(
+ allPanelsData,
+ true,
+ g_TabButtonWidth,
+ g_TabButtonDist,
+ selectPanel,
+ selectPanelGUI);
}
function initTeamData()
{
// Panels
g_PlayerCount = g_GameData.sim.playerStates.length - 1;
if (g_GameData.sim.mapSettings.LockTeams)
{
// Count teams
for (let player = 1; player <= g_PlayerCount; ++player)
{
let playerTeam = g_GameData.sim.playerStates[player].team;
if (!g_Teams[playerTeam])
g_Teams[playerTeam] = [];
g_Teams[playerTeam].push(player);
}
if (g_Teams.every(team => team && team.length < 2))
g_Teams = false; // Each player has his own team. Displaying teams makes no sense.
}
else
g_Teams = false;
// Erase teams data if teams are not displayed
if (!g_Teams)
for (let p = 0; p < g_PlayerCount; ++p)
g_GameData.sim.playerStates[p+1].team = -1;
}
Index: ps/trunk/binaries/data/mods/public/gui/summary/summary.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/summary/summary.xml (revision 23788)
+++ ps/trunk/binaries/data/mods/public/gui/summary/summary.xml (revision 23789)
@@ -1,236 +1,183 @@
continueButton();
if (g_GameData.gui.isInGame)
continueButton();
-
- selectNextTab(1);
-
-
-
- selectNextTab(-1);
-
-
Summary
-
-
-
-
- selectPanel(this);
-
- Score
-
-
-
-
- selectPanel(this);
-
- Structures
-
-
+
+
-
- selectPanel(this);
-
- Units
-
-
-
-
- selectPanel(this);
-
- Resources
-
-
-
-
- selectPanel(this);
-
- Market
-
-
-
-
- selectPanel(this);
-
- Miscellaneous
-
-
-
-
- selectPanel(this);
-
- Charts
-
+
+
Player name
Category:
Category
Value:
Value
Type:
Type
if (Engine.HasXmppClient())
Engine.PushGuiPage("page_lobby.xml", { "dialog": true });
Watch Replay
startReplay();
Continue
continueButton();