// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 // Standard Libraries using System; using System.Linq; // Unity using UnityEditor; using UnityEngine; // GameKit using AWS.GameKit.Runtime.Utils; namespace AWS.GameKit.Editor.GUILayoutExtensions { /// /// A GUI element which displays a tab selector at the top and the selected tab's contents below. /// /// This is a wrapper around the GUILayout.Toolbar() function: https://docs.unity3d.com/ScriptReference/GUILayout.Toolbar.html /// [Serializable] public class TabWidget : IDrawable { // State [SerializeField] private int _selectedTabId; // Data private string[] _tabNames; private IDrawable[] _tabContents; private GUI.ToolbarButtonSize _tabSelectorButtonSize; /// /// Initializes a tab widget. /// /// See Unity's GUILayout.Toolbar() for details on the parameters: https://docs.unity3d.com/ScriptReference/GUILayout.Toolbar.html /// /// An array of all the tabs to display with this tab widget. It must contain at least one element. /// Determines how the toolbar button size is calculated. /// Thrown when the array is empty. public void Initialize(Tab[] tabs, GUI.ToolbarButtonSize tabSelectorButtonSize) { if (tabs.Length == 0) { throw new ArgumentException($"The '{nameof(tabs)}' parameter is empty. It must contain at least one element."); } // Data _tabNames = tabs.Select(tab => tab.DisplayName).ToArray(); _tabContents = tabs.Select(tab => tab.TabContent).ToArray(); // Clamp the selected tab id in case our previously selected tab is out of bounds _selectedTabId = Mathf.Clamp(_selectedTabId, 0, tabs.Length); _tabSelectorButtonSize = tabSelectorButtonSize; } /// /// Change the currently selected tab to the named tab. /// /// The name of the tab to select. Must be the name of one of the tabs passed into the constructor. /// Otherwise, an Error will be logged and the tab selection will not change. public void SelectTab(string tabName) { int nextTabId = Array.IndexOf(_tabNames, tabName); if (nextTabId < 0) { // Wrap the tab names in quotes, like: "NameOne", "NameTwo", "NameThree" string validTabNames = $"\"{string.Join("\", \"", _tabNames)}\""; string currentTabName = _tabNames[_selectedTabId]; Logging.LogError($"There is no tab named \"{tabName}\". Valid tab names are: {validTabNames}. The selected tab will remain \"{currentTabName}\"."); return; } _selectedTabId = nextTabId; } /// /// Draw the tab selector and the contents of the selected tab. /// /// The tab selector buttons will use the default button style from the current UnityEngine.GUISkin. /// public void OnGUI() { OnGUI(GUI.skin.button); } /// /// Draw the tab selector and the contents of the selected tab. /// /// The style to use for the tab selector buttons. public void OnGUI(GUIStyle tabSelectorStyle) { DrawTabSelector(tabSelectorStyle); DrawTabContent(); } private void DrawTabSelector(GUIStyle tabSelectorStyle) { using (new EditorGUILayout.HorizontalScope()) { GUILayout.FlexibleSpace(); _selectedTabId = EditorGUILayoutElements.CreateFeatureToolbar(_selectedTabId, _tabNames, _tabSelectorButtonSize, tabSelectorStyle); GUILayout.FlexibleSpace(); } } private void DrawTabContent() { IDrawable selectedTab = _tabContents[_selectedTabId]; selectedTab.OnGUI(); } } }