public static string GenerateTransitionMethod(FlowSystemEditorWindow flowEditor, FD.FlowWindow windowFrom, FD.FlowWindow windowTo) { var file = Resources.Load("UI.Windows/ABTesting/Templates/TemplateTransitionMethod") as TextAsset; if (file == null) { Debug.LogError("ABTesting Template Loading Error: Could not load template 'TemplateTransitionMethod'"); return string.Empty; } var data = FlowSystem.GetData(); if (data == null) return string.Empty; if (windowTo.IsABTest() == false) { return string.Empty; } var result = string.Empty; var part = file.text; var methodPattern = "(item, h) => WindowSystemFlow.DoFlow<{0}>(this, item, h, null)"; var methods = string.Empty; var methodList = new List<string>(); foreach (var item in windowTo.abTests.items) { var window = FlowSystem.GetWindow(item.attachItem.targetId); if (window == null) { methodList.Add("null"); } else { var classNameWithNamespace = Tpl.GetClassNameWithNamespace(window); methodList.Add(string.Format(methodPattern, classNameWithNamespace)); } } methods = string.Join(", ", methodList.ToArray()); result += part.Replace("{METHOD_NAMES}", methods) .Replace("{FLOW_FROM_ID}", windowFrom.id.ToString()) .Replace("{FLOW_TO_ID}", windowTo.id.ToString()); return result; }
public void DrawTransitionChooser(AttachItem attach, FD.FlowWindow fromWindow, FD.FlowWindow toWindow, bool doubleSided) { if (this.drawWindowContent == false) return; if (toWindow.IsEnabled() == false) return; if (toWindow.IsContainer() == true) return; var factor = 0.5f; var transitionsContainer = fromWindow; var namePrefix = string.Empty; if (fromWindow.IsSmall() == true && fromWindow.IsABTest() == true) { // is ABTest //Debug.Log(fromWindow.id + " => " + toWindow.id + " :: " + attach.index + " :: " + doubleSided); transitionsContainer = FlowSystem.GetWindow(fromWindow.abTests.sourceWindowId); if (transitionsContainer == null) return; namePrefix = string.Format("Variant{0}", attach.index.ToString()); factor = 0.2f; } else { if (toWindow.IsSmall() == true) { if (toWindow.IsFunction() == false) return; } } if (FlowSystem.GetData().modeLayer == ModeLayer.Audio) { if (FlowSystem.GetData().HasView(FlowView.AudioTransitions) == false) return; } else { if (FlowSystem.GetData().HasView(FlowView.VideoTransitions) == false) return; } const float size = 32f; const float offset = size * 0.5f + 5f; Vector2 centerOffset = Flow.OnDrawNodeCurveOffset(this, attach, fromWindow, toWindow, doubleSided); if (doubleSided == true) { var q = Quaternion.LookRotation(toWindow.rect.center - fromWindow.rect.center, Vector3.back); var attachRevert = FlowSystem.GetAttachItem(toWindow.id, fromWindow.id); this.DrawTransitionChooser(attachRevert, toWindow, toWindow, fromWindow, centerOffset, q * Vector2.left * offset, size, factor, namePrefix); this.DrawTransitionChooser(attach, fromWindow, fromWindow, toWindow, centerOffset, q * Vector2.right * offset, size, factor, namePrefix); } else { this.DrawTransitionChooser(attach, transitionsContainer, fromWindow, toWindow, centerOffset, Vector2.zero, size, factor, namePrefix); } }
private void DrawWindowToolbar(FD.FlowWindow window) { /*if (FlowSystem.GetData().modeLayer != ModeLayer.Flow) { return; }*/ //var edit = false; var id = window.id; var buttonStyle = ME.Utilities.CacheStyle("FlowEditor.DrawWindowToolbar.Styles", "toolbarButton", (name) => { var _buttonStyle = new GUIStyle(EditorStyles.toolbarButton); _buttonStyle.stretchWidth = false; return _buttonStyle; }); var buttonDropdownStyle = ME.Utilities.CacheStyle("FlowEditor.DrawWindowToolbar.Styles", "toolbarDropDown", (name) => { var _buttonStyle = new GUIStyle(EditorStyles.toolbarDropDown); _buttonStyle.stretchWidth = false; return _buttonStyle; }); var buttonWarningStyle = ME.Utilities.CacheStyle("FlowEditor.DrawWindowToolbar.Styles", "buttonWarningStyle", (name) => { var _buttonStyle = new GUIStyle(EditorStyles.toolbarButton); _buttonStyle.stretchWidth = false; _buttonStyle.fontStyle = FontStyle.Bold; return _buttonStyle; }); GUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.ExpandWidth(true)); if (this.waitForAttach == false || this.currentAttachComponent == null) { if (this.waitForAttach == true) { if (id != this.currentAttachId) { var currentAttach = FlowSystem.GetWindow(this.currentAttachId); if (currentAttach != null) { //var attachTo = FlowSystem.GetWindow(id); //var hasContainer = currentAttach.HasContainer(); if (currentAttach.IsContainer() == false) { if (FlowSystem.AlreadyAttached(this.currentAttachId, this.currentAttachIndex, id) == true) { if (GUILayout.Button(string.Format("Detach Here{0}", (Event.current.alt == true ? " (Double Direction)" : string.Empty)), buttonStyle) == true) { FlowSystem.Detach(this.currentAttachId, this.currentAttachIndex, id, oneWay: Event.current.alt == false); if (this.onAttach != null) this.onAttach(id, this.currentAttachIndex, false); if (Event.current.shift == false) this.WaitForAttach(-1); } } else { var abTests = (window.abTests.sourceWindowId >= 0/* || currentAttach.attachItems.Any(x => FlowSystem.GetWindow(x.targetId).IsABTest() == true) == true*/); if (this.currentAttachIndex == 0 && (currentAttach.IsABTest() == true || abTests == true)) { /* if (abTests == true) { if (GUILayout.Button("Attach Here", buttonStyle) == true) { this.ShowNotification(new GUIContent("You can't connect using this method. Use `Attach` function on `A/B Test Condition`")); } }*/ } else { if (GUILayout.Button(string.Format("Attach Here{0}", (Event.current.alt == true ? " (Double Direction)" : string.Empty)), buttonStyle) == true) { FlowSystem.Attach(this.currentAttachId, this.currentAttachIndex, id, oneWay: Event.current.alt == false); if (this.onAttach != null) this.onAttach(id, this.currentAttachIndex, true); if (Event.current.shift == false) this.WaitForAttach(-1); } } } } } } else { if (GUILayout.Button("Cancel", buttonStyle) == true) { this.WaitForAttach(-1); } } } else { if (window.IsSmall() == false || window.IsFunction() == true || window.IsABTest() == true) { if (GUILayout.Button("Attach/Detach", buttonStyle) == true) { this.ShowNotification(new GUIContent("Use Attach/Detach buttons to Connect/Disconnect a window")); this.WaitForAttach(id); } } } if (window.IsSmall() == false) { //var isExit = false; var functionWindow = window.GetFunctionContainer(); if (functionWindow != null) { if (functionWindow.functionRootId == 0) functionWindow.functionRootId = id; if (functionWindow.functionExitId == 0) functionWindow.functionExitId = id; //isExit = (functionWindow.functionExitId == id); } var isRoot = (FlowSystem.GetRootWindow() == id || (functionWindow != null && functionWindow.functionRootId == id)); if (GUILayout.Toggle(isRoot, new GUIContent("R", "Set as root"), buttonStyle) != isRoot) { if (functionWindow != null) { if (isRoot == true) { // Was root // Setup root for the first window in function functionWindow.functionRootId = window.id; } else { // Was not root // Setup as root but inside this function only functionWindow.functionRootId = window.id; } } else { if (isRoot == true) { // Was root FlowSystem.SetRootWindow(-1); } else { // Was not root FlowSystem.SetRootWindow(id); } } FlowSystem.SetDirty(); } /* if (functionWindow != null) { if (GUILayout.Toggle(isExit, new GUIContent("E", "Set as exit point"), buttonStyle) != isExit) { if (isExit == true) { // Was exit // Setup exit for the first window in function functionWindow.functionExitId = window.id; } else { // Was not exit // Setup as exit but inside this function only functionWindow.functionExitId = window.id; } FlowSystem.SetDirty(); } }*/ var isDefault = FlowSystem.GetDefaultWindows().Contains(id); if (GUILayout.Toggle(isDefault, new GUIContent("D", "Set as default"), buttonStyle) != isDefault) { if (isDefault == true) { // Was as default FlowSystem.GetDefaultWindows().Remove(id); } else { // Was not as default FlowSystem.GetDefaultWindows().Add(id); } FlowSystem.SetDirty(); } } GUILayout.FlexibleSpace(); if (window.IsSmall() == false && FlowSceneView.IsActive() == false && window.storeType == FD.FlowWindow.StoreType.NewScreen) { var state = GUILayout.Button("Screen", buttonDropdownStyle); if (Event.current.type == EventType.Repaint) { this.layoutStateSelectButtonRect = GUILayoutUtility.GetLastRect(); } if (state == true) { var menu = new GenericMenu(); menu.AddItem(new GUIContent("Select Package"), on: false, func: () => { this.SelectWindow(window); }); if (window.compiled == true) { menu.AddItem(new GUIContent("Edit..."), on: false, func: () => { var path = Path.GetDirectoryName(AssetDatabase.GetAssetPath(window.GetScreen())); var filename = window.compiledDerivedClassName + ".cs"; EditorUtility.OpenWithDefaultApp(string.Format("{0}/../{1}", path, filename)); }); } menu.AddItem(new GUIContent("Create on Scene"), on: false, func: () => { this.CreateOnScene(window); }); var screen = window.GetScreen(); var methodsCount = 0; WindowSystem.CollectCallVariations(screen, (types, names) => { ++methodsCount; }); menu.AddDisabledItem(new GUIContent("Calls/Methods: " + methodsCount.ToString())); menu.AddSeparator("Calls/"); if (window.compiled == true && screen != null) { methodsCount = 0; WindowSystem.CollectCallVariations(screen, (types, names) => { var parameters = new List<string>(); for (int i = 0; i < types.Length; ++i) { parameters.Add(ME.Utilities.FormatParameter(types[i]) + " " + names[i]); } var paramsStr = parameters.Count > 0 ? "(" + string.Join(", ", parameters.ToArray()) + ")" : string.Empty; menu.AddItem(new GUIContent("Calls/OnParametersPass" + paramsStr), on: false, func: () => { Selection.activeObject = screen; }); ++methodsCount; }); if (methodsCount == 0) { menu.AddDisabledItem(new GUIContent("Calls/No `OnParametersPass` Methods Found")); } } else { menu.AddDisabledItem(new GUIContent("Calls/You need to compile window")); } Flow.OnFlowWindowScreenMenuGUI(this, window, menu); menu.DropDown(this.layoutStateSelectButtonRect); } /* if (GUILayout.Button("Edit", buttonStyle) == true) { if (window.compiled == false) { this.ShowNotification(new GUIContent("You need to compile this window to use 'Edit' command")); } else { edit = true; } }*/ } if (GUILayout.Button("X", buttonWarningStyle) == true) { if (EditorUtility.DisplayDialog("Are you sure?", "Current window will be destroyed with all links.", "Yes, destroy", "No") == true) { this.ShowNotification(new GUIContent(string.Format("The window `{0}` was successfully destroyed", window.title))); FlowSystem.DestroyWindow(id); return; } } } else { // Draw Attach/Detach component link if (this.currentAttachId == id) { // Cancel if (GUILayout.Button("Cancel", buttonStyle) == true) { this.WaitForAttach(-1); } } else { // If it's other window if (window.IsSmall() == false || window.IsFunction() == true) { if (FlowSystem.AlreadyAttached(this.currentAttachId, this.currentAttachIndex, id, this.currentAttachComponent) == true) { if (GUILayout.Button("Detach Here", buttonStyle) == true) { FlowSystem.Detach(this.currentAttachId, this.currentAttachIndex, id, oneWay: true, component: this.currentAttachComponent); if (this.onAttach != null) this.onAttach(id, this.currentAttachIndex, false); if (Event.current.shift == false) this.WaitForAttach(-1); } } else { if (GUILayout.Button("Attach Here", buttonStyle) == true) { FlowSystem.Attach(this.currentAttachId, this.currentAttachIndex, id, oneWay: true, component: this.currentAttachComponent); if (this.onAttach != null) this.onAttach(id, this.currentAttachIndex, true); if (Event.current.shift == false) this.WaitForAttach(-1); } } } } GUILayout.FlexibleSpace(); } GUILayout.EndHorizontal(); /*if (edit == true) { FlowSceneView.SetControl(this, window, this.OnItemProgress); }*/ }
public override void OnFlowWindowTransition(int index, FD.FlowWindow fromWindow, FD.FlowWindow toWindow, bool doubleSided, Vector2 centerOffset) { var factor = 0.5f; if (fromWindow.IsSmall() == true && fromWindow.IsABTest() == true) { factor = 0.2f; } var point = Vector2.Lerp(fromWindow.rect.center, toWindow.rect.center, factor) + centerOffset; var rect = new Rect(point, Vector2.zero); if (this.flowEditor.ContainsRect(rect) == false) return; if (doubleSided == true) { var q = Quaternion.LookRotation(toWindow.rect.center - fromWindow.rect.center, Vector3.back); this.DrawBubble(rect, index, fromWindow.id, toWindow.id, q * Vector2.left); this.DrawBubble(rect, index, toWindow.id, fromWindow.id, q * Vector2.right); } else { this.DrawBubble(rect, index, fromWindow.id, toWindow.id, Vector2.zero); } }
public override void OnFlowWindowGUI(FD.FlowWindow window) { var data = FlowSystem.GetData(); if (data == null) return; var flag = window.IsABTest(); if (flag == true) { this.Validate(window); var windowSize = window.rect; var repaint = false; var connectorActive = ME.Utilities.CacheStyle("UI.Windows.ABTesting", "flow shader out 2"); var connectorInactive = ME.Utilities.CacheStyle("UI.Windows.ABTesting", "flow shader out 5"); var connectorOuterActive = ME.Utilities.CacheStyle("UI.Windows.ABTesting", "flow shader in 2"); var connectorOuterInactive = ME.Utilities.CacheStyle("UI.Windows.ABTesting", "flow shader in 5"); var editButtonStyle = ME.Utilities.CacheStyle("UI.Windows.ABTesting.EditButton", "LargeButtonRight", (name) => { var _style = new GUIStyle(name); _style.fixedWidth = 0f; _style.stretchWidth = true; return _style; }); var addButtonStyle = ME.Utilities.CacheStyle("UI.Windows.ABTesting.AddButtonStyle", "MiniButton", (name) => { var _style = new GUIStyle(name); _style.fixedWidth = 0f; _style.stretchWidth = false; return _style; }); var removeButtonStyle = ME.Utilities.CacheStyle("UI.Windows.ABTesting.RemoveButtonStyle", "LargeButtonLeft", (name) => { var _style = new GUIStyle(name); _style.fixedWidth = 0f; _style.stretchWidth = false; return _style; }); var buttonHeight = editButtonStyle.fixedHeight; var height = 0f; const float topOffset = 5f; const float margin = 2f; const float marginHorizontalLeft = 2f; const float bottomOffset = 2f; Color oldColor; Color c; GUILayout.Space(topOffset); System.Action<int, ABTestingItem> onItem = (i, item) => { var hasAttach = (data.AlreadyAttached(window.id, item.attachItem.index, item.attachItem.targetId) == true); var connectorStyle = hasAttach ? connectorActive : connectorInactive; var connectorOuterStyle = hasAttach ? connectorOuterActive : connectorOuterInactive; var size = Mathf.Max(connectorStyle.fixedHeight, buttonHeight); var connectorSize = new Vector2(size, size); GUILayout.BeginHorizontal(); { GUILayout.Space(marginHorizontalLeft); var canEdit = (i > 0); var canRemove = canEdit && (window.abTests.Count() > 2); oldColor = GUI.color; c = (canRemove == true) ? Color.red : Color.grey; GUI.color = c; EditorGUI.BeginDisabledGroup(!canRemove); { if (GUILayout.Button("X", removeButtonStyle) == true) { window.abTests.RemoveAt(i); EditorUtility.SetDirty(window); repaint = true; } } EditorGUI.EndDisabledGroup(); GUI.color = oldColor; EditorGUI.BeginDisabledGroup(!canEdit); { if (GUILayout.Button(canEdit == true ? "Edit Condition" : "On Any Other", editButtonStyle) == true) { this.flowEditor.SetDisabled(); this.selectedItem = window.abTests.items[i]; this.opened = true; } } EditorGUI.EndDisabledGroup(); GUILayout.Space(connectorSize.x); } GUILayout.EndHorizontal(); var rect = GUILayoutUtility.GetLastRect(); rect.x = window.rect.width - connectorSize.x; rect.y += 3f; rect.size = connectorSize; rect = rect.PixelPerfect(); if (Event.current.type == EventType.Repaint) { window.abTests.items[i].editorRect = rect; } if (GUI.Button(rect, string.Empty, connectorStyle) == true) { var index = i; this.flowEditor.WaitForAttach(window.id, index: i + 1, onAttach: (withId, attachIndex, isAttach) => { window.abTests.Attach(index, withId, attachIndex); }); } rect.x += connectorSize.x - 3f; rect = rect.PixelPerfect(); if (GUI.Button(rect, string.Empty, connectorOuterStyle) == true) { var index = i; this.flowEditor.WaitForAttach(window.id, index: i + 1, onAttach: (withId, attachIndex, isAttach) => { window.abTests.Attach(index, withId, attachIndex); }); } var comment = item.comment; if (string.IsNullOrEmpty(comment) == false) GUILayout.Label(comment.Trim(), EditorStyles.helpBox); GUILayout.Space(margin); }; for (int i = 1; i < window.abTests.Count(); ++i) { onItem(i, window.abTests.items[i]); } oldColor = GUI.color; c = Color.green; GUI.color = c; GUILayout.BeginHorizontal(); { GUILayout.FlexibleSpace(); if (GUILayout.Button("+ Add", addButtonStyle) == true) { window.abTests.AddNew(); EditorUtility.SetDirty(window); repaint = true; } GUILayout.FlexibleSpace(); } GUILayout.EndHorizontal(); GUI.color = oldColor; onItem(0, window.abTests.items[0]); if (Event.current.type == EventType.Repaint) { var lastRect = GUILayoutUtility.GetLastRect(); height += lastRect.y; height += lastRect.height; height += bottomOffset; windowSize.height = height; if (windowSize != window.rect) { window.rect = windowSize.PixelPerfect(); EditorUtility.SetDirty(window); } } if (repaint == true) { this.flowEditor.Repaint(); } } }
public override Vector2 OnFlowDrawNodeCurveOffset(UnityEngine.UI.Windows.AttachItem attachItem, FD.FlowWindow window, FD.FlowWindow toWindow, bool doubleSide) { var offset = Vector2.zero; var data = FlowSystem.GetData(); if (data == null) return offset; Vector2 dotOffset = new Vector2(5f, 0f); var flag = window.IsABTest(); if (flag == true) { this.Validate(window); for (int i = 0; i < window.abTests.Count(); ++i) { var abTest = window.abTests.items[i]; if (abTest.attachItem.targetId == attachItem.targetId && abTest.attachItem.index == attachItem.index) { var editorRect = abTest.editorRect; var delta = editorRect.center - window.rect.size * 0.5f + dotOffset; offset = delta; } } } return offset; }
public override bool IsCompilerTransitionAttachedGeneration(FD.FlowWindow windowFrom, FD.FlowWindow windowTo) { return windowTo.IsABTest() == true; }
public override string OnCompilerTransitionAttachedGeneration(FD.FlowWindow windowFrom, FD.FlowWindow windowTo, bool everyPlatformHasUniqueName) { if (windowTo.IsABTest() == true && windowTo.IsSmall() == true) { return FlowABTestingTemplateGenerator.GenerateTransitionMethod(this.flowEditor, windowFrom, windowTo); } return base.OnCompilerTransitionAttachedGeneration(windowFrom, windowTo, everyPlatformHasUniqueName); }