瀏覽代碼

Feature: Added GUICurveField element and hooked up GradientPicker with GUIColorGradient

BearishSun 7 年之前
父節點
當前提交
fc542949b8

+ 1 - 1
Source/EditorCore/GUI/BsGUIColorGradient.h

@@ -48,7 +48,7 @@ namespace bs
 		BS_SCRIPT_EXPORT(pr:getter,n:Gradient)
 		ColorGradient getGradient() const { return mValue; }
 
-		BS_SCRIPT_EXPORT()
+		BS_SCRIPT_EXPORT(in:true)
 		Event<void()> onClicked; /**< Triggered when the user clicks on the GUI element. */
 
 		/** @name Internal

+ 23 - 0
Source/Scripting/MBansheeEditor/GUI/GUIColorGradient.cs

@@ -0,0 +1,23 @@
+using System;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    partial class GUIColorGradient
+    {
+        /// <summary>
+        /// Callback triggered when the user clicks on the GUI element.
+        /// </summary>
+        partial void OnClicked()
+        {
+            GradientPicker.Show(Gradient, (success, colorGradient) =>
+            {
+                if (!success)
+                    return;
+
+                Gradient = colorGradient;
+            });
+
+        }
+    }
+}

+ 146 - 0
Source/Scripting/MBansheeEditor/GUI/GUICurveField.cs

@@ -0,0 +1,146 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2018 Marko Pintera ([email protected]). All rights reserved. **********************//
+using System;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /// <summary>
+    /// Displays a preview of a single animation curve or a range represented by two curves. Clicking on the field
+    /// open an editor window that allows the user to edit the curve(s).
+    /// </summary>
+    public class GUICurveField
+    {
+        private GUIPanel mainPanel;
+        private GUICurveDrawing curveDrawing;
+        private CurveDrawInfo[] drawInfos;
+        private bool drawRange;
+
+        /// <summary>
+        /// Constructs the element displaying a single animation curve.
+        /// </summary>
+        /// <param name="layout">GUI layout to which to add the element to.</param>
+        /// <param name="curve">Curve to display.</param>
+        /// <param name="width">Width of the GUI element in pixels.</param>
+        /// <param name="height">Height of the GUI element in pixels.</param>
+        public GUICurveField(GUILayout layout, AnimationCurve curve, int width = 200, int height = 60)
+        { 
+            drawInfos = new [] { new CurveDrawInfo(new EdAnimationCurve(curve, null), Color.BansheeOrange ) };
+            drawRange = false;
+
+            Initialize(layout, width, height);
+        }
+
+        /// <summary>
+        /// Constructs the element displaying a curve between two animation curves.
+        /// </summary>
+        /// <param name="layout">GUI layout to which to add the element to.</param>
+        /// <param name="curveA">First curve to display.</param>
+        /// <param name="curveB">Second curve to display.</param>
+        /// <param name="width">Width of the GUI element in pixels.</param>
+        /// <param name="height">Height of the GUI element in pixels.</param>
+        public GUICurveField(GUILayout layout, AnimationCurve curveA, AnimationCurve curveB, int width = 200, int height = 60)
+        { 
+            drawInfos = new []
+            {
+                new CurveDrawInfo(new EdAnimationCurve(curveA, null), Color.BansheeOrange ),
+                new CurveDrawInfo(new EdAnimationCurve(curveB, null), Color.Green )
+            };
+            drawRange = true;
+
+            Initialize(layout, width, height);
+        }
+
+        /// <summary>
+        /// Contains common initialization code for all constructors.
+        /// </summary>
+        /// <param name="layout">GUI layout to which to add the element to.</param>
+        /// <param name="width">Width of the GUI element in pixels.</param>
+        /// <param name="height">Height of the GUI element in pixels.</param>
+        private void Initialize(GUILayout layout, int width, int height)
+        {
+            Rect2I padding = new Rect2I(2, 2, 4, 6);
+
+            mainPanel = layout.AddPanel();
+
+            GUIPanel curveDrawingPanel = mainPanel.AddPanel();
+            GUIPanel underlayPanel = mainPanel.AddPanel(1);
+            GUIPanel overlayPanel = mainPanel.AddPanel(-1);
+            curveDrawingPanel.SetPosition(padding.x, padding.y);
+
+            CurveDrawOptions drawOptions = CurveDrawOptions.DrawMarkers;
+            if (drawRange)
+                drawOptions |= CurveDrawOptions.DrawRange;
+
+            curveDrawing = new GUICurveDrawing(curveDrawingPanel, width - padding.width, height - padding.height,
+                drawInfos, drawOptions);
+
+            Refresh();
+
+            GUITexture containerBg = new GUITexture(null, EditorStylesInternal.ContainerBg);
+            containerBg.SetWidth(width);
+            containerBg.SetHeight(height);
+
+            underlayPanel.AddElement(containerBg);
+
+            GUIButton button = new GUIButton(new LocEdString(""), EditorStyles.Blank, GUIOption.FixedWidth(width),
+                GUIOption.FixedHeight(height));
+            overlayPanel.AddElement(button);
+
+            button.OnClick += DoOnClick;
+        }
+
+        /// <summary>
+        /// Triggers when the user clicks on the GUI element.
+        /// </summary>
+        private void DoOnClick()
+        {
+            if (drawRange)
+            {
+                CurveEditorWindow.Show(drawInfos[0].curve.Normal, drawInfos[1].curve.Normal,
+                    (success, curveA, curveB) =>
+                {
+                    if (!success)
+                        return;
+
+                    drawInfos[0].curve = new EdAnimationCurve(curveA, null);
+                    drawInfos[1].curve = new EdAnimationCurve(curveB, null);
+                    curveDrawing.SetCurves(drawInfos);
+                    Refresh();
+                });
+            }
+            else
+            {
+                CurveEditorWindow.Show(drawInfos[0].curve.Normal, (success, curve) =>
+                {
+                    if (!success)
+                        return;
+
+                    drawInfos[0].curve = new EdAnimationCurve(curve, null);
+                    curveDrawing.SetCurves(drawInfos);
+                    Refresh();
+                });
+            }
+        }
+
+        /// <summary>
+        /// Removes the GUI element from the parent layout.
+        /// </summary>
+        public void Destroy()
+        {
+            mainPanel.Destroy();
+        }
+
+        /// <summary>
+        /// Refreshes the curve drawing control. Should be called after curves change.
+        /// </summary>
+        private void Refresh()
+        {
+            Vector2 offset, range;
+            GUICurveDrawing.GetOptimalRangeAndOffset(drawInfos, out offset, out range);
+            curveDrawing.SetRange(range.x, range.y * 2.0f);
+            curveDrawing.SetOffset(offset);
+            curveDrawing.Rebuild();
+        }
+    }
+}

+ 2 - 2
Source/Scripting/MBansheeEditor/Generated/GUIColorGradient.generated.cs

@@ -33,7 +33,7 @@ namespace BansheeEditor
 		}
 
 		/// <summary>Triggered when the user clicks on the GUI element.</summary>
-		public event Action OnClicked;
+		partial void OnClicked();
 
 		[MethodImpl(MethodImplOptions.InternalCall)]
 		private static extern void Internal_setGradient(IntPtr thisPtr, ColorGradient colorGradient);
@@ -43,7 +43,7 @@ namespace BansheeEditor
 		private static extern void Internal_create(GUIColorGradient managedInstance, string styleName);
 		private void Internal_onClicked()
 		{
-			OnClicked?.Invoke();
+			OnClicked();
 		}
 	}
 

+ 2 - 0
Source/Scripting/MBansheeEditor/MBansheeEditor.csproj

@@ -36,6 +36,8 @@
     <Reference Include="System.Core" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="GUI\GUIColorGradient.cs" />
+    <Compile Include="GUI\GUICurveField.cs" />
     <Compile Include="Inspectors\AnimationClipInspector.cs" />
     <Compile Include="Inspectors\AnimationInspector.cs" />
     <Compile Include="Inspectors\AudioClipInspector.cs" />

+ 116 - 43
Source/Scripting/MBansheeEditor/Windows/CurveEditorWindow.cs

@@ -1,5 +1,6 @@
 //********************************** Banshee Engine (www.banshee5d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using System;
 using BansheeEngine;
 
 namespace BansheeEditor
@@ -7,63 +8,115 @@ namespace BansheeEditor
     /// <summary>
     /// Opens a window that allows the user to edit a single animation curve or two curves representing a range.
     /// </summary>
-    [DefaultSize(600, 400)]
-    public class CurveEditorWindow : EditorWindow
+    public class CurveEditorWindow : ModalWindow
     {
+        private EdAnimationCurve curveA; 
+        private EdAnimationCurve curveB; 
+
         private GUICurveEditor curveEditor;
+        private GUIButton guiOK;
+        private GUIButton guiCancel;
+
+        private Action<bool, AnimationCurve, AnimationCurve> closedCallbackRange;
+        private Action<bool, AnimationCurve> closedCallback;
+
+        /// <summary>
+        /// Shows the curve editor window that allows the user to edit a single curve.
+        /// </summary>
+        /// <param name="curve">Curve to initialize the window with.</param>
+        /// <param name="closedCallback">Optional callback to trigger when the user finishes editing the curve or
+        ///                              cancels out of the dialog.</param>
+        /// <returns>An instance of the curve editor window.</returns>
+        public static CurveEditorWindow Show(AnimationCurve curve, Action<bool, AnimationCurve> closedCallback = null)
+        {
+            CurveEditorWindow picker = new CurveEditorWindow(curve, closedCallback);
+            return picker;
+        }
+
+        /// <summary>
+        /// Shows the curve editor window that allows the user to edit a curve range (two curves).
+        /// </summary>
+        /// <param name="curveA">First curve of the range to display/edit.</param>
+        /// <param name="curveB">Second curve of the range to display/edit.</param>
+        /// <param name="closedCallback">Optional callback to trigger when the user finishes editing the curve or
+        ///                              cancels out of the dialog.</param>
+        /// <returns>An instance of the curve editor window.</returns>
+        public static CurveEditorWindow Show(AnimationCurve curveA, AnimationCurve curveB, 
+            Action<bool, AnimationCurve, AnimationCurve> closedCallback = null)
+        {
+            CurveEditorWindow picker = new CurveEditorWindow(curveA, curveB, closedCallback);
+            return picker;
+        }
 
         #region Overrides
 
-        // DEBUG ONLY
-        [MenuItem("Windows/Dbg", 5000)]
-        public static void Open()
+        private CurveEditorWindow(AnimationCurve curve, Action<bool, AnimationCurve> closedCallback = null)
+            : base(false)
         {
-            OpenWindow<CurveEditorWindow>();
+            Title = new LocString("Curve editor");
+            Width = 600;
+            Height = 460;
+
+            curveA = new EdAnimationCurve(curve ?? new AnimationCurve(new KeyFrame[] {}), null);
+            this.closedCallback = closedCallback;
         }
 
-        /// <inheritdoc/>
-        protected override LocString GetDisplayName()
+        private CurveEditorWindow(AnimationCurve curveA, AnimationCurve curveB, 
+            Action<bool, AnimationCurve, AnimationCurve> closedCallback = null)
+            : base(false)
         {
-            return new LocEdString("Curve editor");
+            Title = new LocString("Curve editor");
+            Width = 600;
+            Height = 460;
+
+            this.curveA = new EdAnimationCurve(curveA ?? new AnimationCurve(new KeyFrame[] {}), null);
+            this.curveB = new EdAnimationCurve(curveB ?? new AnimationCurve(new KeyFrame[] {}), null);
+
+            this.closedCallbackRange = closedCallback;
         }
 
         private void OnInitialize()
         {
-            // TODO - Add methods to allow the window to be open with user-defined curve(s)
-            // TODO - Add callbacks that trigger when user finishes editing
-            // TODO - Add OK/Cancel buttons? Make the window modal?
-            // TODO - Add a CurveField GUI element that can be used for curve preview, clicking on which opens this window
+            GUILayout vertLayout = GUI.AddLayoutY();
+            GUILayout editorPanel = vertLayout.AddPanel(GUIOption.FixedHeight(400));
+            GUILayout buttonLayout = vertLayout.AddLayoutX(GUIOption.FixedHeight(40));
+
+            guiOK = new GUIButton(new LocEdString("OK"));
+            guiCancel = new GUIButton(new LocEdString("Cancel"));
+
+            guiOK.OnClick += OnOK;
+            guiCancel.OnClick += OnCancel;
+
+            CurveDrawOptions drawOptions = CurveDrawOptions.DrawKeyframes | CurveDrawOptions.DrawMarkers;
+            if (curveB != null)
+                drawOptions |= CurveDrawOptions.DrawRange;
 
-            curveEditor = new GUICurveEditor(this, this.GUI, 600, 400, false);
+            curveEditor = new GUICurveEditor(editorPanel, 600, 400, false, drawOptions); 
             curveEditor.Redraw();
 
-            EdAnimationCurve[] edAnimCurve =
+            CurveDrawInfo[] drawinfo;
+
+            if (curveB != null)
             {
-                new EdAnimationCurve(),
-                new EdAnimationCurve()
-            };
-
-            edAnimCurve[0].AddKeyframe(0.0f, 1.0f);
-            edAnimCurve[0].AddKeyframe(5.0f, 3.0f);
-            edAnimCurve[0].AddKeyframe(8.0f, -3.0f);
-            edAnimCurve[0].AddKeyframe(15.0f, 2.0f);
-            edAnimCurve[0].Apply();
-
-            edAnimCurve[1].AddKeyframe(0.0f, -3.0f);
-            edAnimCurve[1].AddKeyframe(3.0f, 0.0f);
-            edAnimCurve[1].AddKeyframe(10.0f, -1.0f);
-            edAnimCurve[1].AddKeyframe(13.0f, -5.0f);
-            edAnimCurve[1].Apply();
-
-            CurveDrawInfo[] drawinfo =
+                drawinfo = new []
+                {
+                    new CurveDrawInfo(curveA, Color.BansheeOrange),
+                    new CurveDrawInfo(curveB, Color.Green),
+                };
+            }
+            else
             {
-                new CurveDrawInfo(edAnimCurve[0], Color.Green),
-                new CurveDrawInfo(edAnimCurve[1], Color.Red),
-            };
+                drawinfo = new [] { new CurveDrawInfo(curveA, Color.BansheeOrange), };
+            }
 
             curveEditor.SetCurves(drawinfo);
             curveEditor.CenterAndResize(true);
-            curveEditor.SetDrawRange(true);
+
+            buttonLayout.AddFlexibleSpace();
+            buttonLayout.AddElement(guiOK);
+            buttonLayout.AddSpace(10);
+            buttonLayout.AddElement(guiCancel);
+            buttonLayout.AddFlexibleSpace();
 
             EditorInput.OnPointerPressed += OnPointerPressed;
             EditorInput.OnPointerDoubleClick += OnPointerDoubleClicked;
@@ -86,12 +139,34 @@ namespace BansheeEditor
             EditorInput.OnButtonUp -= OnButtonUp;
         }
 
-        /// <inheritdoc/>
-        protected override void WindowResized(int width, int height)
+        #endregion
+
+        #region GUI
+
+        /// <summary>
+        /// Triggered when the user finishes editing the curve(s) and closes the dialog.
+        /// </summary>
+        void OnOK()
         {
-            Vector2I curveEditorSize = new Vector2I(width, height);
-            curveEditor.SetSize(curveEditorSize.x, curveEditorSize.y);
-            curveEditor.Redraw();
+            if (curveB != null)
+                closedCallbackRange?.Invoke(true, curveA.Normal, curveB.Normal);
+            else
+                closedCallback?.Invoke(true, curveA.Normal);
+
+            Close();
+        }
+
+        /// <summary>
+        /// Triggered when the user cancels editing the curve(s) closes the dialog.
+        /// </summary>
+        void OnCancel()
+        {
+            if (curveB != null)
+                closedCallbackRange?.Invoke(false, curveA.Normal, curveB.Normal);
+            else
+                closedCallback?.Invoke(false, curveA.Normal);
+
+            Close();
         }
 
         #endregion
@@ -104,7 +179,6 @@ namespace BansheeEditor
         private void OnPointerPressed(PointerEvent ev)
         {
             curveEditor.OnPointerPressed(ev);
-
         }
 
         /// <summary>
@@ -123,7 +197,6 @@ namespace BansheeEditor
         private void OnPointerMoved(PointerEvent ev)
         {
             curveEditor.OnPointerMoved(ev);
-
         }
 
         /// <summary>