Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/binaries/data/mods/public/gui/pregame/MainMenuItemHandler.js
/** | |||||
* 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 | class MainMenuItemHandler | ||||
{ | { | ||||
constructor(menuItems, menuSpeed = 1.2, margin = 4, buttonHeight = 28) | constructor(menuItems) | ||||
{ | { | ||||
this.menuItems = menuItems; | this.menuItems = menuItems; | ||||
this.menuSpeed = menuSpeed; | |||||
this.margin = margin; | |||||
this.buttonHeight = buttonHeight; | |||||
this.lastTickTime = Date.now(); | this.lastTickTime = Date.now(); | ||||
this.mainMenu = Engine.GetGUIObjectByName("mainMenu"); | this.mainMenu = Engine.GetGUIObjectByName("mainMenu"); | ||||
this.mainMenuButtons = Engine.GetGUIObjectByName("mainMenuButtons"); | this.mainMenuButtons = Engine.GetGUIObjectByName("mainMenuButtons"); | ||||
this.submenu = Engine.GetGUIObjectByName("submenu"); | this.submenu = Engine.GetGUIObjectByName("submenu"); | ||||
this.submenuButtons = Engine.GetGUIObjectByName("submenuButtons"); | this.submenuButtons = Engine.GetGUIObjectByName("submenuButtons"); | ||||
this.MainMenuPanelRightBorderTop = Engine.GetGUIObjectByName("MainMenuPanelRightBorderTop"); | this.MainMenuPanelRightBorderTop = Engine.GetGUIObjectByName("MainMenuPanelRightBorderTop"); | ||||
this.MainMenuPanelRightBorderBottom = Engine.GetGUIObjectByName("MainMenuPanelRightBorderBottom"); | this.MainMenuPanelRightBorderBottom = Engine.GetGUIObjectByName("MainMenuPanelRightBorderBottom"); | ||||
this.setupMenuButtons(this.mainMenuButtons.children, this.menuItems); | this.setupMenuButtons(this.mainMenuButtons.children, this.menuItems); | ||||
this.setupHotkeys(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) | setupMenuButtons(buttons, menuItems) | ||||
{ | { | ||||
buttons.forEach((button, i) => { | buttons.forEach((button, i) => { | ||||
let item = menuItems[i]; | let item = menuItems[i]; | ||||
button.hidden = !item; | button.hidden = !item; | ||||
if (button.hidden) | if (button.hidden) | ||||
return; | return; | ||||
button.size = new GUISize( | button.size = new GUISize( | ||||
0, (this.buttonHeight + this.margin) * i, | 0, (this.ButtonHeight + this.Margin) * i, | ||||
0, (this.buttonHeight + this.margin) * i + this.buttonHeight, | 0, (this.ButtonHeight + this.Margin) * i + this.ButtonHeight, | ||||
0, 0, 100, 0); | 0, 0, 100, 0); | ||||
button.caption = item.caption; | button.caption = item.caption; | ||||
button.tooltip = item.tooltip; | button.tooltip = item.tooltip; | ||||
button.enabled = item.enabled === undefined || item.enabled; | button.enabled = item.enabled === undefined || item.enabled; | ||||
button.onPress = () => { | button.onPress = () => { | ||||
this.closeSubmenu(); | this.closeSubmenu(); | ||||
if (item.onPress) | if (item.onPress) | ||||
item.onPress(); | item.onPress(); | ||||
else | else | ||||
this.openSubmenu(i); | this.openSubmenu(i); | ||||
}; | }; | ||||
button.hidden = false; | button.hidden = false; | ||||
}); | }); | ||||
if (buttons.length < menuItems.length) | if (buttons.length < menuItems.length) | ||||
error("GUI page has space for " + buttons.length + " menu buttons, but " + menuItems.length + " items are provided!"); | error("GUI page has space for " + buttons.length + " menu buttons, but " + menuItems.length + " items are provided!"); | ||||
} | } | ||||
setupHotkeys(menuItems) | setupHotkeys(menuItems) | ||||
{ | { | ||||
for (let name in menuItems) | for (let i in menuItems) | ||||
{ | { | ||||
let item = menuItems[name]; | let item = menuItems[i]; | ||||
if (item.onPress && item.hotkey) | if (item.onPress && item.hotkey) | ||||
{ | |||||
Engine.SetGlobalHotkey(item.hotkey, () => { | Engine.SetGlobalHotkey(item.hotkey, () => { | ||||
this.closeSubmenu(); | this.closeSubmenu(); | ||||
item.onPress(); | item.onPress(); | ||||
}); | }); | ||||
} | |||||
if (item.submenu) | if (item.submenu) | ||||
this.setupHotkeys(item.submenu); | this.setupHotkeys(item.submenu); | ||||
} | } | ||||
} | } | ||||
openSubmenu(i) | openSubmenu(i) | ||||
{ | { | ||||
this.setupMenuButtons(this.submenuButtons.children, this.menuItems[i].submenu); | this.setupMenuButtons(this.submenuButtons.children, this.menuItems[i].submenu); | ||||
let top = this.mainMenuButtons.size.top + this.mainMenuButtons.children[i].size.top; | let top = this.mainMenuButtons.size.top + this.mainMenuButtons.children[i].size.top; | ||||
this.submenu.size = new GUISize( | this.submenu.size = new GUISize( | ||||
this.submenu.size.left, top - this.margin, | this.submenu.size.left, top - this.Margin, | ||||
this.submenu.size.right, top + ((this.buttonHeight + this.margin) * this.menuItems[i].submenu.length)); | this.submenu.size.right, top + (this.ButtonHeight + this.Margin) * this.menuItems[i].submenu.length); | ||||
this.submenu.hidden = false; | 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() | closeSubmenu() | ||||
{ | { | ||||
this.submenu.hidden = true; | this.submenu.hidden = true; | ||||
this.submenu.size = this.mainMenu.size; | 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() | onTick() | ||||
{ | { | ||||
let now = Date.now(); | let now = Date.now(); | ||||
let maxOffset = this.mainMenu.size.right - this.submenu.size.left; | 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; | this.lastTickTime = now; | ||||
if (this.submenu.hidden || offset <= 0) | if (this.submenu.hidden || offset <= 0) | ||||
return; | return; | ||||
let size = this.submenu.size; | let size = this.submenu.size; | ||||
size.left += offset; | size.left += offset; | ||||
size.right += offset; | size.right += offset; | ||||
this.submenu.size = size; | 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; |
Wildfire Games · Phabricator