public Node(Transform transform) { _transform = transform; if (null != _transform) { _parentTransform = _transform.parent; } if (null == transform) { _name = "ROOT"; } else { _name = transform.name; _transformId = transform.GetInstanceID(); _adapter = transform.GetComponent <ComponentAdapter>(); if (null != _adapter) { _adapterId = _adapter.GetInstanceID(); } } _description = string.Format("[{0}]", GuiLookup.PathToString(transform, "->")); }
internal void Select(DisplayObject target) { var dlm = target as DisplayListMember; // do not analyze anything from this stage if (null != dlm && !DesignerOverlay.IsInspectable(dlm)) { return; } var go = GuiLookup.GetGameObject((Component)target); if (null != go) { _selectionOverlay.Visible = true; var bounds = target.Transform.GlobalBounds; /** * 1. Expand around component * */ bounds = bounds.Expand(PlayModeOverlaySelectionBorderStyle.BorderWidth); /** * 2. Constrain with stage bounds * */ bounds.ConstrainWithin(Rectangle.FromSize(SystemManager.Instance.ScreenSize)); _selectionOverlay.Redraw(bounds, Bounds, GuiLookup.PathToString(go.transform, " -> ")); _selectionOverlay.ValidateNow(); } }
/// <summary> /// Monitors the object for property changes<br/> /// Monitoring an object means putting it on the list which will be checked for changes after the play mode is stopped<br/> /// When put on the list, all the original properties of the object are being saved (cloned)<br/> /// When play mode stopped, properties are being read from all the monitored objects<br/> /// For each property, the original and current value are being compared for change<br/> /// and the changed value list is being made<br/> /// Changed values are being applied to an object "resurrected" by Unity, after the play mode is stopped<br/> /// Here we are monitoring eDriven.Gui COMPONENTS, not transforms or game objects<br/> /// (however, they could also be monitored in some other scenario)<br/> /// </summary> /// <param name="target">Target (component) to monitor</param> public void Watch(Object target) { /** * 1. Get the instance ID because it is the key in the dictionary holding the monitored objects * */ int instanceId = target.GetInstanceID(); //Debug.Log("* Monitoring: " + instanceId); /** * 2. We need to check if the object is already being monitored * This is important because we must not overwrite the original values each time the component is being clicked * because this might lead to the loss of data (only changes from the last component click would be then be saved as the original values) * For instance, take a look at this scenario: * - this component click. Changing the text to "foo". * - other component click. * - this component click. Changing the color to green. * In play mode, all the changes would be accumulated, and there would seem to be no problems. * But after the play mode is stopped, and started again, we would discover that only the component color is being changed to green, * and no text has been changed - due to second component click rewriting the "original" values, thus deleting the change to "foo" * */ if (_monitoredObjects.ContainsKey(instanceId)) { return; } #if DEBUG if (DebugMode) { ComponentAdapter componentAdapter = target as ComponentAdapter; if (null != componentAdapter) { Debug.Log("Monitoring: " + GuiLookup.PathToString(componentAdapter.transform, " -> "), componentAdapter.transform); } } #endif /** * 3. This is the first time we are monitoring this object * Create a new PersistedComponent instance and add it to dictionary * */ _monitoredObjects[instanceId] = new PersistedComponent(target); //_currentInstanceId = target.GetInstanceID(); #if DEBUG if (DebugMode) { Debug.Log(string.Format(" Added [{0}] to monitored objects list. Total: {1}", target.name, _monitoredObjects.Count), target); } #endif //MonitoredObjectAddedSignal.Emit(target); }
public void ApplyChanges() { #if DEBUG if (DebugMode) { StringBuilder sb = new StringBuilder(); foreach (PersistedComponent persistedObject in MonitoredObjects.Values) { //Debug.Log("persistedObject.Target: " + persistedObject.Target); if (null == persistedObject.Target) { sb.AppendLine("Target is null"); } else { var target = persistedObject.Target; // as ComponentAdapterBase; // it doesn't have to be ComponentAdapterBase (if it is a stylesheet for instance) if (target is ComponentAdapterBase) { var transform = (target as ComponentAdapterBase).transform; sb.AppendLine(GuiLookup.PathToString(transform, " -> ")); } else if (target is eDrivenStyleSheet) { //var transform = (target as eDrivenStyleSheetBase).transform; sb.AppendLine("--- Stylesheet"); } } } // Debug.Log(string.Format(@"Applying changes to {0} components: //{1}", _monitoredObjects.Values.Count, sb)); } #endif /** * 3. Handle value changes * Each persistant object has the list of changes (delta between the original and final values) * This changes are being applied by calling the ApplyChanges on each persisted object * Internally, PersistedComponent handles the case of negative or positive instance IDs, * thus looking up for objects using the appropriate lookup * */ foreach (PersistedComponent persistedObject in _monitoredObjects.Values) { persistedObject.ApplyChanges(); } _monitoredObjects.Clear(); }
private static void ApplyMonitoredComponents(Dictionary <int, PersistedComponent> monitoredComponents, StringBuilder sb) { if (0 == monitoredComponents.Count) { return; } sb.AppendLine(string.Format("Monitored components ({0}):", monitoredComponents.Count)); sb.AppendLine( "------------------------------------------------------------------------------------------------------------------------"); foreach (KeyValuePair <int, PersistedComponent> pair in monitoredComponents) { var adapter = pair.Value.Target as ComponentAdapter; var value = pair.Value.ToString(); if (null != adapter) { value = string.Format("{0} [{1}][{2}]", adapter.GetType().Name, pair.Key, GuiLookup.PathToString(adapter.transform, "->")); } sb.AppendLine(value); } sb.AppendLine(); }
/// <summary> /// Recursive! /// </summary> /// <param name="sb"></param> /// <param name="node"></param> private static void DoFix(ref StringBuilder sb, Node node) { bool isRoot = (null == node.Adapter); //if (!isRoot) // Debug.Log(StringUtil.Indent(node.Depth, "Fixing " + node.Adapter)); var childNodes = node.ChildNodes; var unprocessedNodes = ListUtil <Node> .Clone(node.ChildNodes); var adapter = node.Adapter; //Debug.Log(@"adapter: " + adapter); var containerAdapter = adapter as GroupAdapter; //Debug.Log(@"containerAdapter: " + containerAdapter); // Note: the ROOT node has no adapter no groups defined! if (null != containerAdapter) { ChildGroupPack pack = ChildGroupPack.Read(containerAdapter); // Debug.Log(@"pack: //" + pack); foreach (ChildGroup childGroup in pack.Groups) { //sb.AppendLine(StringUtil.Indent(node.Depth + 1, string.Format("== {0} ==", childGroup.GroupName))); //foreach (ComponentAdapter componentAdapter in childGroup.Adapters) for (int i = childGroup.Adapters.Count - 1; i >= 0; i--) { ComponentAdapter componentAdapter = childGroup.Adapters[i]; bool doRemove = false; /** * 1. Handle null * */ if (null == componentAdapter) { //sb.AppendLine(StringUtil.Indent(node.Depth + 1, "*** Not found ***")); // adapter is not child of this container, remove it from the list //toRemove.Add(componentAdapter); doRemove = true; } /** * 2. Not null. Handle the adapter * */ else { var childNode = GetNode(childNodes, componentAdapter); if (null == childNode) { //sb.AppendLine(StringUtil.Indent(node.Depth + 1, "*** Not found ***")); // adapter is not child of this container, remove it from the list //toRemove.Add(componentAdapter); doRemove = true; } else { unprocessedNodes.Remove(childNode); DoFix(ref sb, childNode); } } if (doRemove) { //Debug.Log("list 1: " + ComponentAdapterUtil.DescribeAdapterList(childGroup.Adapters)); childGroup.Adapters.RemoveAt(i); //childGroup.Adapters.Remove(adapterToRemove); if (null != componentAdapter) { sb.AppendLine(string.Format("{0}: {1} [A:{2}] removed", GuiLookup.PathToString(containerAdapter.transform, "->"), componentAdapter, componentAdapter.GetInstanceID())); } else { sb.AppendLine(string.Format("{0}: Adapter at position {1} removed", GuiLookup.PathToString(containerAdapter.transform, "->"), i)); } //Debug.Log("list 2: " + ComponentAdapterUtil.DescribeAdapterList(childGroup.Adapters)); } } } } // orphans foreach (Node childNode in unprocessedNodes) { if (!isRoot) { if (null != containerAdapter) { ChildGroupPack pack = ChildGroupPack.Read(containerAdapter); if (pack.Groups.Count > 0) { pack.Groups[0].Adapters.Add(childNode.Adapter); sb.AppendLine(string.Format("{0}: [{1}] added to the first group", GuiLookup.PathToString(containerAdapter.transform, "->"), childNode.Adapter)); } } } DoFix(ref sb, childNode); } }