0ad/binaries/data/mods/public/gui/campaigns/load_modal/LoadModal.js
guerringuerrin 32e5520507
Some checks failed
checkrefs / lfscheck (push) Has been cancelled
checkrefs / checkrefs (push) Has been cancelled
lint / cppcheck (push) Has been cancelled
lint / copyright (push) Has been cancelled
lint / jenkinsfiles (push) Has been cancelled
pre-commit / build (push) Has been cancelled
Add hotkeys for opening GUI pages across the game
Add registerGlobalGuiPageHotkeys() to
common/functions_utility.js to selectively register
GUI page hotkeys
Allow active GUI pages to close using their corresponding hotkey
Move page_hotkeys.xml from gui/hotkeys/ to gui/
Update page_hotkeys.xml references in MainMenuItems and MenuButtons
Add default tipScrolling fallback in TipsPage when no initData is provided
2026-05-16 20:53:54 +02:00

148 lines
3.9 KiB
JavaScript

/**
* Mimics CampaignRun's necessary interface, but for a broken run
* (i.e. a run that can't be loaded), thus allowing to delete it.
*/
class BrokenRun
{
constructor(file)
{
this.filename = file;
}
getLabel(forList)
{
if (!forList)
return this.filename + ".0adcampaign";
return coloredText(sprintf("%(filename)s (%(error)s)", {
"filename": this.filename + ".0adcampaign",
"error": translate("file cannot be loaded")
}), "red");
}
destroy()
{
Engine.DeleteCampaignSave("saves/campaigns/" + this.filename + ".0adcampaign");
if (CampaignRun.getCurrentRunFilename() === this.filename)
CampaignRun.clearCurrentRun();
}
}
/**
* Lets you load/delete/look at existing campaign runs in your user folder.
*/
class LoadModal extends AutoWatcher
{
constructor(closePageCallback)
{
super("render");
// _watch so render() is called anytime currentRuns are modified.
this.currentRuns = _watch(this.getRuns(), () => this.render());
Engine.GetGUIObjectByName('cancelButton').onPress = closePageCallback.bind(undefined, {
[Engine.openRequest]: { "page": "page_pregame.xml" }
});
Engine.GetGUIObjectByName('deleteGameButton').onPress = () => this.deleteSelectedRun();
Engine.GetGUIObjectByName('startButton').onPress = () => this.startSelectedRun();
this.noCampaignsText = Engine.GetGUIObjectByName("noCampaignsText");
this.selectedRun = -1;
this.runSelection = Engine.GetGUIObjectByName("runSelection");
this.runSelection.onSelectionChange = () =>
{
this.selectedRun = this.runSelection.selected;
if (this.selectedRun === -1)
Engine.GetGUIObjectByName('runDescription').caption = "";
else
Engine.GetGUIObjectByName('runDescription').caption = this.currentRuns[this.selectedRun].getLabel();
};
this.runSelection.onMouseLeftDoubleClickItem = () => this.startSelectedRun();
this._ready = true;
}
getRuns()
{
const out = [];
const files = Engine.ListDirectoryFiles("saves/campaigns/", "*.0adcampaign", false);
for (const file of files)
{
const name = file.replace("saves/campaigns/", "").replace(".0adcampaign", "");
try
{
out.push(new CampaignRun(name).load());
}
catch(err)
{
warn(err.toString());
out.push(new BrokenRun(name));
}
}
return out;
}
loadCampaign(closePageCallback)
{
const filename = this.currentRuns[this.selectedRun].filename;
const run = new CampaignRun(filename)
.load()
.setCurrent();
closePageCallback({ [Engine.openRequest]: {
"page": run.getMenuPath(),
"argument": {
"filename": run.filename
}
} });
}
async deleteSelectedRun()
{
if (this.selectedRun === -1)
return;
const run = this.currentRuns[this.selectedRun];
const buttonIndex = await messageBox(
400, 200,
sprintf(translate("Are you sure you want to delete run %s? This cannot be undone."), run.getLabel()),
translate("Confirmation"),
[translate("No"), translate("Yes")]);
if (buttonIndex === 0)
return;
run.destroy();
this.currentRuns.splice(this.selectedRun, 1);
this.selectedRun = -1;
}
startSelectedRun(closePageCallback)
{
if (this.currentRuns[this.selectedRun] instanceof CampaignRun)
this.loadCampaign(closePageCallback);
}
displayCurrentRuns()
{
this.runSelection.list = this.currentRuns.map(run => run.getLabel(true));
this.runSelection.list_data = this.currentRuns.map(run => run.filename);
}
render()
{
this.noCampaignsText.hidden = !!this.currentRuns.length;
Engine.GetGUIObjectByName('deleteGameButton').enabled = this.selectedRun !== -1;
Engine.GetGUIObjectByName('startButton').enabled = this.selectedRun !== -1 && this.currentRuns[this.selectedRun] instanceof CampaignRun;
this.displayCurrentRuns();
}
}
var g_LoadModal;
function init()
{
registerGlobalGuiPageHotkeys(["options", "hotkeys", "civinfo", "structree", "catafalque", "mapbrowser", "manual", "tips"]);
return new Promise(closePageCallback => { g_LoadModal = new LoadModal(closePageCallback); });
}