Index: binaries/data/mods/mod/gui/common/functions_msgbox.js
===================================================================
--- binaries/data/mods/mod/gui/common/functions_msgbox.js
+++ binaries/data/mods/mod/gui/common/functions_msgbox.js
@@ -1,50 +1,18 @@
-// We want to pass callback functions for the different buttons in a convenient way.
-// Because passing functions accross compartment boundaries is a pain, we just store them here together with some optional arguments.
-// The messageBox page will return the code of the pressed button and the according function will be called.
-var g_MessageBoxBtnFunctions = [];
-var g_MessageBoxCallbackArgs = [];
-
-function messageBoxCallbackFunction(btnCode)
-{
- if (btnCode !== undefined && g_MessageBoxBtnFunctions[btnCode])
- {
- // Cache the variables to make it possible to call a messageBox from a callback function.
- let callbackFunction = g_MessageBoxBtnFunctions[btnCode];
- let callbackArgs = g_MessageBoxCallbackArgs[btnCode];
-
- g_MessageBoxBtnFunctions = [];
- g_MessageBoxCallbackArgs = [];
-
- if (callbackArgs !== undefined)
- callbackFunction(callbackArgs);
- else
- callbackFunction();
- return;
- }
-
- g_MessageBoxBtnFunctions = [];
- g_MessageBoxCallbackArgs = [];
-}
-
function messageBox(mbWidth, mbHeight, mbMessage, mbTitle, mbButtonCaptions, mbBtnCode, mbCallbackArgs)
{
- if (g_MessageBoxBtnFunctions && g_MessageBoxBtnFunctions.length)
- {
- warn("A messagebox was called when a previous callback function is still set, aborting!");
- return;
- }
-
- g_MessageBoxBtnFunctions = mbBtnCode;
- g_MessageBoxCallbackArgs = mbCallbackArgs || g_MessageBoxCallbackArgs;
-
- Engine.PushGuiPage("page_msgbox.xml", {
- "width": mbWidth,
- "height": mbHeight,
- "message": mbMessage,
- "title": mbTitle,
- "buttonCaptions": mbButtonCaptions,
- "callback": mbBtnCode && "messageBoxCallbackFunction"
- });
+ Engine.PushGuiPage(
+ "page_msgbox.xml",
+ {
+ "width": mbWidth,
+ "height": mbHeight,
+ "message": mbMessage,
+ "title": mbTitle,
+ "buttonCaptions": mbButtonCaptions
+ },
+ btnCode => {
+ if (mbBtnCode !== undefined && mbBtnCode[btnCode])
+ mbBtnCode[btnCode](mbCallbackArgs ? mbCallbackArgs[btnCode] : undefined);
+ });
}
function openURL(url)
Index: binaries/data/mods/mod/gui/common/terms.js
===================================================================
--- binaries/data/mods/mod/gui/common/terms.js
+++ binaries/data/mods/mod/gui/common/terms.js
@@ -7,27 +7,27 @@
function openTerms(page)
{
- Engine.PushGuiPage("page_termsdialog.xml", {
- "file": g_Terms[page].file,
- "title": g_Terms[page].title,
- "sprintf": g_Terms[page].sprintf,
- "urlButtons": g_Terms[page].urlButtons || [],
- "termsURL": g_Terms[page].termsURL || undefined,
- "page": page,
- "callback": "acceptTerms"
- });
-}
-
-function acceptTerms(data)
-{
- g_Terms[data.page].accepted = data.accepted;
-
- let value = data.accepted ? getTermsHash(data.page) : "0";
- Engine.ConfigDB_CreateValue("user", g_Terms[data.page].config, value);
- Engine.ConfigDB_WriteValueToFile("user", g_Terms[data.page].config, value, "config/user.cfg");
-
- if (g_Terms[data.page].callback)
- g_Terms[data.page].callback(data);
+ Engine.PushGuiPage(
+ "page_termsdialog.xml",
+ {
+ "file": g_Terms[page].file,
+ "title": g_Terms[page].title,
+ "sprintf": g_Terms[page].sprintf,
+ "urlButtons": g_Terms[page].urlButtons || [],
+ "termsURL": g_Terms[page].termsURL || undefined,
+ "page": page
+ },
+ data => {
+ g_Terms[data.page].accepted = data.accepted;
+
+ let value = data.accepted ? getTermsHash(data.page) : "0";
+ Engine.ConfigDB_CreateValue("user", g_Terms[data.page].config, value);
+ Engine.ConfigDB_WriteValueToFile("user", g_Terms[data.page].config, value, "config/user.cfg");
+
+ if (g_Terms[data.page].callback)
+ g_Terms[data.page].callback(data);
+ }
+ );
}
function checkTerms()
Index: binaries/data/mods/mod/gui/modio/modio.js
===================================================================
--- binaries/data/mods/mod/gui/modio/modio.js
+++ binaries/data/mods/mod/gui/modio/modio.js
@@ -270,7 +270,7 @@
function closePage(data)
{
- Engine.PopGuiPageCB(undefined);
+ Engine.PopGuiPage();
}
function showErrorMessageBox(caption, title, buttonCaptions, buttonActions)
Index: binaries/data/mods/mod/gui/modmod/modmodio.js
===================================================================
--- binaries/data/mods/mod/gui/modmod/modmodio.js
+++ binaries/data/mods/mod/gui/modmod/modmodio.js
@@ -26,7 +26,5 @@
function openModIo(data)
{
if (data.accepted)
- Engine.PushGuiPage("page_modio.xml", {
- "callback": "initMods"
- });
+ Engine.PushGuiPage("page_modio.xml", {}, initMods);
}
Index: binaries/data/mods/mod/gui/msgbox/msgbox.js
===================================================================
--- binaries/data/mods/mod/gui/msgbox/msgbox.js
+++ binaries/data/mods/mod/gui/msgbox/msgbox.js
@@ -29,12 +29,8 @@
captions.forEach((caption, i) => {
mbButton[i] = Engine.GetGUIObjectByName("mbButton" + (i + 1));
- let action = function()
- {
- if (data.callback)
- Engine.PopGuiPageCB(i);
- else
- Engine.PopGuiPage();
+ let action = () => {
+ Engine.PopGuiPage(i);
};
mbButton[i].caption = caption;
Index: binaries/data/mods/mod/gui/termsdialog/termsdialog.js
===================================================================
--- binaries/data/mods/mod/gui/termsdialog/termsdialog.js
+++ binaries/data/mods/mod/gui/termsdialog/termsdialog.js
@@ -82,7 +82,7 @@
function closeTerms(accepted)
{
- Engine.PopGuiPageCB({
+ Engine.PopGuiPage({
"page": g_TermsPage,
"accepted": accepted
});
Index: binaries/data/mods/public/gui/aiconfig/aiconfig.js
===================================================================
--- binaries/data/mods/public/gui/aiconfig/aiconfig.js
+++ binaries/data/mods/public/gui/aiconfig/aiconfig.js
@@ -69,10 +69,7 @@
function returnAI(save = true)
{
let idx = Engine.GetGUIObjectByName("aiSelection").selected;
-
- // Pop the page before calling the callback, so the callback runs
- // in the parent GUI page's context
- Engine.PopGuiPageCB({
+ Engine.PopGuiPage({
"save": save,
"id": g_AIDescriptions[idx].id,
"name": g_AIDescriptions[idx].data.name,
Index: binaries/data/mods/public/gui/civinfo/civinfo.js
===================================================================
--- binaries/data/mods/public/gui/civinfo/civinfo.js
+++ binaries/data/mods/public/gui/civinfo/civinfo.js
@@ -3,11 +3,6 @@
*/
const g_CivData = loadCivData(true, false);
-/**
- * Callback function name on closing gui via Engine.PopGuiPage().
- */
-var g_Callback = "";
-
var g_SelectedCiv = "";
/**
@@ -15,9 +10,6 @@
*/
function init(data = {})
{
- if (data.callback)
- g_Callback = data.callback;
-
var civList = Object.keys(g_CivData).map(civ => ({ "name": g_CivData[civ].Name, "code": civ })).sort(sortNameIgnoreCase);
var civSelection = Engine.GetGUIObjectByName("civSelection");
@@ -94,16 +86,18 @@
function switchToStrucTreePage()
{
- Engine.PopGuiPage();
- Engine.PushGuiPage("page_structree.xml", { "civ": g_SelectedCiv, "callback": g_Callback });
+ Engine.PopGuiPage({
+ "civ": g_SelectedCiv,
+ "nextPage": "page_structree.xml"
+ });
}
-function close()
-{
- if (g_Callback)
- Engine.PopGuiPageCB({ "civ": g_SelectedCiv, "page": "page_civinfo.xml" });
- else
- Engine.PopGuiPage();
+function closePage()
+{
+ Engine.PopGuiPage({
+ "civ": g_SelectedCiv,
+ "lastPage": "page_civinfo.xml"
+ });
}
/**
Index: binaries/data/mods/public/gui/civinfo/civinfo.xml
===================================================================
--- binaries/data/mods/public/gui/civinfo/civinfo.xml
+++ binaries/data/mods/public/gui/civinfo/civinfo.xml
@@ -135,9 +135,7 @@
hotkey="cancel"
>
Close
-
- close();
-
+ closePage();
Index: binaries/data/mods/public/gui/gamesetup/gamesetup.js
===================================================================
--- binaries/data/mods/public/gui/gamesetup/gamesetup.js
+++ binaries/data/mods/public/gui/gamesetup/gamesetup.js
@@ -1047,10 +1047,10 @@
"hotkey_structree": colorizeHotkey("%(hotkey)s", "structree")
}),
"onPress": () => function() {
- Engine.PushGuiPage(g_CivInfo.page, {
- "civ": g_CivInfo.code,
- "callback": "storeCivInfoPage"
- });
+ Engine.PushGuiPage(
+ g_CivInfo.page,
+ { "civ": g_CivInfo.code },
+ storeCivInfoPage);
}
},
"civResetButton": {
@@ -2420,30 +2420,26 @@
{
g_LastViewedAIPlayer = playerSlot;
- Engine.PushGuiPage("page_aiconfig.xml", {
- "callback": "AIConfigCallback",
- "playerSlot": playerSlot,
- "id": g_GameAttributes.settings.PlayerData[playerSlot].AI,
- "difficulty": g_GameAttributes.settings.PlayerData[playerSlot].AIDiff,
- "behavior": g_GameAttributes.settings.PlayerData[playerSlot].AIBehavior
- });
-}
-
-/**
- * Called after closing the dialog.
- */
-function AIConfigCallback(ai)
-{
- g_LastViewedAIPlayer = -1;
-
- if (!ai.save || !g_IsController)
- return;
-
- g_GameAttributes.settings.PlayerData[ai.playerSlot].AI = ai.id;
- g_GameAttributes.settings.PlayerData[ai.playerSlot].AIDiff = ai.difficulty;
- g_GameAttributes.settings.PlayerData[ai.playerSlot].AIBehavior = ai.behavior;
+ Engine.PushGuiPage(
+ "page_aiconfig.xml",
+ {
+ "playerSlot": playerSlot,
+ "id": g_GameAttributes.settings.PlayerData[playerSlot].AI,
+ "difficulty": g_GameAttributes.settings.PlayerData[playerSlot].AIDiff,
+ "behavior": g_GameAttributes.settings.PlayerData[playerSlot].AIBehavior
+ },
+ ai => {
+ g_LastViewedAIPlayer = -1;
+
+ if (!ai.save || !g_IsController)
+ return;
+
+ g_GameAttributes.settings.PlayerData[ai.playerSlot].AI = ai.id;
+ g_GameAttributes.settings.PlayerData[ai.playerSlot].AIDiff = ai.difficulty;
+ g_GameAttributes.settings.PlayerData[ai.playerSlot].AIBehavior = ai.behavior;
- updateGameAttributes();
+ updateGameAttributes();
+ });
}
function reloadPlayerAssignmentChoices()
@@ -2767,5 +2763,13 @@
function storeCivInfoPage(data)
{
g_CivInfo.code = data.civ;
- g_CivInfo.page = data.page;
+
+ if (data.lastPage)
+ g_CivInfo.page = data.lastPage;
+
+ if (data.nextPage)
+ Engine.PushGuiPage(
+ data.nextPage,
+ { "civ": g_CivInfo.code },
+ storeCivInfoPage);
}
Index: binaries/data/mods/public/gui/gamesetup/gamesetup.xml
===================================================================
--- binaries/data/mods/public/gui/gamesetup/gamesetup.xml
+++ binaries/data/mods/public/gui/gamesetup/gamesetup.xml
@@ -6,15 +6,11 @@
Index: binaries/data/mods/public/gui/options/options.js
===================================================================
--- binaries/data/mods/public/gui/options/options.js
+++ binaries/data/mods/public/gui/options/options.js
@@ -4,12 +4,7 @@
var g_Options;
/**
- * Remember whether to unpause running singleplayer games.
- */
-var g_HasCallback;
-
-/**
- * Functions to call after closing the page.
+ * Names of session functions to be called after closing the page.
*/
var g_CloseCallbacks;
@@ -170,8 +165,7 @@
function init(data, hotloadData)
{
- g_CloseCallbacks = new Set();
- g_HasCallback = hotloadData && hotloadData.callback || data && data.callback;
+ g_CloseCallbacks = hotloadData ? hotloadData.closeCallbacks : new Set();
g_TabCategorySelected = hotloadData ? hotloadData.tabCategorySelected : 0;
g_Options = Engine.ReadJSONFile("gui/options/options.json");
@@ -190,7 +184,7 @@
{
return {
"tabCategorySelected": g_TabCategorySelected,
- "callback": g_HasCallback
+ "closeCallbacks": closeCallbacks
};
}
@@ -382,8 +376,5 @@
function closePageWithoutConfirmation()
{
- if (g_HasCallback)
- Engine.PopGuiPageCB(g_CloseCallbacks);
- else
- Engine.PopGuiPage();
+ Engine.PopGuiPage(g_CloseCallbacks);
}
Index: binaries/data/mods/public/gui/pregame/mainmenu.js
===================================================================
--- binaries/data/mods/public/gui/pregame/mainmenu.js
+++ binaries/data/mods/public/gui/pregame/mainmenu.js
@@ -97,7 +97,7 @@
if (Engine.ConfigDB_GetValue("user", "gui.splashscreen.enable") === "true" ||
Engine.ConfigDB_GetValue("user", "gui.splashscreen.version") < Engine.GetFileMTime("gui/splashscreen/splashscreen.txt"))
- Engine.PushGuiPage("page_splashscreen.xml", { "page": "splashscreen", "callback": "SplashScreenClosedCallback" });
+ Engine.PushGuiPage("page_splashscreen.xml", {}, ShowRenderPathMessage);
else
ShowRenderPathMessage();
}
@@ -125,11 +125,6 @@
);
}
-function SplashScreenClosedCallback()
-{
- ShowRenderPathMessage();
-}
-
/**
* Slide menu.
*/
@@ -231,7 +226,14 @@
return translate("Launch the multiplayer lobby to join and host publicly visible games and chat with other players. \\[DISABLED BY BUILD]");
}
-function getManual()
+function openStrucTreePage(page)
+{
+ closeMenu();
+ Engine.PushGuiPage(page, {}, storeCivInfoPage);
+}
+
+function storeCivInfoPage(data)
{
- return translate("Manual");
+ if (data.nextPage)
+ Engine.PushGuiPage(data.nextPage, { "civ": data.civ }, storeCivInfoPage);
}
Index: binaries/data/mods/public/gui/pregame/mainmenu.xml
===================================================================
--- binaries/data/mods/public/gui/pregame/mainmenu.xml
+++ binaries/data/mods/public/gui/pregame/mainmenu.xml
@@ -90,11 +90,7 @@
Open the 0 A.D. Game Manual.
closeMenu();
- Engine.PushGuiPage("page_manual.xml", {
- "page": "manual/intro",
- "title": getManual(),
- "url": "https://trac.wildfiregames.com/wiki/0adManual"
- });
+ Engine.PushGuiPage("page_manual.xml");
@@ -122,10 +118,7 @@
hotkey="structree"
>
Structure Tree
-
- closeMenu();
- Engine.PushGuiPage("page_structree.xml", {});
-
+ openStrucTreePage("page_structree.xml");
@@ -138,10 +131,7 @@
hotkey="civinfo"
>
History
-
- closeMenu();
- Engine.PushGuiPage("page_civinfo.xml");
-
+ openStrucTreePage("page_civinfo.xml");
@@ -352,10 +342,7 @@
Show the Welcome Screen. Useful if you hid it by mistake.
closeMenu();
- Engine.PushGuiPage("page_splashscreen.xml", {
- "page": "splashscreen",
- "callback": "SplashScreenClosedCallback"
- });
+ Engine.PushGuiPage("page_splashscreen.xml", {}, ShowRenderPathMessage);
Index: binaries/data/mods/public/gui/reference/common/core.js
===================================================================
--- binaries/data/mods/public/gui/reference/common/core.js
+++ binaries/data/mods/public/gui/reference/common/core.js
@@ -1,13 +1,4 @@
var g_SelectedCiv = "gaia";
-var g_CallbackSet = false;
-
-function closePage()
-{
- if (g_CallbackSet)
- Engine.PopGuiPageCB(0);
- else
- Engine.PopGuiPage();
-}
/**
* Compile lists of templates buildable/trainable/researchable of a given civ.
Index: binaries/data/mods/public/gui/reference/structree/structree.js
===================================================================
--- binaries/data/mods/public/gui/reference/structree/structree.js
+++ binaries/data/mods/public/gui/reference/structree/structree.js
@@ -9,30 +9,19 @@
var g_TrainList = {};
/**
- * Callback function name on closing gui via Engine.PopGuiPage().
- */
-var g_Callback = "";
-
-/**
* Initialize the page
*
* @param {object} data - Parameters passed from the code that calls this page into existence.
*/
function init(data = {})
{
- if (data.callback)
- g_Callback = data.callback;
-
let civList = Object.keys(g_CivData).map(civ => ({
"name": g_CivData[civ].Name,
"code": civ,
})).sort(sortNameIgnoreCase);
if (!civList.length)
- {
- closePage();
- return;
- }
+ throw new Error("No civs available!");
g_ParsedData = {
"units": {},
@@ -52,16 +41,18 @@
function switchToCivInfoPage()
{
- Engine.PopGuiPage();
- Engine.PushGuiPage("page_civinfo.xml", { "civ": g_SelectedCiv, "callback": g_Callback });
+ Engine.PopGuiPage({
+ "civ": g_SelectedCiv,
+ "nextPage": "page_civinfo.xml"
+ });
}
-function close()
+function closePage()
{
- if (g_Callback)
- Engine.PopGuiPageCB({ "civ": g_SelectedCiv, "page": "page_structree.xml" });
- else
- Engine.PopGuiPage();
+ Engine.PopGuiPage({
+ "civ": g_SelectedCiv,
+ "lastPage": "page_structree.xml"
+ });
}
/**
Index: binaries/data/mods/public/gui/reference/structree/structree.xml
===================================================================
--- binaries/data/mods/public/gui/reference/structree/structree.xml
+++ binaries/data/mods/public/gui/reference/structree/structree.xml
@@ -7,7 +7,7 @@
- close();
+ closePage();
@@ -135,9 +135,7 @@
hotkey="cancel"
>
Close
-
- close();
-
+ closePage();
Index: binaries/data/mods/public/gui/reference/viewer/viewer.js
===================================================================
--- binaries/data/mods/public/gui/reference/viewer/viewer.js
+++ binaries/data/mods/public/gui/reference/viewer/viewer.js
@@ -47,21 +47,11 @@
* @param {object} data - Contains the civCode and the name of the template to display.
* @param {string} data.templateName
* @param {string} [data.civ]
- * @param {*} [data.callback] - If set and loosely equivalent to true, a callback is
- * assumed to be setup ready be called by the Engine upon
- * closure of this page.
*/
function init(data)
{
if (!data || !data.templateName)
- {
- error("Viewer: No template provided");
- closePage();
- return;
- }
-
- if (data.callback)
- g_CallbackSet = true;
+ throw new Error("Viewer: No template provided");
let templateName = removeFiltersFromTemplateName(data.templateName);
let isTech = techDataExists(templateName);
@@ -85,11 +75,7 @@
g_Template = isTech ? loadTechnology(templateName) : loadEntityTemplate(templateName);
if (!g_Template)
- {
- error("Viewer: unable to recognise or load template (" + templateName + ")");
- closePage();
- return;
- }
+ throw new Error("Viewer: unable to recognise or load template (" + templateName + ")");
g_StatsFunctions = [getEntityCostTooltip].concat(g_StatsFunctions);
Index: binaries/data/mods/public/gui/reference/viewer/viewer.xml
===================================================================
--- binaries/data/mods/public/gui/reference/viewer/viewer.xml
+++ binaries/data/mods/public/gui/reference/viewer/viewer.xml
@@ -35,7 +35,7 @@
hotkey="cancel"
>
Close
- closePage();
+ Engine.PopGuiPage();
Index: binaries/data/mods/public/gui/savegame/save.js
===================================================================
--- binaries/data/mods/public/gui/savegame/save.js
+++ binaries/data/mods/public/gui/savegame/save.js
@@ -80,7 +80,7 @@
function closeSave()
{
- Engine.PopGuiPageCB(0);
+ Engine.PopGuiPage();
}
// HACK: Engine.SaveGame* expects this function to be defined on the current page.
Index: binaries/data/mods/public/gui/session/hotkeys/misc.xml
===================================================================
--- binaries/data/mods/public/gui/session/hotkeys/misc.xml
+++ binaries/data/mods/public/gui/session/hotkeys/misc.xml
@@ -37,15 +37,11 @@
-
- Engine.PushGuiPage("page_civinfo.xml", { "civ": g_CivInfo.code, "callback": "storeCivInfoPage" });
-
+ openStrucTree("page_civinfo.xml");
-
- Engine.PushGuiPage("page_structree.xml", { "civ": g_CivInfo.code, "callback": "storeCivInfoPage" });
-
+ openStrucTree("page_structree.xml");
Index: binaries/data/mods/public/gui/session/menu.js
===================================================================
--- binaries/data/mods/public/gui/session/menu.js
+++ binaries/data/mods/public/gui/session/menu.js
@@ -236,10 +236,12 @@
closeOpenDialogs();
pauseGame();
- Engine.PushGuiPage("page_savegame.xml", {
- "savedGameData": getSavedGameData(),
- "callback": "resumeGame"
- });
+ Engine.PushGuiPage(
+ "page_savegame.xml",
+ {
+ "savedGameData": getSavedGameData(),
+ },
+ resumeGame);
}
function openOptions()
@@ -247,18 +249,16 @@
closeOpenDialogs();
pauseGame();
- Engine.PushGuiPage("page_options.xml", {
- "callback": "optionsPageClosed"
- });
-}
+ Engine.PushGuiPage(
+ "page_options.xml",
+ {},
+ callbackFunctionNames => {
+ for (let functionName of callbackFunctionNames)
+ if (global[functionName])
+ global[functionName]();
-function optionsPageClosed(data)
-{
- for (let callback of data)
- if (global[callback])
- global[callback]();
-
- resumeGame();
+ resumeGame();
+ });
}
function openChat(command = "")
@@ -1101,41 +1101,47 @@
pauseGame();
let extendedSimState = Engine.GuiInterfaceCall("GetExtendedSimulationState");
- Engine.PushGuiPage("page_summary.xml", {
- "sim": {
- "mapSettings": g_GameAttributes.settings,
- "playerStates": extendedSimState.players.filter((state, player) =>
- g_IsObserver || player == 0 || player == g_ViewedPlayer ||
- extendedSimState.players[g_ViewedPlayer].hasSharedLos && g_Players[player].isMutualAlly[g_ViewedPlayer]),
- "timeElapsed": extendedSimState.timeElapsed
- },
- "gui": {
- "dialog": true,
- "isInGame": true
+ Engine.PushGuiPage(
+ "page_summary.xml",
+ {
+ "sim": {
+ "mapSettings": g_GameAttributes.settings,
+ "playerStates": extendedSimState.players.filter((state, player) =>
+ g_IsObserver || player == 0 || player == g_ViewedPlayer ||
+ extendedSimState.players[g_ViewedPlayer].hasSharedLos && g_Players[player].isMutualAlly[g_ViewedPlayer]),
+ "timeElapsed": extendedSimState.timeElapsed
+ },
+ "gui": {
+ "dialog": true,
+ "isInGame": true
+ },
+ "selectedData": g_SummarySelectedData
},
- "selectedData": g_SummarySelectedData,
- "callback": "resumeGameAndSaveSummarySelectedData"
- });
+ resumeGameAndSaveSummarySelectedData);
}
-function openStrucTree()
+function openStrucTree(page)
{
closeOpenDialogs();
pauseGame();
// TODO add info about researched techs and unlocked entities
+ Engine.PushGuiPage(
+ page,
+ {
+ "civ": g_CivInfo.code || g_Players[g_ViewedPlayer].civ
+ },
+ data => {
+ g_CivInfo.code = data.civ;
- Engine.PushGuiPage(g_CivInfo.page, {
- "civ": g_CivInfo.code || g_Players[g_ViewedPlayer].civ,
- "callback": "storeCivInfoPage"
- });
-}
+ if (data.lastPage)
+ g_CivInfo.page = data.lastPage;
-function storeCivInfoPage(data)
-{
- g_CivInfo.code = data.civ;
- g_CivInfo.page = data.page;
- resumeGame();
+ if (data.nextPage)
+ openStrucTree(data.nextPage)
+ else
+ resumeGame();
+ });
}
/**
@@ -1226,13 +1232,7 @@
{
closeOpenDialogs();
pauseGame();
-
- Engine.PushGuiPage("page_manual.xml", {
- "page": "manual/intro",
- "title": translate("Manual"),
- "url": "https://trac.wildfiregames.com/wiki/0adManual",
- "callback": "resumeGame"
- });
+ Engine.PushGuiPage("page_manual.xml", {}, resumeGame);
}
function closeOpenDialogs()
Index: binaries/data/mods/public/gui/session/selection_panels.js
===================================================================
--- binaries/data/mods/public/gui/session/selection_panels.js
+++ binaries/data/mods/public/gui/session/selection_panels.js
@@ -1143,11 +1143,13 @@
{
pauseGame();
- Engine.PushGuiPage("page_viewer.xml", {
- "templateName": templateName,
- "callback": "resumeGame",
- "civ": civCode
- });
+ Engine.PushGuiPage(
+ "page_viewer.xml",
+ {
+ "templateName": templateName,
+ "civ": civCode
+ },
+ resumeGame);
}
/**
Index: binaries/data/mods/public/gui/session/top_panel/civ_icon.xml
===================================================================
--- binaries/data/mods/public/gui/session/top_panel/civ_icon.xml
+++ binaries/data/mods/public/gui/session/top_panel/civ_icon.xml
@@ -6,6 +6,6 @@
tooltip_style="sessionToolTipBold"
>
- openStrucTree()
+ openStrucTree(g_CivInfo.page)
Index: binaries/data/mods/public/gui/splashscreen/splashscreen.js
===================================================================
--- binaries/data/mods/public/gui/splashscreen/splashscreen.js
+++ binaries/data/mods/public/gui/splashscreen/splashscreen.js
@@ -1,5 +1,14 @@
+var g_SplashScreenFile = "gui/splashscreen/splashscreen.txt";
+
function init(data)
{
- Engine.GetGUIObjectByName("mainText").caption = Engine.TranslateLines(Engine.ReadFile("gui/splashscreen/" + data.page + ".txt"));
+ Engine.GetGUIObjectByName("mainText").caption = Engine.TranslateLines(Engine.ReadFile(g_SplashScreenFile));
Engine.GetGUIObjectByName("displaySplashScreen").checked = Engine.ConfigDB_GetValue("user", "gui.splashscreen.enable") === "true";
}
+
+function closePage()
+{
+ saveSettingAndWriteToUserConfig("gui.splashscreen.enable", String(Engine.GetGUIObjectByName("displaySplashScreen").checked));
+ saveSettingAndWriteToUserConfig("gui.splashscreen.version", Engine.GetFileMTime(g_SplashScreenFile));
+ Engine.PopGuiPage();
+}
Index: binaries/data/mods/public/gui/splashscreen/splashscreen.xml
===================================================================
--- binaries/data/mods/public/gui/splashscreen/splashscreen.xml
+++ binaries/data/mods/public/gui/splashscreen/splashscreen.xml
@@ -27,11 +27,7 @@
OK
-
+ closePage();
Index: binaries/data/mods/public/gui/summary/summary.js
===================================================================
--- binaries/data/mods/public/gui/summary/summary.js
+++ binaries/data/mods/public/gui/summary/summary.js
@@ -443,7 +443,7 @@
"charts": g_SelectedChart
};
if (g_GameData.gui.isInGame)
- Engine.PopGuiPageCB({
+ Engine.PopGuiPage({
"explicitResume": 0,
"summarySelectedData": summarySelectedData
});
Index: source/gui/CChart.cpp
===================================================================
--- source/gui/CChart.cpp
+++ source/gui/CChart.cpp
@@ -182,6 +182,9 @@
void CChart::UpdateSeries()
{
+ if (!GetGUI())
+ return;
+
CGUISeries* pSeries;
GUI::GetSettingPointer(this, "series", pSeries);
@@ -194,7 +197,7 @@
{
CChartData& data = m_Series[i];
- if (i < pSeriesColor->m_Items.size() && !GUI::ParseColor(pSeriesColor->m_Items[i].GetOriginalString(), data.m_Color, 0))
+ if (i < pSeriesColor->m_Items.size() && !GUI::ParseColor(GetGUI(), pSeriesColor->m_Items[i].GetOriginalString(), data.m_Color, 0))
LOGWARNING("GUI: Error parsing 'series_color' (\"%s\")", utf8_from_wstring(pSeriesColor->m_Items[i].GetOriginalString()));
data.m_Points = pSeries->m_Series[i];
Index: source/gui/CGUI.cpp
===================================================================
--- source/gui/CGUI.cpp
+++ source/gui/CGUI.cpp
@@ -288,10 +288,11 @@
m_ScriptInterface.reset(new ScriptInterface("Engine", "GUIPage", runtime));
m_ScriptInterface->SetCallbackData(this);
- GuiScriptingInit(*m_ScriptInterface);
- m_ScriptInterface->LoadGlobalScripts();
m_BaseObject = new CGUIDummyObject;
m_BaseObject->SetGUI(this);
+
+ GuiScriptingInit(*m_ScriptInterface);
+ m_ScriptInterface->LoadGlobalScripts();
}
CGUI::~CGUI()
@@ -361,7 +362,7 @@
// TODO: Clipping?
- Sprite.Draw(Rect, CellID, m_Sprites, Z);
+ Sprite.Draw(this, Rect, CellID, m_Sprites, Z);
}
void CGUI::Destroy()
@@ -989,6 +990,7 @@
// henceforth, we need to do a rollback before aborting.
// i.e. releasing this object
IGUIObject* object = ConstructObject(type);
+ object->SetGUI(this);
if (!object)
{
@@ -1138,8 +1140,6 @@
CStr action = CStr(child.GetAttributes().GetNamedItem(attr_on));
- // We need to set the GUI this object belongs to because RegisterScriptHandler requires an associated GUI.
- object->SetGUI(this);
object->RegisterScriptHandler(action.LowerCase(), code, this);
}
else if (element_name == elmt_repeat)
@@ -1444,7 +1444,7 @@
else if (attr_name == "size")
{
CClientArea ca;
- if (!GUI::ParseString(attr_value, ca))
+ if (!GUI::ParseString(this, attr_value, ca))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
else
Image->m_Size = ca;
@@ -1452,7 +1452,7 @@
else if (attr_name == "texture_size")
{
CClientArea ca;
- if (!GUI::ParseString(attr_value, ca))
+ if (!GUI::ParseString(this, attr_value, ca))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
else
Image->m_TextureSize = ca;
@@ -1460,7 +1460,7 @@
else if (attr_name == "real_texture_placement")
{
CRect rect;
- if (!GUI::ParseString(attr_value, rect))
+ if (!GUI::ParseString(this, attr_value, rect))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
else
Image->m_TexturePlacementInFile = rect;
@@ -1468,7 +1468,7 @@
else if (attr_name == "cell_size")
{
CSize size;
- if (!GUI::ParseString(attr_value, size))
+ if (!GUI::ParseString(this, attr_value, size))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
else
Image->m_CellSize = size;
@@ -1476,7 +1476,7 @@
else if (attr_name == "fixed_h_aspect_ratio")
{
float val;
- if (!GUI::ParseString(attr_value, val))
+ if (!GUI::ParseString(this, attr_value, val))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
else
Image->m_FixedHAspectRatio = val;
@@ -1484,7 +1484,7 @@
else if (attr_name == "round_coordinates")
{
bool b;
- if (!GUI::ParseString(attr_value, b))
+ if (!GUI::ParseString(this, attr_value, b))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
else
Image->m_RoundCoordinates = b;
@@ -1503,7 +1503,7 @@
else if (attr_name == "z_level")
{
float z_level;
- if (!GUI::ParseString(attr_value, z_level))
+ if (!GUI::ParseString(this, attr_value, z_level))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
else
Image->m_DeltaZ = z_level/100.f;
@@ -1511,7 +1511,7 @@
else if (attr_name == "backcolor")
{
CColor color;
- if (!GUI::ParseString(attr_value, color))
+ if (!GUI::ParseString(this, attr_value, color))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
else
Image->m_BackColor = color;
@@ -1519,7 +1519,7 @@
else if (attr_name == "bordercolor")
{
CColor color;
- if (!GUI::ParseString(attr_value, color))
+ if (!GUI::ParseString(this, attr_value, color))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
else
Image->m_BorderColor = color;
@@ -1527,7 +1527,7 @@
else if (attr_name == "border")
{
bool b;
- if (!GUI::ParseString(attr_value, b))
+ if (!GUI::ParseString(this, attr_value, b))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
else
Image->m_Border = b;
@@ -1567,7 +1567,7 @@
if (attr_name == "add_color")
{
CColor color;
- if (!GUI::ParseColor(attr_value, color, 0))
+ if (!GUI::ParseColor(this, attr_value, color, 0))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
else effects.m_AddColor = color;
}
@@ -1622,7 +1622,7 @@
else if (attr_name == "show_edge_buttons")
{
bool b;
- if (!GUI::ParseString(attr_value.FromUTF8(), b))
+ if (!GUI::ParseString(this, attr_value.FromUTF8(), b))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, attr_value);
else
scrollbar.m_UseEdgeButtons = b;
@@ -1630,7 +1630,7 @@
else if (attr_name == "width")
{
float f;
- if (!GUI::ParseString(attr_value.FromUTF8(), f))
+ if (!GUI::ParseString(this, attr_value.FromUTF8(), f))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, attr_value);
else
scrollbar.m_Width = f;
@@ -1638,7 +1638,7 @@
else if (attr_name == "minimum_bar_size")
{
float f;
- if (!GUI::ParseString(attr_value.FromUTF8(), f))
+ if (!GUI::ParseString(this, attr_value.FromUTF8(), f))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, attr_value);
else
scrollbar.m_MinimumBarSize = f;
@@ -1646,7 +1646,7 @@
else if (attr_name == "maximum_bar_size")
{
float f;
- if (!GUI::ParseString(attr_value.FromUTF8(), f))
+ if (!GUI::ParseString(this, attr_value.FromUTF8(), f))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, attr_value);
else
scrollbar.m_MaximumBarSize = f;
@@ -1700,7 +1700,7 @@
else if (attr_name == "size")
{
CSize size;
- if (!GUI::ParseString(attr_value.FromUTF8(), size))
+ if (!GUI::ParseString(this, attr_value.FromUTF8(), size))
LOGERROR("Error parsing '%s' (\"%s\") inside .", attr_name, attr_value);
else
icon.m_Size = size;
@@ -1708,7 +1708,7 @@
else if (attr_name == "cell_id")
{
int cell_id;
- if (!GUI::ParseString(attr_value.FromUTF8(), cell_id))
+ if (!GUI::ParseString(this, attr_value.FromUTF8(), cell_id))
LOGERROR("GUI: Error parsing '%s' (\"%s\") inside .", attr_name, attr_value);
else
icon.m_CellID = cell_id;
@@ -1722,7 +1722,9 @@
void CGUI::Xeromyces_ReadTooltip(XMBElement Element, CXeromyces* pFile)
{
- IGUIObject* object = new CTooltip;
+ // TODO: seems like this should know about the UI to begin with
+ IGUIObject* object = new CTooltip();
+ object->SetGUI(this);
for (XMBAttribute attr : Element.GetAttributes())
{
Index: source/gui/CGUISprite.h
===================================================================
--- source/gui/CGUISprite.h
+++ source/gui/CGUISprite.h
@@ -163,7 +163,7 @@
CGUISpriteInstance(const CGUISpriteInstance& Sprite);
CGUISpriteInstance& operator=(const CGUISpriteInstance&);
CGUISpriteInstance& operator=(const CStr& SpriteName);
- void Draw(CRect Size, int CellID, std::map& Sprites, float Z) const;
+ void Draw(const CGUI* guiPage, CRect Size, int CellID, std::map& Sprites, float Z) const;
void Invalidate();
bool IsEmpty() const;
const CStr& GetName() { return m_SpriteName; }
Index: source/gui/CGUISprite.cpp
===================================================================
--- source/gui/CGUISprite.cpp
+++ source/gui/CGUISprite.cpp
@@ -30,11 +30,11 @@
m_Images.push_back(image);
}
-void CGUISpriteInstance::Draw(CRect Size, int CellID, std::map& Sprites, float Z) const
+void CGUISpriteInstance::Draw(const CGUI* guiPage, CRect Size, int CellID, std::map& Sprites, float Z) const
{
if (m_CachedSize != Size || m_CachedCellID != CellID)
{
- GUIRenderer::UpdateDrawCallCache(m_DrawCallCache, m_SpriteName, Size, CellID, Sprites);
+ GUIRenderer::UpdateDrawCallCache(guiPage, m_DrawCallCache, m_SpriteName, Size, CellID, Sprites);
m_CachedSize = Size;
m_CachedCellID = CellID;
}
Index: source/gui/COList.cpp
===================================================================
--- source/gui/COList.cpp
+++ source/gui/COList.cpp
@@ -232,7 +232,7 @@
if (attr_name == "color")
{
CColor color;
- if (!GUI::ParseString(attr_value.FromUTF8(), color))
+ if (!GUI::ParseString(GetGUI(), attr_value.FromUTF8(), color))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str());
else
column.m_TextColor = color;
@@ -243,13 +243,13 @@
}
else if (attr_name == "hidden")
{
- if (!GUI::ParseString(attr_value.FromUTF8(), hidden))
+ if (!GUI::ParseString(GetGUI(),attr_value.FromUTF8(), hidden))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str());
}
else if (attr_name == "width")
{
float width;
- if (!GUI::ParseString(attr_value.FromUTF8(), width))
+ if (!GUI::ParseString(GetGUI(),attr_value.FromUTF8(), width))
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str());
else
{
Index: source/gui/GUIManager.h
===================================================================
--- source/gui/GUIManager.h
+++ source/gui/GUIManager.h
@@ -72,15 +72,15 @@
* Load a new GUI page and make it active. All current pages will be retained,
* and will still be drawn and receive tick events, but will not receive
* user inputs.
+ * If given, the callbackHandler function will be executed once this page is closed.
*/
- void PushPage(const CStrW& pageName, shared_ptr initData);
+ void PushPage(const CStrW& pageName, ScriptInterface* srcScriptInterface, shared_ptr initData, JS::HandleValue callbackFunction);
/**
* Unload the currently active GUI page, and make the previous page active.
* (There must be at least two pages when you call this.)
*/
- void PopPage();
- void PopPageCB(shared_ptr args);
+ void PopPage(shared_ptr args);
/**
* Called when a file has been modified, to hotload changes.
@@ -103,11 +103,6 @@
InReaction HandleEvent(const SDL_Event_* ev);
/**
- * See CGUI::GetPreDefinedColor; applies to the currently active page.
- */
- bool GetPreDefinedColor(const CStr& name, CColor& output) const;
-
- /**
* See CGUI::SendEventToAll; applies to the currently active page.
*/
void SendEventToAll(const CStr& eventName) const;
@@ -145,16 +140,22 @@
*/
const CParamNode& GetTemplate(const std::string& templateName);
-private:
- struct SGUIPage
+ class SGUIPage
{
+ public:
+ SGUIPage(const CStrW& pageName, const shared_ptr initData, shared_ptr scriptRuntime);
+ void LoadPage(shared_ptr scriptRuntime);
+
CStrW name;
boost::unordered_set inputs; // for hotloading
shared_ptr initData; // data to be passed to the init() function
shared_ptr gui; // the actual GUI page
+
+ // Function executed by the parent GUI page when this GUI page is closed
+ JS::PersistentRootedValue callbackFunction;
};
- void LoadPage(SGUIPage& page);
+private:
shared_ptr top() const;
Index: source/gui/GUIManager.cpp
===================================================================
--- source/gui/GUIManager.cpp
+++ source/gui/GUIManager.cpp
@@ -83,91 +83,87 @@
{
// The page stack is cleared (including the script context where initData came from),
// therefore we have to clone initData.
+
shared_ptr initDataClone;
if (!initData.isUndefined())
- {
initDataClone = srcScriptInterface->WriteStructuredClone(initData);
- }
+
m_PageStack.clear();
- PushPage(pageName, initDataClone);
+
+ PushPage(pageName, nullptr, initDataClone, JS::UndefinedHandleValue);
}
-void CGUIManager::PushPage(const CStrW& pageName, shared_ptr initData)
+void CGUIManager::PushPage(const CStrW& pageName, ScriptInterface* srcScriptInterface, shared_ptr initData, JS::HandleValue callbackFunction)
{
- m_PageStack.push_back(SGUIPage());
- m_PageStack.back().name = pageName;
- m_PageStack.back().initData = initData;
- LoadPage(m_PageStack.back());
+ if (!m_PageStack.empty() && callbackFunction.isObject())
+ {
+ JSContext* cxSrc = srcScriptInterface->GetContext();
+ JSAutoRequest rqSrc(cxSrc);
+ JS::RootedObject callbackObj(cxSrc, &callbackFunction.toObject());
+
+ if (JS_ObjectIsFunction(cxSrc, callbackObj))
+ {
+ m_PageStack.back().callbackFunction.reset();
+ m_PageStack.back().callbackFunction.init(srcScriptInterface->GetJSRuntime(), callbackFunction);
+ }
+ }
+
+ m_PageStack.emplace_back(SGUIPage(pageName, initData, m_ScriptRuntime));
ResetCursor();
}
-void CGUIManager::PopPage()
+void CGUIManager::PopPage(shared_ptr args)
{
if (m_PageStack.size() < 2)
{
- debug_warn(L"Tried to pop GUI page when there's < 2 in the stack");
+ LOGWARNING("Tried to pop GUI page when there's < 2 in the stack");
return;
}
m_PageStack.pop_back();
-}
-void CGUIManager::PopPageCB(shared_ptr args)
-{
- shared_ptr initDataClone = m_PageStack.back().initData;
- PopPage();
+ if (m_PageStack.back().callbackFunction.isUndefined())
+ return;
- shared_ptr scriptInterface = m_PageStack.back().gui->GetScriptInterface();
+ shared_ptr scriptInterface = top()->GetScriptInterface();
JSContext* cx = scriptInterface->GetContext();
JSAutoRequest rq(cx);
- JS::RootedValue initDataVal(cx);
- if (!initDataClone)
- {
- LOGERROR("Called PopPageCB when initData (which should contain the callback function name) isn't set!");
- return;
- }
-
- scriptInterface->ReadStructuredClone(initDataClone, &initDataVal);
-
- if (!scriptInterface->HasProperty(initDataVal, "callback"))
- {
- LOGERROR("Called PopPageCB when the callback function name isn't set!");
- return;
- }
-
- std::string callback;
- if (!scriptInterface->GetProperty(initDataVal, "callback", callback))
- {
- LOGERROR("Failed to get the callback property as a string from initData in PopPageCB!");
- return;
- }
-
JS::RootedValue global(cx, scriptInterface->GetGlobalObject());
- if (!scriptInterface->HasProperty(global, callback.c_str()))
- {
- LOGERROR("The specified callback function %s does not exist in the page %s", callback, utf8_from_wstring(m_PageStack.back().name));
- return;
- }
-
JS::RootedValue argVal(cx);
if (args)
scriptInterface->ReadStructuredClone(args, &argVal);
- if (!scriptInterface->CallFunctionVoid(global, callback.c_str(), argVal))
- {
- LOGERROR("Failed to call the callback function %s in the page %s", callback, utf8_from_wstring(m_PageStack.back().name));
- return;
- }
+
+ JS::RootedObject globalObj(cx, &global.toObject());
+ JS::RootedValue funcVal(cx, m_PageStack.back().callbackFunction);
+ m_PageStack.back().callbackFunction.reset();
+ m_PageStack.back().callbackFunction.init(m_ScriptRuntime->m_rt, JS::UndefinedValue());
+ JS::AutoValueVector paramData(cx);
+ paramData.append(argVal);
+ JS::RootedValue result(cx);
+ JS_CallFunctionValue(cx, globalObj, funcVal, paramData, &result);
}
-void CGUIManager::LoadPage(SGUIPage& page)
+CGUIManager::SGUIPage::SGUIPage(const CStrW& pageName, const shared_ptr initData, shared_ptr scriptRuntime)
+ : name(pageName), initData(initData), inputs(), gui(), callbackFunction()
+{
+ // TODO: Should this be moved to LoadPage?
+ callbackFunction.reset();
+ callbackFunction.init(scriptRuntime->m_rt, JS::UndefinedValue());
+
+ LoadPage(scriptRuntime);
+
+ callbackFunction.reset();
+}
+
+void CGUIManager::SGUIPage::LoadPage(shared_ptr scriptRuntime)
{
// If we're hotloading then try to grab some data from the previous page
shared_ptr hotloadData;
- if (page.gui)
+ if (gui)
{
- shared_ptr scriptInterface = page.gui->GetScriptInterface();
+ shared_ptr scriptInterface = gui->GetScriptInterface();
JSContext* cx = scriptInterface->GetContext();
JSAutoRequest rq(cx);
@@ -177,13 +173,13 @@
hotloadData = scriptInterface->WriteStructuredClone(hotloadDataVal);
}
- page.inputs.clear();
- page.gui.reset(new CGUI(m_ScriptRuntime));
+ inputs.clear();
+ gui.reset(new CGUI(scriptRuntime));
- page.gui->Initialize();
+ gui->Initialize();
- VfsPath path = VfsPath("gui") / page.name;
- page.inputs.insert(path);
+ VfsPath path = VfsPath("gui") / name;
+ inputs.insert(path);
CXeromyces xero;
if (xero.Load(g_VFS, path, "gui_page") != PSRETURN_OK)
@@ -197,7 +193,7 @@
if (root.GetNodeName() != elmt_page)
{
- LOGERROR("GUI page '%s' must have root element ", utf8_from_wstring(page.name));
+ LOGERROR("GUI page '%s' must have root element ", utf8_from_wstring(name));
return;
}
@@ -205,7 +201,7 @@
{
if (node.GetNodeName() != elmt_include)
{
- LOGERROR("GUI page '%s' must only have elements inside ", utf8_from_wstring(page.name));
+ LOGERROR("GUI page '%s' must only have elements inside ", utf8_from_wstring(name));
continue;
}
@@ -222,18 +218,18 @@
VfsPaths pathnames;
vfs::GetPathnames(g_VFS, directory, L"*.xml", pathnames);
for (const VfsPath& path : pathnames)
- page.gui->LoadXmlFile(path, page.inputs);
+ gui->LoadXmlFile(path, inputs);
}
else
{
VfsPath path = VfsPath("gui") / nameW;
- page.gui->LoadXmlFile(path, page.inputs);
+ gui->LoadXmlFile(path, inputs);
}
}
- page.gui->SendEventToAll("load");
+ gui->SendEventToAll("load");
- shared_ptr scriptInterface = page.gui->GetScriptInterface();
+ shared_ptr scriptInterface = gui->GetScriptInterface();
JSContext* cx = scriptInterface->GetContext();
JSAutoRequest rq(cx);
@@ -241,15 +237,15 @@
JS::RootedValue hotloadDataVal(cx);
JS::RootedValue global(cx, scriptInterface->GetGlobalObject());
- if (page.initData)
- scriptInterface->ReadStructuredClone(page.initData, &initDataVal);
+ if (initData)
+ scriptInterface->ReadStructuredClone(initData, &initDataVal);
if (hotloadData)
scriptInterface->ReadStructuredClone(hotloadData, &hotloadDataVal);
if (scriptInterface->HasProperty(global, "init") &&
!scriptInterface->CallFunctionVoid(global, "init", initDataVal, hotloadDataVal))
- LOGERROR("GUI page '%s': Failed to call init() function", utf8_from_wstring(page.name));
+ LOGERROR("GUI page '%s': Failed to call init() function", utf8_from_wstring(name));
}
Status CGUIManager::ReloadChangedFile(const VfsPath& path)
@@ -258,7 +254,7 @@
if (p.inputs.count(path))
{
LOGMESSAGE("GUI file '%s' changed - reloading page '%s'", path.string8(), utf8_from_wstring(p.name));
- LoadPage(p);
+ p.LoadPage(m_ScriptRuntime);
// TODO: this can crash if LoadPage runs an init script which modifies the page stack and breaks our iterators
}
@@ -269,7 +265,7 @@
{
// TODO: this can crash if LoadPage runs an init script which modifies the page stack and breaks our iterators
for (SGUIPage& p : m_PageStack)
- LoadPage(p);
+ p.LoadPage(m_ScriptRuntime);
return INFO::OK;
}
@@ -346,12 +342,6 @@
return IN_PASS;
}
-
-bool CGUIManager::GetPreDefinedColor(const CStr& name, CColor& output) const
-{
- return top()->GetPreDefinedColor(name, output);
-}
-
void CGUIManager::SendEventToAll(const CStr& eventName) const
{
top()->SendEventToAll(eventName);
Index: source/gui/GUIRenderer.h
===================================================================
--- source/gui/GUIRenderer.h
+++ source/gui/GUIRenderer.h
@@ -27,6 +27,7 @@
#include
+class CGUI;
struct SGUIImageEffects;
struct SGUIImage;
@@ -79,7 +80,7 @@
namespace GUIRenderer
{
- void UpdateDrawCallCache(DrawCalls& Calls, const CStr& SpriteName, const CRect& Size, int CellID, std::map& Sprites);
+ void UpdateDrawCallCache(const CGUI* guiPage, DrawCalls& Calls, const CStr& SpriteName, const CRect& Size, int CellID, std::map& Sprites);
void Draw(DrawCalls& Calls, float Z);
}
Index: source/gui/GUIRenderer.cpp
===================================================================
--- source/gui/GUIRenderer.cpp
+++ source/gui/GUIRenderer.cpp
@@ -57,7 +57,7 @@
}
-void GUIRenderer::UpdateDrawCallCache(DrawCalls& Calls, const CStr& SpriteName, const CRect& Size, int CellID, std::map& Sprites)
+void GUIRenderer::UpdateDrawCallCache(const CGUI* guiPage, DrawCalls& Calls, const CStr& SpriteName, const CRect& Size, int CellID, std::map& Sprites)
{
// This is called only when something has changed (like the size of the
// sprite), so it doesn't need to be particularly efficient.
@@ -142,7 +142,7 @@
CColor color;
// Check color is valid
- if (!GUI::ParseString(value, color))
+ if (!GUI::ParseString(guiPage, value, color))
{
LOGERROR("GUI: Error parsing sprite 'color' (\"%s\")", utf8_from_wstring(value));
return;
Index: source/gui/GUItext.cpp
===================================================================
--- source/gui/GUItext.cpp
+++ source/gui/GUItext.cpp
@@ -144,7 +144,7 @@
// Displace the sprite
CSize displacement;
// Parse the value
- if (!GUI::ParseString(tagAttrib.value, displacement))
+ if (!GUI::ParseString(pGUI, tagAttrib.value, displacement))
LOGERROR("Error parsing 'displace' value for tag [ICON]");
else
SpriteCall.m_Area += displacement;
@@ -190,7 +190,7 @@
case TextChunk::Tag::TAG_COLOR:
TextCall.m_UseCustomColor = true;
- if (!GUI::ParseString(tag.m_TagValue, TextCall.m_Color) && pObject)
+ if (!GUI::ParseString(pGUI, tag.m_TagValue, TextCall.m_Color) && pObject)
LOGERROR("Error parsing the value of a [color]-tag in GUI text when reading object \"%s\".", pObject->GetPresentableName().c_str());
break;
case TextChunk::Tag::TAG_FONT:
Index: source/gui/GUIutil.h
===================================================================
--- source/gui/GUIutil.h
+++ source/gui/GUIutil.h
@@ -42,7 +42,7 @@
class CMatrix3D;
template
-bool __ParseString(const CStrW& Value, T& tOutput);
+bool __ParseString(const CGUI* guiPage, const CStrW& Value, T& tOutput);
// Model-view-projection matrix with (0,0) in top-left of screen
CMatrix3D GetDefaultGuiMatrix();
@@ -209,12 +209,12 @@
*
* @see __ParseString()
*/
- static bool ParseString(const CStrW& Value, T& tOutput)
+ static bool ParseString(const CGUI* guiPage, const CStrW& Value, T& tOutput)
{
- return __ParseString(Value, tOutput);
+ return __ParseString(guiPage, Value, tOutput);
}
- static bool ParseColor(const CStrW& Value, CColor& tOutput, int DefaultAlpha);
+ static bool ParseColor(const CGUI* guiPage, const CStrW& Value, CColor& tOutput, int DefaultAlpha);
private:
Index: source/gui/GUIutil.cpp
===================================================================
--- source/gui/GUIutil.cpp
+++ source/gui/GUIutil.cpp
@@ -27,7 +27,7 @@
extern int g_xres, g_yres;
template <>
-bool __ParseString(const CStrW& Value, bool& Output)
+bool __ParseString(const CGUI* UNUSED(guiPage), const CStrW& Value, bool& Output)
{
if (Value == L"true")
Output = true;
@@ -40,28 +40,28 @@
}
template <>
-bool __ParseString(const CStrW& Value, int& Output)
+bool __ParseString(const CGUI* UNUSED(guiPage), const CStrW& Value, int& Output)
{
Output = Value.ToInt();
return true;
}
template <>
-bool __ParseString(const CStrW& Value, u32& Output)
+bool __ParseString(const CGUI* UNUSED(guiPage), const CStrW& Value, u32& Output)
{
Output = Value.ToUInt();
return true;
}
template <>
-bool __ParseString(const CStrW& Value, float& Output)
+bool __ParseString(const CGUI* UNUSED(guiPage), const CStrW& Value, float& Output)
{
Output = Value.ToFloat();
return true;
}
template <>
-bool __ParseString(const CStrW& Value, CRect& Output)
+bool __ParseString(const CGUI* UNUSED(guiPage), const CStrW& Value, CRect& Output)
{
const unsigned int NUM_COORDS = 4;
float coords[NUM_COORDS];
@@ -96,18 +96,20 @@
}
template <>
-bool __ParseString(const CStrW& Value, CClientArea& Output)
+bool __ParseString(const CGUI* UNUSED(guiPage), const CStrW& Value, CClientArea& Output)
{
return Output.SetClientArea(Value.ToUTF8());
}
template <>
-bool GUI::ParseColor(const CStrW& Value, CColor& Output, int DefaultAlpha)
+bool GUI::ParseColor(const CGUI* guiPage, const CStrW& Value, CColor& Output, int DefaultAlpha)
{
+ ENSURE(guiPage);
+
// First, check our database in g_GUI for pre-defined colors
// If we find anything, we'll ignore DefaultAlpha
// If it fails, it won't do anything with Output
- if (g_GUI->GetPreDefinedColor(Value.ToUTF8(), Output))
+ if (guiPage && guiPage->GetPreDefinedColor(Value.ToUTF8(), Output))
return true;
return Output.ParseString(Value.ToUTF8(), DefaultAlpha);
@@ -115,18 +117,20 @@
template <>
-bool __ParseString(const CStrW& Value, CColor& Output)
+bool __ParseString(const CGUI* guiPage, const CStrW& Value, CColor& Output)
{
- // First, check our database in g_GUI for pre-defined colors
+ ENSURE(guiPage);
+
+ // First, check our database in guiPage for pre-defined colors
// If it fails, it won't do anything with Output
- if (g_GUI->GetPreDefinedColor(Value.ToUTF8(), Output))
+ if (guiPage->GetPreDefinedColor(Value.ToUTF8(), Output))
return true;
return Output.ParseString(Value.ToUTF8());
}
template <>
-bool __ParseString(const CStrW& Value, CSize& Output)
+bool __ParseString(const CGUI* UNUSED(guiPage), const CStrW& Value, CSize& Output)
{
const unsigned int NUM_COORDS = 2;
float coords[NUM_COORDS];
@@ -161,7 +165,7 @@
}
template <>
-bool __ParseString(const CStrW& Value, CPos& Output)
+bool __ParseString(const CGUI* UNUSED(guiPage), const CStrW& Value, CPos& Output)
{
const unsigned int NUM_COORDS = 2;
float coords[NUM_COORDS];
@@ -196,7 +200,7 @@
}
template <>
-bool __ParseString(const CStrW& Value, EAlign& Output)
+bool __ParseString(const CGUI* UNUSED(guiPage), const CStrW& Value, EAlign& Output)
{
if (Value == L"left")
Output = EAlign_Left;
@@ -211,7 +215,7 @@
}
template <>
-bool __ParseString(const CStrW& Value, EVAlign& Output)
+bool __ParseString(const CGUI* UNUSED(guiPage), const CStrW& Value, EVAlign& Output)
{
if (Value == L"top")
Output = EVAlign_Top;
@@ -226,14 +230,14 @@
}
template <>
-bool __ParseString(const CStrW& Value, CGUIString& Output)
+bool __ParseString(const CGUI* UNUSED(guiPage), const CStrW& Value, CGUIString& Output)
{
Output.SetValue(Value);
return true;
}
template <>
-bool __ParseString(const CStrW& Value, CStr& Output)
+bool __ParseString(const CGUI* UNUSED(guiPage), const CStrW& Value, CStr& Output)
{
// Do very little.
Output = Value.ToUTF8();
@@ -241,27 +245,27 @@
}
template <>
-bool __ParseString(const CStrW& Value, CStrW& Output)
+bool __ParseString(const CGUI* UNUSED(guiPage), const CStrW& Value, CStrW& Output)
{
Output = Value;
return true;
}
template <>
-bool __ParseString(const CStrW& Value, CGUISpriteInstance& Output)
+bool __ParseString(const CGUI* UNUSED(guiPage), const CStrW& Value, CGUISpriteInstance& Output)
{
Output = CGUISpriteInstance(Value.ToUTF8());
return true;
}
template <>
-bool __ParseString(const CStrW& UNUSED(Value), CGUIList& UNUSED(Output))
+bool __ParseString(const CGUI* UNUSED(guiPage), const CStrW& UNUSED(Value), CGUIList& UNUSED(Output))
{
return false;
}
template <>
-bool __ParseString(const CStrW& UNUSED(Value), CGUISeries& UNUSED(Output))
+bool __ParseString(const CGUI* UNUSED(guiPage), const CStrW& UNUSED(Value), CGUISeries& UNUSED(Output))
{
return false;
}
Index: source/gui/IGUIObject.cpp
===================================================================
--- source/gui/IGUIObject.cpp
+++ source/gui/IGUIObject.cpp
@@ -229,7 +229,7 @@
else if (set.m_Type == GUIST_##type) \
{ \
type _Value; \
- if (!GUI::ParseString(Value, _Value)) \
+ if (!GUI::ParseString(GetGUI(), Value, _Value)) \
return PSRETURN_GUI_UnableToParse; \
GUI::SetSetting(this, Setting, _Value, SkipMessage); \
}
Index: source/gui/scripting/JSInterface_GUIManager.h
===================================================================
--- source/gui/scripting/JSInterface_GUIManager.h
+++ source/gui/scripting/JSInterface_GUIManager.h
@@ -23,10 +23,9 @@
namespace JSI_GUIManager
{
- void PushGuiPage(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name, JS::HandleValue initData);
+ void PushGuiPage(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name, JS::HandleValue initData, JS::HandleValue callbackFunction);
void SwitchGuiPage(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name, JS::HandleValue initData);
- void PopGuiPage(ScriptInterface::CxPrivate* pCxPrivate);
- void PopGuiPageCB(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue args);
+ void PopGuiPage(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue args);
JS::Value GetGUIObjectByName(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name);
std::wstring SetCursor(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name);
void ResetCursor(ScriptInterface::CxPrivate* pCxPrivate);
Index: source/gui/scripting/JSInterface_GUIManager.cpp
===================================================================
--- source/gui/scripting/JSInterface_GUIManager.cpp
+++ source/gui/scripting/JSInterface_GUIManager.cpp
@@ -25,11 +25,9 @@
#include "ps/GameSetup/Config.h"
#include "scriptinterface/ScriptInterface.h"
-// Note that the initData argument may only contain clonable data.
-// Functions aren't supported for example!
-void JSI_GUIManager::PushGuiPage(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name, JS::HandleValue initData)
+void JSI_GUIManager::PushGuiPage(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name, JS::HandleValue initData, JS::HandleValue callbackFunction)
{
- g_GUI->PushPage(name, pCxPrivate->pScriptInterface->WriteStructuredClone(initData));
+ g_GUI->PushPage(name, pCxPrivate->pScriptInterface, pCxPrivate->pScriptInterface->WriteStructuredClone(initData), callbackFunction);
}
void JSI_GUIManager::SwitchGuiPage(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name, JS::HandleValue initData)
@@ -37,14 +35,9 @@
g_GUI->SwitchPage(name, pCxPrivate->pScriptInterface, initData);
}
-void JSI_GUIManager::PopGuiPage(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
+void JSI_GUIManager::PopGuiPage(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue args)
{
- g_GUI->PopPage();
-}
-
-void JSI_GUIManager::PopGuiPageCB(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue args)
-{
- g_GUI->PopPageCB(pCxPrivate->pScriptInterface->WriteStructuredClone(args));
+ g_GUI->PopPage(pCxPrivate->pScriptInterface->WriteStructuredClone(args));
}
JS::Value JSI_GUIManager::GetGUIObjectByName(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name)
@@ -82,10 +75,9 @@
void JSI_GUIManager::RegisterScriptFunctions(const ScriptInterface& scriptInterface)
{
- scriptInterface.RegisterFunction("PushGuiPage");
+ scriptInterface.RegisterFunction("PushGuiPage");
scriptInterface.RegisterFunction("SwitchGuiPage");
- scriptInterface.RegisterFunction("PopGuiPage");
- scriptInterface.RegisterFunction("PopGuiPageCB");
+ scriptInterface.RegisterFunction("PopGuiPage");
scriptInterface.RegisterFunction("GetGUIObjectByName");
scriptInterface.RegisterFunction("SetCursor");
scriptInterface.RegisterFunction("ResetCursor");
Index: source/gui/tests/test_ParseString.h
===================================================================
--- source/gui/tests/test_ParseString.h
+++ source/gui/tests/test_ParseString.h
@@ -68,12 +68,12 @@
TestLogger nolog;
CRect test;
- TS_ASSERT(__ParseString(CStrW(L"0.0 10.0 20.0 30.0"), test));
+ TS_ASSERT(__ParseString(nullptr, CStrW(L"0.0 10.0 20.0 30.0"), test));
TS_ASSERT_EQUALS(CRect(0.0, 10.0, 20.0, 30.0), test);
- TS_ASSERT(!__ParseString(CStrW(L"0 10 20"), test));
- TS_ASSERT(!__ParseString(CStrW(L"0 10 20 30 40"), test));
- TS_ASSERT(!__ParseString(CStrW(L"0,0 10,0 20,0 30,0"), test));
+ TS_ASSERT(!__ParseString(nullptr, CStrW(L"0 10 20"), test));
+ TS_ASSERT(!__ParseString(nullptr, CStrW(L"0 10 20 30 40"), test));
+ TS_ASSERT(!__ParseString(nullptr, CStrW(L"0,0 10,0 20,0 30,0"), test));
}
void test_size()
@@ -81,12 +81,12 @@
TestLogger nolog;
CSize test;
- TS_ASSERT(__ParseString(CStrW(L"0.0 10.0"), test));
+ TS_ASSERT(__ParseString(nullptr, CStrW(L"0.0 10.0"), test));
TS_ASSERT_EQUALS(CSize(0.0, 10.0), test);
- TS_ASSERT(!__ParseString(CStrW(L"0"), test));
- TS_ASSERT(!__ParseString(CStrW(L"0 10 20"), test));
- TS_ASSERT(!__ParseString(CStrW(L"0,0 10,0"), test));
+ TS_ASSERT(!__ParseString(nullptr, CStrW(L"0"), test));
+ TS_ASSERT(!__ParseString(nullptr, CStrW(L"0 10 20"), test));
+ TS_ASSERT(!__ParseString(nullptr, CStrW(L"0,0 10,0"), test));
}
void test_pos()
@@ -94,11 +94,11 @@
TestLogger nolog;
CPos test;
- TS_ASSERT(__ParseString(CStrW(L"0.0 10.0"), test));
+ TS_ASSERT(__ParseString(nullptr, CStrW(L"0.0 10.0"), test));
TS_ASSERT_EQUALS(CPos(0.0, 10.0), test);
- TS_ASSERT(!__ParseString(CStrW(L"0"), test));
- TS_ASSERT(!__ParseString(CStrW(L"0 10 20"), test));
- TS_ASSERT(!__ParseString(CStrW(L"0,0 10,0"), test));
+ TS_ASSERT(!__ParseString(nullptr, CStrW(L"0"), test));
+ TS_ASSERT(!__ParseString(nullptr, CStrW(L"0 10 20"), test));
+ TS_ASSERT(!__ParseString(nullptr, CStrW(L"0,0 10,0"), test));
}
};