Browse Source

Reorderable list for commands

master
chrisgregan 11 years ago
parent
commit
5fa7b2a347
  1. 49
      Assets/Fungus/FungusScript/Editor/FungusCommandEditor.cs
  2. 195
      Assets/Fungus/FungusScript/Editor/FungusCommandListAdaptor.cs
  3. 8
      Assets/Fungus/FungusScript/Editor/FungusCommandListAdaptor.cs.meta
  4. 115
      Assets/Fungus/FungusScript/Editor/FungusScriptEditor.cs
  5. 9
      Assets/Fungus/FungusScript/Editor/FungusScriptWindow.cs
  6. 3
      Assets/Fungus/FungusScript/Editor/FungusVariableListAdaptor.cs
  7. 130
      Assets/Fungus/FungusScript/Editor/SequenceEditor.cs
  8. 9
      Assets/Fungus/FungusScript/Scripts/Sequence.cs
  9. BIN
      Assets/Shuttle/ShuttleGame.unity

49
Assets/Fungus/FungusScript/Editor/FungusCommandEditor.cs

@ -103,26 +103,17 @@ namespace Fungus.Script
GUILayout.BeginHorizontal();
string commandName = FungusScriptEditor.GetCommandName(t.GetType());
GUILayout.Label(commandName, EditorStyles.largeLabel);
GUILayout.FlexibleSpace();
bool enabled = GUILayout.Toggle(t.enabled, "");
bool enabled = GUILayout.Toggle(t.enabled, new GUIContent());
if (t.enabled != enabled)
{
Undo.RecordObject(t, "Set Enabled");
t.enabled = enabled;
}
if (GUILayout.Button("Up", EditorStyles.miniButtonLeft))
{
UnityEditorInternal.ComponentUtility.MoveComponentUp(t);
}
if (GUILayout.Button("Down", EditorStyles.miniButtonMid))
{
UnityEditorInternal.ComponentUtility.MoveComponentDown(t);
}
string commandName = FungusScriptEditor.GetCommandName(t.GetType());
GUILayout.Label(commandName + " Command", EditorStyles.boldLabel);
GUILayout.FlexibleSpace();
if (fungusScript != null)
{
@ -133,17 +124,15 @@ namespace Fungus.Script
if (fungusScript.copyCommand != null)
{
if (GUILayout.Button("Paste", EditorStyles.miniButtonMid))
if (GUILayout.Button("Paste", EditorStyles.miniButton))
{
Sequence parentSequence = t.GetComponent<Sequence>();
if (parentSequence != null)
{
CopyComponent<FungusCommand>(fungusScript.copyCommand, t.gameObject);
PasteCommand(fungusScript.copyCommand, parentSequence);
}
}
}
if (GUILayout.Button("Delete", EditorStyles.miniButtonRight))
{
Undo.DestroyObjectImmediate(t);
return;
}
GUILayout.EndHorizontal();
@ -169,16 +158,24 @@ namespace Fungus.Script
DrawDefaultInspector();
}
T CopyComponent<T>(T original, GameObject destination) where T : Component
static public FungusCommand PasteCommand(FungusCommand copyCommand, Sequence sequence)
{
System.Type type = original.GetType();
Component copy = Undo.AddComponent(destination, type);
System.Type type = copyCommand.GetType();
Component copy = Undo.AddComponent(sequence.gameObject, type);
System.Reflection.FieldInfo[] fields = type.GetFields();
foreach (System.Reflection.FieldInfo field in fields)
{
field.SetValue(copy, field.GetValue(original));
field.SetValue(copy, field.GetValue(copyCommand));
}
return copy as T;
FungusScript fungusScript = sequence.GetFungusScript();
Undo.RecordObject(fungusScript, "Paste Command");
FungusCommand newCommand = copy as FungusCommand;
sequence.commandList.Add(newCommand);
return newCommand;
}
static public T ObjectField<T>(GUIContent label, GUIContent nullLabel, T selectedObject, List<T> objectList) where T : MonoBehaviour

195
Assets/Fungus/FungusScript/Editor/FungusCommandListAdaptor.cs

@ -0,0 +1,195 @@
// Copyright (c) 2012-2013 Rotorz Limited. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
using UnityEngine;
using UnityEditor;
using System;
using Rotorz.ReorderableList;
namespace Fungus.Script
{
public class FungusCommandListAdaptor : IReorderableListAdaptor {
private SerializedProperty _arrayProperty;
public float fixedItemHeight;
public SerializedProperty this[int index] {
get { return _arrayProperty.GetArrayElementAtIndex(index); }
}
public SerializedProperty arrayProperty {
get { return _arrayProperty; }
}
public FungusCommandListAdaptor(SerializedProperty arrayProperty, float fixedItemHeight) {
if (arrayProperty == null)
throw new ArgumentNullException("Array property was null.");
if (!arrayProperty.isArray)
throw new InvalidOperationException("Specified serialized propery is not an array.");
this._arrayProperty = arrayProperty;
this.fixedItemHeight = fixedItemHeight;
}
public FungusCommandListAdaptor(SerializedProperty arrayProperty) : this(arrayProperty, 0f) {
}
public int Count {
get { return _arrayProperty.arraySize; }
}
public virtual bool CanDrag(int index) {
return true;
}
public virtual bool CanRemove(int index) {
return true;
}
public void Add() {
int newIndex = _arrayProperty.arraySize;
++_arrayProperty.arraySize;
ResetValue(_arrayProperty.GetArrayElementAtIndex(newIndex));
}
public void Insert(int index) {
_arrayProperty.InsertArrayElementAtIndex(index);
ResetValue(_arrayProperty.GetArrayElementAtIndex(index));
}
public void Duplicate(int index) {
_arrayProperty.InsertArrayElementAtIndex(index);
}
public void Remove(int index) {
// Remove the Fungus Command component
FungusCommand command = _arrayProperty.GetArrayElementAtIndex(index).objectReferenceValue as FungusCommand;
Undo.DestroyObjectImmediate(command);
_arrayProperty.GetArrayElementAtIndex(index).objectReferenceValue = null;
_arrayProperty.DeleteArrayElementAtIndex(index);
}
public void Move(int sourceIndex, int destIndex) {
if (destIndex > sourceIndex)
--destIndex;
_arrayProperty.MoveArrayElement(sourceIndex, destIndex);
}
public void Clear() {
_arrayProperty.ClearArray();
}
public void DrawItem(Rect position, int index)
{
FungusCommand command = this[index].objectReferenceValue as FungusCommand;
FungusScript fungusScript = command.GetFungusScript();
bool error = false;
string summary = command.GetSummary().Replace("\n", "").Replace("\r", "");
if (summary.Length > 80)
{
summary = summary.Substring(0, 80) + "...";
}
if (summary.StartsWith("Error:"))
{
error = true;
}
if (!command.enabled)
{
GUI.backgroundColor = Color.grey;
}
else if (error)
{
GUI.backgroundColor = Color.red;
}
else if (fungusScript.selectedCommand == command)
{
GUI.backgroundColor = Color.yellow;
}
Rect buttonRect = position;
buttonRect.width = 80;
Rect summaryRect = position;
summaryRect.x += 85;
summaryRect.width -= 85;
string commandName = FungusScriptEditor.GetCommandName(command.GetType());
if (GUI.Button(buttonRect, commandName, EditorStyles.miniButton))
{
fungusScript.selectedCommand = command;
GUIUtility.keyboardControl = 0; // Fix for textarea not refeshing (change focus)
}
GUI.backgroundColor = Color.white;
GUIStyle labelStyle = new GUIStyle(EditorStyles.miniLabel);
labelStyle.wordWrap = true;
if (!command.enabled)
{
labelStyle.normal.textColor = Color.grey;
}
else if (error)
{
labelStyle.normal.textColor = Color.red;
}
GUI.Label(summaryRect, summary, labelStyle);
if (Event.current.type == EventType.Repaint &&
command.IsExecuting())
{
GLDraw.DrawBox(position, Color.green, 1.5f);
}
}
public virtual float GetItemHeight(int index) {
return fixedItemHeight != 0f
? fixedItemHeight
: EditorGUI.GetPropertyHeight(this[index], GUIContent.none, false)
;
}
private void ResetValue(SerializedProperty element) {
switch (element.type) {
case "string":
element.stringValue = "";
break;
case "Vector2f":
element.vector2Value = Vector2.zero;
break;
case "Vector3f":
element.vector3Value = Vector3.zero;
break;
case "Rectf":
element.rectValue = new Rect();
break;
case "Quaternionf":
element.quaternionValue = Quaternion.identity;
break;
case "int":
element.intValue = 0;
break;
case "float":
element.floatValue = 0f;
break;
case "UInt8":
element.boolValue = false;
break;
case "ColorRGBA":
element.colorValue = Color.black;
break;
default:
if (element.type.StartsWith("PPtr"))
element.objectReferenceValue = null;
break;
}
}
}
}

8
Assets/Fungus/FungusScript/Editor/FungusCommandListAdaptor.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 44d3aa3e5c3bf4b99b9899e8d5f5bc52
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

115
Assets/Fungus/FungusScript/Editor/FungusScriptEditor.cs

@ -2,7 +2,6 @@ using UnityEditor;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Fungus;
using Rotorz.ReorderableList;
using System.Linq;
@ -74,120 +73,6 @@ namespace Fungus.Script
DrawVariablesGUI();
}
public void DrawSequenceGUI(FungusScript fungusScript)
{
if (fungusScript.selectedSequence == null)
{
return;
}
Sequence sequence = fungusScript.selectedSequence;
EditorGUI.BeginChangeCheck();
string name = EditorGUILayout.TextField(new GUIContent("Name", "Name of sequence displayed in editor window"), sequence.name);
string desc = EditorGUILayout.TextField(new GUIContent("Description", "Sequence description displayed in editor window"), sequence.description);
EditorGUILayout.Separator();
if (name != sequence.name)
{
// The name is the gameobject name, so have to undo seperately
Undo.RecordObject(sequence.gameObject, "Set Sequence Name");
sequence.name = name;
}
if (desc != sequence.description)
{
Undo.RecordObject(sequence, "Set Sequence Description");
sequence.description = desc;
}
GUILayout.Box("Commands", GUILayout.ExpandWidth(true));
FungusCommand[] commands = sequence.GetComponents<FungusCommand>();
foreach (FungusCommand command in commands)
{
FungusCommandEditor commandEditor = Editor.CreateEditor(command) as FungusCommandEditor;
commandEditor.DrawCommandRowGUI();
}
if (Application.isPlaying)
{
return;
}
EditorGUILayout.Separator();
GUILayout.Box("New Command", GUILayout.ExpandWidth(true));
EditorGUI.BeginChangeCheck();
EditorGUILayout.BeginHorizontal();
List<string> commandNames = new List<string>();
List<System.Type> commandTypes = EditorExtensions.FindDerivedTypes(typeof(FungusCommand)).ToList();
foreach (System.Type type in commandTypes)
{
object[] attributes = type.GetCustomAttributes(false);
foreach (object obj in attributes)
{
CommandCategoryAttribute categoryAttr = obj as CommandCategoryAttribute;
if (categoryAttr != null)
{
string commandItem = categoryAttr.Category + " / " + GetCommandName(type);
commandNames.Add(commandItem);
break;
}
}
}
int selectedCommandIndex = EditorGUILayout.Popup(fungusScript.selectedAddCommandIndex, commandNames.ToArray());
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(fungusScript, "Select Command");
fungusScript.selectedAddCommandIndex = selectedCommandIndex;
}
if (selectedCommandIndex >= commandTypes.Count)
{
EditorGUILayout.EndHorizontal();
return;
}
System.Type selectedType = commandTypes[selectedCommandIndex];
if (fungusScript.selectedSequence == null ||
selectedType == null)
{
EditorGUILayout.EndHorizontal();
return;
}
if (GUILayout.Button(new GUIContent("Add", "Add the selected command to the sequence"), EditorStyles.miniButton))
{
Undo.AddComponent(fungusScript.selectedSequence.gameObject, selectedType);
}
EditorGUILayout.EndHorizontal();
object[] helpAttributes = selectedType.GetCustomAttributes(typeof(HelpTextAttribute), false);
foreach (object obj in helpAttributes)
{
HelpTextAttribute helpTextAttr = obj as HelpTextAttribute;
if (helpTextAttr != null)
{
GUIStyle labelStyle = new GUIStyle(EditorStyles.miniLabel);
labelStyle.wordWrap = true;
EditorGUILayout.HelpBox(helpTextAttr.HelpText, MessageType.Info);
break;
}
}
EditorGUILayout.Separator();
}
public void DrawVariablesGUI()
{
serializedObject.Update();

9
Assets/Fungus/FungusScript/Editor/FungusScriptWindow.cs

@ -51,7 +51,7 @@ namespace Fungus.Script
GUILayout.BeginHorizontal();
DrawScriptView(fungusScript);
ResizeViews(fungusScript);
DrawCommandView(fungusScript);
DrawSequenceView(fungusScript);
GUILayout.EndHorizontal();
}
@ -179,7 +179,7 @@ namespace Fungus.Script
}
}
void DrawCommandView(FungusScript fungusScript)
void DrawSequenceView(FungusScript fungusScript)
{
GUILayout.Space(5);
@ -236,12 +236,15 @@ namespace Fungus.Script
GUILayout.EndHorizontal();
if (fungusScript.selectedSequence != null)
{
EditorGUILayout.Separator();
FungusScriptEditor editor = Editor.CreateEditor(fungusScript) as FungusScriptEditor;
SequenceEditor editor = Editor.CreateEditor(fungusScript.selectedSequence) as SequenceEditor;
editor.DrawSequenceGUI(fungusScript);
GUILayout.FlexibleSpace();
}
EditorGUILayout.EndVertical();

3
Assets/Fungus/FungusScript/Editor/FungusVariableListAdaptor.cs

@ -198,8 +198,7 @@ namespace Fungus.Script
if (fungusScript.selectedSequence != null &&
fungusScript.selectedCommand != null)
{
FungusCommand[] commands = fungusScript.selectedSequence.GetComponents<FungusCommand>();
foreach (FungusCommand command in commands)
foreach (FungusCommand command in fungusScript.selectedSequence.commandList)
{
if (fungusScript.selectedCommand == command &&
command.HasReference(variable))

130
Assets/Fungus/FungusScript/Editor/SequenceEditor.cs

@ -3,6 +3,8 @@ using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Rotorz.ReorderableList;
namespace Fungus.Script
{
@ -10,6 +12,134 @@ namespace Fungus.Script
[CustomEditor (typeof(Sequence))]
public class SequenceEditor : Editor
{
public void DrawSequenceGUI(FungusScript fungusScript)
{
if (fungusScript.selectedSequence == null)
{
return;
}
serializedObject.Update();
Sequence sequence = fungusScript.selectedSequence;
EditorGUI.BeginChangeCheck();
string name = EditorGUILayout.TextField(new GUIContent("Name", "Name of sequence displayed in editor window"), sequence.name);
string desc = EditorGUILayout.TextField(new GUIContent("Description", "Sequence description displayed in editor window"), sequence.description);
EditorGUILayout.Separator();
if (name != sequence.name)
{
// The name is the gameobject name, so have to undo seperately
Undo.RecordObject(sequence.gameObject, "Set Sequence Name");
sequence.name = name;
}
if (desc != sequence.description)
{
Undo.RecordObject(sequence, "Set Sequence Description");
sequence.description = desc;
}
ReorderableListGUI.Title("Command Sequence");
SerializedProperty commandListProperty = serializedObject.FindProperty("commandList");
FungusCommandListAdaptor adaptor = new FungusCommandListAdaptor(commandListProperty, 0);
ReorderableListControl.DrawControlFromState(adaptor, null, ReorderableListFlags.DisableContextMenu | ReorderableListFlags.HideAddButton);
if (Application.isPlaying)
{
return;
}
EditorGUI.BeginChangeCheck();
EditorGUILayout.Separator();
EditorGUILayout.BeginHorizontal();
List<string> commandNames = new List<string>();
List<System.Type> commandTypes = EditorExtensions.FindDerivedTypes(typeof(FungusCommand)).ToList();
foreach (System.Type type in commandTypes)
{
object[] attributes = type.GetCustomAttributes(false);
foreach (object obj in attributes)
{
CommandCategoryAttribute categoryAttr = obj as CommandCategoryAttribute;
if (categoryAttr != null)
{
string commandItem = categoryAttr.Category + " / " + FungusScriptEditor.GetCommandName(type);
commandNames.Add(commandItem);
break;
}
}
}
Rect newRect = GUILayoutUtility.GetRect(100, 30);
int selectedCommandIndex = EditorGUI.Popup(newRect, fungusScript.selectedAddCommandIndex, commandNames.ToArray());
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(fungusScript, "Select Command");
fungusScript.selectedAddCommandIndex = selectedCommandIndex;
}
if (selectedCommandIndex >= commandTypes.Count)
{
EditorGUILayout.EndHorizontal();
return;
}
System.Type selectedType = commandTypes[selectedCommandIndex];
if (fungusScript.selectedSequence == null ||
selectedType == null)
{
EditorGUILayout.EndHorizontal();
return;
}
if (GUILayout.Button(new GUIContent("Add Command", "Add the selected command to the sequence"), EditorStyles.miniButton))
{
FungusCommand newCommand = Undo.AddComponent(fungusScript.selectedSequence.gameObject, selectedType) as FungusCommand;
Undo.RecordObject(fungusScript, "Add Command");
fungusScript.selectedSequence.commandList.Add(newCommand);
}
/*
if (fungusScript.copyCommand != null)
{
if (GUILayout.Button("Paste", EditorStyles.miniButton))
{
FungusCommandEditor.PasteCommand(fungusScript.copyCommand, fungusScript.selectedSequence);
}
}
*/
EditorGUILayout.EndHorizontal();
object[] helpAttributes = selectedType.GetCustomAttributes(typeof(HelpTextAttribute), false);
foreach (object obj in helpAttributes)
{
HelpTextAttribute helpTextAttr = obj as HelpTextAttribute;
if (helpTextAttr != null)
{
GUIStyle labelStyle = new GUIStyle(EditorStyles.miniLabel);
labelStyle.wordWrap = true;
EditorGUILayout.HelpBox(helpTextAttr.HelpText, MessageType.Info);
break;
}
}
EditorGUILayout.Separator();
serializedObject.ApplyModifiedProperties();
}
static public Sequence SequenceField(GUIContent label, GUIContent nullLabel, FungusScript fungusScript, Sequence sequence)
{
if (fungusScript == null)

9
Assets/Fungus/FungusScript/Scripts/Sequence.cs

@ -9,6 +9,7 @@ using System.Collections.Generic;
namespace Fungus.Script
{
[ExecuteInEditMode]
public class Sequence : MonoBehaviour
{
[HideInInspector]
@ -23,6 +24,8 @@ namespace Fungus.Script
[System.NonSerialized]
public FungusCommand activeCommand;
public List<FungusCommand> commandList = new List<FungusCommand>();
int executionCount;
public virtual void Start()
@ -48,8 +51,7 @@ namespace Fungus.Script
public bool HasError()
{
FungusCommand[] commands = GetComponents<FungusCommand>();
foreach (FungusCommand command in commands)
foreach (FungusCommand command in commandList)
{
if (command.errorMessage.Length > 0)
{
@ -87,8 +89,7 @@ namespace Fungus.Script
FungusCommand nextCommand = null;
bool executeNext = (currentCommand == null);
FungusCommand[] commands = GetComponents<FungusCommand>();
foreach (FungusCommand command in commands)
foreach (FungusCommand command in commandList)
{
if (command == currentCommand)
{

BIN
Assets/Shuttle/ShuttleGame.unity

Binary file not shown.
Loading…
Cancel
Save