Browse Source

Separated early events from DrawOverlay()

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

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

@ -11,7 +11,7 @@ using Object = UnityEngine.Object;
namespace Fungus.EditorUtils namespace Fungus.EditorUtils
{ {
public class FlowchartWindow : EditorWindow public class FlowchartWindow : EventWindow
{ {
protected class ClipboardObject protected class ClipboardObject
{ {
@ -148,7 +148,7 @@ namespace Fungus.EditorUtils
protected int blockPopupSelection = -1; protected int blockPopupSelection = -1;
protected Vector2 popupScroll; protected Vector2 popupScroll;
protected bool mouseOverPopup; protected bool mouseOverPopup;
[MenuItem("Tools/Fungus/Flowchart Window")] [MenuItem("Tools/Fungus/Flowchart Window")]
static void Init() static void Init()
{ {
@ -247,6 +247,93 @@ namespace Fungus.EditorUtils
return fungusState.SelectedFlowchart; return fungusState.SelectedFlowchart;
} }
protected virtual void HandleEarlyEvents(Flowchart flowchart, Event e)
{
switch (e.type)
{
case EventType.MouseDown:
// Clear search filter focus
if (!searchRect.Contains(e.mousePosition) && !popupRect.Contains(e.mousePosition))
{
CloseBlockPopup();
}
if (e.button == 0 && searchRect.Contains(e.mousePosition))
{
blockPopupSelection = 0;
popupScroll = Vector2.zero;
}
rightClickDown = -Vector2.one;
break;
case EventType.KeyDown:
if (GUI.GetNameOfFocusedControl() == searchFieldName)
{
var centerBlock = false;
var selectBlock = false;
var closePopup = false;
var useEvent = false;
switch (e.keyCode)
{
case KeyCode.DownArrow:
++blockPopupSelection;
centerBlock = true;
useEvent = true;
break;
case KeyCode.UpArrow:
--blockPopupSelection;
centerBlock = true;
useEvent = true;
break;
case KeyCode.Return:
centerBlock = true;
selectBlock = true;
closePopup = true;
useEvent = true;
break;
case KeyCode.Escape:
closePopup = true;
useEvent = true;
break;
}
blockPopupSelection = Mathf.Clamp(blockPopupSelection, 0, filteredBlocks.Length - 1);
if (centerBlock && filteredBlocks.Length > 0)
{
var block = filteredBlocks[blockPopupSelection];
CenterBlock(flowchart, block);
if (selectBlock)
{
SelectBlock(flowchart, block);
}
}
if (closePopup)
{
CloseBlockPopup();
}
if (useEvent)
{
e.Use();
}
}
else if (e.keyCode == KeyCode.Escape && flowchart.SelectedBlocks.Count > 0)
{
DeselectAll(flowchart);
e.Use();
}
break;
}
}
protected virtual void OnGUI() protected virtual void OnGUI()
{ {
var flowchart = GetFlowchart(); var flowchart = GetFlowchart();
@ -286,6 +373,8 @@ namespace Fungus.EditorUtils
} }
deleteList.Clear(); deleteList.Clear();
HandleEarlyEvents(flowchart, Event.current);
// Clear search filter focus // Clear search filter focus
if (Event.current.type == EventType.MouseDown && !searchRect.Contains(Event.current.mousePosition) && if (Event.current.type == EventType.MouseDown && !searchRect.Contains(Event.current.mousePosition) &&
!popupRect.Contains(Event.current.mousePosition)) !popupRect.Contains(Event.current.mousePosition))
@ -311,6 +400,8 @@ namespace Fungus.EditorUtils
ValidateCommands(flowchart); ValidateCommands(flowchart);
ExecuteCommands(flowchart); ExecuteCommands(flowchart);
base.HandleEvents(Event.current);
if (forceRepaintCount > 0) if (forceRepaintCount > 0)
{ {
// Redraw on next frame to get crisp refresh rate // Redraw on next frame to get crisp refresh rate
@ -319,191 +410,139 @@ namespace Fungus.EditorUtils
} }
protected virtual void DrawOverlay(Flowchart flowchart) protected virtual void DrawOverlay(Flowchart flowchart)
{ {
// Main toolbar group
GUILayout.BeginHorizontal(EditorStyles.toolbar); GUILayout.BeginHorizontal(EditorStyles.toolbar);
GUILayout.Space(2);
if (GUILayout.Button(new GUIContent(addTexture, "Add a new block"), EditorStyles.toolbarButton))
{
Vector2 newNodePosition = new Vector2(50 / flowchart.Zoom - flowchart.ScrollPos.x,
50 / flowchart.Zoom - flowchart.ScrollPos.y);
CreateBlock(flowchart, newNodePosition);
}
// Separator
GUILayout.Label("", EditorStyles.toolbarButton, GUILayout.Width(8));
GUILayout.Label("Scale", EditorStyles.miniLabel);
var newZoom = GUILayout.HorizontalSlider(
flowchart.Zoom, minZoomValue, maxZoomValue, GUILayout.MinWidth(40), GUILayout.MaxWidth(100)
);
GUILayout.Label(flowchart.Zoom.ToString("0.0#x"), EditorStyles.miniLabel, GUILayout.Width(30));
if (newZoom != flowchart.Zoom)
{
DoZoom(flowchart, newZoom - flowchart.Zoom, Vector2.one * 0.5f);
}
if (GUILayout.Button("Center", EditorStyles.toolbarButton))
{ {
flowchart.ScrollPos = flowchart.CenterPosition; GUILayout.Space(2);
}
GUILayout.FlexibleSpace(); // Draw add block button
if (GUILayout.Button(new GUIContent(addTexture, "Add a new block"), EditorStyles.toolbarButton))
{
DeselectAll(flowchart);
Vector2 newNodePosition = new Vector2(
50 / flowchart.Zoom - flowchart.ScrollPos.x, 50 / flowchart.Zoom - flowchart.ScrollPos.y
);
CreateBlock(flowchart, newNodePosition);
}
GUILayout.Label("", EditorStyles.toolbarButton, GUILayout.Width(8)); // Separator
var blocks = flowchart.GetComponents<Block>(); // Draw scale bar and labels
GUILayout.Label("Scale", EditorStyles.miniLabel);
var newZoom = GUILayout.HorizontalSlider(
flowchart.Zoom, minZoomValue, maxZoomValue, GUILayout.MinWidth(40), GUILayout.MaxWidth(100)
);
GUILayout.Label(flowchart.Zoom.ToString("0.0#x"), EditorStyles.miniLabel, GUILayout.Width(30));
// Intercept mouse and keyboard events before search field uses them if (newZoom != flowchart.Zoom)
if (GUI.GetNameOfFocusedControl() == searchFieldName)
{
if (Event.current.type == EventType.KeyDown)
{ {
var centerBlock = false; DoZoom(flowchart, newZoom - flowchart.Zoom, Vector2.one * 0.5f);
var selectBlock = false; }
var closePopup = false;
var useEvent = false;
switch (Event.current.keyCode) // Draw center button
{ if (GUILayout.Button("Center", EditorStyles.toolbarButton))
case KeyCode.DownArrow: {
++blockPopupSelection; flowchart.ScrollPos = flowchart.CenterPosition;
centerBlock = true; }
useEvent = true;
break;
case KeyCode.UpArrow: GUILayout.FlexibleSpace();
--blockPopupSelection;
centerBlock = true;
useEvent = true;
break;
case KeyCode.Return: // Draw search bar
centerBlock = true; GUI.SetNextControlName(searchFieldName);
selectBlock = true; var newString = EditorGUILayout.TextField(searchString, GUI.skin.FindStyle("ToolbarSeachTextField"), GUILayout.Width(150));
closePopup = true; if (newString != searchString)
useEvent = true; {
break; searchString = newString;
filteredBlocks = flowchart.GetComponents<Block>().Where(block => {
case KeyCode.Escape: return block.BlockName.ToLower().Contains(searchString.ToLower());
closePopup = true; }).ToArray();
useEvent = true;
break;
}
blockPopupSelection = Mathf.Clamp(blockPopupSelection, 0, filteredBlocks.Length - 1); blockPopupSelection = Mathf.Clamp(blockPopupSelection, 0, filteredBlocks.Length - 1);
}
if (centerBlock && filteredBlocks.Length > 0) if (Event.current.type == EventType.Repaint)
{ {
var block = filteredBlocks[blockPopupSelection]; searchRect = GUILayoutUtility.GetLastRect();
CenterBlock(flowchart, block); popupRect = searchRect;
popupRect.width += 12;
if (selectBlock) popupRect.y += popupRect.height;
{ popupRect.height = Mathf.Min(filteredBlocks.Length * 16, position.height - 22);
SelectBlock(flowchart, block); }
}
}
if (closePopup) if (GUILayout.Button("", GUI.skin.FindStyle("ToolbarSeachCancelButton")))
{ {
CloseBlockPopup(); CloseBlockPopup();
} }
if (useEvent) // Eat all click events on toolbar
if (Event.current.type == EventType.MouseDown)
{
if (Event.current.mousePosition.y < searchRect.height)
{ {
Event.current.Use(); Event.current.Use();
} }
} }
} }
else if (Event.current.type == EventType.MouseDown && Event.current.button == 0 &&
searchRect.Contains(Event.current.mousePosition))
{
blockPopupSelection = 0;
}
GUI.SetNextControlName(searchFieldName);
var newString = EditorGUILayout.TextField(searchString, GUI.skin.FindStyle("ToolbarSeachTextField"), GUILayout.Width(150));
if (newString != searchString)
{
searchString = newString;
}
// Update this every frame in case of redo/undo while popup is open
filteredBlocks = blocks.Where(block => block.BlockName.ToLower().Contains(searchString.ToLower())).ToArray();
blockPopupSelection = Mathf.Clamp(blockPopupSelection, 0, filteredBlocks.Length - 1);
if (Event.current.type == EventType.Repaint)
{
searchRect = GUILayoutUtility.GetLastRect();
popupRect = searchRect;
popupRect.width += 12;
popupRect.y += popupRect.height;
popupRect.height = Mathf.Min(filteredBlocks.Length * 16, position.height - 22);
}
if (GUILayout.Button("", GUI.skin.FindStyle("ToolbarSeachCancelButton")))
{
CloseBlockPopup();
}
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
// Name and description group
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.BeginVertical();
GUILayout.Label(flowchart.name, EditorStyles.whiteBoldLabel);
GUILayout.Space(2);
if (flowchart.Description.Length > 0)
{ {
GUILayout.Label(flowchart.Description, EditorStyles.helpBox); GUILayout.FlexibleSpace();
}
GUILayout.EndVertical();
GUILayout.BeginVertical();
{
GUILayout.Label(flowchart.name, EditorStyles.whiteBoldLabel);
GUILayout.Space(2);
if (flowchart.Description.Length > 0)
{
GUILayout.Label(flowchart.Description, EditorStyles.helpBox);
}
}
GUILayout.EndVertical();
}
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
// Variables group
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
{
GUILayout.BeginVertical(GUILayout.Width(440));
{
GUILayout.FlexibleSpace();
GUILayout.BeginVertical(GUILayout.Width(440)); flowchart.VariablesScrollPos = GUILayout.BeginScrollView(flowchart.VariablesScrollPos);
{
GUILayout.FlexibleSpace(); GUILayout.Space(8);
var rawMousePosition = Event.current.mousePosition; // mouse position outside of scrollview to test against toolbar rect
flowchart.VariablesScrollPos = GUILayout.BeginScrollView(flowchart.VariablesScrollPos, GUILayout.MaxHeight(position.height * 0.75f));
GUILayout.FlexibleSpace(); FlowchartEditor flowchartEditor = Editor.CreateEditor (flowchart) as FlowchartEditor;
flowchartEditor.DrawVariablesGUI();
GUILayout.Space(8); Rect variableWindowRect = GUILayoutUtility.GetLastRect();
if (flowchart.VariablesExpanded && flowchart.Variables.Count > 0)
{
variableWindowRect.y -= 20;
variableWindowRect.height += 20;
}
FlowchartEditor flowchartEditor = Editor.CreateEditor (flowchart) as FlowchartEditor; // Eat mouse events
flowchartEditor.DrawVariablesGUI(); if (Event.current.type == EventType.MouseDown)
DestroyImmediate(flowchartEditor); {
if (Event.current.mousePosition.x <= variableWindowRect.width &&
Event.current.mousePosition.y <= variableWindowRect.height)
{
Event.current.Use();
}
}
}
GUILayout.EndScrollView();
}
GUILayout.EndVertical();
Rect variableWindowRect = GUILayoutUtility.GetLastRect(); GUILayout.FlexibleSpace();
if (flowchart.VariablesExpanded &&
flowchart.Variables.Count > 0)
{
variableWindowRect.y -= 20;
variableWindowRect.height += 20;
}
if (Event.current.type == EventType.Repaint)
{
Rect toolbarRect = new Rect(0, 0, position.width, 18);
mouseOverPopup = (GUI.GetNameOfFocusedControl() == searchFieldName && popupRect.Contains(rawMousePosition));
mouseOverVariables = variableWindowRect.Contains(Event.current.mousePosition) ||
toolbarRect.Contains(rawMousePosition) || mouseOverPopup;
} }
GUILayout.EndScrollView();
GUILayout.EndVertical();
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
// Draw block search popup on top of other controls // Draw block search popup on top of other controls

Loading…
Cancel
Save