Пример #1
0
		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;
			
		}
Пример #2
0
		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);

			}

		}
Пример #3
0
		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);

			}*/
			
		}
Пример #4
0
		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);

			}

		}
Пример #5
0
		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();

				}

			}

		}
Пример #6
0
		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;

		}
Пример #7
0
		public override bool IsCompilerTransitionAttachedGeneration(FD.FlowWindow windowFrom, FD.FlowWindow windowTo) {

			return windowTo.IsABTest() == true;

		}
Пример #8
0
		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);
			
		}