Browse Source

Display UnityEvent properties

CommandEditors are now only created / destroyed when needed instead of
every frame (much more efficient too).
Workarounds for compatibility issues with ReorderableList and
UnityEvent rendering. Selection rectangle now obscures the built-in
grabber on reorderable list and shift selection changes now happen on
next frame instead of immediately.

As a side effect, the shift selection logic is now more straightforward.
master
chrisgregan 10 years ago
parent
commit
74483ec24a
  1. 68
      Assets/Fungus/Flowchart/Editor/BlockInspector.cs
  2. 131
      Assets/Fungus/Flowchart/Editor/CommandListAdaptor.cs

68
Assets/Fungus/Flowchart/Editor/BlockInspector.cs

@ -2,6 +2,7 @@ using UnityEngine;
using UnityEngine.Serialization; using UnityEngine.Serialization;
using UnityEditor; using UnityEditor;
using System.Collections; using System.Collections;
using System.Collections.Generic;
namespace Fungus namespace Fungus
{ {
@ -26,6 +27,23 @@ namespace Fungus
protected bool resize = false; protected bool resize = false;
protected float topPanelHeight = 50; protected float topPanelHeight = 50;
// Cache the block and command editors so we only create and destroy them
// when a different block / command is selected.
protected BlockEditor activeBlockEditor;
protected CommandEditor activeCommandEditor;
protected Command activeCommand; // Command currently being inspected
// Cached command editors to avoid creating / destroying editors more than necessary
protected Dictionary<Command, CommandEditor> cachedCommandEditors = new Dictionary<Command, CommandEditor>();
protected void OnDisable()
{
foreach (CommandEditor commandEditor in cachedCommandEditors.Values)
{
DestroyImmediate(commandEditor);
}
}
public override void OnInspectorGUI () public override void OnInspectorGUI ()
{ {
BlockInspector blockInspector = target as BlockInspector; BlockInspector blockInspector = target as BlockInspector;
@ -38,15 +56,21 @@ namespace Fungus
Flowchart flowchart = block.GetFlowchart(); Flowchart flowchart = block.GetFlowchart();
BlockEditor blockEditor = Editor.CreateEditor(block) as BlockEditor; if (activeBlockEditor == null ||
blockEditor.DrawBlockName(flowchart); block != activeBlockEditor.target)
{
DestroyImmediate(activeBlockEditor);
activeBlockEditor = Editor.CreateEditor(block) as BlockEditor;
}
activeBlockEditor.DrawBlockName(flowchart);
// Using a custom rect area to get the correct 5px indent for the scroll views // Using a custom rect area to get the correct 5px indent for the scroll views
Rect blockRect = new Rect(5, topPanelHeight, Screen.width - 6, Screen.height - 70); Rect blockRect = new Rect(5, topPanelHeight, Screen.width - 6, Screen.height - 70);
GUILayout.BeginArea(blockRect); GUILayout.BeginArea(blockRect);
blockScrollPos = GUILayout.BeginScrollView(blockScrollPos, GUILayout.Height(flowchart.blockViewHeight)); blockScrollPos = GUILayout.BeginScrollView(blockScrollPos, GUILayout.Height(flowchart.blockViewHeight));
blockEditor.DrawBlockGUI(flowchart); activeBlockEditor.DrawBlockGUI(flowchart);
GUILayout.EndScrollView(); GUILayout.EndScrollView();
Command inspectCommand = null; Command inspectCommand = null;
@ -61,23 +85,49 @@ namespace Fungus
{ {
GUILayout.EndArea(); GUILayout.EndArea();
Repaint(); Repaint();
DestroyImmediate(blockEditor);
return; return;
} }
// Only change the activeCommand at the start of the GUI call sequence
if (Event.current.type == EventType.Layout)
{
activeCommand = inspectCommand;
}
DrawCommandUI(flowchart, inspectCommand);
}
public void DrawCommandUI(Flowchart flowchart, Command inspectCommand)
{
ResizeScrollView(flowchart); ResizeScrollView(flowchart);
GUILayout.Space(7); GUILayout.Space(7);
blockEditor.DrawButtonToolbar(); activeBlockEditor.DrawButtonToolbar();
commandScrollPos = GUILayout.BeginScrollView(commandScrollPos); commandScrollPos = GUILayout.BeginScrollView(commandScrollPos);
if (inspectCommand != null) if (inspectCommand != null)
{ {
CommandEditor commandEditor = Editor.CreateEditor(inspectCommand) as CommandEditor; if (activeCommandEditor == null ||
commandEditor.DrawCommandInspectorGUI(); inspectCommand != activeCommandEditor.target)
DestroyImmediate(commandEditor); {
// See if we have a cached version of the command editor already,
// if not then create a new one.
if (cachedCommandEditors.ContainsKey(inspectCommand))
{
activeCommandEditor = cachedCommandEditors[inspectCommand];
}
else
{
activeCommandEditor = Editor.CreateEditor(inspectCommand) as CommandEditor;
cachedCommandEditors[inspectCommand] = activeCommandEditor;
}
}
if (activeCommandEditor != null)
{
activeCommandEditor.DrawCommandInspectorGUI();
}
} }
GUILayout.EndScrollView(); GUILayout.EndScrollView();
@ -97,8 +147,6 @@ namespace Fungus
GUI.color = Color.white; GUI.color = Color.white;
Repaint(); Repaint();
DestroyImmediate(blockEditor);
} }
private void ResizeScrollView(Flowchart flowchart) private void ResizeScrollView(Flowchart flowchart)

131
Assets/Fungus/Flowchart/Editor/CommandListAdaptor.cs

@ -18,11 +18,7 @@ namespace Fungus
public float fixedItemHeight; public float fixedItemHeight;
public Rect nodeRect = new Rect(); public Rect nodeRect = new Rect();
public static bool pinShiftToTop;
public static int firstSelectedIndex = 0;
public static int lastSelectedIndex = 0;
public SerializedProperty this[int index] { public SerializedProperty this[int index] {
get { return _arrayProperty.GetArrayElementAtIndex(index); } get { return _arrayProperty.GetArrayElementAtIndex(index); }
} }
@ -247,11 +243,20 @@ namespace Fungus
commandLabelRect.y -= 2; commandLabelRect.y -= 2;
commandLabelRect.width -= (indentSize * command.indentLevel - 22); commandLabelRect.width -= (indentSize * command.indentLevel - 22);
commandLabelRect.height += 5; commandLabelRect.height += 5;
// There's a weird incompatibility between the Reorderable list control used for the command list and
// the UnityEvent list control used in some commands. In play mode, if you click on the reordering grabber
// for a command in the list it causes the UnityEvent list to spew null exception errors.
// The workaround for now is to hide the reordering grabber from mouse clicks by extending the command
// selection rectangle to cover it. We are planning to totally replace the command list display system.
Rect clickRect = position;
clickRect.x -= 20;
clickRect.width += 20;
// Select command via left click // Select command via left click
if (Event.current.type == EventType.MouseDown && if (Event.current.type == EventType.MouseDown &&
Event.current.button == 0 && Event.current.button == 0 &&
position.Contains(Event.current.mousePosition)) clickRect.Contains(Event.current.mousePosition))
{ {
if (flowchart.selectedCommands.Contains(command) && Event.current.button == 0) if (flowchart.selectedCommands.Contains(command) && Event.current.button == 0)
{ {
@ -259,84 +264,104 @@ namespace Fungus
// Command key and shift key is not pressed // Command key and shift key is not pressed
if (!EditorGUI.actionKey && !Event.current.shift) if (!EditorGUI.actionKey && !Event.current.shift)
{ {
flowchart.selectedCommands.Remove(command); BlockEditor.actionList.Add ( delegate {
flowchart.ClearSelectedCommands(); flowchart.selectedCommands.Remove(command);
flowchart.ClearSelectedCommands();
});
} }
// Command key pressed // Command key pressed
if (EditorGUI.actionKey) if (EditorGUI.actionKey)
{ {
flowchart.selectedCommands.Remove(command); BlockEditor.actionList.Add ( delegate {
} flowchart.selectedCommands.Remove(command);
// Shift key pressed });
if (Event.current.shift) Event.current.Use();
{
flowchart.ClearSelectedCommands();
if (pinShiftToTop)
{
for (int i = firstSelectedIndex; i < index+1; ++i)
{
flowchart.AddSelectedCommand(flowchart.selectedBlock.commandList[i]);
}
}
else
{
for (int i = index; i < lastSelectedIndex+1; ++i)
{
flowchart.AddSelectedCommand(flowchart.selectedBlock.commandList[i]);
}
}
} }
} }
else else
{ {
bool shift = Event.current.shift;
// Left click and no command key // Left click and no command key
if (!Event.current.shift && !EditorGUI.actionKey && Event.current.button == 0) if (!shift && !EditorGUI.actionKey && Event.current.button == 0)
{ {
flowchart.ClearSelectedCommands(); BlockEditor.actionList.Add ( delegate {
flowchart.ClearSelectedCommands();
});
Event.current.Use();
} }
flowchart.AddSelectedCommand(command);
BlockEditor.actionList.Add ( delegate {
bool firstSelectedCommandFound = false; flowchart.AddSelectedCommand(command);
});
// Find first and last selected commands
int firstSelectedIndex = -1;
int lastSelectedIndex = -1;
if (flowchart.selectedCommands.Count > 0) if (flowchart.selectedCommands.Count > 0)
{ {
if ( flowchart.selectedBlock != null) if ( flowchart.selectedBlock != null)
{ {
for (int i = 0; i < flowchart.selectedBlock.commandList.Count; i++) for (int i = 0; i < flowchart.selectedBlock.commandList.Count; i++)
{ {
Command commandInBlock = flowchart.selectedBlock.commandList[i]; Command commandInBlock = flowchart.selectedBlock.commandList[i];
foreach (Command selectedCommand in flowchart.selectedCommands)
{
if (commandInBlock == selectedCommand)
{
firstSelectedIndex = i;
break;
}
}
}
for (int i = flowchart.selectedBlock.commandList.Count - 1; i >=0; i--)
{
Command commandInBlock = flowchart.selectedBlock.commandList[i];
foreach (Command selectedCommand in flowchart.selectedCommands) foreach (Command selectedCommand in flowchart.selectedCommands)
{ {
if (commandInBlock == selectedCommand) if (commandInBlock == selectedCommand)
{ {
if (!firstSelectedCommandFound)
{
firstSelectedIndex = i;
firstSelectedCommandFound = true;
}
lastSelectedIndex = i; lastSelectedIndex = i;
break;
} }
} }
} }
} }
} }
if (Event.current.shift) if (shift)
{ {
for (int i = firstSelectedIndex; i < lastSelectedIndex; ++i) int currentIndex = command.commandIndex;
if (firstSelectedIndex == -1 ||
lastSelectedIndex == -1)
{ {
flowchart.AddSelectedCommand(flowchart.selectedBlock.commandList[i]); // No selected command found - select entire list
firstSelectedIndex = 0;
lastSelectedIndex = currentIndex;
}
else
{
if (currentIndex < firstSelectedIndex)
{
firstSelectedIndex = currentIndex;
}
if (currentIndex > lastSelectedIndex)
{
lastSelectedIndex = currentIndex;
}
}
for (int i = Math.Min(firstSelectedIndex, lastSelectedIndex); i < Math.Max(firstSelectedIndex, lastSelectedIndex); ++i)
{
Command selectedCommand = flowchart.selectedBlock.commandList[i];
BlockEditor.actionList.Add ( delegate {
flowchart.AddSelectedCommand(selectedCommand);
});
} }
} }
if (index == firstSelectedIndex)
{ Event.current.Use();
pinShiftToTop = false;
}
else if (index == lastSelectedIndex)
{
pinShiftToTop = true;
}
} }
GUIUtility.keyboardControl = 0; // Fix for textarea not refeshing (change focus) GUIUtility.keyboardControl = 0; // Fix for textarea not refeshing (change focus)
} }

Loading…
Cancel
Save