Unify loadgame and savegame dialog following e0ea53a8ee
, refs #2030.
This way the save dialog gains the sortable list and details section feature from10b49f9c18
/ D246 by removing a folder of code, refs #4413. Fixes a style warning about the old dialog using a style for an 'olist' type for a 'list' type, refsbe963ec9b7
/ D2232. Subsequently move the gui/common/ helper file to the page code, meaning it's not loaded for every GUI page needlessly anymore. Fix map preview aspect ratio. Use object-oriented code for the moved savegame code, refs #5387, but conserve the rest of the code to limit the changes for auditability. Differential Revision: https://code.wildfiregames.com/D2290 Tested on: Jenkins This was SVN commit r22923.
This commit is contained in:
parent
003d588d13
commit
bdc6a7d3fd
52
binaries/data/mods/public/gui/loadgame/SavegameWriter.js
Normal file
52
binaries/data/mods/public/gui/loadgame/SavegameWriter.js
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* This class obtains the current simulation state to be saved along the savegame,
|
||||
* asks the user whether to overwrite a savegame and performs the saving.
|
||||
*/
|
||||
class SavegameWriter
|
||||
{
|
||||
constructor(data)
|
||||
{
|
||||
this.savedGameData = data && data.savedGameData || {};
|
||||
let simulationState = Engine.GuiInterfaceCall("GetSimulationState");
|
||||
this.savedGameData.timeElapsed = simulationState.timeElapsed;
|
||||
this.savedGameData.states = simulationState.players.map(pState => pState.state);
|
||||
}
|
||||
|
||||
getSavedGameData()
|
||||
{
|
||||
return this.savedGameData;
|
||||
}
|
||||
|
||||
saveGame()
|
||||
{
|
||||
let gameSelection = Engine.GetGUIObjectByName("gameSelection");
|
||||
let gameLabel = gameSelection.list[gameSelection.selected];
|
||||
let gameID = gameSelection.list_data[gameSelection.selected];
|
||||
let desc = Engine.GetGUIObjectByName("saveGameDesc").caption;
|
||||
let name = gameID || "savegame";
|
||||
|
||||
if (!gameID)
|
||||
{
|
||||
this.reallySaveGame(name, desc, true);
|
||||
return;
|
||||
}
|
||||
|
||||
messageBox(
|
||||
500, 200,
|
||||
sprintf(translate("\"%(label)s\""), { "label": gameLabel }) + "\n" +
|
||||
translate("Saved game will be permanently overwritten, are you sure?"),
|
||||
translate("OVERWRITE SAVE"),
|
||||
[translate("No"), translate("Yes")],
|
||||
[null, () => { this.reallySaveGame(name, desc, false); }]);
|
||||
}
|
||||
|
||||
reallySaveGame(name, desc, nameIsPrefix)
|
||||
{
|
||||
if (nameIsPrefix)
|
||||
Engine.SaveGamePrefix(name, desc, this.savedGameData);
|
||||
else
|
||||
Engine.SaveGame(name, desc, this.savedGameData);
|
||||
|
||||
Engine.PopGuiPage();
|
||||
}
|
||||
}
|
@ -64,8 +64,7 @@ function reallyDeleteGame(gameID)
|
||||
if (!Engine.DeleteSavedGame(gameID))
|
||||
error("Could not delete saved game: " + gameID);
|
||||
|
||||
// Run init again to refresh saved game list
|
||||
init();
|
||||
updateSavegameList();
|
||||
}
|
||||
|
||||
function deleteTooltip()
|
@ -1,3 +1,5 @@
|
||||
var g_SavegameWriter;
|
||||
|
||||
var g_SavedGamesMetadata = [];
|
||||
|
||||
/**
|
||||
@ -5,7 +7,29 @@ var g_SavedGamesMetadata = [];
|
||||
*/
|
||||
const g_CivData = loadCivData(false, false);
|
||||
|
||||
function init()
|
||||
function init(data)
|
||||
{
|
||||
let save = Engine.IsGameStarted();
|
||||
if (save)
|
||||
g_SavegameWriter = new SavegameWriter(data);
|
||||
|
||||
let confirmButton = Engine.GetGUIObjectByName("confirmButton");
|
||||
confirmButton.caption = save ? translate("Save") : translate("Load");
|
||||
confirmButton.onPress = save ? () => { g_SavegameWriter.saveGame(); } : loadGame;
|
||||
Engine.GetGUIObjectByName("title").caption = save ? translate("Save Game") : translate("Load Game")
|
||||
Engine.GetGUIObjectByName("saveGameDesc").hidden = !save;
|
||||
|
||||
updateSavegameList();
|
||||
|
||||
// Select the most recent savegame to be loaded, or no savegame to be overwritten
|
||||
let gameSelection = Engine.GetGUIObjectByName("gameSelection");
|
||||
if (!save && gameSelection.list.length)
|
||||
gameSelection.selected = 0;
|
||||
else
|
||||
selectionChanged();
|
||||
}
|
||||
|
||||
function updateSavegameList()
|
||||
{
|
||||
let savedGames = Engine.GetSavedGames();
|
||||
|
||||
@ -17,6 +41,10 @@ function init()
|
||||
|
||||
let gameSelection = Engine.GetGUIObjectByName("gameSelection");
|
||||
gameSelection.enabled = !!savedGames.length;
|
||||
gameSelection.onSelectionChange = selectionChanged;
|
||||
gameSelection.onSelectionColumnChange = updateSavegameList;
|
||||
gameSelection.onMouseLeftDoubleClickItem = loadGame;
|
||||
|
||||
Engine.GetGUIObjectByName("gameSelectionFeedback").hidden = !!savedGames.length;
|
||||
|
||||
let selectedGameId = gameSelection.list_data[gameSelection.selected];
|
||||
@ -87,9 +115,6 @@ function init()
|
||||
gameSelection.selected = selectedGameIndex;
|
||||
else if (gameSelection.selected >= g_SavedGamesMetadata.length) // happens when deleting the last saved game
|
||||
gameSelection.selected = g_SavedGamesMetadata.length - 1;
|
||||
else if (gameSelection.selected == -1 && g_SavedGamesMetadata.length)
|
||||
gameSelection.selected = 0;
|
||||
selectionChanged();
|
||||
|
||||
Engine.GetGUIObjectByName("deleteGameButton").tooltip = deleteTooltip();
|
||||
}
|
||||
@ -99,7 +124,7 @@ function selectionChanged()
|
||||
let metadata = g_SavedGamesMetadata[Engine.GetGUIObjectByName("gameSelection").selected];
|
||||
Engine.GetGUIObjectByName("invalidGame").hidden = !!metadata;
|
||||
Engine.GetGUIObjectByName("validGame").hidden = !metadata;
|
||||
Engine.GetGUIObjectByName("loadGameButton").enabled = !!metadata;
|
||||
Engine.GetGUIObjectByName("confirmButton").enabled = !!metadata || Engine.IsGameStarted();
|
||||
Engine.GetGUIObjectByName("deleteGameButton").enabled = !!metadata;
|
||||
|
||||
if (!metadata)
|
||||
@ -170,8 +195,7 @@ function loadGame()
|
||||
message,
|
||||
translate("Warning"),
|
||||
[translate("No"), translate("Yes")],
|
||||
[init, function(){ reallyLoadGame(gameId); }]
|
||||
);
|
||||
[undefined, () => { reallyLoadGame(gameId); }]);
|
||||
}
|
||||
|
||||
function reallyLoadGame(gameId)
|
||||
@ -179,10 +203,7 @@ function reallyLoadGame(gameId)
|
||||
let metadata = Engine.StartSavedGame(gameId);
|
||||
if (!metadata)
|
||||
{
|
||||
// Probably the file wasn't found
|
||||
// Show error and refresh saved game list
|
||||
error("Could not load saved game: " + gameId);
|
||||
init();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -10,9 +10,7 @@
|
||||
|
||||
<object type="image" style="ModernDialog" size="50%-460 50%-325 50%+460 50%+325">
|
||||
|
||||
<object type="text" style="TitleText" size="50%-128 -18 50%+128 14">
|
||||
<translatableAttribute id="caption">Load Game</translatableAttribute>
|
||||
</object>
|
||||
<object name="title" type="text" style="TitleText" size="50%-128 -18 50%+128 14"/>
|
||||
|
||||
<object type="image" size="0 20 630 100%">
|
||||
<object name="gameSelection"
|
||||
@ -24,10 +22,6 @@
|
||||
type="olist"
|
||||
auto_scroll="true"
|
||||
>
|
||||
<action on="SelectionChange">selectionChanged();</action>
|
||||
<action on="SelectionColumnChange">init();</action>
|
||||
<action on="MouseLeftDoubleClickItem">loadGame();</action>
|
||||
|
||||
<column id="date" color="255 255 255" width="25%">
|
||||
<translatableAttribute id="heading" context="replay">Date / Time</translatableAttribute>
|
||||
</column>
|
||||
@ -49,6 +43,10 @@
|
||||
<translatableAttribute id="caption">No saved games found.</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="saveGameDesc" size="24 100%-96 100%-24 100%-72" type="input" style="ModernInput">
|
||||
<action on="Press">saveGame();</action>
|
||||
</object>
|
||||
|
||||
<object type="button" size="0%+25 100%-60 33%+10 100%-32" style="StoneButton" hotkey="cancel">
|
||||
<translatableAttribute id="caption">Cancel</translatableAttribute>
|
||||
<action on="Press">Engine.PopGuiPage();</action>
|
||||
@ -59,16 +57,12 @@
|
||||
<action on="Press">deleteGame();</action>
|
||||
</object>
|
||||
|
||||
<object name="loadGameButton" type="button" style="StoneButton" size="66%-5 100%-60 100%-25 100%-32">
|
||||
<translatableAttribute id="caption">Load</translatableAttribute>
|
||||
<action on="Press">loadGame();</action>
|
||||
</object>
|
||||
|
||||
<object name="confirmButton" type="button" style="StoneButton" size="66%-5 100%-60 100%-25 100%-32"/>
|
||||
</object>
|
||||
|
||||
<object name="filterPanel" size="630 25 100%-20 60">
|
||||
<object name="compatibilityFilter" type="checkbox" checked="true" style="ModernTickBox" size="0 0 20 20">
|
||||
<action on="Press">init();</action>
|
||||
<action on="Press">updateSavegameList();</action>
|
||||
</object>
|
||||
|
||||
<object type="text" size="25 0 100% 100%" text_align="left" textcolor="white">
|
||||
@ -79,7 +73,7 @@
|
||||
<object name="validGame" type="image" size="630 60 100%-20 100%">
|
||||
<object size="0 0 100%-15 1" type="image" sprite="ModernWhiteLine" z="25" />
|
||||
<object name="savedMapName" size="0 0 100% 20" type="text" style="ModernLabelText" />
|
||||
<object name="savedInfoPreview" size="20 20 240 240" type="image" sprite="" />
|
||||
<object name="savedInfoPreview" size="0 30 260 218" type="image" />
|
||||
|
||||
<object size="0 250 50% 270" type="text" style="ModernLeftLabelText">
|
||||
<translatableAttribute id="caption">Players:</translatableAttribute>
|
||||
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<page>
|
||||
<include>common/modern/setup.xml</include>
|
||||
<include>common/modern/styles.xml</include>
|
||||
<include>common/modern/sprites.xml</include>
|
||||
|
||||
<include>common/setup.xml</include>
|
||||
<include>common/sprites.xml</include>
|
||||
<include>common/styles.xml</include>
|
||||
|
||||
<include>savegame/save.xml</include>
|
||||
</page>
|
@ -1,84 +0,0 @@
|
||||
var g_Descriptions;
|
||||
var g_SavedGameData;
|
||||
|
||||
function selectDescription()
|
||||
{
|
||||
let gameSelection = Engine.GetGUIObjectByName("gameSelection");
|
||||
let gameID = gameSelection.list_data[gameSelection.selected];
|
||||
Engine.GetGUIObjectByName("deleteGameButton").enabled = !!gameID;
|
||||
|
||||
if (!gameID)
|
||||
return;
|
||||
|
||||
Engine.GetGUIObjectByName("saveGameDesc").caption = g_Descriptions[gameID];
|
||||
}
|
||||
|
||||
function init(data)
|
||||
{
|
||||
g_SavedGameData = data && data.savedGameData || {};
|
||||
let simulationState = Engine.GuiInterfaceCall("GetSimulationState");
|
||||
g_SavedGameData.timeElapsed = simulationState.timeElapsed;
|
||||
g_SavedGameData.states = simulationState.players.map(pState => pState.state);
|
||||
|
||||
let savedGames = Engine.GetSavedGames().sort(sortDecreasingDate);
|
||||
|
||||
let gameSelection = Engine.GetGUIObjectByName("gameSelection");
|
||||
gameSelection.enabled = savedGames.length != 0;
|
||||
|
||||
if (!savedGames.length)
|
||||
{
|
||||
gameSelection.list = [translate("No saved games found")];
|
||||
gameSelection.selected = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
g_Descriptions = {};
|
||||
for (let game of savedGames)
|
||||
g_Descriptions[game.id] = game.metadata.description || "";
|
||||
|
||||
let engineInfo = Engine.GetEngineInfo();
|
||||
gameSelection.list = savedGames.map(game => generateSavegameLabel(game.metadata, engineInfo));
|
||||
gameSelection.list_data = savedGames.map(game => game.id);
|
||||
gameSelection.selected = Math.min(gameSelection.selected, gameSelection.list.length - 1);
|
||||
|
||||
Engine.GetGUIObjectByName("deleteGameButton").tooltip = deleteTooltip();
|
||||
}
|
||||
|
||||
function saveGame()
|
||||
{
|
||||
let gameSelection = Engine.GetGUIObjectByName("gameSelection");
|
||||
let gameLabel = gameSelection.list[gameSelection.selected];
|
||||
let gameID = gameSelection.list_data[gameSelection.selected];
|
||||
let desc = Engine.GetGUIObjectByName("saveGameDesc").caption;
|
||||
let name = gameID || "savegame";
|
||||
|
||||
if (!gameID)
|
||||
{
|
||||
reallySaveGame(name, desc, true);
|
||||
return;
|
||||
}
|
||||
|
||||
messageBox(
|
||||
500, 200,
|
||||
sprintf(translate("\"%(label)s\""), { "label": gameLabel }) + "\n" +
|
||||
translate("Saved game will be permanently overwritten, are you sure?"),
|
||||
translate("OVERWRITE SAVE"),
|
||||
[translate("No"), translate("Yes")],
|
||||
[null, function(){ reallySaveGame(name, desc, false); }]
|
||||
);
|
||||
}
|
||||
|
||||
function reallySaveGame(name, desc, nameIsPrefix)
|
||||
{
|
||||
if (nameIsPrefix)
|
||||
Engine.SaveGamePrefix(name, desc, g_SavedGameData);
|
||||
else
|
||||
Engine.SaveGame(name, desc, g_SavedGameData);
|
||||
|
||||
closeSave();
|
||||
}
|
||||
|
||||
function closeSave()
|
||||
{
|
||||
Engine.PopGuiPage();
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<objects>
|
||||
|
||||
<script directory="gui/common/"/>
|
||||
<script directory="gui/savegame/"/>
|
||||
|
||||
<!-- Add a translucent black background to fade out the page -->
|
||||
<object type="image" z="0" sprite="ModernFade"/>
|
||||
|
||||
<object type="image" style="ModernDialog" size="50%-300 50%-200 50%+300 50%+200">
|
||||
<object type="image" z="0" sprite="ModernFade"/>
|
||||
<object type="text" style="TitleText" size="50%-128 -18 50%+128 14">
|
||||
<translatableAttribute id="caption">Save Game</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="gameSelection"
|
||||
style="ModernList"
|
||||
type="list"
|
||||
|
||||
size="24 24 100%-24 100%-124">
|
||||
<action on="selectionchange">
|
||||
selectDescription();
|
||||
</action>
|
||||
</object>
|
||||
|
||||
<object size="24 100%-124 100%-24 100%-100" name="descLabel" type="text" style="ModernLeftLabelText">
|
||||
<translatableAttribute id="caption">Description:</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="saveGameDesc" size="24 100%-96 100%-24 100%-72" type="input" style="ModernInput">
|
||||
<action on="Press">saveGame();</action>
|
||||
</object>
|
||||
|
||||
<object name="saveButton" type="button" size="0%+25 100%-60 33%+10 100%-32" style="StoneButton" hotkey="cancel">
|
||||
<translatableAttribute id="caption">Cancel</translatableAttribute>
|
||||
<action on="Press">closeSave(true);</action>
|
||||
</object>
|
||||
|
||||
<object name="deleteGameButton" type="button" size="33%+20 100%-60 66%-15 100%-32" style="StoneButton" hotkey="session.savedgames.delete">
|
||||
<translatableAttribute id="caption">Delete</translatableAttribute>
|
||||
<action on="Press">deleteGame();</action>
|
||||
</object>
|
||||
|
||||
<object type="button" style="StoneButton" size="66%-5 100%-60 100%-25 100%-32">
|
||||
<translatableAttribute id="caption">Save</translatableAttribute>
|
||||
<action on="Press">saveGame();</action>
|
||||
</object>
|
||||
|
||||
</object>
|
||||
|
||||
</objects>
|
@ -226,7 +226,7 @@ function openSave()
|
||||
pauseGame();
|
||||
|
||||
Engine.PushGuiPage(
|
||||
"page_savegame.xml",
|
||||
"page_loadgame.xml",
|
||||
{ "savedGameData": getSavedGameData() },
|
||||
resumeGame);
|
||||
}
|
||||
|
@ -263,7 +263,6 @@
|
||||
"gui/reference/structree/**.js",
|
||||
"gui/reference/viewer/**.js",
|
||||
"gui/replaymenu/**.js",
|
||||
"gui/savegame/**.js",
|
||||
"gui/splashscreen/**.js",
|
||||
"gui/summary/**.js"
|
||||
],
|
||||
@ -298,7 +297,6 @@
|
||||
"gui/reference/structree/**.xml",
|
||||
"gui/reference/viewer/**.xml",
|
||||
"gui/replaymenu/**.xml",
|
||||
"gui/savegame/**.xml",
|
||||
"gui/splashscreen/**.xml",
|
||||
"gui/summary/**.xml"
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user