/// <summary> /// Successively copy the properties from the <paramref name="sourcePanel"/> to the <paramref name="targetPanel"/>, then swap the panels in the parent /// and finally move the children from the <paramref name="sourcePanel"/> to the <paramref name="targetPanel"/>. /// </summary> private void CopySwapExchange([NotNull] PanelViewModel sourcePanel, [NotNull] UIElementDesign targetPanel, [CanBeNull] Func <IEnumerable <UIElementViewModel>, IEnumerable <UIElementViewModel> > childSorter = null) { var targetPanelElement = targetPanel.UIElement as Panel; if (targetPanelElement == null) { throw new ArgumentException(@"The target element must be a Panel", nameof(targetPanel)); } // Clone common properties CopyCommonProperties(Editor.NodeContainer, sourcePanel.AssetSidePanel, targetPanelElement); // Initialize the new hierarchy of elements that starts from the target and contains all the children IEnumerable <UIElementViewModel> children = sourcePanel.Children.ToList(); var hierarchy = UIAssetPropertyGraph.CloneSubHierarchies(Asset.Session.AssetNodeContainer, Asset.Asset, children.Select(c => c.Id.ObjectId), SubHierarchyCloneFlags.None, out _); hierarchy.RootParts.Add(targetPanel.UIElement); hierarchy.Parts.Add(targetPanel); // Remove all children from the source panel. foreach (var child in children) { Asset.AssetHierarchyPropertyGraph.RemovePartFromAsset(child.UIElementDesign); } // Swap panels in the parent var elementParent = Parent as UIElementViewModel; var rootParent = Parent as UIRootViewModel; if (rootParent != null) { // special case of RootElement rootParent.ReplaceRootElement(sourcePanel, hierarchy, targetPanelElement.Id); } else if (elementParent != null) { // Remove current panel from Parent var index = elementParent.Children.IndexOf(sourcePanel); Asset.AssetHierarchyPropertyGraph.RemovePartFromAsset(sourcePanel.UIElementDesign); Asset.AssetHierarchyPropertyGraph.AddPartToAsset(hierarchy.Parts, targetPanel, elementParent.AssetSideUIElement, index); } else { throw new InvalidOperationException(); } // Sort the children list before re-inserting them in the target panel. children = childSorter?.Invoke(children) ?? children; // Then populate the target panel foreach (var child in children) { Asset.InsertUIElement(hierarchy.Parts, hierarchy.Parts[child.Id.ObjectId], targetPanelElement); } }
private static IEnumerable <UIElementDesign> GetOrCreateChildPartDesigns([NotNull] UIAssetBase asset, [NotNull] UIElementDesign partDesign) { var assetControl = (ContentControl)partDesign.UIElement; if (assetControl.Content != null) { if (!asset.Hierarchy.Parts.TryGetValue(assetControl.Content.Id, out UIElementDesign elementDesign)) { elementDesign = new UIElementDesign(assetControl.Content); } if (assetControl.Content != elementDesign.UIElement) { throw new InvalidOperationException(); } yield return(elementDesign); } }
private static IEnumerable <UIElementDesign> GetOrCreateChildPartDesigns([NotNull] UIAssetBase asset, [NotNull] UIElementDesign elementDesign) { var assetPanel = (Panel)elementDesign.UIElement; foreach (var child in assetPanel.Children) { if (!asset.Hierarchy.Parts.TryGetValue(child.Id, out UIElementDesign childDesign)) { childDesign = new UIElementDesign(child); } if (child != childDesign.UIElement) { throw new InvalidOperationException(); } yield return(childDesign); } }
public UIPageRootViewModel([NotNull] UIEditorBaseViewModel editor, [NotNull] UIPageViewModel asset, UIElementDesign rootElement) : base(editor, asset, rootElement?.Yield()) { NotifyGameSidePartAdded().Forget(); }
// Note: constructor needed by UIElementViewModelFactory public ContentControlViewModel([NotNull] UIEditorBaseViewModel editor, [NotNull] UIBaseViewModel asset, [NotNull] UIElementDesign elementDesign) : base(editor, asset, elementDesign, GetOrCreateChildPartDesigns((UIAssetBase)asset.Asset, elementDesign)) { contentNode = editor.NodeContainer.GetOrCreateNode(AssetSideUIElement)[nameof(ContentControl.Content)]; contentNode.ValueChanged += ContentChanged; }
// Note: constructor needed by UIElementViewModelFactory public PanelViewModel([NotNull] UIEditorBaseViewModel editor, [NotNull] UIBaseViewModel asset, [NotNull] UIElementDesign elementDesign) : base(editor, asset, elementDesign, GetOrCreateChildPartDesigns((UIAssetBase)asset.Asset, elementDesign)) { childrenNode = editor.NodeContainer.GetOrCreateNode(AssetSidePanel)[nameof(Panel.Children)].Target; childrenNode.ItemChanged += ChildrenContentChanged; ChangeLayoutTypeCommand = new AnonymousCommand <IUIElementFactory>(ServiceProvider, ChangeLayoutType); UngroupCommand = new AnonymousCommand(ServiceProvider, Ungroup); }
public UIElementViewModel ProvideViewModel([NotNull] UIEditorBaseViewModel editor, [NotNull] UIBaseViewModel asset, [NotNull] UIElementDesign elementDesign) { if (editor == null) { throw new ArgumentNullException(nameof(editor)); } if (elementDesign == null) { throw new ArgumentNullException(nameof(elementDesign)); } var elementViewModelType = typeof(UIElementViewModel); // try to get the viewmodel type var elementType = elementDesign.UIElement.GetType(); while (elementType != null) { if (elementViewModelTypes.ContainsKey(elementType)) { elementViewModelType = elementViewModelTypes[elementType]; break; } elementType = elementType.BaseType; } return((UIElementViewModel)Activator.CreateInstance(elementViewModelType, editor, asset, elementDesign)); }