private protected virtual bool IsNodeTreeValid(Node node) { Type ChildNodeType; IList <string> PropertyNames = NodeTreeHelper.EnumChildNodeProperties(node); bool IsValid = true; foreach (string PropertyName in PropertyNames) { if (NodeTreeHelperChild.IsChildNodeProperty(node, PropertyName, out ChildNodeType)) { IsValid &= InvariantFailed(IsNodeTreeChildNodeValid(node, PropertyName)); } else if (NodeTreeHelperOptional.IsOptionalChildNodeProperty(node, PropertyName, out ChildNodeType)) { IsValid &= InvariantFailed(IsNodeTreeOptionalNodeValid(node, PropertyName)); } else if (NodeTreeHelperList.IsNodeListProperty(node, PropertyName, out ChildNodeType)) { IsValid &= InvariantFailed(IsNodeTreeListValid(node, PropertyName)); } else if (NodeTreeHelperBlockList.IsBlockListProperty(node, PropertyName, /*out Type ChildInterfaceType,*/ out ChildNodeType)) { IsValid &= InvariantFailed(IsNodeTreeBlockListValid(node, PropertyName)); } } return(IsValid); }
private static bool OnUpdate(Node node, WalkCallbacks <string> callback, string data) { IList <string> PropertyNames = NodeTreeHelper.EnumChildNodeProperties(node); foreach (string PropertyName in PropertyNames) { if (NodeTreeHelperOptional.IsOptionalChildNodeProperty(node, PropertyName, out Type ChildNodeType)) { NodeTreeHelperOptional.GetChildNode(node, PropertyName, out bool IsAssigned, out Node ChildNode); if (!IsAssigned) { if (ChildNode is null) { Node NewChildNode = NodeHelper.CreateDefaultFromType(ChildNodeType); NodeTreeHelperOptional.SetOptionalChildNode(node, PropertyName, NewChildNode); NodeTreeHelperOptional.UnassignChildNode(node, PropertyName); } } else if (ChildNode is null) { Node NewChildNode = NodeHelper.CreateDefaultFromType(ChildNodeType); NodeTreeHelperOptional.SetOptionalChildNode(node, PropertyName, NewChildNode); } else if (NodeHelper.IsDefaultNode(ChildNode)) { } } } return(true); }
/// <summary> /// Recursively build a path of properties from a base node to the final property. /// </summary> /// <param name="type">The current object type.</param> /// <param name="path">The remaining path to parse.</param> /// <param name="propertyPath">Accumulated properties in the path so far.</param> public static void BuildPropertyPath(Type type, string path, IList <PropertyInfo> propertyPath) { if (path.Length == 0) { return; } int Index = path.IndexOf(InferenceEngine.Dot); int ThisPathIndex = (Index >= 0) ? Index : path.Length; string PropertyName = path.Substring(0, ThisPathIndex); int NextPathIndex = (Index >= 0) ? Index + 1 : path.Length; string NextPath = path.Substring(NextPathIndex); if (type.GetInterface(nameof(IOnceReference)) != null) { Type[] GenericArguments = type.GetGenericArguments(); Debug.Assert(GenericArguments.Length == 1); type = GenericArguments[0]; } PropertyInfo Property = NodeTreeHelper.GetPropertyOf(type, PropertyName); Debug.Assert(Property != null); propertyPath.Add(Property); Type NestedType = ToCompilerType(Property.PropertyType); BuildPropertyPath(NestedType, NextPath, propertyPath); }
private void CutOrDelete(IDataObject dataObject, out bool isDeleted) { isDeleted = false; string Content = NodeTreeHelper.GetString(StateView.State.Node, PropertyName); Debug.Assert(Content != null); Debug.Assert(Start <= End); Debug.Assert(End <= Content.Length); if (Start < End) { if (dataObject != null) { dataObject.SetData(typeof(string), Content.Substring(Start, End - Start)); } Content = Content.Substring(0, Start) + Content.Substring(End); FocusController Controller = StateView.ControllerView.Controller; int OldCaretPosition = StateView.ControllerView.CaretPosition; int NewCaretPosition = Start; Controller.ChangeTextAndCaretPosition(StateView.State.ParentIndex, PropertyName, Content, OldCaretPosition, NewCaretPosition, true); StateView.ControllerView.ClearSelection(); isDeleted = true; } }
/// <summary> /// Checks that templates are valid for blocks. /// </summary> /// <param name="blockTemplateTable">Table of templates.</param> /// <param name="nodeTemplateTable">Table of templates with all frames.</param> public virtual bool IsBlockValid(FrameTemplateReadOnlyDictionary blockTemplateTable, FrameTemplateReadOnlyDictionary nodeTemplateTable) { Contract.RequireNotNull(blockTemplateTable, out FrameTemplateReadOnlyDictionary BlockTemplateTable); Contract.RequireNotNull(nodeTemplateTable, out FrameTemplateReadOnlyDictionary NodeTemplateTable); IList <Type> BlockKeys = NodeHelper.GetNodeKeys(); FrameTemplateDictionary DefaultDictionary = CreateEmptyTemplateDictionary(); foreach (Type Key in BlockKeys) { AddBlockNodeTypes(DefaultDictionary, Key); } bool IsValid = true; foreach (KeyValuePair <Type, IFrameTemplate> Entry in DefaultDictionary) { IsValid &= BlockTemplateTable.ContainsKey(Entry.Key); } foreach (KeyValuePair <Type, IFrameTemplate> Entry in BlockTemplateTable) { Type NodeType = Entry.Key; IFrameTemplate Template = Entry.Value; int CommentFrameCount = 0; IsValid &= NodeTreeHelper.IsBlockInterfaceType(NodeType); IsValid &= Template.IsValid; IsValid &= Template.Root.IsValid(NodeType, NodeTemplateTable, ref CommentFrameCount); } Debug.Assert(IsValid); return(IsValid); }
/// <summary> /// Gets the value corresponding to a value property. /// The value type can be obtained from <see cref="ValuePropertyTypeTable"/>. /// </summary> /// <param name="propertyName">Property name.</param> /// <param name="value">Value of the property upon return.</param> /// <param name="minValue">Min value of the property upon return. Only applies to enum and booleans.</param> /// <param name="maxValue">Max value of the property upon return. Only applies to enum and booleans.</param> public virtual void PropertyToValue(string propertyName, out object value, out int minValue, out int maxValue) { Debug.Assert(!string.IsNullOrEmpty(propertyName)); Debug.Assert(ValuePropertyTypeTable.ContainsKey(propertyName)); value = null; minValue = -1; maxValue = -1; bool IsHandled = false; switch (ValuePropertyTypeTable[propertyName]) { case ValuePropertyType.Boolean: case ValuePropertyType.Enum: value = NodeTreeHelper.GetEnumValue(Node, propertyName); NodeTreeHelper.GetEnumRange(Node.GetType(), propertyName, out minValue, out maxValue); IsHandled = true; break; case ValuePropertyType.String: value = NodeTreeHelper.GetString(Node, propertyName); IsHandled = true; break; case ValuePropertyType.Guid: value = NodeTreeHelper.GetGuid(Node, propertyName); IsHandled = true; break; } Debug.Assert(IsHandled); }
/// <summary> /// Checks that templates are valid for blocks. /// </summary> /// <param name="blockTemplateTable">Table of templates.</param> /// <param name="nodeTemplateTable">Table of templates with all frames.</param> public virtual bool IsBlockValid(IFrameTemplateReadOnlyDictionary blockTemplateTable, IFrameTemplateReadOnlyDictionary nodeTemplateTable) { Debug.Assert(blockTemplateTable != null); List <Type> BlockKeys = new List <Type>(NodeHelper.CreateNodeDictionary <object>().Keys); IFrameTemplateDictionary DefaultDictionary = CreateEmptyTemplateDictionary(); foreach (Type Key in BlockKeys) { AddBlockNodeTypes(DefaultDictionary, Key); } bool IsValid = true; foreach (KeyValuePair <Type, IFrameTemplate> Entry in DefaultDictionary) { IsValid &= blockTemplateTable.ContainsKey(Entry.Key); } foreach (KeyValuePair <Type, IFrameTemplate> Entry in blockTemplateTable) { Type NodeType = Entry.Key; IFrameTemplate Template = Entry.Value; int CommentFrameCount = 0; IsValid &= NodeTreeHelper.IsBlockType(NodeType); IsValid &= Template.IsValid; IsValid &= Template.Root.IsValid(NodeType, nodeTemplateTable, ref CommentFrameCount); } Debug.Assert(IsValid); return(IsValid); }
private protected virtual string GetFocusedStringContent(IFocusStringContentFocus textCellFocus) { IFocusStringContentFocusableCellView CellView = textCellFocus.CellView; Node Node = CellView.StateView.State.Node; string PropertyName = CellView.PropertyName; return(NodeTreeHelper.GetString(Node, PropertyName)); }
/// <summary> /// Gets the frame that creates cells associated to a property in a state. /// This overload uses selectors to choose the correct frame. /// </summary> /// <param name="state">The state.</param> /// <param name="propertyName">The property name.</param> /// <param name="selectorStack">A list of selectors to choose the correct frame.</param> public virtual IFocusFrame PropertyToFrame(IFocusNodeState state, string propertyName, IList <IFocusFrameSelectorList> selectorStack) { Type OwnerType = state.Node.GetType(); Type InterfaceType = NodeTreeHelper.NodeTypeToInterfaceType(OwnerType); IFocusNodeTemplate Template = (IFocusNodeTemplate)NodeTypeToTemplate(InterfaceType); IFocusFrame Frame = Template.PropertyToFrame(propertyName, selectorStack); return(Frame); }
/// <summary> /// Returns a clone of the node of this state. /// </summary> /// <returns>The cloned node.</returns> public override INode CloneNode() { INode NewNode = null; NodeTreeHelperOptional.GetChildNode(Optional, out bool IsAssigned, out INode ChildNode); if (ChildNode != null) { // Create a clone, initially empty and full of null references. NewNode = NodeHelper.CreateEmptyNode(ChildNode.GetType()); // Clone and assign reference to all nodes, optional or not, list and block lists. foreach (KeyValuePair <string, IReadOnlyInner> Entry in InnerTable) { string PropertyName = Entry.Key; IReadOnlyInner Inner = Entry.Value; ((IReadOnlyInner <IReadOnlyBrowsingChildIndex>)Inner).CloneChildren(NewNode); } // Copy other properties. foreach (KeyValuePair <string, ValuePropertyType> Entry in ValuePropertyTypeTable) { string PropertyName = Entry.Key; ValuePropertyType Type = Entry.Value; bool IsHandled = false; switch (Type) { case ValuePropertyType.Boolean: NodeTreeHelper.CopyBooleanProperty(Node, NewNode, Entry.Key); IsHandled = true; break; case ValuePropertyType.Enum: NodeTreeHelper.CopyEnumProperty(Node, NewNode, Entry.Key); IsHandled = true; break; case ValuePropertyType.String: NodeTreeHelper.CopyStringProperty(Node, NewNode, Entry.Key); IsHandled = true; break; case ValuePropertyType.Guid: NodeTreeHelper.CopyGuidProperty(Node, NewNode, Entry.Key); IsHandled = true; break; } Debug.Assert(IsHandled); } // Also copy comments. NodeTreeHelper.CopyDocumentation(Node, NewNode, cloneCommentGuid: true); } return(NewNode); }
/// <summary> /// Checks that a frame visibility is correctly constructed. /// </summary> /// <param name="nodeType">Type of the node this frame visibility can describe.</param> public override bool IsValid(Type nodeType) { bool IsValid = true; IsValid &= !string.IsNullOrEmpty(PropertyName); IsValid &= NodeTreeHelper.IsEnumProperty(nodeType, PropertyName) || NodeTreeHelper.IsBooleanProperty(nodeType, PropertyName); return(IsValid); }
/// <summary> /// Gets the frame that creates cells associated to a comment in a state. /// This overload uses selectors to choose the correct frame. /// </summary> /// <param name="state">The state.</param> /// <param name="selectorStack">A list of selectors to choose the correct frame.</param> public virtual IFocusCommentFrame GetCommentFrame(IFocusNodeState state, IList <IFocusFrameSelectorList> selectorStack) { Type OwnerType = state.Node.GetType(); Type InterfaceType = NodeTreeHelper.NodeTypeToInterfaceType(OwnerType); IFocusNodeTemplate Template = (IFocusNodeTemplate)NodeTypeToTemplate(InterfaceType); IFocusCommentFrame Frame = Template.GetCommentFrame(selectorStack); return(Frame); }
/// <summary> /// Initializes a new instance of the <see cref="FocusDiscreteContentSelection"/> class. /// </summary> /// <param name="stateView">The state view that encompasses the selection.</param> /// <param name="propertyName">The property name.</param> public FocusDiscreteContentSelection(IFocusNodeStateView stateView, string propertyName) : base(stateView) { Node Node = stateView.State.Node; Debug.Assert(NodeTreeHelper.IsEnumProperty(Node, propertyName) || NodeTreeHelper.IsBooleanProperty(Node, propertyName)); PropertyName = propertyName; }
/// <summary> /// Copy the selection in the clipboard. /// </summary> /// <param name="dataObject">The clipboard data object that can already contain other custom formats.</param> public override void Copy(IDataObject dataObject) { string Content = NodeTreeHelper.GetString(StateView.State.Node, PropertyName); Debug.Assert(Content != null); Debug.Assert(Start <= End); Debug.Assert(End <= Content.Length); dataObject.SetData(typeof(string), Content.Substring(Start, End - Start)); }
/// <summary> /// Checks that a frame is correctly constructed. /// </summary> /// <param name="nodeType">Type of the node this frame can describe.</param> /// <param name="nodeTemplateTable">Table of templates with all frames.</param> /// <param name="commentFrameCount">Number of comment frames found so far.</param> public override bool IsValid(Type nodeType, FrameTemplateReadOnlyDictionary nodeTemplateTable, ref int commentFrameCount) { bool IsValid = true; IsValid &= base.IsValid(nodeType, nodeTemplateTable, ref commentFrameCount); IsValid &= NodeTreeHelper.IsStringProperty(nodeType, PropertyName); Debug.Assert(IsValid); return(IsValid); }
/// <summary> /// Checks that a frame is correctly constructed. /// </summary> /// <param name="nodeType">Type of the node this frame can describe.</param> /// <param name="nodeTemplateTable">Table of templates with all frames.</param> /// <param name="commentFrameCount">Number of comment frames found so far.</param> public override bool IsValid(Type nodeType, IFrameTemplateReadOnlyDictionary nodeTemplateTable, ref int commentFrameCount) { bool IsValid = true; IsValid &= base.IsValid(nodeType, nodeTemplateTable, ref commentFrameCount); IsValid &= !string.IsNullOrEmpty(PropertyName) && NodeTreeHelper.GetPropertyOf(nodeType, PropertyName) != null; Debug.Assert(IsValid); return(IsValid); }
/// <summary> /// Initializes a new instance of the <see cref="WriteableInsertionCollectionNodeIndex"/> class. /// </summary> /// <param name="parentNode">The node in which the insertion operation is taking place.</param> /// <param name="propertyName">The property for the index.</param> /// <param name="node">The inserted node.</param> public WriteableInsertionCollectionNodeIndex(INode parentNode, string propertyName, INode node) { Debug.Assert(parentNode != null); Debug.Assert(!string.IsNullOrEmpty(propertyName)); Debug.Assert(node != null); Debug.Assert(NodeTreeHelper.IsAssignable(parentNode, propertyName, node)); ParentNode = parentNode; PropertyName = propertyName; Node = node; }
/// <summary> /// Returns the value of an enum or boolean. /// </summary> /// <param name="index">Index of the node.</param> /// <param name="propertyName">Name of the property to read.</param> /// <param name="minValue">Minimum valid value for this property upon return.</param> /// <param name="maxValue">Maximum valid value for this property upon return.</param> public virtual int GetDiscreteValue(IReadOnlyIndex index, string propertyName, out int minValue, out int maxValue) { Debug.Assert(Contains(index)); IReadOnlyNodeState State = StateTable[index]; Debug.Assert(State.ValuePropertyTypeTable.ContainsKey(propertyName)); Debug.Assert(State.ValuePropertyTypeTable[propertyName] == Constants.ValuePropertyType.Boolean || State.ValuePropertyTypeTable[propertyName] == Constants.ValuePropertyType.Enum); return(NodeTreeHelper.GetEnumValueAndRange(State.Node, propertyName, out minValue, out maxValue)); }
/// <summary> /// Initializes a new instance of the <see cref="WriteableInsertionPlaceholderNodeIndex"/> class. /// </summary> /// <param name="parentNode">Node containing the replaced node.</param> /// <param name="propertyName">Property in <paramref name="parentNode"/> corresponding to the indexed node.</param> /// <param name="node">The assigned node.</param> public WriteableInsertionPlaceholderNodeIndex(Node parentNode, string propertyName, Node node) { Contract.RequireNotNull(parentNode, out Node ParentNode); Contract.RequireNotNull(propertyName, out string PropertyName); Contract.RequireNotNull(node, out Node Node); Debug.Assert(NodeTreeHelper.IsAssignable(ParentNode, PropertyName, Node)); this.ParentNode = ParentNode; this.PropertyName = PropertyName; this.Node = Node; }
/// <summary> /// Gets the frame that creates cells associated to a comment in a state. /// </summary> /// <param name="state">The state.</param> public virtual IFrameCommentFrame GetCommentFrame(IFrameNodeState state) { // Call overloads of this method if they exist. ControllerTools.AssertNoOverride(this, typeof(FrameTemplateSet)); Type OwnerType = state.Node.GetType(); Type InterfaceType = NodeTreeHelper.NodeTypeToInterfaceType(OwnerType); IFrameNodeTemplate Template = NodeTypeToTemplate(InterfaceType); IFrameCommentFrame Frame = Template.GetCommentFrame(); return(Frame); }
/// <summary> /// Returns the value of a guid. /// </summary> /// <param name="index">Index of the node.</param> /// <param name="propertyName">Name of the property to read.</param> public virtual Guid GetGuidValue(IReadOnlyIndex index, string propertyName) { Debug.Assert(Contains(index)); IReadOnlyNodeState State = StateTable[index]; Debug.Assert(State.ValuePropertyTypeTable.ContainsKey(propertyName)); Debug.Assert(State.ValuePropertyTypeTable[propertyName] == Constants.ValuePropertyType.Guid); Guid Value = NodeTreeHelper.GetGuid(State.Node, propertyName); return(Value); }
private protected virtual void SetNodeTypeToDefault(IFrameTemplateDictionary dictionary, Type nodeType) { Debug.Assert(dictionary.ContainsKey(nodeType)); Debug.Assert(dictionary[nodeType] == null); FrameHorizontalPanelFrame RootFrame = (FrameHorizontalPanelFrame)CreateHorizontalPanelFrame(); FrameNodeTemplate RootTemplate = (FrameNodeTemplate)CreateNodeTemplate(); RootTemplate.NodeType = nodeType; RootTemplate.Root = RootFrame; // Set the template, even if empty, in case the node recursively refers to itself (ex: expressions). dictionary[nodeType] = RootTemplate; RootFrame.Items.Add(CreateCommentFrame()); Type ChildNodeType; IList <string> Properties = NodeTreeHelper.EnumChildNodeProperties(nodeType); foreach (string PropertyName in Properties) { bool IsHandled = false; if (NodeTreeHelperChild.IsChildNodeProperty(nodeType, PropertyName, out ChildNodeType)) { FramePlaceholderFrame NewFrame = (FramePlaceholderFrame)CreatePlaceholderFrame(); NewFrame.PropertyName = PropertyName; RootFrame.Items.Add(NewFrame); IsHandled = true; } else if (NodeTreeHelperOptional.IsOptionalChildNodeProperty(nodeType, PropertyName, out ChildNodeType)) { FrameOptionalFrame NewFrame = (FrameOptionalFrame)CreateOptionalFrame(); NewFrame.PropertyName = PropertyName; RootFrame.Items.Add(NewFrame); IsHandled = true; } else if (NodeTreeHelperList.IsNodeListProperty(nodeType, PropertyName, out Type ListNodeType)) { FrameHorizontalListFrame NewFrame = (FrameHorizontalListFrame)CreateHorizontalListFrame(); NewFrame.PropertyName = PropertyName; RootFrame.Items.Add(NewFrame); IsHandled = true; } else if (NodeTreeHelperBlockList.IsBlockListProperty(nodeType, PropertyName, out Type ChildInterfaceType, out Type ChildItemType)) { FrameHorizontalBlockListFrame NewFrame = (FrameHorizontalBlockListFrame)CreateHorizontalBlockListFrame(); NewFrame.PropertyName = PropertyName; RootFrame.Items.Add(NewFrame); IsHandled = true; }
/// <summary> /// Initializes a new instance of the <see cref="WriteableInsertionOptionalNodeIndex"/> class. /// </summary> /// <param name="parentNode">Node containing the indexed optional node.</param> /// <param name="propertyName">Property in <paramref name="parentNode"/> corresponding to the indexed optional node.</param> /// <param name="node">The assigned node.</param> public WriteableInsertionOptionalNodeIndex(INode parentNode, string propertyName, INode node) { Debug.Assert(parentNode != null); Debug.Assert(!string.IsNullOrEmpty(propertyName)); Debug.Assert(node != null); Debug.Assert(NodeTreeHelper.IsAssignable(parentNode, propertyName, node)); ParentNode = parentNode; PropertyName = propertyName; Node = node; Optional = NodeTreeHelperOptional.GetOptionalReference(parentNode, propertyName); Debug.Assert(Optional != null); }
/// <summary> /// Create cells for the provided state view. /// </summary> /// <param name="context">Context used to build the cell view tree.</param> /// <param name="parentCellView">The parent cell view.</param> public override IFrameCellView BuildNodeCells(IFrameCellViewTreeContext context, IFrameCellViewCollection parentCellView) { IFrameNodeState State = context.StateView.State; int Value = NodeTreeHelper.GetEnumValue(State.Node, PropertyName); Debug.Assert(Value >= 0 && Value < Items.Count); IFrameKeywordFrame KeywordFrame = Items[Value]; IFrameDiscreteContentFocusableCellView CellView = CreateDiscreteContentFocusableCellView(context.StateView, parentCellView, KeywordFrame); ValidateDiscreteContentFocusableCellView(context, KeywordFrame, CellView); return(CellView); }
/// <summary> /// Initializes a new instance of the <see cref="WriteableInsertionOptionalNodeIndex"/> class. /// </summary> /// <param name="parentNode">Node containing the indexed optional node.</param> /// <param name="propertyName">Property in <paramref name="parentNode"/> corresponding to the indexed optional node.</param> /// <param name="node">The assigned node.</param> public WriteableInsertionOptionalNodeIndex(Node parentNode, string propertyName, Node node) { Contract.RequireNotNull(parentNode, out Node ParentNode); Contract.RequireNotNull(propertyName, out string PropertyName); Contract.RequireNotNull(node, out Node Node); Debug.Assert(PropertyName.Length > 0); Debug.Assert(NodeTreeHelper.IsAssignable(ParentNode, PropertyName, Node)); this.ParentNode = ParentNode; this.PropertyName = PropertyName; this.Node = Node; Optional = NodeTreeHelperOptional.GetOptionalReference(ParentNode, PropertyName); Debug.Assert(Optional != null); }
private protected void DrawTextCaret(ILayoutStringContentFocus textCellFocus) { ILayoutStringContentFocusableCellView CellView = textCellFocus.CellView; Node Node = CellView.StateView.State.Node; string PropertyName = CellView.PropertyName; string Text = NodeTreeHelper.GetString(Node, PropertyName); Point CellOrigin = CellView.CellOrigin; Padding CellPadding = CellView.CellPadding; Point OriginWithPadding = CellOrigin.Moved(CellPadding.Left, CellPadding.Top); DrawContext.ShowCaret(OriginWithPadding, Text, FocusedTextStyle, ActualCaretMode, CaretPosition); }
/// <summary> /// Replaces the selection with the content of the clipboard. /// </summary> /// <param name="isChanged">True if something was replaced or added.</param> public override void Paste(out bool isChanged) { isChanged = false; if (ClipboardHelper.TryReadInt(out int NewValue) && NewValue >= 0) { int OldValue = NodeTreeHelper.GetEnumValueAndRange(StateView.State.Node, PropertyName, out int Min, out int Max); if (OldValue != NewValue && NewValue >= Min && NewValue <= Max) { FocusController Controller = StateView.ControllerView.Controller; Controller.ChangeDiscreteValue(StateView.State.ParentIndex, PropertyName, NewValue); isChanged = true; } } }
/// <inheritdoc/> public override void CloneChildren(Node parentNode) { NodeTreeHelperBlockList.ClearChildBlockList(parentNode, PropertyName); // Clone and insert all blocks. This will clone all children recursively. for (int BlockIndex = 0; BlockIndex < BlockStateList.Count; BlockIndex++) { IReadOnlyBlockState BlockState = BlockStateList[BlockIndex]; ((IReadOnlyBlockState <IReadOnlyInner <IReadOnlyBrowsingChildIndex> >)BlockState).CloneBlock(parentNode, BlockIndex); } // Copy comments. IBlockList BlockList = NodeTreeHelperBlockList.GetBlockList(Owner.Node, PropertyName); IBlockList NewBlockList = NodeTreeHelperBlockList.GetBlockList(parentNode, PropertyName); NodeTreeHelper.CopyDocumentation(BlockList, NewBlockList, cloneCommentGuid: true); }
private protected virtual void AddBlockNodeTypes(FrameTemplateDictionary dictionary, Type nodeType) { IList <string> Properties = NodeTreeHelper.EnumChildNodeProperties(nodeType); foreach (string PropertyName in Properties) { if (NodeTreeHelperBlockList.IsBlockListProperty(nodeType, PropertyName, /*out Type ChildInterfaceType,*/ out Type ChildItemType)) { Type BlockListType = NodeTreeHelperBlockList.BlockListBlockType(nodeType, PropertyName); if (!dictionary.ContainsKey(BlockListType)) { dictionary.Add(BlockListType, null); } } } }
/// <summary> /// Creates a clone of the block and assigns it in the provided parent. /// </summary> /// <param name="parentNode">The node that will contains a reference to the cloned block upon return.</param> /// <param name="blockIndex">Position where to insert the block in <paramref name="parentNode"/>.</param> public virtual void CloneBlock(Node parentNode, int blockIndex) { Pattern PatternClone = ClonePattern(); Debug.Assert(PatternClone != null); Identifier SourceClone = CloneSource(); Debug.Assert(SourceClone != null); IBlock NewBlock = NodeTreeHelperBlockList.CreateBlock(parentNode, ParentInner.PropertyName, ChildBlock.Replication, PatternClone, SourceClone); NodeTreeHelperBlockList.InsertIntoBlockList(parentNode, ParentInner.PropertyName, blockIndex, NewBlock); NodeTreeHelper.CopyDocumentation(ChildBlock, NewBlock, cloneCommentGuid: true); // Clone children recursively. CloneChildren(parentNode, NewBlock); }