/// <summary> /// Checks if an existing item at the focus can be moved up or down. /// </summary> /// <param name="direction">Direction of the move, relative to the current position of the item.</param> /// <param name="inner">Inner to use to move the item upon return.</param> /// <param name="index">Index of the item to move upon return.</param> /// <returns>True if an item can be moved at the focus.</returns> public virtual bool IsItemMoveable(int direction, out IFocusCollectionInner inner, out IFocusBrowsingCollectionNodeIndex index) { inner = null; index = null; bool IsMoveable = false; IFocusNodeState State = Focus.CellView.StateView.State; if (Focus.CellView.Frame is IFocusInsertFrame AsInsertFrame) { IsMoveable = false; } else { IsMoveable = false; // Search recursively for a collection parent, up to 3 levels up. for (int i = 0; i < 3 && State != null; i++) { IFocusCollectionInner ListInner = null; if (State.ParentInner is IFocusBlockListInner AsBlockListInner) { ListInner = AsBlockListInner; } else if (State.ParentInner is IFocusListInner AsListInner && IsDeepestList(State)) { ListInner = AsListInner; } if (ListInner != null) { inner = ListInner; index = State.ParentIndex as IFocusBrowsingCollectionNodeIndex; Debug.Assert(index != null); if (Controller.IsMoveable(inner, index, direction)) { IsMoveable = true; } break; } State = State.ParentState; } } return(IsMoveable); }
private protected virtual bool IsNewItemInsertableAtInsertFrame(IFocusNodeState state, IFocusInsertFrame frame, out IFocusCollectionInner inner, out IFocusInsertionCollectionNodeIndex index) { inner = null; index = null; bool Result = false; Type InsertType = frame.InsertType; Debug.Assert(InsertType != Type.Missing); Debug.Assert(!InsertType.IsInterface); Debug.Assert(!InsertType.IsAbstract); // Type InterfaceType = NodeTreeHelper.NodeTypeToInterfaceType(InsertType); //Node NewItem = NodeHelper.CreateDefaultFromInterface(InterfaceType); Node NewItem = NodeHelper.CreateDefaultFromType(InsertType); IFocusCollectionInner CollectionInner = null; frame.CollectionNameToInner(ref state, ref CollectionInner); Debug.Assert(CollectionInner != null); if (CollectionInner is IFocusBlockListInner AsBlockListInner) { inner = AsBlockListInner; if (AsBlockListInner.Count == 0) { Pattern NewPattern = NodeHelper.CreateEmptyPattern(); Identifier NewSource = NodeHelper.CreateEmptyIdentifier(); index = CreateNewBlockNodeIndex(state.Node, CollectionInner.PropertyName, NewItem, 0, NewPattern, NewSource); } else { index = CreateExistingBlockNodeIndex(state.Node, CollectionInner.PropertyName, NewItem, 0, 0); } Result = true; } else if (CollectionInner is IFocusListInner AsListInner) { inner = AsListInner; index = CreateListNodeIndex(state.Node, AsListInner.PropertyName, NewItem, 0); Result = true; } return(Result); }
/// <summary> /// Returns the inner for the collection associated to this frame, for a given state. /// </summary> /// <param name="state">The state, modified if <see cref="IFrameInsertFrame.CollectionName"/> points to a different state.</param> /// <param name="inner">The inner associated to the collection in <paramref name="state"/>.</param> public virtual void CollectionNameToInner(ref IFocusNodeState state, ref IFocusCollectionInner inner) { Debug.Assert(inner == null); string[] Split = CollectionName.Split('.'); for (int i = 0; i < Split.Length; i++) { string PropertyName = Split[i]; if (i + 1 < Split.Length) { Debug.Assert(state.InnerTable.ContainsKey(PropertyName)); bool IsHandled = false; switch (state.InnerTable[PropertyName]) { case IFocusPlaceholderInner <IFocusBrowsingPlaceholderNodeIndex> AsPlaceholderInner: state = AsPlaceholderInner.ChildState; IsHandled = true; break; case IFocusOptionalInner <IFocusBrowsingOptionalNodeIndex> AsOptionalInner: Debug.Assert(AsOptionalInner.IsAssigned); state = AsOptionalInner.ChildState; IsHandled = true; break; } Debug.Assert(IsHandled); } else { Debug.Assert(state.InnerTable.ContainsKey(PropertyName)); inner = state.InnerTable[PropertyName] as IFocusCollectionInner; } } Debug.Assert(inner != null); Debug.Assert(state.InnerTable.ContainsKey(inner.PropertyName)); Debug.Assert(state.InnerTable[inner.PropertyName] == inner); }
/// <summary> /// Checks if a new item can be inserted at the focus. /// </summary> /// <param name="inner">Inner to use to insert the new item upon return.</param> /// <param name="index">Index of the new item to insert upon return.</param> /// <returns>True if a new item can be inserted at the focus.</returns> public virtual bool IsNewItemInsertable(out IFocusCollectionInner inner, out IFocusInsertionCollectionNodeIndex index) { inner = null; index = null; bool Result = false; IFocusNodeState State = Focus.CellView.StateView.State; IFocusFrame Frame = Focus.CellView.Frame; if (Frame is IFocusInsertFrame AsInsertFrame) { Result = IsNewItemInsertableAtInsertFrame(State, AsInsertFrame, out inner, out index); } else if (Focus.CellView is IFocusStringContentFocusableCellView AsStringContentFocusableCellView) { Result = IsNewItemInsertableAtStringContentCellView(State, AsStringContentFocusableCellView, out inner, out index); } return(Result); }
/// <summary> /// Checks if an existing item can be removed at the focus. /// </summary> /// <param name="inner">Inner to use to remove the item upon return.</param> /// <param name="index">Index of the item to remove upon return.</param> /// <returns>True if an item can be removed at the focus.</returns> public virtual bool IsItemRemoveable(out IFocusCollectionInner inner, out IFocusBrowsingCollectionNodeIndex index) { inner = null; index = null; bool IsRemoveable = false; IFocusNodeState State = Focus.CellView.StateView.State; if (Focus.CellView.Frame is IFocusInsertFrame AsInsertFrame) { IsRemoveable = false; } else { IsRemoveable = false; // Search recursively for a collection parent, up to 4 levels up. for (int i = 0; i < 4 && State != null; i++) { if (State.ParentInner is IFocusCollectionInner AsCollectionInner) { inner = AsCollectionInner; index = State.ParentIndex as IFocusBrowsingCollectionNodeIndex; Debug.Assert(index != null); if (Controller.IsRemoveable(inner, index)) { IsRemoveable = true; break; } } State = State.ParentState; } } return(IsRemoveable); }
private protected virtual bool IsNewItemInsertableAtStringContentCellView(IFocusNodeState state, IFocusStringContentFocusableCellView cellView, out IFocusCollectionInner inner, out IFocusInsertionCollectionNodeIndex index) { inner = null; index = null; bool Result = false; if (CaretPosition == 0) { Result = IsListExtremumItem(state, cellView, IsFirstFocusableCellView, InsertAbove, out inner, out index); } else if (CaretPosition == MaxCaretPosition) { Result = IsListExtremumItem(state, cellView, IsLastFocusableCellView, InsertBelow, out inner, out index); } return(Result); }
private protected virtual bool IsExtremumCheckParent(IFocusNodeState state, IFocusContentFocusableCellView cellView, System.Func <IFocusNodeState, IFocusContentFocusableCellView, bool> isGoodFocusableCellView, System.Func <int, int> getInsertPosition, out IFocusCollectionInner inner, out IFocusInsertionCollectionNodeIndex index) { inner = null; index = null; bool Result = false; IFocusNodeState ParentState = state.ParentState; if (ParentState != null && isGoodFocusableCellView(state, cellView)) { Result = IsListExtremumItem(ParentState, cellView, isGoodFocusableCellView, getInsertPosition, out inner, out index); } return(Result); }
private protected virtual bool IsListExtremumItem(IFocusNodeState state, IFocusContentFocusableCellView cellView, System.Func <IFocusNodeState, IFocusContentFocusableCellView, bool> isGoodFocusableCellView, System.Func <int, int> getInsertPosition, out IFocusCollectionInner inner, out IFocusInsertionCollectionNodeIndex index) { inner = null; index = null; IFocusInner ParentInner = state.ParentInner; if (ParentInner == null) { return(false); } Node NewItem; int BlockPosition; int ItemPosition; bool IsHandled = false; bool Result = false; switch (ParentInner) { case IFocusPlaceholderInner AsPlaceholderInner: case IFocusOptionalInner AsOptionalInner: Result = IsExtremumCheckParent(state, cellView, isGoodFocusableCellView, getInsertPosition, out inner, out index); IsHandled = true; break; // Check the parent state if there is a deeper list (typically, for a qualified name, there would be one). case IFocusListInner AsListInner: if (IsDeepestList(state)) { NewItem = NodeHelper.CreateDefaultFromType(AsListInner.InterfaceType); ItemPosition = (state.ParentIndex as IFocusBrowsingListNodeIndex).Index; inner = AsListInner; index = CreateListNodeIndex(inner.Owner.Node, inner.PropertyName, NewItem, getInsertPosition(ItemPosition)); Result = true; } else { Result = IsExtremumCheckParent(state, cellView, isGoodFocusableCellView, getInsertPosition, out inner, out index); } IsHandled = true; break; case IFocusBlockListInner AsBlockListInner: NewItem = NodeHelper.CreateDefaultFromType(AsBlockListInner.InterfaceType); BlockPosition = (state.ParentIndex as IFocusBrowsingExistingBlockNodeIndex).BlockIndex; ItemPosition = (state.ParentIndex as IFocusBrowsingExistingBlockNodeIndex).Index; inner = AsBlockListInner; index = CreateExistingBlockNodeIndex(inner.Owner.Node, inner.PropertyName, NewItem, BlockPosition, getInsertPosition(ItemPosition)); Result = true; IsHandled = true; break; } Debug.Assert(IsHandled); return(Result); }