/// <summary> /// Constructs a new color picker window. /// </summary> /// <param name="color">Initial color to display.</param> /// <param name="closedCallback">Optional callback to trigger when the user selects a color or cancels out /// of the dialog.</param> protected ColorPicker(Color color, Action <bool, Color> closedCallback = null) : base(false) { Title = new LocEdString("Color Picker"); colRed = color.r; colGreen = color.g; colBlue = color.b; colAlpha = color.a; RGBToHSV(); this.closedCallback = closedCallback; }
/// <summary> /// Creates necessary GUI elements for selecting a material variation. /// </summary> /// <param name="material">Material for which to provide variation selection.</param> /// <param name="layout">GUI layout to which to append GUI elements.</param> internal MaterialVariationGUI(Material material, GUILayout layout) { this.material = material; variation = material.Variation; Shader shader = material.Shader.Value; if (shader == null) { return; } ShaderVariationParamInfo[] variationParams = shader.VariationParams; foreach (var param in variationParams) { if (param.isInternal) { continue; } LocString[] names = new LocString[param.values.Length]; int[] values = new int[names.Length]; for (int i = 0; i < names.Length; i++) { names[i] = new LocEdString(param.values[i].name); values[i] = param.values[i].value; } GUIListBoxField listBox = new GUIListBoxField(names, new LocEdString(param.name)); listBox.OnSelectionChanged += idx => { int value = values[idx]; variation.SetInt(param.identifier, value); material.Variation = variation; }; int curValue = variation.GetInt(param.identifier); for (int j = 0; j < values.Length; j++) { if (curValue == values[j]) { listBox.Index = j; break; } } layout.AddElement(listBox); } }
/// <summary> /// Creates a new material parameter GUI. /// </summary> /// <param name="shaderParam">Shader parameter to create the GUI for. Must be of 4D vector type.</param> /// <param name="material">Material the parameter is a part of.</param> /// <param name="layout">Layout to append the GUI elements to.</param> internal MaterialParamVec4GUI(ShaderParameter shaderParam, Material material, GUILayout layout) : base(shaderParam) { LocString title = new LocEdString(shaderParam.name); guiElem = new GUIVector4Field(title); guiElem.OnValueChanged += (x) => { material.SetVector4(shaderParam.name, x); EditorApplication.SetDirty(material); }; layout.AddElement(guiElem); }
/// <summary> /// Creates a new material parameter GUI. /// </summary> /// <param name="shaderParam">Shader parameter to create the GUI for. Must be of texture type.</param> /// <param name="material">Material the parameter is a part of.</param> /// <param name="layout">Layout to append the GUI elements to.</param> internal MaterialParamTextureGUI(ShaderParameter shaderParam, Material material, GUILayout layout) : base(shaderParam) { LocString title = new LocEdString(shaderParam.name); GUITextureFieldType type = shaderParam.type == ShaderParameterType.Texture2D ? GUITextureFieldType.TextureOrSpriteTexture : GUITextureFieldType.Texture; guiElem = new GUITextureField(type, title); switch (shaderParam.type) { case ShaderParameterType.Texture2D: case ShaderParameterType.Texture3D: case ShaderParameterType.TextureCube: guiElem.OnChanged += (x) => { string path = ProjectLibrary.GetPath(x.UUID); if (!string.IsNullOrEmpty(path)) { if (ProjectLibrary.GetEntry(path) is FileEntry fileEntry) { if (fileEntry.ResourceMetas.Length > 0) { ResourceMeta meta = fileEntry.ResourceMetas[0]; if (meta.ResType == ResourceType.SpriteTexture) { material.SetSpriteTexture(shaderParam.name, x.As <SpriteTexture>()); } else if (meta.ResType == ResourceType.Texture) { material.SetTexture(shaderParam.name, x.As <Texture>()); } } } } else { material.SetTexture(shaderParam.name, null); } EditorApplication.SetDirty(material); }; break; } layout.AddElement(guiElem); }
/// <summary> /// Creates a new material parameter GUI. /// </summary> /// <param name="shaderParam">Shader parameter to create the GUI for. Must be of color type.</param> /// <param name="material">Material the parameter is a part of.</param> /// <param name="layout">Layout to append the GUI elements to.</param> internal MaterialParamColorGUI(ShaderParameter shaderParam, Material material, GUILayout layout) : base(shaderParam) { LocString title = new LocEdString(shaderParam.name); var guiToggle = new GUIToggle(new GUIContent( EditorBuiltin.GetEditorToggleIcon(EditorToggleIcon.AnimateProperty), new LocString("Animate"))); guiColor = new GUIColorField(title); guiColorGradient = new GUIColorGradientField(title); bool isAnimated = material.IsAnimated(shaderParam.name); guiColor.Active = !isAnimated; guiColorGradient.Active = isAnimated; fieldLayout = layout.AddLayoutX(); fieldLayout.AddElement(guiColor); fieldLayout.AddElement(guiColorGradient); fieldLayout.AddSpace(10); fieldLayout.AddElement(guiToggle); guiColor.OnChanged += (x) => { material.SetColor(shaderParam.name, x); EditorApplication.SetDirty(material); }; guiColorGradient.OnChanged += x => { material.SetColorGradient(shaderParam.name, x); EditorApplication.SetDirty(material); }; guiToggle.OnToggled += x => { guiColor.Active = !x; guiColorGradient.Active = x; if (x) { ColorGradient gradient = material.GetColorGradient(shaderParam.name); if (gradient.NumKeys == 0) { material.SetColorGradient(shaderParam.name, new ColorGradient(material.GetColor(shaderParam.name))); } } }; }
/// <summary> /// Constructs a new color picker window. /// </summary> /// <param name="color">Initial color to display.</param> /// <param name="hdr">If true, the color intensity can be selected along with the color itself.</param> /// <param name="closedCallback">Optional callback to trigger when the user selects a color or cancels out /// of the dialog.</param> protected ColorPicker(Color color, bool hdr, Action <bool, Color> closedCallback = null) : base(false) { Title = new LocEdString("Color Picker"); colRedHDR = color.r; colGreenHDR = color.g; colBlueHDR = color.b; colAlpha = color.a; this.hdr = hdr; HDRToLDR(); RGBToHSV(); this.closedCallback = closedCallback; }
/// <summary> /// Attempts to open a project at the path currently entered in the project path input box. /// </summary> private void OpenProject() { string projectPath = projectInputBox.Value; if (EditorApplication.IsValidProject(projectPath)) { EditorSettings.AutoLoadLastProject = autoLoadToggle.Value; Close(); EditorApplication.LoadProject(projectPath); } else { // Remove invalid project from recent projects list RecentProject[] recentProjects = EditorSettings.RecentProjects; for (int i = 0; i < recentProjects.Length; i++) { if (PathEx.Compare(recentProjects[i].path, projectPath)) { RecentProject[] newRecentProjects = new RecentProject[recentProjects.Length - 1]; int idx = 0; for (int j = 0; j < recentProjects.Length; j++) { if (i == j) { continue; } newRecentProjects[idx] = recentProjects[j]; idx++; } EditorSettings.RecentProjects = newRecentProjects; EditorSettings.Save(); RefreshRecentProjects(); break; } } // Warn user LocString message = new LocEdString("Provided project path \"{0}\" doesn't contain a valid project."); message.SetParameter(0, projectPath); DialogBox.Open(new LocEdString("Error"), message, DialogBox.Type.OK); } }
/// <summary> /// Creates a new material parameter GUI. /// </summary> /// <param name="shaderParam">Shader parameter to create the GUI for. Must be of 4x4 matrix type.</param> /// <param name="material">Material the parameter is a part of.</param> /// <param name="layout">Layout to append the GUI elements to.</param> internal MaterialParamMat4GUI(ShaderParameter shaderParam, Material material, GUILayout layout) : base(shaderParam) { LocString title = new LocEdString(shaderParam.name); GUILabel guiTitle = new GUILabel(title, GUIOption.FixedWidth(100)); mainLayout = layout.AddLayoutY(); GUILayoutX titleLayout = mainLayout.AddLayoutX(); titleLayout.AddElement(guiTitle); titleLayout.AddFlexibleSpace(); GUILayoutY contentLayout = mainLayout.AddLayoutY(); GUILayoutX[] rows = new GUILayoutX[MAT_SIZE]; for (int i = 0; i < rows.Length; i++) { rows[i] = contentLayout.AddLayoutX(); } for (int row = 0; row < MAT_SIZE; row++) { for (int col = 0; col < MAT_SIZE; col++) { int index = row * MAT_SIZE + col; guiMatFields[index] = new GUIFloatField(row + "," + col, 20, "", GUIOption.FixedWidth(80)); GUIFloatField field = guiMatFields[index]; rows[row].AddElement(field); rows[row].AddSpace(5); int hoistedRow = row; int hoistedCol = col; field.OnChanged += (x) => { Matrix4 value = material.GetMatrix4(shaderParam.name); value[hoistedRow, hoistedCol] = x; material.SetMatrix4(shaderParam.name, value); EditorApplication.SetDirty(material); }; } } }
/// <summary> /// Creates a new material parameter GUI. /// </summary> /// <param name="shaderParam">Shader parameter to create the GUI for. Must be of floating point type.</param> /// <param name="material">Material the parameter is a part of.</param> /// <param name="layout">Layout to append the GUI elements to.</param> internal MaterialParamFloatGUI(ShaderParameter shaderParam, Material material, GUILayout layout) : base(shaderParam) { LocString title = new LocEdString(shaderParam.name); var guiToggle = new GUIToggle(new GUIContent( EditorBuiltin.GetEditorToggleIcon(EditorToggleIcon.AnimateProperty), new LocString("Animate"))); guiConstant = new GUIFloatField(title); guiCurves = new GUICurvesField(title); bool isAnimated = material.IsAnimated(shaderParam.name); guiConstant.Active = !isAnimated; guiCurves.Active = isAnimated; fieldLayout = layout.AddLayoutX(); fieldLayout.AddElement(guiConstant); fieldLayout.AddElement(guiCurves); fieldLayout.AddSpace(10); fieldLayout.AddElement(guiToggle); guiConstant.OnChanged += (x) => { material.SetFloat(shaderParam.name, x); EditorApplication.SetDirty(material); }; guiCurves.OnChanged += x => { material.SetFloatCurve(shaderParam.name, x); EditorApplication.SetDirty(material); }; guiToggle.OnToggled += x => { guiConstant.Active = !x; guiCurves.Active = x; }; }
/// <summary> /// Sets a resource whose GUI is to be displayed in the inspector. Clears any previous contents of the window. /// </summary> /// <param name="resourcePath">Resource path relative to the project of the resource to inspect.</param> private void SetObjectToInspect(string resourcePath) { activeResourcePath = resourcePath; if (!ProjectLibrary.Exists(resourcePath)) { return; } ResourceMeta meta = ProjectLibrary.GetMeta(resourcePath); if (meta == null) { return; } Type resourceType = meta.Type; currentType = InspectorType.Resource; inspectorScrollArea = new GUIScrollArea(ScrollBarType.ShowIfDoesntFit, ScrollBarType.NeverShow); GUI.AddElement(inspectorScrollArea); inspectorLayout = inspectorScrollArea.Layout; GUIPanel titlePanel = inspectorLayout.AddPanel(); titlePanel.SetHeight(RESOURCE_TITLE_HEIGHT); GUILayoutY titleLayout = titlePanel.AddLayoutY(); titleLayout.SetPosition(PADDING, PADDING); string name = Path.GetFileNameWithoutExtension(resourcePath); string type = resourceType.Name; LocString title = new LocEdString(name + " (" + type + ")"); GUILabel titleLabel = new GUILabel(title); titleLayout.AddFlexibleSpace(); GUILayoutX titleLabelLayout = titleLayout.AddLayoutX(); titleLabelLayout.AddElement(titleLabel); titleLayout.AddFlexibleSpace(); GUIPanel titleBgPanel = titlePanel.AddPanel(1); GUITexture titleBg = new GUITexture(null, EditorStylesInternal.InspectorTitleBg); titleBgPanel.AddElement(titleBg); inspectorLayout.AddSpace(COMPONENT_SPACING); inspectorResource = new InspectorResource(); inspectorResource.mainPanel = inspectorLayout.AddPanel(); inspectorLayout.AddFlexibleSpace(); inspectorResource.previewPanel = inspectorLayout.AddPanel(); var persistentProperties = persistentData.GetProperties(meta.UUID.ToString()); inspectorResource.inspector = InspectorUtility.GetInspector(resourceType); inspectorResource.inspector.Initialize(inspectorResource.mainPanel, inspectorResource.previewPanel, activeResourcePath, persistentProperties); }
/// <summary> /// Updates the contents of the details panel according to the currently selected element. /// </summary> private void RefreshDetailsPanel() { detailsArea.Layout.Clear(); if (sSelectedElementIdx != -1) { GUILayoutX paddingX = detailsArea.Layout.AddLayoutX(); paddingX.AddSpace(5); GUILayoutY paddingY = paddingX.AddLayoutY(); paddingX.AddSpace(5); paddingY.AddSpace(5); GUILayoutY mainLayout = paddingY.AddLayoutY(); paddingY.AddSpace(5); ConsoleEntryData entry = filteredEntries[sSelectedElementIdx]; LocString message = new LocEdString(entry.message); GUILabel messageLabel = new GUILabel(message, EditorStyles.MultiLineLabel, GUIOption.FlexibleHeight()); mainLayout.AddElement(messageLabel); mainLayout.AddSpace(10); if (entry.callstack != null) { foreach (var call in entry.callstack) { string fileName = Path.GetFileName(call.file); string callMessage; if (string.IsNullOrEmpty(call.method)) { callMessage = "\tin " + fileName + ":" + call.line; } else { callMessage = "\t" + call.method + " in " + fileName + ":" + call.line; } GUIButton callBtn = new GUIButton(new LocEdString(callMessage)); mainLayout.AddElement(callBtn); CallStackEntry hoistedCall = call; callBtn.OnClick += () => { CodeEditor.OpenFile(hoistedCall.file, hoistedCall.line); }; } } mainLayout.AddFlexibleSpace(); } else { GUILayoutX centerX = detailsArea.Layout.AddLayoutX(); centerX.AddFlexibleSpace(); GUILayoutY centerY = centerX.AddLayoutY(); centerX.AddFlexibleSpace(); centerY.AddFlexibleSpace(); GUILabel nothingSelectedLbl = new GUILabel(new LocEdString("(No entry selected)")); centerY.AddElement(nothingSelectedLbl); centerY.AddFlexibleSpace(); } }
/// <summary> /// Recreates all the GUI elements used by this inspector. /// </summary> private void BuildGUI() { Layout.Clear(); Animation animation = InspectedObject as Animation; if (animation == null) { return; } animationClipField.OnChanged += x => { AnimationClip clip = Resources.Load <AnimationClip>(x.UUID); animation.DefaultClip = clip; MarkAsModified(); ConfirmModify(); }; wrapModeField.OnSelectionChanged += x => { animation.WrapMode = (AnimWrapMode)x; MarkAsModified(); ConfirmModify(); }; speedField.OnChanged += x => { animation.Speed = x; MarkAsModified(); }; speedField.OnConfirmed += ConfirmModify; speedField.OnFocusLost += ConfirmModify; cullingField.OnChanged += x => { animation.Cull = x; MarkAsModified(); ConfirmModify(); }; overrideBoundsField.OnChanged += x => { animation.UseBounds = x; MarkAsModified(); ConfirmModify(); }; centerField.OnValueChanged += x => { AABox bounds = animation.Bounds; Vector3 min = x - bounds.Size * 0.5f; Vector3 max = x + bounds.Size * 0.5f; animation.Bounds = new AABox(min, max); MarkAsModified(); }; centerField.OnConfirm += x => ConfirmModify(); centerField.OnFocusLost += ConfirmModify; sizeField.OnValueChanged += x => { AABox bounds = animation.Bounds; Vector3 min = bounds.Center - x * 0.5f; Vector3 max = bounds.Center + x * 0.5f; animation.Bounds = new AABox(min, max); MarkAsModified(); }; sizeField.OnConfirm += x => ConfirmModify(); sizeField.OnFocusLost += ConfirmModify; Layout.AddElement(animationClipField); Layout.AddElement(wrapModeField); Layout.AddElement(speedField); Layout.AddElement(cullingField); Layout.AddElement(overrideBoundsField); GUILayoutX boundsLayout = Layout.AddLayoutX(); boundsLayout.AddElement(new GUILabel(new LocEdString("Bounds"), GUIOption.FixedWidth(100))); GUILayoutY boundsContent = boundsLayout.AddLayoutY(); boundsContent.AddElement(centerField); boundsContent.AddElement(sizeField); // Morph shapes Renderable renderable = animation.SceneObject.GetComponent <Renderable>(); MorphShapes morphShapes = renderable?.Mesh.Value?.MorphShapes; if (morphShapes != null) { GUIToggle morphShapesToggle = new GUIToggle(new LocEdString("Morph shapes"), EditorStyles.Foldout); Layout.AddElement(morphShapesToggle); GUILayoutY channelsLayout = Layout.AddLayoutY(); morphShapesToggle.OnToggled += x => { channelsLayout.Active = x; Persistent.SetBool("Channels_Expanded", x); }; channelsLayout.Active = Persistent.GetBool("Channels_Expanded"); MorphChannel[] channels = morphShapes.Channels; for (int i = 0; i < channels.Length; i++) { GUILayoutY channelLayout = channelsLayout.AddLayoutY(); GUILayoutX channelTitleLayout = channelLayout.AddLayoutX(); channelLayout.AddSpace(5); GUILayoutY channelContentLayout = channelLayout.AddLayoutY(); string channelName = channels[i].Name; GUIToggle channelNameField = new GUIToggle(channelName, EditorStyles.Expand, GUIOption.FlexibleWidth()); channelTitleLayout.AddSpace(15); // Indent channelTitleLayout.AddElement(channelNameField); channelTitleLayout.AddFlexibleSpace(); channelNameField.OnToggled += x => { channelContentLayout.Active = x; Persistent.SetBool(channelName + "_Expanded", x); }; channelContentLayout.Active = Persistent.GetBool(channelName + "_Expanded"); MorphShape[] shapes = channels[i].Shapes; for (int j = 0; j < shapes.Length; j++) { GUILayoutX shapeLayout = channelContentLayout.AddLayoutX(); channelContentLayout.AddSpace(5); LocString nameString = new LocString("[{0}]. {1}"); nameString.SetParameter(0, j.ToString()); nameString.SetParameter(1, shapes[j].Name); GUILabel shapeNameField = new GUILabel(shapes[j].Name); LocString weightString = new LocEdString("Weight: {0}"); weightString.SetParameter(0, shapes[j].Weight.ToString()); GUILabel weightField = new GUILabel(weightString); shapeLayout.AddSpace(30); // Indent shapeLayout.AddElement(shapeNameField); shapeLayout.AddFlexibleSpace(); shapeLayout.AddElement(weightField); } } } }
/// <inheritdoc/> protected internal override void Initialize() { Animation animation = (Animation)InspectedObject; drawer.AddDefault(animation); // Morph shapes Renderable renderable = animation.SceneObject.GetComponent <Renderable>(); MorphShapes morphShapes = renderable?.Mesh.Value?.MorphShapes; if (morphShapes != null) { GUIToggle morphShapesToggle = new GUIToggle(new LocEdString("Morph shapes"), EditorStyles.Foldout); Layout.AddElement(morphShapesToggle); GUILayoutY channelsLayout = Layout.AddLayoutY(); morphShapesToggle.OnToggled += x => { channelsLayout.Active = x; Persistent.SetBool("Channels_Expanded", x); }; channelsLayout.Active = Persistent.GetBool("Channels_Expanded"); MorphChannel[] channels = morphShapes.Channels; for (int i = 0; i < channels.Length; i++) { GUILayoutY channelLayout = channelsLayout.AddLayoutY(); GUILayoutX channelTitleLayout = channelLayout.AddLayoutX(); channelLayout.AddSpace(5); GUILayoutY channelContentLayout = channelLayout.AddLayoutY(); string channelName = channels[i].Name; GUIToggle channelNameField = new GUIToggle(channelName, EditorStyles.Expand, GUIOption.FlexibleWidth()); channelTitleLayout.AddSpace(15); // Indent channelTitleLayout.AddElement(channelNameField); channelTitleLayout.AddFlexibleSpace(); channelNameField.OnToggled += x => { channelContentLayout.Active = x; Persistent.SetBool(channelName + "_Expanded", x); }; channelContentLayout.Active = Persistent.GetBool(channelName + "_Expanded"); MorphShape[] shapes = channels[i].Shapes; for (int j = 0; j < shapes.Length; j++) { GUILayoutX shapeLayout = channelContentLayout.AddLayoutX(); channelContentLayout.AddSpace(5); LocString nameString = new LocString("[{0}]. {1}"); nameString.SetParameter(0, j.ToString()); nameString.SetParameter(1, shapes[j].Name); GUILabel shapeNameField = new GUILabel(shapes[j].Name); LocString weightString = new LocEdString("Weight: {0}"); weightString.SetParameter(0, shapes[j].Weight.ToString()); GUILabel weightField = new GUILabel(weightString); shapeLayout.AddSpace(30); // Indent shapeLayout.AddElement(shapeNameField); shapeLayout.AddFlexibleSpace(); shapeLayout.AddElement(weightField); } } } }