Page MenuHomeWildfire Games
Paste P136

Diff of GridBrowser + example
ActivePublic

Authored by nani on Oct 13 2018, 12:48 PM.
Index: binaries/data/mods/public/gui/common/GridBrowser.js
===================================================================
--- binaries/data/mods/public/gui/common/GridBrowser.js (nonexistent)
+++ binaries/data/mods/public/gui/common/GridBrowser.js (working copy)
@@ -0,0 +1,118 @@
+/*
+ * Function that arranges a list of "boxed-like" xml objects with centered and page based way mode.
+ * Needs an object as container and a object to display the page numbering(if not make hidden object and assign it to it)
+ * childWidth,childHeight: dimensions of each grid box
+ * The grid will ajust in accordance to the screen size from when init() method is called
+ *
+ * To add advanced, more detailed, objects inside each box redefine
+ * the function "defineChildren" after the your GridBrowser is instantiated.
+ *
+ * For example look at mapbrowser.js implementation.
+ */
+function GridBrowser(containerName, pageCounterName)
+{
+ // object name which contains all the grid objects
+ this.containerName = containerName;
+ // object name which constains a text object type for the numbering of each page
+ this.pageCounterName = pageCounterName;
+}
+
+// the list of whatever you are storing
+GridBrowser.prototype.init = function(list, childWidth, childHeight)
+{
+ this.container = Engine.GetGUIObjectByName(this.containerName);
+ this.pageCounter = Engine.GetGUIObjectByName(this.pageCounterName);
+ this.children = this.container.children; // list of xml objects
+
+ this.numBoxesCreated = this.children.length; //hardcoded in the xml file, maximum capable of showing
+
+ this.list = list;
+ this.currentPage = 0;
+
+ this.setChildDimensions(childWidth, childHeight);
+}
+
+GridBrowser.prototype.defineChildren = function(n, pageList)
+{
+ //empty onpurpose, add modifications only at the object instances
+}
+
+GridBrowser.prototype.setChildDimensions = function(childWidth, childHeight)
+{
+ this.child = {};
+ this.child.width = childWidth;
+ this.child.height = childHeight;
+ this.updateGrid();
+}
+
+GridBrowser.prototype.updateGrid = function()
+{
+ let rect = this.container.getComputedSize();
+ rect.width = Math.max(rect.right - rect.left, 0);
+ rect.height = Math.max(rect.bottom - rect.top, 0);
+
+ this.nColumns = Math.max(1, Math.floor(rect.width / this.child.width));
+ this.nRows = Math.max(1, Math.floor(rect.height / this.child.height));
+ this.maxNumBoxesInScreen = Math.min(this.nColumns * this.nRows, this.numBoxesCreated);
+ this.xCenter = this.child.width * this.nColumns / 2;
+
+ this.generateGrid();
+ this.currentPage = 0;
+ this.numOfPages = this.calcNumPages();
+ this.generatePage();
+}
+
+GridBrowser.prototype.generateGrid = function()
+{
+ for (let n = 0; n < this.numBoxesCreated; n++)
+ {
+ const x = n % this.nColumns;
+ const y = Math.floor(n / this.nColumns);
+
+ let xmin = this.child.width * x;
+ let xmax = this.child.width * (x + 1);
+ let ymin = this.child.height * y;
+ let ymax = this.child.height * (y + 1);
+ xmin = "50%" + "-" + this.xCenter + "+" + xmin;
+ xmax = "50%" + "-" + this.xCenter + "+" + xmax;
+ this.children[n].size = [xmin, ymin, xmax, ymax].join(" ");
+ }
+}
+
+GridBrowser.prototype.generatePage = function(page = undefined)
+{
+ this.currentPage = Math.max(Math.min(page == undefined ? this.currentPage : page, this.numOfPages - 1), 0);
+ let nubOfBoxesToShow = (this.currentPage == this.numOfPages - 1) ? this.list.length % this.maxNumBoxesInScreen : this.maxNumBoxesInScreen;
+ let subList = this.list.slice(this.currentPage * this.maxNumBoxesInScreen, this.currentPage * this.maxNumBoxesInScreen + nubOfBoxesToShow);
+
+ for (let n = 0; n < nubOfBoxesToShow; n++)
+ {
+ this.children[n].hidden = false;
+ this.defineChildren(n, subList);
+ }
+
+ for (let n = nubOfBoxesToShow; n < this.numBoxesCreated; ++n)
+ {
+ this.children[n].hidden = true;
+ }
+ this.updatePageCounter()
+}
+
+GridBrowser.prototype.calcNumPages = function()
+{
+ return Math.ceil(this.list.length / this.maxNumBoxesInScreen);
+}
+GridBrowser.prototype.updatePageCounter = function()
+{
+ this.pageCounter.caption = `${this.currentPage+1}/${this.numOfPages}`;
+}
+GridBrowser.prototype.nextPage = function()
+{
+ this.currentPage = (this.currentPage + 1) % this.numOfPages;
+ this.generatePage();
+}
+GridBrowser.prototype.previousPage = function()
+{
+ this.currentPage = (this.currentPage + this.numOfPages - 1) % this.numOfPages;
+ this.generatePage();
+}
\ No newline at end of file
Index: binaries/data/mods/public/gui/gamesetup/gamesetup.js
===================================================================
--- binaries/data/mods/public/gui/gamesetup/gamesetup.js (revision 21902)
+++ binaries/data/mods/public/gui/gamesetup/gamesetup.js (working copy)
@@ -1829,6 +1829,7 @@
function loadMapData(name)
{
+
if (!name || !g_MapPath[g_GameAttributes.mapType])
return undefined;
@@ -2407,6 +2408,20 @@
updateGUIObjects();
}
+function MapBrowserOpen()
+{
+ Engine.PushGuiPage("page_mapbrowser.xml", {
+ "callback": "MapBrowserCallback"
+ });
+}
+/**
+ * Called after closing the dialog.
+ */
+function MapBrowserCallback(mapSelected)
+{
+
+}
+
function openAIConfig(playerSlot)
{
g_LastViewedAIPlayer = playerSlot;
Index: binaries/data/mods/public/gui/gamesetup/gamesetup.xml
===================================================================
--- binaries/data/mods/public/gui/gamesetup/gamesetup.xml (revision 21902)
+++ binaries/data/mods/public/gui/gamesetup/gamesetup.xml (working copy)
@@ -137,8 +137,11 @@
<!-- Map Preview -->
<object type="image" sprite="ModernDarkBoxGold" name="gamePreviewBox" size="100%-426 40 100%-24 336">
- <object type="image" sprite="snMapPreview" size="1 1 401 294" name="mapPreview"/>
+ <object type="image" size="1 1 401 294" name="mapPreview"/>
<object name="mapInfoName" type="text" style="ModernLeftLabelText" size="5 100%-20 100% 100%-1"/>
+ <object type="button" size="0% 0% 100% 100%">
+ <action on="Press">MapBrowserOpen();</action>
+ </object>
</object>
<!-- Settings -->
Index: binaries/data/mods/public/gui/mapbrowser/mapbrowser.js
===================================================================
--- binaries/data/mods/public/gui/mapbrowser/mapbrowser.js (nonexistent)
+++ binaries/data/mods/public/gui/mapbrowser/mapbrowser.js (working copy)
@@ -0,0 +1,98 @@
+
+var g_MapPath = {
+ "random": "maps/random/",
+ "scenario": "maps/scenarios/",
+ "skirmish": "maps/skirmishes/"
+};
+
+function loadMapData(name)
+{
+ if (name == "random")
+ return {
+ "settings":
+ {
+ "Name": "",
+ "Description": ""
+ }
+ };
+
+ if (!g_MapData[name])
+ g_MapData[name] = g_GameAttributes.mapType == "random" ?
+ Engine.ReadJSONFile(name + ".json") :
+ Engine.LoadMapSettings(name);
+
+ return g_MapData[name];
+}
+
+function getFilteredMaps()
+{
+ let maps = [];
+ for (let mapType of Object.keys(g_MapPath))
+ {
+ const mapFilePath = g_MapPath[mapType];
+ const mapFileExtension = (mapType == "random") ? ".json" : ".xml";
+
+ for (let mapFileName of listFiles(mapFilePath, mapFileExtension, false))
+ {
+ if (mapFileName.startsWith("_"))
+ continue;
+ maps.push(
+ {
+ "loaded": false,
+ "filePath": mapFilePath,
+ "fileName": mapFileName,
+ "fileExtension": mapFileExtension,
+ "type": mapType,
+ });
+ }
+ }
+ return maps;
+}
+
+
+
+function getMapPreview(mapType, mapFullFileName)
+{
+ let mapData = (mapType == "random") ? Engine.ReadJSONFile(mapFullFileName + ".json") : Engine.LoadMapSettings(mapFullFileName);
+ if (!mapData || !mapData.settings || !mapData.settings.Preview)
+ return "nopreview.png";
+ return mapData.settings.Preview;
+}
+
+
+let mapBrowser = new GridBrowser("MapBrowserContainer", "currentPageNum")
+
+mapBrowser.defineChildren = function(n, pageList)
+{
+ let map = pageList[n];
+
+ if (!map.loaded)
+ {
+ map.preview = getMapPreview(map.type, map.filePath + map.fileName)
+ map.loaded = true;
+ }
+
+ Engine.GetGUIObjectByName(`mapPreview[${n}]`).sprite = "cropped:0.78125,0.5859375:session/icons/mappreview/" + map.preview;
+ Engine.GetGUIObjectByName(`mapInfoName[${n}]`).caption = map.fileName;
+ Engine.GetGUIObjectByName(`mapSelect[${n}]`).onPress = () => true;
+
+}
+
+
+
+
+function init(settings)
+{
+ let mapList = getFilteredMaps();
+ mapBrowser.init(mapList,400 * 0.65, 300 * 0.65);
+}
+
+function MapBrowserReturn()
+{
+ // Pop the page before calling the callback, so the callback runs
+ // in the parent GUI page's context
+ Engine.PopGuiPageCB(
+ {
+ "dummy": "dummy",
+ });
+}
\ No newline at end of file
Index: binaries/data/mods/public/gui/mapbrowser/mapbrowser.xml
===================================================================
--- binaries/data/mods/public/gui/mapbrowser/mapbrowser.xml (nonexistent)
+++ binaries/data/mods/public/gui/mapbrowser/mapbrowser.xml (working copy)
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<objects>
+
+ <script directory="gui/common/"/>
+ <script directory="gui/mapbrowser/"/>
+
+ <!-- Add a translucent black background to fade out the menu page -->
+ <object type="image" sprite="ModernFade"/>
+
+ <object type="image" style="ModernDialog" size="0%+20 0%+30 100%-20 100%-30">
+
+ <object style="ModernLabelText" type="text" size="50%-128 -18 50%+128 14">
+ <translatableAttribute id="caption">Map Browser</translatableAttribute>
+ </object>
+
+ <object size="0%+10 0%+20 100%-10 100%-100" name="MapBrowserContainer">
+ <repeat count="60" >
+ <object hidden="true">
+ <object type="image" sprite="ModernDarkBoxGold" size="0%+8 0%+8 100%-8 100%-8">
+ <object type="image" size="0%+1 0%+1 100%-1 100%-1" name="mapPreview[n]"/>
+ <object name="mapInfoName[n]" type="text" style="ModernLabelText" size="0%+10 100%-21 100%-10 100%-1"/>
+ <object type="button" name="mapSelect[n]"/>
+ </object>
+ </object>
+ </repeat>
+ <!-- Recalculate grid to fill all screen space -->
+ <action on="WindowResized">
+ mapBrowser.updateGrid();
+ </action>
+ </object>
+
+ <object type="button" style="ModernButtonRed" size="0%+40 100%-50 0%+40+250 100%-50+30" hotkey="cancel">
+ <translatableAttribute id="caption">Close</translatableAttribute>
+ <action on="Press">MapBrowserReturn(false);</action>
+ </object>
+
+ <object type="text" style="ModernRightLabelText" size="50%+40 100%-50-50 50%+40+120 100%-50+30">
+ <translatableAttribute id="caption">Page:</translatableAttribute>
+ </object>
+ <object name="currentPageNum" type="text" style="ModernLeftLabelText" size="50%+40+125 100%-50-50 50%+40+125+125 100%-50+30">
+ 1/1
+ </object>
+ <object type="button" style="ModernButtonRed" size="50%+40 100%-50 50%+40+125 100%-50+30">
+ <translatableAttribute id="caption">Previous</translatableAttribute>
+ <action on="Press">mapBrowser.previousPage();</action>
+ </object>
+ <object type="button" style="ModernButtonRed" size="50%+40+125 100%-50 50%+40+125+125 100%-50+30">
+ <translatableAttribute id="caption">Next</translatableAttribute>
+ <action on="Press">mapBrowser.nextPage();</action>
+ </object>
+ </object>
+</objects>
Index: binaries/data/mods/public/gui/mapbrowser/mapbrowser.js
===================================================================
--- binaries/data/mods/public/gui/mapbrowser/mapbrowser.js (nonexistent)
+++ binaries/data/mods/public/gui/mapbrowser/mapbrowser.js (working copy)
@@ -0,0 +1,98 @@
+
+var g_MapPath = {
+ "random": "maps/random/",
+ "scenario": "maps/scenarios/",
+ "skirmish": "maps/skirmishes/"
+};
+
+function loadMapData(name)
+{
+ if (name == "random")
+ return {
+ "settings":
+ {
+ "Name": "",
+ "Description": ""
+ }
+ };
+
+ if (!g_MapData[name])
+ g_MapData[name] = g_GameAttributes.mapType == "random" ?
+ Engine.ReadJSONFile(name + ".json") :
+ Engine.LoadMapSettings(name);
+
+ return g_MapData[name];
+}
+
+function getFilteredMaps()
+{
+ let maps = [];
+ for (let mapType of Object.keys(g_MapPath))
+ {
+ const mapFilePath = g_MapPath[mapType];
+ const mapFileExtension = (mapType == "random") ? ".json" : ".xml";
+
+ for (let mapFileName of listFiles(mapFilePath, mapFileExtension, false))
+ {
+ if (mapFileName.startsWith("_"))
+ continue;
+ maps.push(
+ {
+ "loaded": false,
+ "filePath": mapFilePath,
+ "fileName": mapFileName,
+ "fileExtension": mapFileExtension,
+ "type": mapType,
+ });
+ }
+ }
+ return maps;
+}
+
+
+
+function getMapPreview(mapType, mapFullFileName)
+{
+ let mapData = (mapType == "random") ? Engine.ReadJSONFile(mapFullFileName + ".json") : Engine.LoadMapSettings(mapFullFileName);
+ if (!mapData || !mapData.settings || !mapData.settings.Preview)
+ return "nopreview.png";
+ return mapData.settings.Preview;
+}
+
+
+let mapBrowser = new GridBrowser("MapBrowserContainer", "currentPageNum")
+
+mapBrowser.defineChildren = function(n, pageList)
+{
+ let map = pageList[n];
+
+ if (!map.loaded)
+ {
+ map.preview = getMapPreview(map.type, map.filePath + map.fileName)
+ map.loaded = true;
+ }
+
+ Engine.GetGUIObjectByName(`mapPreview[${n}]`).sprite = "cropped:0.78125,0.5859375:session/icons/mappreview/" + map.preview;
+ Engine.GetGUIObjectByName(`mapInfoName[${n}]`).caption = map.fileName;
+ Engine.GetGUIObjectByName(`mapSelect[${n}]`).onPress = () => true;
+
+}
+
+
+
+
+function init(settings)
+{
+ let mapList = getFilteredMaps();
+ mapBrowser.init(mapList,400 * 0.65, 300 * 0.65);
+}
+
+function MapBrowserReturn()
+{
+ // Pop the page before calling the callback, so the callback runs
+ // in the parent GUI page's context
+ Engine.PopGuiPageCB(
+ {
+ "dummy": "dummy",
+ });
+}
\ No newline at end of file
Index: binaries/data/mods/public/gui/mapbrowser/mapbrowser.xml
===================================================================
--- binaries/data/mods/public/gui/mapbrowser/mapbrowser.xml (nonexistent)
+++ binaries/data/mods/public/gui/mapbrowser/mapbrowser.xml (working copy)
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<objects>
+
+ <script directory="gui/common/"/>
+ <script directory="gui/mapbrowser/"/>
+
+ <!-- Add a translucent black background to fade out the menu page -->
+ <object type="image" sprite="ModernFade"/>
+
+ <object type="image" style="ModernDialog" size="0%+20 0%+30 100%-20 100%-30">
+
+ <object style="ModernLabelText" type="text" size="50%-128 -18 50%+128 14">
+ <translatableAttribute id="caption">Map Browser</translatableAttribute>
+ </object>
+
+ <object size="0%+10 0%+20 100%-10 100%-100" name="MapBrowserContainer">
+ <repeat count="60" >
+ <object hidden="true">
+ <object type="image" sprite="ModernDarkBoxGold" size="0%+8 0%+8 100%-8 100%-8">
+ <object type="image" size="0%+1 0%+1 100%-1 100%-1" name="mapPreview[n]"/>
+ <object name="mapInfoName[n]" type="text" style="ModernLabelText" size="0%+10 100%-21 100%-10 100%-1"/>
+ <object type="button" name="mapSelect[n]"/>
+ </object>
+ </object>
+ </repeat>
+ <!-- Recalculate grid to fill all screen space -->
+ <action on="WindowResized">
+ mapBrowser.updateGrid();
+ </action>
+ </object>
+
+ <object type="button" style="ModernButtonRed" size="0%+40 100%-50 0%+40+250 100%-50+30" hotkey="cancel">
+ <translatableAttribute id="caption">Close</translatableAttribute>
+ <action on="Press">MapBrowserReturn(false);</action>
+ </object>
+
+ <object type="text" style="ModernRightLabelText" size="50%+40 100%-50-50 50%+40+120 100%-50+30">
+ <translatableAttribute id="caption">Page:</translatableAttribute>
+ </object>
+ <object name="currentPageNum" type="text" style="ModernLeftLabelText" size="50%+40+125 100%-50-50 50%+40+125+125 100%-50+30">
+ 1/1
+ </object>
+ <object type="button" style="ModernButtonRed" size="50%+40 100%-50 50%+40+125 100%-50+30">
+ <translatableAttribute id="caption">Previous</translatableAttribute>
+ <action on="Press">mapBrowser.previousPage();</action>
+ </object>
+ <object type="button" style="ModernButtonRed" size="50%+40+125 100%-50 50%+40+125+125 100%-50+30">
+ <translatableAttribute id="caption">Next</translatableAttribute>
+ <action on="Press">mapBrowser.nextPage();</action>
+ </object>
+ </object>
+</objects>
Index: binaries/data/mods/public/gui/page_mapbrowser.xml
===================================================================
--- binaries/data/mods/public/gui/page_mapbrowser.xml (nonexistent)
+++ binaries/data/mods/public/gui/page_mapbrowser.xml (working copy)
@@ -0,0 +1,14 @@
+<?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>mapbrowser/mapbrowser.xml</include>
+ <include>common/global.xml</include>
+</page>

Event Timeline

nani created this paste.Oct 13 2018, 12:48 PM
nani created this object with visibility "Public (No Login Required)".

Changed some methods of GridBrowser but works as previous,

now can dynamically change grid columns rows automatically, handles change on screen size on-time

smiley added a subscriber: smiley.Oct 13 2018, 1:41 PM

(Good enough for a Revision proposal)

@nani could you make it official proposal (diff) ?