Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/mod/gui/common/functions_msgbox.js
// 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. | |||||
elexis: The function is created an executed in the same GUI page, so it's actually not passed around. | |||||
// 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) | function messageBox(mbWidth, mbHeight, mbMessage, mbTitle, mbButtonCaptions, mbBtnCode, mbCallbackArgs) | ||||
{ | { | ||||
if (g_MessageBoxBtnFunctions && g_MessageBoxBtnFunctions.length) | Engine.PushGuiPage( | ||||
"page_msgbox.xml", | |||||
{ | { | ||||
warn("A messagebox was called when a previous callback function is still set, aborting!"); | |||||
Done Inline ActionsWith the proposed code one can stack messageboxes from the same page and have the correct callback handler called:
Whereas the previous code opened one message box and complained 4 times. elexis: With the proposed code one can stack messageboxes from the same page and have the correct… | |||||
return; | |||||
} | |||||
g_MessageBoxBtnFunctions = mbBtnCode; | |||||
g_MessageBoxCallbackArgs = mbCallbackArgs || g_MessageBoxCallbackArgs; | |||||
Engine.PushGuiPage("page_msgbox.xml", { | |||||
"width": mbWidth, | "width": mbWidth, | ||||
"height": mbHeight, | "height": mbHeight, | ||||
"message": mbMessage, | "message": mbMessage, | ||||
"title": mbTitle, | "title": mbTitle, | ||||
"buttonCaptions": mbButtonCaptions, | "buttonCaptions": mbButtonCaptions | ||||
"callback": mbBtnCode && "messageBoxCallbackFunction" | }, | ||||
btnCode => { | |||||
if (mbBtnCode !== undefined && mbBtnCode[btnCode]) | |||||
mbBtnCode[btnCode](mbCallbackArgs ? mbCallbackArgs[btnCode] : undefined); | |||||
}); | }); | ||||
} | } | ||||
function openURL(url) | function openURL(url) | ||||
{ | { | ||||
Engine.OpenURL(url); | Engine.OpenURL(url); | ||||
messageBox( | messageBox( | ||||
600, 200, | 600, 200, | ||||
sprintf( | sprintf( | ||||
translate("Opening %(url)s\n in default web browser. Please wait…"), | translate("Opening %(url)s\n in default web browser. Please wait…"), | ||||
{ "url": url } | { "url": url } | ||||
), | ), | ||||
translate("Opening page")); | translate("Opening page")); | ||||
} | } |
Wildfire Games · Phabricator
The function is created an executed in the same GUI page, so it's actually not passed around.
Passing functions around isn't paintful currently (sm38, sm45). It doesn't work with the Structured-Clone algorithm, but the JS::HandleValue, JS::PersistentRooted, JS::Heap types can hold a variable rooted only in the runtime, not the context. We will see if that changes for future SM versions, but I expect SM won't lose functionality.