diff --git a/Editor/Toolbar/Settings/ToolbarSettings.cs b/Editor/Toolbar/Settings/ToolbarSettings.cs index 75148c8..80645f1 100644 --- a/Editor/Toolbar/Settings/ToolbarSettings.cs +++ b/Editor/Toolbar/Settings/ToolbarSettings.cs @@ -7,10 +7,12 @@ namespace Module.NavigationTool.Editor.Toolbar private const string PREF_IS_UI_ENABLED = "ToolbarSettings_IsUiEnabled"; private const string PREF_IS_UI_LAYER_ENABLED = "ToolbarSettings_IsUiLayerEnabled"; private const string PREF_IS_SCENE_ENABLED = "ToolbarSettings_IsSceneEnabled"; + private const string PREF_IS_BUILD_ENABLED = "ToolbarSettings.IsBuildEnabled"; + private const string PREF_IS_BUILD_AND_RUN_ENABLED = "ToolbarSettings.IsBuildAndRunEnabled"; private const string PREF_IS_TIME_SCALE_ENABLED = "ToolbarSettings.IsTimeScaleEnabled"; private const string PREF_TIME_SCALE_MIN = "ToolbarSettings.TimeScaleMin"; private const string PREF_TIME_SCALE_MAX = "ToolbarSettings.TimeScaleMax"; - + public static bool IsUiEnabled { get => EditorPrefs.GetBool(PREF_IS_UI_ENABLED, false); @@ -29,18 +31,30 @@ namespace Module.NavigationTool.Editor.Toolbar set => EditorPrefs.SetBool(PREF_IS_SCENE_ENABLED, value); } + public static bool IsBuildEnabled + { + get => EditorPrefs.GetBool(PREF_IS_BUILD_ENABLED, false); + set => EditorPrefs.SetBool(PREF_IS_BUILD_ENABLED, value); + } + + public static bool IsBuildAndRunEnabled + { + get => EditorPrefs.GetBool(PREF_IS_BUILD_AND_RUN_ENABLED, true); + set => EditorPrefs.SetBool(PREF_IS_BUILD_AND_RUN_ENABLED, value); + } + public static bool IsTimeScaleEnabled { get => EditorPrefs.GetBool(PREF_IS_TIME_SCALE_ENABLED, false); set => EditorPrefs.SetBool(PREF_IS_TIME_SCALE_ENABLED, value); } - + public static float TimeScaleMinValue { get => EditorPrefs.GetFloat(PREF_TIME_SCALE_MIN, 0.0f); set => EditorPrefs.SetFloat(PREF_TIME_SCALE_MIN, value); } - + public static float TimeScaleMaxValue { get => EditorPrefs.GetFloat(PREF_TIME_SCALE_MAX, 1.0f); diff --git a/Editor/Toolbar/Settings/ToolbarSettingsProvider.cs b/Editor/Toolbar/Settings/ToolbarSettingsProvider.cs index 1707a98..ec6e6ae 100644 --- a/Editor/Toolbar/Settings/ToolbarSettingsProvider.cs +++ b/Editor/Toolbar/Settings/ToolbarSettingsProvider.cs @@ -35,6 +35,10 @@ namespace Module.NavigationTool.Editor.Toolbar EditorGUILayout.LabelField("Scene", EditorStyles.boldLabel); ToolbarSettings.IsSceneEnabled = EditorGUILayout.Toggle("Enable Scene picker", ToolbarSettings.IsSceneEnabled); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Build Target", EditorStyles.boldLabel); + ToolbarSettings.IsBuildEnabled = EditorGUILayout.Toggle("Enable Build Target picker", ToolbarSettings.IsBuildEnabled); + EditorGUILayout.Space(); EditorGUILayout.LabelField("Time", EditorStyles.boldLabel); ToolbarSettings.IsTimeScaleEnabled = EditorGUILayout.Toggle("Enable Time Scale slider", ToolbarSettings.IsTimeScaleEnabled); diff --git a/Editor/Toolbar/ToolbarDrawer.cs b/Editor/Toolbar/ToolbarDrawer.cs index e319c5e..122480b 100644 --- a/Editor/Toolbar/ToolbarDrawer.cs +++ b/Editor/Toolbar/ToolbarDrawer.cs @@ -61,11 +61,11 @@ namespace Module.NavigationTool.Editor.Toolbar if (drawer.Visible && !valid) { - var rect = new Rect(0.0f, 0.0f, drawer.CalculateWidth(), HEIGHT); + var rect = new Rect(2.0f, 0.0f, drawer.CalculateWidth(), HEIGHT); drawer.Setup(rect); var container = new ToolbarIMGUIContainer(drawer.OnGUI, drawer.Priority); - container.style.width = rect.width; + container.style.width = rect.width + 4.0f; DICT_MAPPING.Add(drawer, container); added = true; diff --git a/Editor/Toolbar/Tools/ToolBuild.cs b/Editor/Toolbar/Tools/ToolBuild.cs new file mode 100644 index 0000000..fd1dd22 --- /dev/null +++ b/Editor/Toolbar/Tools/ToolBuild.cs @@ -0,0 +1,77 @@ +using JetBrains.Annotations; +using UnityEditor; +using UnityEngine; +using UTools = UnityEditor.Tools; + +namespace Module.NavigationTool.Editor.Toolbar +{ + [UsedImplicitly] + internal sealed class ToolBuild : AbstractToolbarDrawer + { + public override bool Visible => ToolbarSettings.IsBuildEnabled; + public override bool Enabled => !Application.isPlaying; + public override EToolbarPlacement Placement => EToolbarPlacement.Left; + public override int Priority => (int)EToolbarPriority.Low; + + private static bool IS_DIRTY = true; + private static GUIContent[] BUTTON_LIST = new GUIContent[0]; + private static GUIContent[] CONTENT_LIST = new GUIContent[0]; + private static GUIContent DROPDOWN = new GUIContent(); + + private static void Initialize() + { + if (!IS_DIRTY) + return; + + BUTTON_LIST = new[] + { + new GUIContent("Build"), + new GUIContent("Build & Run") + }; + + CONTENT_LIST = new[] + { + new GUIContent("Build"), + new GUIContent("Build and Run") + }; + + DROPDOWN = EditorGUIUtility.IconContent("d_icon dropdown"); + + IS_DIRTY = false; + } + + public override void Update() + { + Initialize(); + } + + protected override void Draw(Rect rect) + { + var rect0 = new Rect(rect.x, rect.y, rect.width - 16.0f, rect.height); + var rect1 = new Rect(rect0.xMax, rect.y, 16.0f, rect.height); + + int currentSelected = ToolbarSettings.IsBuildAndRunEnabled ? 1 : 0; + + if (GUI.Button(rect0, BUTTON_LIST[currentSelected], styles.buttonNoPadding)) + { + BuildPlayerOptions options = BuildPlayerWindow.DefaultBuildMethods.GetBuildPlayerOptions(new BuildPlayerOptions()); + options.options |= BuildOptions.AutoRunPlayer; + BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(options); + } + + if (GUI.Button(rect1, DROPDOWN, styles.button)) + { + EditorUtility.DisplayCustomMenu(rect, CONTENT_LIST, currentSelected, (_, _, selected) => + { + if (selected != -1) + ToolbarSettings.IsBuildAndRunEnabled = selected == 1; + }, null); + } + } + + public override float CalculateWidth() + { + return 100.0f; + } + } +} \ No newline at end of file diff --git a/Editor/Toolbar/Tools/ToolBuild.cs.meta b/Editor/Toolbar/Tools/ToolBuild.cs.meta new file mode 100644 index 0000000..f6dedf8 --- /dev/null +++ b/Editor/Toolbar/Tools/ToolBuild.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f8e26a1e2caa4d49bb92f6887ac243dd +timeCreated: 1644777135 \ No newline at end of file diff --git a/Editor/Toolbar/Tools/ToolBuildTargetPicker.cs b/Editor/Toolbar/Tools/ToolBuildTargetPicker.cs new file mode 100644 index 0000000..20fb23a --- /dev/null +++ b/Editor/Toolbar/Tools/ToolBuildTargetPicker.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using JetBrains.Annotations; +using UnityEditor; +using UnityEngine; +using UTools = UnityEditor.Tools; + +namespace Module.NavigationTool.Editor.Toolbar +{ + [UsedImplicitly] + internal sealed class ToolBuildTargetPicker : AbstractToolbarDrawer + { + public override bool Visible => ToolbarSettings.IsBuildEnabled; + public override bool Enabled => !Application.isPlaying; + public override EToolbarPlacement Placement => EToolbarPlacement.Left; + public override int Priority => (int)EToolbarPriority.Low; + + private static bool IS_DIRTY = true; + private static int[] HASHES = new int[0]; + private static BuildTargetGroup[] GROUPS = new BuildTargetGroup[0]; + private static BuildTarget[] TARGETS = new BuildTarget[0]; + private static GUIContent[] TARGET_LIST = new GUIContent[0]; + private static int SELECTED_INDEX = -1; + + private static void Initialize() + { + if (!IS_DIRTY) + return; + + BuildTarget target = EditorUserBuildSettings.activeBuildTarget; + BuildTargetGroup group = BuildPipeline.GetBuildTargetGroup(target); + + PopulateBuildTargetList(); + SELECTED_INDEX = Array.IndexOf(HASHES, GetHashCode(group, target)); + IS_DIRTY = false; + } + + public override void Update() + { + Initialize(); + } + + protected override void Draw(Rect rect) + { + BuildTarget target = EditorUserBuildSettings.activeBuildTarget; + BuildTargetGroup group = BuildPipeline.GetBuildTargetGroup(target); + GUIContent content = SELECTED_INDEX != -1 ? GetButtonContent(group) : GUIContent.none; + + if (GUI.Button(rect, content, styles.buttonNoPadding)) + { + EditorUtility.DisplayCustomMenu(rect, TARGET_LIST, SELECTED_INDEX, (_, _, selected) => + { + if (selected != -1 && selected != SELECTED_INDEX) + SetBuildTargetTo(selected); + }, null); + } + } + + public override float CalculateWidth() + { + return 40.0f; + } + + private static void SetBuildTargetTo(int index) + { + if (index < 0) + return; + + BuildTargetGroup group = GROUPS[index]; + BuildTarget target = TARGETS[index]; + + if (!EditorUserBuildSettings.SwitchActiveBuildTarget(@group, target)) + return; + + IS_DIRTY = true; + SELECTED_INDEX = index; + } + + private static void PopulateBuildTargetList() + { + var hashes = new List(); + var groups = new List(); + var targets = new List(); + var contentList = new List(); + + Type type = typeof(BuildTarget); + Array values = Enum.GetValues(type); + + for (var i = 0; i < values.Length; i++) + { + var target = (BuildTarget)values.GetValue(i); + BuildTargetGroup group = BuildPipeline.GetBuildTargetGroup(target); + + if (target < 0 || !BuildPipeline.IsBuildTargetSupported(group, target)) + continue; + if (!IsValid(type, target)) + continue; + + hashes.Add(GetHashCode(group, target)); + groups.Add(group); + targets.Add(target); + contentList.Add(new GUIContent(ObjectNames.NicifyVariableName(target.ToString()))); + } + + HASHES = hashes.ToArray(); + GROUPS = groups.ToArray(); + TARGETS = targets.ToArray(); + TARGET_LIST = contentList.ToArray(); + } + + private static bool IsValid(Type type, BuildTarget target) + { + MemberInfo[] members = type.GetMember(target.ToString(), BindingFlags.Public | BindingFlags.Static); + + if (members.Length == 0) + return false; + + for (var j = 0; j < members.Length; j++) + { + if (members[j].GetCustomAttribute() == null) + return true; + } + + return false; + } + + private static GUIContent GetButtonContent(BuildTargetGroup group) + { + var name = $"BuildSettings.{group}.Small"; + + if (group == BuildTargetGroup.WSA) + name = "BuildSettings.Metro.Small"; + + return EditorGUIUtility.IconContent(name); + } + + private static int GetHashCode(BuildTargetGroup group, BuildTarget target) + { + return ((int)group << 16) + (int)target; + } + } +} \ No newline at end of file diff --git a/Editor/Toolbar/Tools/ToolBuildTargetPicker.cs.meta b/Editor/Toolbar/Tools/ToolBuildTargetPicker.cs.meta new file mode 100644 index 0000000..c63a733 --- /dev/null +++ b/Editor/Toolbar/Tools/ToolBuildTargetPicker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 966d40900b7547b6997863f3fbbf2cd5 +timeCreated: 1644752271 \ No newline at end of file diff --git a/Editor/Toolbar/Tools/ToolUICanvasPicker.cs b/Editor/Toolbar/Tools/ToolUICanvasPicker.cs index 984ffef..b46bf34 100644 --- a/Editor/Toolbar/Tools/ToolUICanvasPicker.cs +++ b/Editor/Toolbar/Tools/ToolUICanvasPicker.cs @@ -80,7 +80,7 @@ namespace Module.NavigationTool.Editor.Toolbar public override float CalculateWidth() { - return 100.0f; + return 72.0f; } private static void Focus(int instanceId) diff --git a/Editor/Toolbar/Utilities/Styles.cs b/Editor/Toolbar/Utilities/Styles.cs index 12a9bfd..cbbb879 100644 --- a/Editor/Toolbar/Utilities/Styles.cs +++ b/Editor/Toolbar/Utilities/Styles.cs @@ -6,6 +6,7 @@ namespace Module.NavigationTool.Editor.Toolbar { public GUIStyle popup; public GUIStyle button; + public GUIStyle buttonNoPadding; public GUIStyle slider; public GUIStyle label; public GUIStyle labelCenter; @@ -20,6 +21,8 @@ namespace Module.NavigationTool.Editor.Toolbar this.skin = skin; popup = skin.FindStyle("ToolbarPopup"); button = skin.FindStyle("toolbarbutton"); + buttonNoPadding = skin.FindStyle("toolbarbutton"); + buttonNoPadding.padding = new RectOffset(); slider = skin.FindStyle("ToolbarSlider"); label = skin.FindStyle("ToolbarLabel"); labelCenter = skin.FindStyle("ToolbarLabel"); diff --git a/package.json b/package.json index 4876679..5f1bec9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.module.navigationtool", - "version": "1.3.3", + "version": "1.4.0", "displayName": "Module.NavigationTool", "description": "Support for navigation tools, like favorites, history and toolbars", "unity": "2019.2",