void CreateFaceButtons(List <Type> types) { foreach (var type in types) { var customMenuAttribute = (MainMenuItemAttribute)type.GetCustomAttributes(typeof(MainMenuItemAttribute), false).FirstOrDefault(); if (customMenuAttribute != null && !customMenuAttribute.shown) { continue; } var isTool = typeof(ITool).IsAssignableFrom(type); var isWorkspace = typeof(Workspace).IsAssignableFrom(type); var isSettingsProvider = typeof(ISettingsMenuProvider).IsAssignableFrom(type); var buttonData = new MainMenuUI.ButtonData(); buttonData.name = type.Name; if (customMenuAttribute != null) { buttonData.name = customMenuAttribute.name; buttonData.sectionName = customMenuAttribute.sectionName; buttonData.description = customMenuAttribute.description; } else if (isTool) { buttonData.name = type.Name.Replace("Tool", string.Empty); } else if (isWorkspace) { // For workspaces that haven't specified a custom attribute, do some menu categorization automatically buttonData.name = type.Name.Replace("Workspace", string.Empty); buttonData.sectionName = "Workspaces"; } else if (isSettingsProvider) { // For workspaces that haven't specified a custom attribute, do some menu categorization automatically buttonData.name = type.Name.Replace("Module", string.Empty); buttonData.sectionName = "Settings"; } var selectedType = type; // Local variable for proper closure m_MainMenuUI.CreateFaceButton(buttonData, b => { b.button.onClick.RemoveAllListeners(); if (isTool) { m_ToolButtons[selectedType] = b; b.button.onClick.AddListener(() => { if (visible && targetRayOrigin) { this.SelectTool(targetRayOrigin, selectedType); UpdateToolButtons(); } }); } else if (isWorkspace) { b.button.onClick.AddListener(() => { if (visible) { this.CreateWorkspace(selectedType); } }); } else if (isSettingsProvider) { b.button.onClick.AddListener(() => { var provider = settingsMenuProviders[selectedType]; provider.settingsMenuInstance = m_MainMenuUI.AddSubmenu(buttonData.sectionName, provider.settingsMenuPrefab); }); } if (customMenuAttribute != null && customMenuAttribute.tooltip != null) { b.tooltipText = customMenuAttribute.tooltip.tooltipText; } }); } }
void CreateFaceButtons() { var types = new HashSet <Type>(); types.UnionWith(menuTools); types.UnionWith(menuWorkspaces); types.UnionWith(settingsMenuProviders.Keys.Select(provider => provider.Key)); types.UnionWith(settingsMenuItemProviders.Keys.Select(provider => provider.Key)); if (Application.isPlaying) { types.RemoveWhere(type => type.GetCustomAttributes(true).OfType <EditorOnlyWorkspaceAttribute>().Any()); } foreach (var type in types) { var customMenuAttribute = (MainMenuItemAttribute)type.GetCustomAttributes(typeof(MainMenuItemAttribute), false).FirstOrDefault(); if (customMenuAttribute != null && !customMenuAttribute.shown) { continue; } var isTool = typeof(ITool).IsAssignableFrom(type) && menuTools.Contains(type); var isWorkspace = typeof(Workspace).IsAssignableFrom(type); var isSettingsProvider = typeof(ISettingsMenuProvider).IsAssignableFrom(type); var isSettingsItemProvider = typeof(ISettingsMenuItemProvider).IsAssignableFrom(type); ITooltip tooltip = null; MainMenuUI.ButtonData buttonData = null; var selectedType = type; // Local variable for closure if (customMenuAttribute != null && customMenuAttribute.shown) { tooltip = customMenuAttribute.tooltip; buttonData = new MainMenuUI.ButtonData(customMenuAttribute.name) { sectionName = customMenuAttribute.sectionName, description = customMenuAttribute.description }; } if (isTool) { if (buttonData == null) { buttonData = new MainMenuUI.ButtonData(type.Name); } var mainMenuButton = CreateFaceButton(buttonData, tooltip, () => { if (targetRayOrigin) { this.SelectTool(targetRayOrigin, selectedType, hideMenu: typeof(IInstantiateMenuUI).IsAssignableFrom(selectedType)); UpdateToolButtons(); } }); m_ToolButtons[type] = mainMenuButton; // Assign Tools Menu button preview properties if (mainMenuButton != null) { mainMenuButton.toolType = selectedType; } m_ToolsSpatialMenuElements.Add(new SpatialMenu.SpatialMenuElementContainer(buttonData.name, buttonData.description, node => { this.SelectTool(this.RequestRayOriginFromNode(node), selectedType, hideMenu: typeof(IInstantiateMenuUI).IsAssignableFrom(selectedType)); })); UpdateToolButtons(); } if (isWorkspace) { // For workspaces that haven't specified a custom attribute, do some menu categorization automatically if (buttonData == null) { buttonData = new MainMenuUI.ButtonData(type.Name) { sectionName = "Workspaces" } } ; CreateFaceButton(buttonData, tooltip, () => { this.CreateWorkspace(selectedType); }); m_WorkspaceSpatialMenuElements.Add(new SpatialMenu.SpatialMenuElementContainer(buttonData.name, buttonData.description, node => this.CreateWorkspace(selectedType))); } if (isSettingsProvider) { foreach (var providerPair in settingsMenuProviders) { var kvp = providerPair.Key; if (kvp.Key == type && (kvp.Value == null || kvp.Value == rayOrigin)) { AddSettingsMenu(providerPair.Value, buttonData, tooltip); } } } if (isSettingsItemProvider) { foreach (var providerPair in settingsMenuItemProviders) { var kvp = providerPair.Key; if (kvp.Key == type && (kvp.Value == null || kvp.Value == rayOrigin)) { AddSettingsMenuItem(providerPair.Value); } } } } } MainMenuButton CreateFaceButton(MainMenuUI.ButtonData buttonData, ITooltip tooltip, Action buttonClickCallback) { var mainMenuButton = m_MainMenuUI.CreateFaceButton(buttonData); if (mainMenuButton == null) { return(null); } var button = mainMenuButton.button; button.onClick.RemoveAllListeners(); button.onClick.AddListener(() => { if (m_MenuHideFlags == 0) { buttonClickCallback(); } }); mainMenuButton.hovered += OnButtonHovered; mainMenuButton.clicked += OnButtonClicked; mainMenuButton.tooltip = tooltip; return(mainMenuButton); } void UpdateToolButtons() { foreach (var kvp in m_ToolButtons) { kvp.Value.selected = this.IsToolActive(targetRayOrigin, kvp.Key); } } void OnButtonClicked(Transform rayOrigin) { this.Pulse(this.RequestNodeFromRayOrigin(rayOrigin), m_ButtonClickPulse); this.ClearToolMenuButtonPreview(); } void OnButtonHovered(Transform rayOrigin, Type buttonType, string buttonDescription) { this.Pulse(this.RequestNodeFromRayOrigin(rayOrigin), m_ButtonHoverPulse); // Pass the pointer which is over us, so this information can supply context (e.g. selecting a tool for a different hand) // Enable preview-mode on a Tools Menu button; Display on the opposite proxy device by evaluating the entering RayOrigin // Disable any existing previews being displayed in ToolsMenus this.ClearToolMenuButtonPreview(); if (buttonType != null && rayOrigin != null) { this.PreviewInToolMenuButton(rayOrigin, buttonType, buttonDescription); } } void OnToggleHovered(Transform rayOrigin) { this.Pulse(this.RequestNodeFromRayOrigin(rayOrigin), m_ButtonHoverPulse); } void SendVisibilityPulse() { this.Pulse(node, m_MenuHideFlags == 0 ? m_HidePulse : m_ShowPulse); }