自定義Timeline工具1

yanghui01發表於2024-05-23

效果

就是第1行繪製了一個工具欄,高度為17;

然後繪製了一個視窗分隔條,左側用於放軌道,右側用於放軌道片段,分隔條可以在一定範圍內拖動。

public class MyTimelineWnd : EditorWindow
{
    [MenuItem("MyTools/MyTimelineWnd", false, 1)]
    static void ShowWindow()
    {
        var win = GetWindow(typeof(MyTimelineWnd), false, "MyTimelineWnd");
        win.minSize = new Vector2(500, 300);
    }

    private const float Toolbar_Height = 17;
    private const float Split_Left_Min_Size = 180;
    private const float Split_Left_Max_Size = 260;

    private readonly Color Color_Split = new Color(0.5f, 0.5f, 0.5f, 0.3f);
    private readonly Color Color_Tog_Play_On = new Color(30f / 255.0f, 144f / 255.0f, 255f / 255.0f, 1.0f); //steelBlue

    private MyGUIContents m_GuiContents;

    private bool m_SplitCickDown = false;
    private float m_SplitLeftWidth = 220;

    private bool m_IsPlaying = false;

    private int m_FrameRate = 30;

    void OnEnable()
    {
        if (null == m_GuiContents)
            m_GuiContents = new MyGUIContents();
    }

    void OnGUI()
    {
        DrawToolbar();
        DrawSplit();
    }

    private void DrawToolbar()
    {
        GUILayout.BeginHorizontal(EditorStyles.toolbar);
        DrawToolbar_SplitLeft();
        DrawToolbar_SplitRight();
        GUILayout.EndHorizontal();
    }

    private void DrawToolbar_SplitLeft()
    {
        GUILayout.BeginHorizontal(GUILayout.Width(m_SplitLeftWidth));
        //第一幀
        if (GUILayout.Button(m_GuiContents.Btn_FirstKey, EditorStyles.toolbarButton))
        {
            //todo:
        }

        //上一幀
        if (GUILayout.Button(m_GuiContents.Btn_LastKey, EditorStyles.toolbarButton))
        {
            //todo:
        }

        //播放
        bool isPlaying = false;
        if (m_IsPlaying)
        {
            var oldColor = GUI.color;
            GUI.color = Color_Tog_Play_On;
            isPlaying = GUILayout.Toggle(m_IsPlaying, m_GuiContents.Tog_Play, EditorStyles.toolbarButton);
            GUI.color = oldColor;
        }
        else
        {
            isPlaying = GUILayout.Toggle(m_IsPlaying, m_GuiContents.Tog_Play, EditorStyles.toolbarButton);
        }

        if (m_IsPlaying != isPlaying)
        {
            m_IsPlaying = isPlaying;
            //todo:
        }

        //下一幀
        if (GUILayout.Button(m_GuiContents.Btn_NextKey, EditorStyles.toolbarButton))
        {
            //todo:
        }

        //最後一幀
        if (GUILayout.Button(m_GuiContents.Btn_LastKey, EditorStyles.toolbarButton))
        {
            //todo:
        }

        GUILayout.Space(10);

        //當前在哪一幀
        var rect = EditorGUILayout.GetControlRect(false, 30, EditorStyles.toolbarTextField, GUILayout.MinWidth(28));
        EditorGUI.TextField(rect, "0", EditorStyles.toolbarTextField);

        GUILayout.EndHorizontal();
    }

    private void DrawToolbar_SplitRight()
    {
        GUILayout.FlexibleSpace();
        GUILayout.Label(m_GuiContents.Label_Duration);
        var r = EditorGUILayout.GetControlRect(false, 30, EditorStyles.toolbarTextField, GUILayout.MinWidth(28),
        GUILayout.MaxWidth(40));
        EditorGUI.TextField(r, $"{m_FrameRate}", EditorStyles.toolbarTextField);

        if (GUILayout.Button(m_GuiContents.Btn_Popup, EditorStyles.toolbarButton))
        {
            var menu = new GenericMenu();
            GenericMenu.MenuFunction2 menuCall = (data) =>
            {
                //todo
                m_FrameRate = (int)data;
            };

            menu.AddItem(m_GuiContents.Frame_Rate_30, 30==m_FrameRate, menuCall, 30);
            menu.AddItem(m_GuiContents.Frame_Rate_50, 50==m_FrameRate, menuCall, 50);
            menu.AddItem(m_GuiContents.Frame_Rate60, 60==m_FrameRate, menuCall, 60);

            menu.ShowAsContext();
        }
    }

    private void DrawSplit()
    {
        //分隔窗
        var splitRect = new Rect(m_SplitLeftWidth, 0, 6, position.height);
        EditorGUIUtility.AddCursorRect(splitRect, MouseCursor.SplitResizeLeftRight);
        EditorGUI.DrawRect(splitRect, Color_Split);

        if (Event.current.type == EventType.MouseDown)
        {
            if (splitRect.Contains(Event.current.mousePosition))
                m_SplitCickDown = true;
        }

        if (m_SplitCickDown)
        {
            if (Event.current.type == EventType.MouseDrag)
            {
                m_SplitLeftWidth += Event.current.delta.x;
                m_SplitLeftWidth = Mathf.Max(Split_Left_Min_Size, Mathf.Min(m_SplitLeftWidth, Split_Left_Max_Size));
                Event.current.Use();
            }
            else if (Event.current.type == EventType.MouseUp)
            {
                m_SplitCickDown = false;
                Event.current.Use();
                //Debug.Log($"MouseUp: {Event.current.type}");
            }
        }
    }

}

class MyGUIContents
{
    public readonly GUIContent Btn_FirstKey = EditorGUIUtility.TrIconContent("Animation.FirstKey");
    public readonly GUIContent Btn_PrevKey = EditorGUIUtility.TrIconContent("Animation.PrevKey");
    public readonly GUIContent Tog_Play = EditorGUIUtility.TrIconContent("Animation.Play");
    public readonly GUIContent Btn_NextKey = EditorGUIUtility.TrIconContent("Animation.NextKey");
    public readonly GUIContent Btn_LastKey = EditorGUIUtility.TrIconContent("Animation.LastKey");

    public readonly GUIContent Btn_Popup = EditorGUIUtility.TrIconContent("_Popup");

    public readonly GUIContent Label_Duration = new GUIContent("duration:");
    public readonly GUIContent Frame_Rate_30 = new GUIContent("Frame Rate 30");
    public readonly GUIContent Frame_Rate_50 = new GUIContent("Frame Rate 50");
    public readonly GUIContent Frame_Rate60 = new GUIContent("Frame Rate 60");

}

相關文章