Browse Source

Merge branch 'snozbot/master' into icons

master
Zach Vinless 8 years ago
parent
commit
8fc7708a3a
  1. 191
      Assets/Fungus/Scripts/Editor/FlowchartWindow.cs

191
Assets/Fungus/Scripts/Editor/FlowchartWindow.cs

@ -36,9 +36,14 @@ namespace Fungus.EditorUtils
protected Texture2D addTexture;
protected Rect selectionBox;
protected Vector2 startSelectionBoxPosition = new Vector2(-1.0f, -1.0f);
protected Vector2 startSelectionBoxPosition = -Vector2.one;
protected List<Block> mouseDownSelectionState = new List<Block>();
// Context Click occurs on MouseDown which interferes with panning
// Track right click positions manually to show menus on MouseUp
protected Vector2 rightClickDown = -Vector2.one;
protected readonly float rightClickTolerance = 5f;
[MenuItem("Tools/Fungus/Flowchart Window")]
static void Init()
{
@ -156,6 +161,9 @@ namespace Fungus.EditorUtils
if (isSelected)
{
// Deselect
flowchart.SelectedBlocks.Remove(deleteBlock);
// Revert to showing properties for the Flowchart
Selection.activeGameObject = flowchart.gameObject;
}
@ -168,6 +176,9 @@ namespace Fungus.EditorUtils
// Handle selection box events after block and overlay events
HandleSelectionBox(flowchart);
ValidateCommands(flowchart);
ExecuteCommands(flowchart);
if (forceRepaintCount > 0)
{
// Redraw on next frame to get crisp refresh rate
@ -197,7 +208,10 @@ namespace Fungus.EditorUtils
);
GUILayout.Label(flowchart.Zoom.ToString("0.0#x"), EditorStyles.miniLabel, GUILayout.Width(30));
DoZoom(flowchart, newZoom - flowchart.Zoom, Vector2.one * 0.5f);
if (newZoom != flowchart.Zoom)
{
DoZoom(flowchart, newZoom - flowchart.Zoom, Vector2.one * 0.5f);
}
if (GUILayout.Button("Center", EditorStyles.toolbarButton))
{
@ -288,6 +302,22 @@ namespace Fungus.EditorUtils
// Calc rect for script view
Rect scriptViewRect = new Rect(0, 0, this.position.width / flowchart.Zoom, this.position.height / flowchart.Zoom);
// Update right click start outside of EditorZoomArea
if (Event.current.button == 1)
{
if (Event.current.type == EventType.MouseDown)
{
rightClickDown = Event.current.mousePosition;
}
else if (Event.current.type == EventType.MouseDrag)
{
if (Vector2.Distance(rightClickDown, Event.current.mousePosition) > rightClickTolerance)
{
rightClickDown = -Vector2.one;
}
}
}
EditorZoomArea.Begin(flowchart.Zoom, scriptViewRect);
DrawGrid(flowchart);
@ -296,7 +326,10 @@ namespace Fungus.EditorUtils
// The center of the Flowchart depends on the block positions and window dimensions, so we calculate it
// here in the FlowchartWindow class and store it on the Flowchart object for use later.
CalcFlowchartCenter(flowchart, blocks);
if (flowchart != null && blocks.Length > 0)
{
CalcFlowchartCenter(flowchart, blocks);
}
// Draw connections
foreach (var block in blocks)
@ -455,15 +488,51 @@ namespace Fungus.EditorUtils
GLDraw.EndGroup();
EditorZoomArea.End();
// Handle right click up outside of EditorZoomArea to avoid strange offsets
if (Event.current.type == EventType.MouseUp && Event.current.button == 1 &&
rightClickDown != -Vector2.one && !mouseOverVariables)
{
var menu = new GenericMenu();
var mousePosition = rightClickDown;
Block hitBlock = null;
foreach (var block in blocks)
{
if (block._NodeRect.Contains(rightClickDown / flowchart.Zoom - flowchart.ScrollPos))
{
hitBlock = block;
break;
}
}
// Clicked on a block
if (hitBlock != null)
{
flowchart.AddSelectedBlock(hitBlock);
// Use a copy because flowchart.SelectedBlocks gets modified
var blockList = new List<Block>(flowchart.SelectedBlocks);
menu.AddItem(new GUIContent ("Duplicate"), false, DuplicateBlocks, blockList);
menu.AddItem(new GUIContent ("Delete"), false, DeleteBlocks, blockList);
}
// Clicked on empty space in grid
else
{
DeselectAll(flowchart);
menu.AddItem(new GUIContent("Add Block"), false, () => CreateBlock(flowchart, mousePosition / flowchart.Zoom - flowchart.ScrollPos));
}
var menuRect = new Rect();
menuRect.position = new Vector2(mousePosition.x, mousePosition.y - 12f);
menu.DropDown(menuRect);
Event.current.Use();
}
// If event has yet to be used and user isn't multiselecting or panning, clear selection
bool validModifier = Event.current.alt || GetAppendModifierDown();
if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && !validModifier)
{
Undo.RecordObject(flowchart, "Deselect");
flowchart.ClearSelectedCommands();
flowchart.ClearSelectedBlocks();
Selection.activeGameObject = flowchart.gameObject;
DeselectAll(flowchart);
}
// Draw selection box
@ -474,12 +543,11 @@ namespace Fungus.EditorUtils
}
}
public virtual void CalcFlowchartCenter(Flowchart flowchart, Block[] blocks)
public virtual Vector2 GetBlockCenter(Flowchart flowchart, Block[] blocks)
{
if (flowchart == null ||
blocks.Count() == 0)
if (blocks.Length == 0)
{
return;
return Vector2.zero;
}
Vector2 min = blocks[0]._NodeRect.min;
@ -493,8 +561,12 @@ namespace Fungus.EditorUtils
max.y = Mathf.Max(max.y, block._NodeRect.center.y);
}
Vector2 center = (min + max) * -0.5f;
return (min + max) * 0.5f;
}
public virtual void CalcFlowchartCenter(Flowchart flowchart, Block[] blocks)
{
var center = -GetBlockCenter(flowchart, blocks);
center.x += position.width * 0.5f / flowchart.Zoom;
center.y += position.height * 0.5f / flowchart.Zoom;
@ -559,7 +631,7 @@ namespace Fungus.EditorUtils
if (Event.current.rawType == EventType.MouseUp)
{
selectionBox.size = Vector2.zero;
selectionBox.position = Vector2.one * -1;
selectionBox.position = -Vector2.one;
startSelectionBoxPosition = selectionBox.position;
var tempList = new List<Block>(flowchart.SelectedBlocks);
@ -688,6 +760,14 @@ namespace Fungus.EditorUtils
flowchart.SelectedBlock = block;
SetBlockForInspector(flowchart, block);
}
protected virtual void DeselectAll(Flowchart flowchart)
{
Undo.RecordObject(flowchart, "Deselect");
flowchart.ClearSelectedCommands();
flowchart.ClearSelectedBlocks();
Selection.activeGameObject = flowchart.gameObject;
}
public static Block CreateBlock(Flowchart flowchart, Vector2 position)
{
@ -701,18 +781,6 @@ namespace Fungus.EditorUtils
return newBlock;
}
protected virtual void DeleteBlock(Flowchart flowchart, Block block)
{
var commandList = block.CommandList;
foreach (var command in commandList)
{
Undo.DestroyObjectImmediate(command);
}
Undo.DestroyObjectImmediate((Block)block);
flowchart.ClearSelectedCommands();
}
protected virtual void DrawWindow(int windowId)
{
var block = windowBlockMap[windowId];
@ -854,20 +922,6 @@ namespace Fungus.EditorUtils
descriptionStyle.wordWrap = true;
GUILayout.Label(block.Description, descriptionStyle);
}
if (Event.current.type == EventType.ContextClick)
{
flowchart.AddSelectedBlock(block);
GenericMenu menu = new GenericMenu ();
// Use a copy because flowchart.SelectedBlocks gets modified
var blockList = new List<Block>(flowchart.SelectedBlocks);
menu.AddItem(new GUIContent ("Duplicate"), false, DuplicateBlocks, blockList);
menu.AddItem(new GUIContent ("Delete"), false, DeleteBlocks, blockList);
menu.ShowAsContext();
}
}
protected virtual void DrawConnections(Flowchart flowchart, Block block, bool highlightedOnly)
@ -989,6 +1043,11 @@ namespace Fungus.EditorUtils
}
protected static void DuplicateBlocks(object obj)
{
DuplicateBlocks(obj, new Vector2(20, 0));
}
protected static void DuplicateBlocks(object obj, Vector2 offset)
{
var flowchart = GetFlowchart();
@ -999,9 +1058,7 @@ namespace Fungus.EditorUtils
foreach (var block in blocks)
{
Vector2 newPosition = new Vector2(block._NodeRect.position.x +
block._NodeRect.width + 20,
block._NodeRect.y);
Vector2 newPosition = block._NodeRect.position + offset;
Block oldBlock = block;
@ -1087,9 +1144,57 @@ namespace Fungus.EditorUtils
}
}
protected virtual bool GetAppendModifierDown()
protected virtual bool GetAppendModifierDown()
{
return Event.current.shift || EditorGUI.actionKey;
}
protected virtual void ValidateCommands(Flowchart flowchart)
{
if (Event.current.type == EventType.ValidateCommand)
{
var c = Event.current.commandName;
if (c == "Delete" || c == "Duplicate")
{
if (flowchart.SelectedBlocks.Count > 0)
{
Event.current.Use();
}
}
else if (c == "SelectAll")
{
Event.current.Use();
}
}
}
protected virtual void ExecuteCommands(Flowchart flowchart)
{
if (Event.current.type == EventType.ExecuteCommand)
{
switch (Event.current.commandName)
{
case "Delete":
DeleteBlocks(flowchart.SelectedBlocks);
Event.current.Use();
break;
case "Duplicate":
DuplicateBlocks(new List<Block>(flowchart.SelectedBlocks));
Event.current.Use();
break;
case "SelectAll":
Undo.RecordObject(flowchart, "Selection");
flowchart.ClearSelectedBlocks();
foreach (var block in flowchart.GetComponents<Block>())
{
flowchart.AddSelectedBlock(block);
}
Event.current.Use();
break;
}
}
}
}
}
Loading…
Cancel
Save