Example #1
0
        private static IList <ItemInfo> GetPlaceholderSlot(CompactLayout layout, int visibleLine)
        {
            var itemInfo = new ItemInfo();

            itemInfo.IsDisplayed = true;

            itemInfo.Item  = PlaceholderInfo.Empty;
            itemInfo.Level = 0;
            itemInfo.Id    = layout.TotalLineCount - 1;
            itemInfo.Slot  = itemInfo.Id;

            itemInfo.IsCollapsible    = false;
            itemInfo.IsCollapsed      = false;
            itemInfo.ItemType         = BaseLayout.GetItemType(itemInfo.Item);
            itemInfo.IsSummaryVisible = false;

            itemInfo.LayoutInfo = layout.GenerateLayoutInfo(itemInfo, null, visibleLine, visibleLine);

            return(new List <ItemInfo> {
                itemInfo
            });
        }
Example #2
0
        internal override AddRemoveLayoutResult RemoveItem(object changedItem, object addRemoveItem, int addRemoveItemIndex)
        {
            int removedItemsCount = 1;
            int removedLinesCount = 0;

            bool      isVisible          = true;
            GroupInfo changedGroupInfo   = this.GetGroupInfo(changedItem);
            bool      changedGroupIsRoot = changedGroupInfo == null;
            int       flatSlot           = -1;
            int       rowSlot            = -1;

            int level = changedGroupIsRoot ? 0 : changedGroupInfo.Level + 1;

            IGroup removedGroup = addRemoveItem as IGroup;

            // We added/removed group so we need to index all subgroups.
            if (removedGroup != null && changedItem != addRemoveItem)
            {
                GroupInfo groupInfo = this.GetGroupInfo(addRemoveItem);
                System.Diagnostics.Debug.Assert(groupInfo != null, "Cannot remove group that are not indexed.");
                flatSlot          = groupInfo.Index;
                isVisible         = groupInfo.IsVisible();
                removedItemsCount = groupInfo.GetLineSpan();

                removedLinesCount = removedItemsCount;

                if (!removedGroup.HasItems)
                {
                    foreach (var nextGroupIndex in this.GroupHeadersTable.GetIndexes(flatSlot + 1))
                    {
                        GroupInfo nextGroupInfo = this.GroupHeadersTable.GetValueAt(nextGroupIndex);
                        if (nextGroupInfo.Level <= groupInfo.Level)
                        {
                            break;
                        }

                        this.RemoveGroupInfo(nextGroupInfo);
                    }
                }

                this.UpdateGroupHeadersTable(groupInfo.Index, -removedItemsCount);

                this.itemInfoTable.Remove(removedGroup);
                this.GroupHeadersTable.RemoveIndexesAndValues(flatSlot, removedItemsCount);

                if (isVisible)
                {
                    if (groupInfo.IsExpanded)
                    {
                        int collapsedItems = removedItemsCount - this.GetCollapsedSlotsCount(flatSlot, flatSlot + removedItemsCount - 1);
                        this.VisibleLineCount -= collapsedItems;
                    }
                    else
                    {
                        this.VisibleLineCount -= 1;
                    }
                }

                this.collapsedSlotsTable.RemoveIndexesAndValues(flatSlot, removedItemsCount);

                if (changedGroupInfo != null)
                {
                    // Update the group last slot.
                    changedGroupInfo.LastSubItemSlot -= removedItemsCount;
                }
            }
            else
            {
                // We added new item (not group) into root group.
                if (changedGroupIsRoot)
                {
                    if (isVisible)
                    {
                        removedLinesCount = this.GetRemovedSlots(this.ItemsSource.Count, removedItemsCount);

                        this.VisibleLineCount -= removedLinesCount;

                        flatSlot = addRemoveItemIndex;
                    }

                    // slot should be already correct.
                    // No need to correct collapsed slots. They should be empty (e.g. no groups to collapse).
                    System.Diagnostics.Debug.Assert(this.GroupHeadersTable.IsEmpty, "GroupHeaders table should be empty.");
                    System.Diagnostics.Debug.Assert(this.collapsedSlotsTable.IsEmpty, "CollapsedSlots table should be empty since we don't have groups.");
                }
                else
                {
                    var children = (changedGroupInfo.Item as IGroup).Items.Count;

                    // Be carefull that this represents lines/slots rather than items. Also consider if collapsed table should use this
                    removedLinesCount = this.GetRemovedSlots(children, removedItemsCount);

                    flatSlot = changedGroupInfo.Index + 1 + addRemoveItemIndex;

                    // Update the group last slot.
                    changedGroupInfo.LastSubItemSlot -= removedItemsCount;
                    this.GroupHeadersTable.RemoveIndex(flatSlot);

                    isVisible = changedGroupInfo.IsExpanded && changedGroupInfo.IsVisible();
                    if (isVisible)
                    {
                        this.collapsedSlotsTable.RemoveIndexes(flatSlot, removedLinesCount);
                        this.VisibleLineCount -= removedLinesCount;
                    }
                    else
                    {
                        this.collapsedSlotsTable.RemoveIndexesAndValues(flatSlot, removedLinesCount);
                    }

                    this.UpdateGroupHeadersTable(changedGroupInfo.Index, -removedItemsCount);
                }
            }

            rowSlot = this.GetRowSlotFromFlatSlot(flatSlot);

            // Update parent groups last slot.
            CompactLayout.UpdateParentGroupInfosLastSlot(-removedItemsCount, changedGroupInfo);

            // Update TotalCount.
            this.TotalSlotCount -= removedLinesCount;

            this.RemoveFromRenderInfo(removedLinesCount, rowSlot);

            var layoutResult = new AddRemoveLayoutResult(rowSlot, removedLinesCount);

            foreach (var strategy in this.LayoutStrategies)
            {
                strategy.OnItemRemoved(layoutResult);
            }

            // return result indexes so that changed can be reflected to UI.
            return(layoutResult);
        }
Example #3
0
        internal override AddRemoveLayoutResult AddItem(object changedItem, object addRemoveItem, int addRemoveItemIndex)
        {
            int  addedItemsCount    = 1;
            bool isVisible          = true;
            var  groupInfo          = this.GetGroupInfo(changedItem);
            bool changedGroupIsRoot = groupInfo == null;
            int  flatSlot           = -1; // = addRemoveItemIndex;
            int  rowSlot            = -1;
            int  addedLinesCount    = 0;

            int level = changedGroupIsRoot ? 0 : groupInfo.Level + 1;

            // We added/removed group so we need to index all subgroups.
            if (addRemoveItem is IGroup && changedItem != addRemoveItem)
            {
                flatSlot  = this.GetInsertedGroupSlot(changedItem, addRemoveItemIndex);
                isVisible = groupInfo != null ? (groupInfo.IsExpanded && groupInfo.IsVisible()) : true;

                // We give a list in which to insert groups so that we can manually correct the indexes in groupHeadersTable.
                List <GroupInfo> insertedGroups = new List <GroupInfo>();
                addedItemsCount = this.CountAndPopulateTables(addRemoveItem, flatSlot, level, this.GroupLevels, groupInfo, false, insertedGroups);

                addedLinesCount = addedItemsCount;

                bool first         = true;
                int  innerMostSlot = flatSlot;
                foreach (var newGroupInfo in insertedGroups)
                {
                    int groupInfoToInsertSpan = newGroupInfo.GetLineSpan();
                    if (first)
                    {
                        first = false;
                        this.GroupHeadersTable.InsertIndexes(newGroupInfo.Index, groupInfoToInsertSpan);
                        if (isVisible)
                        {
                            this.collapsedSlotsTable.InsertIndexes(flatSlot, addedItemsCount);
                            this.VisibleLineCount += addedItemsCount;
                        }
                        else
                        {
                            this.collapsedSlotsTable.InsertIndexesAndValues(flatSlot, addedItemsCount, false);
                        }
                    }
                    this.GroupHeadersTable.AddValue(newGroupInfo.Index, newGroupInfo);

                    // We get the inner most group so that we update groups after inner most (the upper one are newly created and their index and last slot count are correct.
                    // We get it only if the change is in the root group. In existing groups we know the correct slot.
                    if (changedGroupIsRoot)
                    {
                        innerMostSlot = newGroupInfo.Index;
                    }
                }

                // Update groups after current one.
                this.UpdateGroupHeadersTable(innerMostSlot, addedItemsCount);

                if (groupInfo != null)
                {
                    // Update the group last slot.
                    groupInfo.LastSubItemSlot += addedItemsCount;
                }
            }
            else
            {
                // We added new item (not group) into root group.
                if (changedGroupIsRoot)
                {
                    if (isVisible)
                    {
                        addedLinesCount = this.GetAddedSlots(this.ItemsSource.Count, addedItemsCount);

                        this.VisibleLineCount += addedLinesCount;

                        flatSlot = addRemoveItemIndex;
                    }

                    // slot should be already correct.
                    // No need to correct collapsed slots. They should be empty (e.g. no groups to collapse).
                    System.Diagnostics.Debug.Assert(this.GroupHeadersTable.IsEmpty, "GroupHeaders table should be empty.");
                    System.Diagnostics.Debug.Assert(this.collapsedSlotsTable.IsEmpty, "CollapsedSlots table should be empty since we don't have groups.");
                }
                else
                {
                    // We added new item (not group) into existing bottom level group (not root group).
                    var children = (groupInfo.Item as IGroup).Items.Count;

                    addedLinesCount = this.GetAddedSlots(children, addedItemsCount);

                    flatSlot = groupInfo.Index + 1 + addRemoveItemIndex;

                    // We give a list in which to insert groups so that we can manually correct the indexes in groupHeadersTable.

                    // Update the group last slot.
                    groupInfo.LastSubItemSlot += addedItemsCount;

                    if (addedItemsCount > 0)
                    {
                        this.GroupHeadersTable.InsertIndex(flatSlot);
                    }

                    isVisible = groupInfo.IsExpanded && groupInfo.IsVisible();
                    if (addedItemsCount > 0)
                    {
                        if (isVisible)
                        {
                            this.collapsedSlotsTable.InsertIndexes(flatSlot, addedItemsCount);
                            this.VisibleLineCount += addedLinesCount;
                        }
                        else
                        {
                            this.collapsedSlotsTable.InsertIndexesAndValues(flatSlot, addedItemsCount, false);
                        }
                    }

                    this.UpdateGroupHeadersTable(groupInfo.Index, addedItemsCount);
                }
            }

            rowSlot = this.GetRowSlotFromFlatSlot(flatSlot);

            // Update parent groups last slot.
            CompactLayout.UpdateParentGroupInfosLastSlot(addedItemsCount, groupInfo);

            // Update TotalCount.
            this.TotalSlotCount += addedLinesCount;

            // Update Visible line count if not collapsed.
            double length = isVisible ? this.averageItemLength : 0;

            if (addedLinesCount >= 0)
            {
                this.InsertToRenderInfo(rowSlot, null, addedLinesCount);
            }
            var layoutResult = new AddRemoveLayoutResult(rowSlot, addedLinesCount);

            foreach (var strategy in this.LayoutStrategies)
            {
                strategy.OnItemAdded(layoutResult);
            }

            // return result indexes so that changed can be reflected to UI.
            return(layoutResult);
        }