2 * This class sets up the main menu buttons, animates submenu that opens when
3 * clicking on category buttons, assigns the defined actions and hotkeys to every button.
5 class MainMenuItemHandler
9 this.menuItems = menuItems;
10 this.lastTickTime = Date.now();
12 this.lastOpenItem = undefined;
14 this.mainMenu = Engine.GetGUIObjectByName("mainMenu");
15 this.mainMenuButtons = Engine.GetGUIObjectByName("mainMenuButtons");
16 this.submenu = Engine.GetGUIObjectByName("submenu");
17 this.submenuButtons = Engine.GetGUIObjectByName("submenuButtons");
18 this.MainMenuPanelRightBorderTop = Engine.GetGUIObjectByName("MainMenuPanelRightBorderTop");
19 this.MainMenuPanelRightBorderBottom = Engine.GetGUIObjectByName("MainMenuPanelRightBorderBottom");
21 this.setupMenuButtons(this.mainMenuButtons.children, this.menuItems);
22 this.setupHotkeys(this.menuItems);
24 Engine.GetGUIObjectByName("closeMenuButton").onPress = this.closeSubmenu.bind(this);
27 setupMenuButtons(buttons, menuItems)
29 buttons.forEach((button, i) => {
30 let item = menuItems[i];
31 button.hidden = !item;
35 button.size = new GUISize(
36 0, (this.ButtonHeight + this.Margin) * i,
37 0, (this.ButtonHeight + this.Margin) * i + this.ButtonHeight,
39 button.caption = item.caption;
40 button.tooltip = item.tooltip;
41 button.enabled = item.enabled === undefined || item.enabled;
42 button.onPress = this.pressButton.bind(this, item, i);
43 button.hidden = false;
46 if (buttons.length < menuItems.length)
47 error("GUI page has space for " + buttons.length + " menu buttons, but " + menuItems.length + " items are provided!");
51 * Expand selected submenu, or collapse if it already is expanded.
55 if (this.submenu.hidden)
57 this.performButtonAction(item, i);
62 if (this.lastOpenItem && this.lastOpenItem != item)
63 this.performButtonAction(item, i);
65 this.lastOpenItem = undefined;
70 * Expand submenu or perform action specified by the button object.
72 performButtonAction(item, i)
74 this.lastOpenItem = item;
82 setupHotkeys(menuItems)
84 for (let i in menuItems)
86 let item = menuItems[i];
87 if (item.onPress && item.hotkey)
88 Engine.SetGlobalHotkey(item.hotkey, () => {
94 this.setupHotkeys(item.submenu);
100 this.setupMenuButtons(this.submenuButtons.children, this.menuItems[i].submenu);
102 let top = this.mainMenuButtons.size.top + this.mainMenuButtons.children[i].size.top;
104 this.submenu.size = new GUISize(
105 this.submenu.size.left, top - this.Margin,
106 this.submenu.size.right, top + (this.ButtonHeight + this.Margin) * this.menuItems[i].submenu.length);
108 this.submenu.hidden = false;
111 let size = this.MainMenuPanelRightBorderTop.size;
112 size.bottom = this.submenu.size.top + this.Margin;
114 this.MainMenuPanelRightBorderTop.size = size;
118 let size = this.MainMenuPanelRightBorderBottom.size;
119 size.top = this.submenu.size.bottom;
120 this.MainMenuPanelRightBorderBottom.size = size;
124 this.lastTickTime = Date.now();
125 this.mainMenu.onTick = this.onTick.bind(this);
130 this.submenu.hidden = true;
131 this.submenu.size = this.mainMenu.size;
133 let size = this.MainMenuPanelRightBorderTop.size;
137 this.MainMenuPanelRightBorderTop.size = size;
142 let now = Date.now();
143 if (now == this.lastTickTime)
146 let maxOffset = this.mainMenu.size.right - this.submenu.size.left;
147 let offset = Math.min(this.MenuSpeed * (now - this.lastTickTime), maxOffset);
149 this.lastTickTime = now;
151 if (this.submenu.hidden || !offset)
153 delete this.mainMenu.onTick;
157 let size = this.submenu.size;
159 size.right += offset;
160 this.submenu.size = size;
165 * Vertical size per button.
167 MainMenuItemHandler.prototype.ButtonHeight = 28;
170 * Distance between consecutive buttons.
172 MainMenuItemHandler.prototype.Margin = 4;
175 * Collapse / expansion speed in pixels per milliseconds used when animating the button menu size.
177 MainMenuItemHandler.prototype.MenuSpeed = 1.2;