using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.Experimental.GraphView;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
using UnityEditor;
using System.Linq;
using System;
using Status = UnityEngine.UIElements.DropdownMenuAction.Status;
namespace GraphProcessor
{
public class ToolbarView : VisualElement
{
protected enum ElementType
{
Button,
Toggle,
DropDownButton,
Separator,
Custom,
FlexibleSpace,
}
protected class ToolbarButtonData
{
public GUIContent content;
public ElementType type;
public bool value;
public bool visible = true;
public Action buttonCallback;
public Action< bool > toggleCallback;
public int size;
public Action customDrawFunction;
}
List< ToolbarButtonData > leftButtonDatas = new List< ToolbarButtonData >();
List< ToolbarButtonData > rightButtonDatas = new List< ToolbarButtonData >();
protected BaseGraphView graphView;
ToolbarButtonData showProcessor;
ToolbarButtonData showParameters;
public ToolbarView(BaseGraphView graphView)
{
name = "ToolbarView";
this.graphView = graphView;
graphView.initialized += () => {
leftButtonDatas.Clear();
rightButtonDatas.Clear();
AddButtons();
};
Add(new IMGUIContainer(DrawImGUIToolbar));
}
protected ToolbarButtonData AddButton(string name, Action callback, bool left = true)
=> AddButton(new GUIContent(name), callback, left);
protected ToolbarButtonData AddButton(GUIContent content, Action callback, bool left = true)
{
var data = new ToolbarButtonData{
content = content,
type = ElementType.Button,
buttonCallback = callback
};
((left) ? leftButtonDatas : rightButtonDatas).Add(data);
return data;
}
protected void AddSeparator(int sizeInPixels = 10, bool left = true)
{
var data = new ToolbarButtonData{
type = ElementType.Separator,
size = sizeInPixels,
};
((left) ? leftButtonDatas : rightButtonDatas).Add(data);
}
protected void AddCustom(Action imguiDrawFunction, bool left = true)
{
if (imguiDrawFunction == null)
throw new ArgumentException("imguiDrawFunction can't be null");
var data = new ToolbarButtonData{
type = ElementType.Custom,
customDrawFunction = imguiDrawFunction,
};
((left) ? leftButtonDatas : rightButtonDatas).Add(data);
}
protected void AddFlexibleSpace(bool left = true)
{
((left) ? leftButtonDatas : rightButtonDatas).Add(new ToolbarButtonData{ type = ElementType.FlexibleSpace });
}
protected ToolbarButtonData AddToggle(string name, bool defaultValue, Action< bool > callback, bool left = true)
=> AddToggle(new GUIContent(name), defaultValue, callback, left);
protected ToolbarButtonData AddToggle(GUIContent content, bool defaultValue, Action< bool > callback, bool left = true)
{
var data = new ToolbarButtonData{
content = content,
type = ElementType.Toggle,
value = defaultValue,
toggleCallback = callback
};
((left) ? leftButtonDatas : rightButtonDatas).Add(data);
return data;
}
protected ToolbarButtonData AddDropDownButton(string name, Action callback, bool left = true)
=> AddDropDownButton(new GUIContent(name), callback, left);
protected ToolbarButtonData AddDropDownButton(GUIContent content, Action callback, bool left = true)
{
var data = new ToolbarButtonData{
content = content,
type = ElementType.DropDownButton,
buttonCallback = callback
};
((left) ? leftButtonDatas : rightButtonDatas).Add(data);
return data;
}
///
/// Also works for toggles
///
///
///
protected void RemoveButton(string name, bool left)
{
((left) ? leftButtonDatas : rightButtonDatas).RemoveAll(b => b.content.text == name);
}
///
/// Hide the button
///
/// Display name of the button
protected void HideButton(string name)
{
leftButtonDatas.Concat(rightButtonDatas).All(b => {
if (b?.content?.text == name)
b.visible = false;
return true;
});
}
///
/// Show the button
///
/// Display name of the button
protected void ShowButton(string name)
{
leftButtonDatas.Concat(rightButtonDatas).All(b => {
if (b?.content?.text == name)
b.visible = true;
return true;
});
}
protected virtual void AddButtons()
{
AddButton("Center", graphView.ResetPositionAndZoom);
bool processorVisible = graphView.GetPinnedElementStatus< ProcessorView >() != Status.Hidden;
showProcessor = AddToggle("Show Processor", processorVisible, (v) => graphView.ToggleView< ProcessorView>());
bool exposedParamsVisible = graphView.GetPinnedElementStatus< ExposedParameterView >() != Status.Hidden;
showParameters = AddToggle("Show Parameters", exposedParamsVisible, (v) => graphView.ToggleView< ExposedParameterView>());
AddButton("Show In Project", () => EditorGUIUtility.PingObject(graphView.graph), false);
}
public virtual void UpdateButtonStatus()
{
if (showProcessor != null)
showProcessor.value = graphView.GetPinnedElementStatus< ProcessorView >() != Status.Hidden;
if (showParameters != null)
showParameters.value = graphView.GetPinnedElementStatus< ExposedParameterView >() != Status.Hidden;
}
void DrawImGUIButtonList(List< ToolbarButtonData > buttons)
{
foreach (var button in buttons.ToList())
{
if (!button.visible)
continue;
switch (button.type)
{
case ElementType.Button:
if (GUILayout.Button(button.content, EditorStyles.toolbarButton) && button.buttonCallback != null)
button.buttonCallback();
break;
case ElementType.Toggle:
EditorGUI.BeginChangeCheck();
button.value = GUILayout.Toggle(button.value, button.content, EditorStyles.toolbarButton);
if (EditorGUI.EndChangeCheck() && button.toggleCallback != null)
button.toggleCallback(button.value);
break;
case ElementType.DropDownButton:
if (EditorGUILayout.DropdownButton(button.content, FocusType.Passive, EditorStyles.toolbarDropDown))
button.buttonCallback();
break;
case ElementType.Separator:
EditorGUILayout.Separator();
EditorGUILayout.Space(button.size);
break;
case ElementType.Custom:
button.customDrawFunction();
break;
case ElementType.FlexibleSpace:
GUILayout.FlexibleSpace();
break;
}
}
}
protected virtual void DrawImGUIToolbar()
{
GUILayout.BeginHorizontal(EditorStyles.toolbar);
DrawImGUIButtonList(leftButtonDatas);
GUILayout.FlexibleSpace();
DrawImGUIButtonList(rightButtonDatas);
GUILayout.EndHorizontal();
}
}
}