Index: binaries/data/mods/public/gui/pregame/BackgroundHandler.js
===================================================================
--- binaries/data/mods/public/gui/pregame/BackgroundHandler.js
+++ binaries/data/mods/public/gui/pregame/BackgroundHandler.js
@@ -2,47 +2,71 @@
{
constructor(layers)
{
+ this.backgroundLayers = layers.map((layer, i) =>
+ new BackgroundLayer(layer, i));
+
this.initTime = Date.now();
- this.layerSet = layers;
- this.initBackgrounds();
+ this.backgrounds = Engine.GetGUIObjectByName("backgrounds");
+ this.backgrounds.onTick = this.onTick.bind(this);
+ this.backgrounds.onWindowResized = this.onWindowResized.bind(this);
+ this.onWindowResized();
}
- initBackgrounds()
+ onWindowResized()
{
- this.layerSet.forEach((layer, i) => {
-
- let background = Engine.GetGUIObjectByName("background[" + i + "]");
- background.sprite = layer.sprite;
- background.z = i;
- background.hidden = false;
- });
+ let size = this.backgrounds.getComputedSize();
+ this.backgroundsSize = deepfreeze(new GUISize(size.top, size.left, size.right, size.bottom));
}
onTick()
{
- let now = Date.now();
+ let time = Date.now() - this.initTime;
+ for (let background of this.backgroundLayers)
+ background.update(time, this.backgroundsSize);
+ }
+}
- this.layerSet.forEach((layer, i) => {
+class BackgroundLayer
+{
+ constructor(layer, i)
+ {
+ this.layer = layer;
- let background = Engine.GetGUIObjectByName("background[" + i + "]");
+ this.background = Engine.GetGUIObjectByName("background[" + i + "]");
+ this.background.sprite = this.layer.sprite;
+ this.background.z = i;
+ this.background.hidden = false;
+ }
- let screen = background.parent.getComputedSize();
- let h = screen.bottom - screen.top;
- let w = h * 16/9;
- let iw = h * 2;
-
- let offset = layer.offset((now - this.initTime) / 1000, w);
-
- if (layer.tiling)
- {
- let left = offset % iw;
- if (left >= 0)
- left -= iw;
- background.size = new GUISize(left, screen.top, screen.right, screen.bottom);
- }
- else
- background.size = new GUISize(screen.right/2 - h + offset, screen.top, screen.right/2 + h + offset, screen.bottom);
- });
+ update(time, backgroundsSize)
+ {
+ let height = backgroundsSize.bottom - backgroundsSize.top;
+ let width = height * this.AspectRatio;
+ let offset = this.layer.offset(time / 1000, width);
+
+ if (this.layer.tiling)
+ {
+ let iw = height * 2;
+ let left = offset % iw;
+ if (left >= 0)
+ left -= iw;
+ this.background.size = new GUISize(
+ left,
+ backgroundsSize.top,
+ backgroundsSize.right,
+ backgroundsSize.bottom);
+ }
+ else
+ {
+ let right = backgroundsSize.right / 2 + offset;
+ this.background.size = new GUISize(
+ right - height,
+ backgroundsSize.top,
+ right + height,
+ backgroundsSize.bottom);
+ }
}
}
+
+BackgroundLayer.prototype.AspectRatio = 16 / 9;
Index: binaries/data/mods/public/gui/pregame/MainMenuItemHandler.js
===================================================================
--- binaries/data/mods/public/gui/pregame/MainMenuItemHandler.js
+++ binaries/data/mods/public/gui/pregame/MainMenuItemHandler.js
@@ -1,11 +1,12 @@
+/**
+ * This class sets up the main menu buttons, animates submenu that opens when
+ * clicking on category buttons, assigns the defined actions and hotkeys to every button.
+ */
class MainMenuItemHandler
{
- constructor(menuItems, menuSpeed = 1.2, margin = 4, buttonHeight = 28)
+ constructor(menuItems)
{
this.menuItems = menuItems;
- this.menuSpeed = menuSpeed;
- this.margin = margin;
- this.buttonHeight = buttonHeight;
this.lastTickTime = Date.now();
this.mainMenu = Engine.GetGUIObjectByName("mainMenu");
@@ -17,7 +18,9 @@
this.setupMenuButtons(this.mainMenuButtons.children, this.menuItems);
this.setupHotkeys(this.menuItems);
- Engine.GetGUIObjectByName("closeMenuButton").onPress = () => { this.closeSubmenu(); };
+
+ this.mainMenu.onTick = this.onTick.bind(this);
+ Engine.GetGUIObjectByName("closeMenuButton").onPress = this.closeSubmenu.bind(this);
}
setupMenuButtons(buttons, menuItems)
@@ -29,8 +32,8 @@
return;
button.size = new GUISize(
- 0, (this.buttonHeight + this.margin) * i,
- 0, (this.buttonHeight + this.margin) * i + this.buttonHeight,
+ 0, (this.ButtonHeight + this.Margin) * i,
+ 0, (this.ButtonHeight + this.Margin) * i + this.ButtonHeight,
0, 0, 100, 0);
button.caption = item.caption;
button.tooltip = item.tooltip;
@@ -57,12 +60,10 @@
let item = menuItems[name];
if (item.onPress && item.hotkey)
- {
Engine.SetGlobalHotkey(item.hotkey, () => {
this.closeSubmenu();
item.onPress();
});
- }
if (item.submenu)
this.setupHotkeys(item.submenu);
@@ -72,20 +73,39 @@
openSubmenu(i)
{
this.setupMenuButtons(this.submenuButtons.children, this.menuItems[i].submenu);
+
let top = this.mainMenuButtons.size.top + this.mainMenuButtons.children[i].size.top;
+
this.submenu.size = new GUISize(
- this.submenu.size.left, top - this.margin,
- this.submenu.size.right, top + ((this.buttonHeight + this.margin) * this.menuItems[i].submenu.length));
+ this.submenu.size.left, top - this.Margin,
+ this.submenu.size.right, top + (this.ButtonHeight + this.Margin) * this.menuItems[i].submenu.length);
+
this.submenu.hidden = false;
- this.MainMenuPanelRightBorderTop.size = "100%-2 0 100% " + (this.submenu.size.top + this.margin);
- this.MainMenuPanelRightBorderBottom.size = "100%-2 " + this.submenu.size.bottom + " 100% 100%";
+
+ {
+ let size = this.MainMenuPanelRightBorderTop.size;
+ size.bottom = this.submenu.size.top + this.Margin;
+ size.rbottom = 0;
+ this.MainMenuPanelRightBorderTop.size = size;
+ }
+
+ {
+ let size = this.MainMenuPanelRightBorderBottom.size;
+ size.top = this.submenu.size.bottom;
+ this.MainMenuPanelRightBorderBottom.size = size;
+ }
}
closeSubmenu()
{
this.submenu.hidden = true;
this.submenu.size = this.mainMenu.size;
- this.MainMenuPanelRightBorderTop.size = "100%-2 0 100% 100%";
+
+ let size = this.MainMenuPanelRightBorderTop.size;
+ size.top = 0;
+ size.bottom = 0;
+ size.rbottom = 100;
+ this.MainMenuPanelRightBorderTop.size = size;
}
onTick()
@@ -93,7 +113,7 @@
let now = Date.now();
let maxOffset = this.mainMenu.size.right - this.submenu.size.left;
- let offset = Math.min(this.menuSpeed * (now - this.lastTickTime), maxOffset);
+ let offset = Math.min(this.MenuSpeed * (now - this.lastTickTime), maxOffset);
this.lastTickTime = now;
@@ -106,3 +126,18 @@
this.submenu.size = size;
}
}
+
+/**
+ * Vertical size per button.
+ */
+MainMenuItemHandler.prototype.ButtonHeight = 28;
+
+/**
+ * Distance between consecutive buttons.
+ */
+MainMenuItemHandler.prototype.Margin = 4;
+
+/**
+ * Collapse / expansion speed in pixels per milliseconds used when animating the button menu size.
+ */
+MainMenuItemHandler.prototype.MenuSpeed = 1.2;
Index: binaries/data/mods/public/gui/pregame/MainMenuPage.js
===================================================================
--- binaries/data/mods/public/gui/pregame/MainMenuPage.js
+++ binaries/data/mods/public/gui/pregame/MainMenuPage.js
@@ -1,35 +1,24 @@
/**
- * Available backgrounds, added by the files in backgrounds/.
+ * This is the handler that coordinates all other handlers on this GUI page.
*/
-var g_BackgroundLayerData = [];
-
-var g_BackgroundHandler;
-var g_MenuHandler;
-var g_SplashScreenHandler;
-
-function init(data, hotloadData)
-{
- g_MenuHandler = new MainMenuItemHandler(g_MainMenuItems);
- g_BackgroundHandler = new BackgroundHandler(pickRandom(g_BackgroundLayerData));
- g_SplashScreenHandler = new SplashScreenHandler(data, hotloadData && hotloadData.splashScreenHandler);
-
- new MusicHandler();
- new ProjectInformationHandler(g_ProjectInformation);
- new CommunityButtonHandler();
-}
-
-function onTick()
+class MainMenuPage
{
- g_MenuHandler.onTick();
- g_BackgroundHandler.onTick();
- g_SplashScreenHandler.onTick();
-}
+ constructor(data, hotloadData, mainMenuItems, backgroundLayerData, projectInformation, communityButtons)
+ {
+ this.backgroundHandler = new BackgroundHandler(pickRandom(backgroundLayerData));
+ this.menuHandler = new MainMenuItemHandler(mainMenuItems);
+ this.splashScreenHandler = new SplashScreenHandler(data, hotloadData && hotloadData.splashScreenHandler);
+ this.musicHandler = new MusicHandler();
+ this.projectInformationHandler = new ProjectInformationHandler(projectInformation);
+ this.communityButtonHandler = new CommunityButtonHandler(communityButtons);
+ }
-function getHotloadData()
-{
- return {
- "splashScreenHandler": g_SplashScreenHandler.getHotloadData()
- };
+ getHotloadData()
+ {
+ return {
+ "splashScreenHandler": this.splashScreenHandler.getHotloadData()
+ };
+ }
}
class MusicHandler
@@ -53,18 +42,18 @@
class CommunityButtonHandler
{
- constructor()
+ constructor(communityButtons)
{
let buttons = Engine.GetGUIObjectByName("communityButtons").children;
- g_CommunityButtons.forEach((buttonInfo, i) => {
+ communityButtons.forEach((buttonInfo, i) => {
let button = buttons[i];
button.hidden = false;
for (let propertyName in buttonInfo)
button[propertyName] = buttonInfo[propertyName];
});
- if (buttons.length < g_CommunityButtons.length)
+ if (buttons.length < communityButtons.length)
error("GUI page has space for " + buttons.length + " community buttons, but " + menuItems.length + " items are provided!");
}
}
Index: binaries/data/mods/public/gui/pregame/backgrounds.xml
===================================================================
--- binaries/data/mods/public/gui/pregame/backgrounds.xml
+++ binaries/data/mods/public/gui/pregame/backgrounds.xml
@@ -1,5 +1,5 @@
-
-
+