예제 #1
0
        /// <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);
        }
예제 #2
0
        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);
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }