diff --git a/.editorconfig b/.editorconfig index 22ce701..aa21d10 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,38 +1,37 @@ -# see editorconfig.org for usage and download of other editor plugins (emacs, notepad++, vim, etc..) -# -# installation: -# -# * visual studio 2010+ -# * Tools | Extensions and Updates -> Online -> EditorConfig -# * [https://github.com/editorconfig/editorconfig-visualstudio] -# * sublime text 2+ -# * Tools | Command Palette... Install Package -> EditorConfig -# * [https://github.com/sindresorhus/editorconfig-sublime] +# see http://editorconfig.org/ for docs on this file root = true -# | feature supported by -# +---------------------------------------------------------------------------- -# | vstudio | sublime -# | indent_style X | X -# | indent_size X | X -# | tab_width X | -# | end_of_line X | X -# | charset | X -# | trim_trailing_whitespace X | X -# | insert_final_newline X | X - [*] indent_style = space indent_size = 4 -tab_width = 4 end_of_line = lf ; help with sharing files across os's (i.e. network share or through local vm) charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true +# trailing whitespace is significant in markdown (bad choice, bad!) [*.{md,markdown}] trim_trailing_whitespace = false -[.hgignore] +# keep these and the VS stuff below in sync with .hgeol's CRLF extensions +[*.{vcproj,bat,cmd,xaml,tt,t4,ttinclude}] end_of_line = crlf + +# this VS-specific stuff is based on experiments to see how VS will modify a file after it has been manually edited. +# the settings are meant to closely match what VS does to minimize unnecessary diffs. this duplicates settings in * +# but let's be explicit here to be safe (in case someone wants to copy-paste this out to another .editorconfig). +[*.{vcxproj,vcxproj.filters,csproj}] +indent_style = space +indent_size = 2 +end_of_line = crlf +charset = utf-8-bom +trim_trailing_whitespace = true +insert_final_newline = false +[*.{sln,sln.template}] +indent_style = tab +indent_size = 4 +end_of_line = crlf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = false diff --git a/.hgeol b/.hgeol new file mode 100644 index 0000000..80cfca5 --- /dev/null +++ b/.hgeol @@ -0,0 +1,25 @@ +[repository] +native = LF +[eol] +only-consistent = False +[patterns] +**.cs = LF +**.md = LF +**.txt = LF +.editorconfig = LF +.hgignore = LF +.hgtags = LF +LICENSE = LF + +## keep CRLF's in sync with .editorconfig + +# vs can handle these as lf, but really wants them as crlf +**.vcproj = CRLF +**.vcxproj = CRLF +**.vcxproj.filters = CRLF +**.csproj = CRLF +**.sln = CRLF +**.sln.template = CRLF +**.bat = CRLF +**.cmd = CRLF +**.xaml = CRLF diff --git a/LICENSE b/LICENSE index 55c18c6..f7471fd 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014, Unity Technologies +Copyright (c) 2014-2015, Unity Technologies Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index e0590f2..5e80697 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,36 @@ -# README # - -The Unity UI system is open and available for use in your games and applications. This document details how to get it up and running on your computer and start modifying the code! - -### What license is the UI system shipped under? ### -Like the rest of the Unity open source projects, the UI system is released under an MIT/X11 license. - -### How do I get started? ### -* Clone this repository onto a location on your computer. -* Configure your IDE for the Unity coding standard, look in the .editorconfig file for more information -+ Open the project in Visual Studio or MonoDevelop - + If you are using MonoDevelop - * Ensure you enable XBuild (Preferences -> Projects -> Build ->"Compile projects using MSBuild/XBuild") - * You may need to restart MonoDevelop - * Build the solution - -+ A folder will be created in the root directory called "Output", the generated dll's will output here in the correct folder structure - * If you wish to use these dll's - * Locate your Unity install location - * Windows: Copy the contents of Output folder to: `Data\UnityExtensions\Unity\GUISystem\{UNITY_VERSION}` - * OSX: Copy the contents of Output folder to: `Unity.app/Contents/UnityExtensions/Unity/GUISystem/{UNITY_VERSION}` - -+ If you want the dll's to copy automatically on build - + For each visual studio project file - * Open the file in a text editor - * Locate the section: - * Follow the instructions in the comments - -### Will you be taking pull requests? ### -At this stage the UI system is undergoing further development internally with many design decisions still being debated and implemented. Also, we are waiting to see the volume of pull requests and the time it will take the process them. As such, we are prioritizing first bug fix pull requests and will iterate on this process going forward. \ No newline at end of file +# README # + +The Unity UI system is open and available for use in your games and applications. This document details how to get it up and running on your computer and start modifying the code! + +### What license is the UI system shipped under? ### +The UI system is released under an MIT/X11 license; see the LICENSE file. + +This means that you pretty much can customize and embed it in any software under any license without any other constraints than preserving the copyright and license information while adding your own copyright and license information. + +You can keep the source to yourself or share your customized version under the same MIT license or a compatible license. + +If you want to contribute patches back, please keep it under the unmodified MIT license so it can be integrated in future versions and shared under the same license. + +### How do I get started? ### +* Clone this repository onto a location on your computer. +* Configure your IDE for the Unity coding standard, look in the .editorconfig file for more information +* Open the project in Visual Studio or MonoDevelop + * If you are using MonoDevelop + * Ensure you enable XBuild (Preferences -> Projects -> Build ->"Compile projects using MSBuild/XBuild") + * You may need to restart MonoDevelop + * Build the solution + +* A folder will be created in the root directory called "Output", the generated dll's will output here in the correct folder structure + * If you wish to use these dll's + * Locate your Unity install location + * Windows: Copy the contents of Output folder to: `Data\UnityExtensions\Unity\GUISystem\{UNITY_VERSION}` + * OSX: Copy the contents of Output folder to: `Unity.app/Contents/UnityExtensions/Unity/GUISystem/{UNITY_VERSION}` + +* If you want the dll's to copy automatically on build + * For each visual studio project file + * Open the file in a text editor + * Locate the section: + * Follow the instructions in the comments + +### Will you be taking pull requests? ### +At this stage the UI system is undergoing further development internally with many design decisions still being debated and implemented. Also, we are waiting to see the volume of pull requests and the time it will take the process them. As such, we are prioritizing first bug fix pull requests and will iterate on this process going forward. diff --git a/UnityEditor.UI/EventSystem/EventSystemEditor.cs b/UnityEditor.UI/EventSystem/EventSystemEditor.cs index d17feeb..729b584 100644 --- a/UnityEditor.UI/EventSystem/EventSystemEditor.cs +++ b/UnityEditor.UI/EventSystem/EventSystemEditor.cs @@ -20,9 +20,7 @@ public override void OnInspectorGUI() // no input modules :( if (GUILayout.Button("Add Default Input Modules")) { - Undo.RecordObject(eventSystem, "Add default input modules"); - eventSystem.gameObject.AddComponent(); - eventSystem.gameObject.AddComponent(); + Undo.AddComponent(eventSystem.gameObject); } } diff --git a/UnityEditor.UI/EventSystem/EventTriggerEditor.cs b/UnityEditor.UI/EventSystem/EventTriggerEditor.cs index 232d07e..37811df 100644 --- a/UnityEditor.UI/EventSystem/EventTriggerEditor.cs +++ b/UnityEditor.UI/EventSystem/EventTriggerEditor.cs @@ -16,7 +16,7 @@ public class EventTriggerEditor : Editor protected virtual void OnEnable() { - m_DelegatesProperty = serializedObject.FindProperty("delegates"); + m_DelegatesProperty = serializedObject.FindProperty("m_Delegates"); m_AddButonContent = new GUIContent("Add New Event Type"); m_EventIDName = new GUIContent(""); // Have to create a copy since otherwise the tooltip will be overwritten. diff --git a/UnityEditor.UI/UI/CanvasScalerEditor.cs b/UnityEditor.UI/UI/CanvasScalerEditor.cs index 9bff83d..25b02c9 100644 --- a/UnityEditor.UI/UI/CanvasScalerEditor.cs +++ b/UnityEditor.UI/UI/CanvasScalerEditor.cs @@ -25,6 +25,7 @@ private class Styles public GUIContent matchContent; public GUIContent widthContent; public GUIContent heightContent; + public GUIContent uiScaleModeContent; public GUIStyle leftAlignedLabel; public GUIStyle rightAlignedLabel; @@ -33,6 +34,7 @@ public Styles() matchContent = new GUIContent("Match"); widthContent = new GUIContent("Width"); heightContent = new GUIContent("Height"); + uiScaleModeContent = new GUIContent("UI Scale Mode"); leftAlignedLabel = new GUIStyle(EditorStyles.label); rightAlignedLabel = new GUIStyle(EditorStyles.label); @@ -91,11 +93,11 @@ public override void OnInspectorGUI() EditorGUI.BeginDisabledGroup(showWorld || showWorldDiffers); if (showWorld || showWorldDiffers) { - EditorGUILayout.Popup(m_UiScaleMode.displayName, 0, new string[] { "World" }); + EditorGUILayout.Popup(s_Styles.uiScaleModeContent.text, 0, new[] { "World" }); } else { - EditorGUILayout.PropertyField(m_UiScaleMode); + EditorGUILayout.PropertyField(m_UiScaleMode, s_Styles.uiScaleModeContent); } EditorGUI.EndDisabledGroup(); EditorGUI.showMixedValue = false; diff --git a/UnityEditor.UI/UI/DropdownEditor.cs b/UnityEditor.UI/UI/DropdownEditor.cs new file mode 100644 index 0000000..1dd16e4 --- /dev/null +++ b/UnityEditor.UI/UI/DropdownEditor.cs @@ -0,0 +1,48 @@ +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomEditor(typeof(Dropdown), true)] + [CanEditMultipleObjects] + public class DropdownEditor : SelectableEditor + { + SerializedProperty m_Template; + SerializedProperty m_CaptionText; + SerializedProperty m_CaptionImage; + SerializedProperty m_ItemText; + SerializedProperty m_ItemImage; + SerializedProperty m_OnSelectionChanged; + SerializedProperty m_Value; + SerializedProperty m_Options; + + protected override void OnEnable() + { + base.OnEnable(); + m_Template = serializedObject.FindProperty("m_Template"); + m_CaptionText = serializedObject.FindProperty("m_CaptionText"); + m_CaptionImage = serializedObject.FindProperty("m_CaptionImage"); + m_ItemText = serializedObject.FindProperty("m_ItemText"); + m_ItemImage = serializedObject.FindProperty("m_ItemImage"); + m_OnSelectionChanged = serializedObject.FindProperty("m_OnValueChanged"); + m_Value = serializedObject.FindProperty("m_Value"); + m_Options = serializedObject.FindProperty("m_Options"); + } + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + EditorGUILayout.Space(); + + serializedObject.Update(); + EditorGUILayout.PropertyField(m_Template); + EditorGUILayout.PropertyField(m_CaptionText); + EditorGUILayout.PropertyField(m_CaptionImage); + EditorGUILayout.PropertyField(m_ItemText); + EditorGUILayout.PropertyField(m_ItemImage); + EditorGUILayout.PropertyField(m_Value); + EditorGUILayout.PropertyField(m_Options); + EditorGUILayout.PropertyField(m_OnSelectionChanged); + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/UnityEditor.UI/UI/GraphicEditor.cs b/UnityEditor.UI/UI/GraphicEditor.cs index be4ceab..3fc16ee 100644 --- a/UnityEditor.UI/UI/GraphicEditor.cs +++ b/UnityEditor.UI/UI/GraphicEditor.cs @@ -16,6 +16,7 @@ public class GraphicEditor : Editor protected SerializedProperty m_Script; protected SerializedProperty m_Color; protected SerializedProperty m_Material; + protected SerializedProperty m_RaycastTarget; private GUIContent m_CorrectButtonContent; protected AnimBool m_ShowNativeSize; @@ -33,6 +34,7 @@ protected virtual void OnEnable() m_Script = serializedObject.FindProperty("m_Script"); m_Color = serializedObject.FindProperty("m_Color"); m_Material = serializedObject.FindProperty("m_Material"); + m_RaycastTarget = serializedObject.FindProperty("m_RaycastTarget"); m_ShowNativeSize = new AnimBool(false); m_ShowNativeSize.valueChanged.AddListener(Repaint); @@ -43,6 +45,7 @@ public override void OnInspectorGUI() serializedObject.Update(); EditorGUILayout.PropertyField(m_Script); AppearanceControlsGUI(); + RaycastControlsGUI(); serializedObject.ApplyModifiedProperties(); } @@ -81,5 +84,10 @@ protected void AppearanceControlsGUI() EditorGUILayout.PropertyField(m_Color); EditorGUILayout.PropertyField(m_Material); } + + protected void RaycastControlsGUI() + { + EditorGUILayout.PropertyField(m_RaycastTarget); + } } } diff --git a/UnityEditor.UI/UI/ImageEditor.cs b/UnityEditor.UI/UI/ImageEditor.cs index 0283caa..676a5e0 100644 --- a/UnityEditor.UI/UI/ImageEditor.cs +++ b/UnityEditor.UI/UI/ImageEditor.cs @@ -75,6 +75,7 @@ public override void OnInspectorGUI() SpriteGUI(); AppearanceControlsGUI(); + RaycastControlsGUI(); m_ShowType.target = m_Sprite.objectReferenceValue != null; if (EditorGUILayout.BeginFadeGroup(m_ShowType.faded)) diff --git a/UnityEditor.UI/UI/InputFieldEditor.cs b/UnityEditor.UI/UI/InputFieldEditor.cs index f724c7b..aa6b9e2 100644 --- a/UnityEditor.UI/UI/InputFieldEditor.cs +++ b/UnityEditor.UI/UI/InputFieldEditor.cs @@ -1,3 +1,4 @@ +using UnityEditor.AnimatedValues; using UnityEngine; using UnityEngine.UI; @@ -16,11 +17,17 @@ public class InputFieldEditor : SelectableEditor SerializedProperty m_KeyboardType; SerializedProperty m_CharacterLimit; SerializedProperty m_CaretBlinkRate; + SerializedProperty m_CaretWidth; + SerializedProperty m_CaretColor; + SerializedProperty m_CustomCaretColor; SerializedProperty m_SelectionColor; SerializedProperty m_HideMobileInput; SerializedProperty m_Placeholder; - SerializedProperty m_OnValueChange; - SerializedProperty m_EndEdit; + SerializedProperty m_OnValueChanged; + SerializedProperty m_OnEndEdit; + SerializedProperty m_ReadOnly; + + AnimBool m_CustomColor; protected override void OnEnable() { @@ -34,11 +41,24 @@ protected override void OnEnable() m_KeyboardType = serializedObject.FindProperty("m_KeyboardType"); m_CharacterLimit = serializedObject.FindProperty("m_CharacterLimit"); m_CaretBlinkRate = serializedObject.FindProperty("m_CaretBlinkRate"); + m_CaretWidth = serializedObject.FindProperty("m_CaretWidth"); + m_CaretColor = serializedObject.FindProperty("m_CaretColor"); + m_CustomCaretColor = serializedObject.FindProperty("m_CustomCaretColor"); m_SelectionColor = serializedObject.FindProperty("m_SelectionColor"); m_HideMobileInput = serializedObject.FindProperty("m_HideMobileInput"); m_Placeholder = serializedObject.FindProperty("m_Placeholder"); - m_OnValueChange = serializedObject.FindProperty("m_OnValueChange"); - m_EndEdit = serializedObject.FindProperty("m_EndEdit"); + m_OnValueChanged = serializedObject.FindProperty("m_OnValueChanged"); + m_OnEndEdit = serializedObject.FindProperty("m_OnEndEdit"); + m_ReadOnly = serializedObject.FindProperty("m_ReadOnly"); + + m_CustomColor = new AnimBool(m_CustomCaretColor.boolValue); + m_CustomColor.valueChanged.AddListener(Repaint); + } + + protected override void OnDisable() + { + base.OnDisable(); + m_CustomColor.valueChanged.RemoveListener(Repaint); } public override void OnInspectorGUI() @@ -58,13 +78,6 @@ public override void OnInspectorGUI() { EditorGUILayout.HelpBox("Using Rich Text with input is unsupported.", MessageType.Warning); } - - if (text.alignment != TextAnchor.UpperLeft && - text.alignment != TextAnchor.UpperCenter && - text.alignment != TextAnchor.UpperRight) - { - EditorGUILayout.HelpBox("Using a non upper alignment with input is unsupported.", MessageType.Warning); - } } EditorGUI.BeginDisabledGroup(m_TextComponent == null || m_TextComponent.objectReferenceValue == null); @@ -98,13 +111,26 @@ public override void OnInspectorGUI() EditorGUILayout.PropertyField(m_Placeholder); EditorGUILayout.PropertyField(m_CaretBlinkRate); + EditorGUILayout.PropertyField(m_CaretWidth); + + EditorGUILayout.PropertyField(m_CustomCaretColor); + + m_CustomColor.target = m_CustomCaretColor.boolValue; + + if (EditorGUILayout.BeginFadeGroup(m_CustomColor.faded)) + { + EditorGUILayout.PropertyField(m_CaretColor); + } + EditorGUILayout.EndFadeGroup(); + EditorGUILayout.PropertyField(m_SelectionColor); EditorGUILayout.PropertyField(m_HideMobileInput); + EditorGUILayout.PropertyField(m_ReadOnly); EditorGUILayout.Space(); - EditorGUILayout.PropertyField(m_OnValueChange); - EditorGUILayout.PropertyField(m_EndEdit); + EditorGUILayout.PropertyField(m_OnValueChanged); + EditorGUILayout.PropertyField(m_OnEndEdit); EditorGUI.EndDisabledGroup(); diff --git a/UnityEditor.UI/UI/InterceptedEventsPreview.cs b/UnityEditor.UI/UI/InterceptedEventsPreview.cs index aa93fc4..4d5e09c 100644 --- a/UnityEditor.UI/UI/InterceptedEventsPreview.cs +++ b/UnityEditor.UI/UI/InterceptedEventsPreview.cs @@ -13,7 +13,7 @@ class InterceptedEventsPreview : ObjectPreview protected class ComponentInterceptedEvents { public GUIContent componentName; - public GUIContent[] interceptedEvents; + public int[] interceptedEvents; } class Styles @@ -45,24 +45,27 @@ public Styles() } } - private Dictionary m_TargetEvents; + private Dictionary> m_TargetEvents; private bool m_InterceptsAnyEvent = false; private GUIContent m_Title; private Styles m_Styles = new Styles(); public override void Initialize(UnityEngine.Object[] targets) { + Profiler.BeginSample("ComponentInterceptedEvents.Initialize"); + base.Initialize(targets); - m_TargetEvents = new Dictionary(targets.Count()); + m_TargetEvents = new Dictionary>(targets.Count()); m_InterceptsAnyEvent = false; - foreach (var t in targets) + for (int i = 0; i < targets.Length; ++i) { - GameObject go = t as GameObject; - ComponentInterceptedEvents[] interceptedEvents = GetEventsInfo(go); + GameObject go = targets[i] as GameObject; + List interceptedEvents = GetEventsInfo(go); m_TargetEvents.Add(go, interceptedEvents); if (interceptedEvents.Any()) m_InterceptsAnyEvent = true; } + Profiler.EndSample(); } public override GUIContent GetPreviewTitle() @@ -83,6 +86,8 @@ public override void OnPreviewGUI(Rect r, GUIStyle background) { if (Event.current.type != EventType.Repaint) return; + Profiler.BeginSample("InterceptedEventsPreview.OnPreviewGUI"); + if (m_Styles == null) m_Styles = new Styles(); @@ -90,13 +95,14 @@ public override void OnPreviewGUI(Rect r, GUIStyle background) Vector2 maxEventLabelSize = Vector2.zero; int totalInterceptedEvents = 0; - ComponentInterceptedEvents[] componentIncerceptedEvents = m_TargetEvents[target as GameObject]; + List componentIncerceptedEvents = m_TargetEvents[target as GameObject]; // Find out the maximum size needed for any given label. foreach (ComponentInterceptedEvents componentInterceptedEvents in componentIncerceptedEvents) { - foreach (GUIContent eventContent in componentInterceptedEvents.interceptedEvents) + foreach (int eventIndex in componentInterceptedEvents.interceptedEvents) { + GUIContent eventContent = s_PossibleEvents[eventIndex]; ++totalInterceptedEvents; Vector2 labelSize = m_Styles.labelStyle.CalcSize(eventContent); if (maxEventLabelSize.x < labelSize.x) @@ -116,7 +122,7 @@ public override void OnPreviewGUI(Rect r, GUIStyle background) // Figure out how many rows and columns we can/should have int columns = Mathf.Max(Mathf.FloorToInt(r.width / maxEventLabelSize.x), 1); - int rows = Mathf.Max(totalInterceptedEvents / columns, 1) + componentIncerceptedEvents.Length; + int rows = Mathf.Max(totalInterceptedEvents / columns, 1) + componentIncerceptedEvents.Count; // Centering float initialX = r.x + Mathf.Max(0, (r.width - (maxEventLabelSize.x * columns)) / 2); @@ -129,8 +135,9 @@ public override void OnPreviewGUI(Rect r, GUIStyle background) GUI.Label(labelRect, componentInterceptedEvents.componentName, m_Styles.componentName); labelRect.y += labelRect.height; labelRect.x = initialX; - foreach (GUIContent eventContent in componentInterceptedEvents.interceptedEvents) + foreach (int eventIndex in componentInterceptedEvents.interceptedEvents) { + GUIContent eventContent = s_PossibleEvents[eventIndex]; GUI.Label(labelRect, eventContent, m_Styles.labelStyle); if (currentColumn < columns - 1) { @@ -151,67 +158,116 @@ public override void OnPreviewGUI(Rect r, GUIStyle background) labelRect.x = initialX; } } + Profiler.EndSample(); } - protected static ComponentInterceptedEvents[] GetEventsInfo(GameObject gameObject) - { - // TODO: could this becached somewhere? - List interfaces = new List(); - foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) - { - Type[] types = assembly.GetTypes(); - foreach (var type in types) - { - if (!type.IsInterface) - continue; + //Lookup cache to avoid recalculating which types uses which events: + //Caches all interfaces that inherit from IEventSystemHandler + static List s_EventSystemInterfaces = null; + //Caches all GUIContents in a single list to avoid creating too much GUIContent and strings. + private static List s_PossibleEvents = null; + //Caches all events used by each interface + static Dictionary> s_InterfaceEventSystemEvents = null; + //Caches each concrete type and it's events + static readonly Dictionary s_ComponentEvents2 = new Dictionary(); - if (!typeof(IEventSystemHandler).IsAssignableFrom(type)) - continue; - interfaces.Add(type); - } - } + protected static List GetEventsInfo(GameObject gameObject) + { + InitializeEvetnsInterfaceCacheIfNeeded(); List componentEvents = new List(); - List events = new List(); + MonoBehaviour[] mbs = gameObject.GetComponents(); for (int i = 0, imax = mbs.Length; i < imax; ++i) { + ComponentInterceptedEvents componentEvent = null; + MonoBehaviour mb = mbs[i]; if (mb == null) continue; Type type = mb.GetType(); - - if (typeof(IEventSystemHandler).IsAssignableFrom(type)) + if (!s_ComponentEvents2.ContainsKey(type)) { - foreach (var eventInterface in interfaces) + List events = null; + Profiler.BeginSample("ComponentInterceptedEvents.GetEventsInfo.NewType"); + if (typeof(IEventSystemHandler).IsAssignableFrom(type)) { - if (!eventInterface.IsAssignableFrom(type)) - continue; - - MethodInfo[] methodInfos = eventInterface.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - foreach (MethodInfo methodInfo in methodInfos) + for (int index = 0; index < s_EventSystemInterfaces.Count; index++) { - events.Add(new GUIContent(methodInfo.Name)); + var eventInterface = s_EventSystemInterfaces[index]; + if (!eventInterface.IsAssignableFrom(type)) + continue; + + if (events == null) + events = new List(); + + events.AddRange(s_InterfaceEventSystemEvents[eventInterface]); } } + + if (events != null) + { + componentEvent = new ComponentInterceptedEvents(); + componentEvent.componentName = new GUIContent(type.Name); + componentEvent.interceptedEvents = events.OrderBy(index => s_PossibleEvents[index].text).ToArray(); + } + s_ComponentEvents2.Add(type, componentEvent); + + Profiler.EndSample(); } + else + { + componentEvent = s_ComponentEvents2[type]; + } + - if (events.Count > 0) + if (componentEvent != null) { - ComponentInterceptedEvents componentEvent = new ComponentInterceptedEvents(); - componentEvent.componentName = new GUIContent(type.Name); - componentEvent.interceptedEvents = events.OrderBy(e => e.text).ToArray(); componentEvents.Add(componentEvent); - - events.Clear(); } } - return componentEvents.ToArray(); + return componentEvents; + } + + private static void InitializeEvetnsInterfaceCacheIfNeeded() + { + if (s_EventSystemInterfaces != null) + return; + + s_EventSystemInterfaces = new List(); + s_PossibleEvents = new List(); + s_InterfaceEventSystemEvents = new Dictionary>(); + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + for (int i = 0; i < assemblies.Length; ++i) + { + Type[] types = assemblies[i].GetTypes(); + for (int ti = 0; ti < types.Length; ++ti) + { + var type = types[ti]; + if (!type.IsInterface) + continue; + + if (!typeof(IEventSystemHandler).IsAssignableFrom(type)) + continue; + + s_EventSystemInterfaces.Add(type); + List eventIndexList = new List(); + + MethodInfo[] methodInfos = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + for (int mi = 0; mi < methodInfos.Length; mi++) + { + MethodInfo methodInfo = methodInfos[mi]; + eventIndexList.Add(s_PossibleEvents.Count); + s_PossibleEvents.Add(new GUIContent(methodInfo.Name)); + } + s_InterfaceEventSystemEvents.Add(type, eventIndexList); + } + } } } } diff --git a/UnityEditor.UI/UI/MenuOptions.cs b/UnityEditor.UI/UI/MenuOptions.cs index 6d8f2ad..94d0016 100644 --- a/UnityEditor.UI/UI/MenuOptions.cs +++ b/UnityEditor.UI/UI/MenuOptions.cs @@ -11,21 +11,31 @@ namespace UnityEditor.UI static internal class MenuOptions { private const string kUILayerName = "UI"; - private const float kWidth = 160f; - private const float kThickHeight = 30f; - private const float kThinHeight = 20f; - private const string kStandardSpritePath = "UI/Skin/UISprite.psd"; - private const string kBackgroundSpriteResourcePath = "UI/Skin/Background.psd"; - private const string kInputFieldBackgroundPath = "UI/Skin/InputFieldBackground.psd"; - private const string kKnobPath = "UI/Skin/Knob.psd"; - private const string kCheckmarkPath = "UI/Skin/Checkmark.psd"; - - private static Vector2 s_ThickGUIElementSize = new Vector2(kWidth, kThickHeight); - private static Vector2 s_ThinGUIElementSize = new Vector2(kWidth, kThinHeight); - private static Vector2 s_ImageGUIElementSize = new Vector2(100f, 100f); - private static Color s_DefaultSelectableColor = new Color(1f, 1f, 1f, 1f); - private static Color s_PanelColor = new Color(1f, 1f, 1f, 0.392f); - private static Color s_TextColor = new Color(50f / 255f, 50f / 255f, 50f / 255f, 1f); + + private const string kStandardSpritePath = "UI/Skin/UISprite.psd"; + private const string kBackgroundSpritePath = "UI/Skin/Background.psd"; + private const string kInputFieldBackgroundPath = "UI/Skin/InputFieldBackground.psd"; + private const string kKnobPath = "UI/Skin/Knob.psd"; + private const string kCheckmarkPath = "UI/Skin/Checkmark.psd"; + private const string kDropdownArrowPath = "UI/Skin/DropdownArrow.psd"; + private const string kMaskPath = "UI/Skin/UIMask.psd"; + + static private DefaultControls.Resources s_StandardResources; + + static private DefaultControls.Resources GetStandardResources() + { + if (s_StandardResources.standard == null) + { + s_StandardResources.standard = AssetDatabase.GetBuiltinExtraResource(kStandardSpritePath); + s_StandardResources.background = AssetDatabase.GetBuiltinExtraResource(kBackgroundSpritePath); + s_StandardResources.inputField = AssetDatabase.GetBuiltinExtraResource(kInputFieldBackgroundPath); + s_StandardResources.knob = AssetDatabase.GetBuiltinExtraResource(kKnobPath); + s_StandardResources.checkmark = AssetDatabase.GetBuiltinExtraResource(kCheckmarkPath); + s_StandardResources.dropdown = AssetDatabase.GetBuiltinExtraResource(kDropdownArrowPath); + s_StandardResources.mask = AssetDatabase.GetBuiltinExtraResource(kMaskPath); + } + return s_StandardResources; + } private static void SetPositionVisibleinSceneView(RectTransform canvasRTransform, RectTransform itemTransform) { @@ -72,313 +82,101 @@ private static void SetPositionVisibleinSceneView(RectTransform canvasRTransform itemTransform.localScale = Vector3.one; } - private static GameObject CreateUIElementRoot(string name, MenuCommand menuCommand, Vector2 size) + private static void PlaceUIElementRoot(GameObject element, MenuCommand menuCommand) { GameObject parent = menuCommand.context as GameObject; if (parent == null || parent.GetComponentInParent() == null) { parent = GetOrCreateCanvasGameObject(); } - GameObject child = new GameObject(name); - - Undo.RegisterCreatedObjectUndo(child, "Create " + name); - Undo.SetTransformParent(child.transform, parent.transform, "Parent " + child.name); - GameObjectUtility.SetParentAndAlign(child, parent); - RectTransform rectTransform = child.AddComponent(); - rectTransform.sizeDelta = size; + string uniqueName = GameObjectUtility.GetUniqueNameForSibling(parent.transform, element.name); + element.name = uniqueName; + Undo.RegisterCreatedObjectUndo(element, "Create " + element.name); + Undo.SetTransformParent(element.transform, parent.transform, "Parent " + element.name); + GameObjectUtility.SetParentAndAlign(element, parent); if (parent != menuCommand.context) // not a context click, so center in sceneview - { - SetPositionVisibleinSceneView(parent.GetComponent(), rectTransform); - } - Selection.activeGameObject = child; - return child; - } + SetPositionVisibleinSceneView(parent.GetComponent(), element.GetComponent()); - [MenuItem("GameObject/UI/Panel", false, 2000)] - static public void AddPanel(MenuCommand menuCommand) - { - GameObject panelRoot = CreateUIElementRoot("Panel", menuCommand, s_ThickGUIElementSize); - - // Set RectTransform to stretch - RectTransform rectTransform = panelRoot.GetComponent(); - rectTransform.anchorMin = Vector2.zero; - rectTransform.anchorMax = Vector2.one; - rectTransform.anchoredPosition = Vector2.zero; - rectTransform.sizeDelta = Vector2.zero; - - Image image = panelRoot.AddComponent(); - image.sprite = AssetDatabase.GetBuiltinExtraResource(kBackgroundSpriteResourcePath); - image.type = Image.Type.Sliced; - image.color = s_PanelColor; + Selection.activeGameObject = element; } - [MenuItem("GameObject/UI/Button", false, 2001)] - static public void AddButton(MenuCommand menuCommand) - { - GameObject buttonRoot = CreateUIElementRoot("Button", menuCommand, s_ThickGUIElementSize); - - GameObject childText = new GameObject("Text"); - GameObjectUtility.SetParentAndAlign(childText, buttonRoot); - - Image image = buttonRoot.AddComponent(); - image.sprite = AssetDatabase.GetBuiltinExtraResource(kStandardSpritePath); - image.type = Image.Type.Sliced; - image.color = s_DefaultSelectableColor; + // Graphic elements - Button bt = buttonRoot.AddComponent