Exemplo n.º 1
0
 public override sealed ITEMPOSITION TrackRow(int absRow, ref int singleColumnSubItemAdjust)
 {
     if (absRow >= TotalCount)
     {
         throw new ArgumentOutOfRangeException("absRow");
     }
     TREENODE tn1;
     TREENODE tn2;
     int curImmedSubItemGain; // ImmedSubItemGain is virtual, avoid calling multiple times.
     int curTotalCount;
     int curFullSubItemGain;
     var curIndex = 0;
     var pos = new ITEMPOSITION();
     pos.ParentNode = tn2 = this;
     pos.ParentAbsolute = VirtualTreeConstant.NullIndex;
     var parentAbsoluteAdjust = 0;
     tn2 = NextMultiLineSibling(tn2.FirstChild);
     if (tn2 != null)
     {
         for (;;)
         {
             curIndex += tn2.Index;
             if (curIndex >= absRow)
             {
                 pos.Index = tn2.Index + absRow - curIndex;
                 break;
             }
             else if ((curImmedSubItemGain = tn2.ImmedSubItemGain) + curIndex >= absRow)
             {
                 pos.Index = tn2.Index;
                 pos.SubItemOffset = absRow - curIndex;
                 break;
             }
             else if (!tn2.Expanded)
             {
                 // The node was returned from NextMultiLineSibling because of the
                 // subitem gain, not the expansion. Move to the next node.
                 curIndex += curImmedSubItemGain - tn2.Index;
                 singleColumnSubItemAdjust += curImmedSubItemGain;
                 tn2 = NextMultiLineSibling(tn2.NextSibling);
                 if (tn2 == null)
                 {
                     // Same as else clause below
                     pos.Index = absRow - curIndex;
                     pos.SubItemOffset = 0;
                     break;
                 }
             }
             else
             {
                 curFullSubItemGain = tn2.FullSubItemGain;
                 curTotalCount = curFullSubItemGain + tn2.FullCount;
                 if (curIndex + curTotalCount >= absRow)
                 {
                     curIndex += curImmedSubItemGain;
                     absRow -= ++curIndex;
                     singleColumnSubItemAdjust += curImmedSubItemGain;
                     pos.ParentAbsolute += curIndex;
                     // We want the subitemgain for recursion cases, but
                     // not if we end up returning this parent absolute.
                     // Save this value so we can take it off later.
                     parentAbsoluteAdjust = curImmedSubItemGain;
                     curIndex = 0;
                     tn1 = tn2;
                     tn2 = NextMultiLineSibling(tn1.FirstChild);
                     pos.ParentNode = tn1;
                     ++pos.Level;
                     if (tn2 == null)
                     {
                         pos.Index = absRow;
                         break;
                     }
                 }
                 else
                 {
                     curIndex += curTotalCount - tn2.Index; // UNDONE_SUBITEM Does this need a SubItemGain adjust?
                     singleColumnSubItemAdjust += curFullSubItemGain;
                     tn1 = NextMultiLineSibling(tn2.NextSibling);
                     if (tn1 != null)
                     {
                         tn2 = tn1;
                     }
                     else
                     {
                         pos.Index = absRow - curIndex;
                         pos.SubItemOffset = 0; // UNDONE_SUBITEM
                         break;
                     }
                 }
             }
         } //for(;;)
         pos.ParentAbsolute -= parentAbsoluteAdjust;
     }
     else
     {
         pos.Index = absRow;
     }
     return pos;
 }
Exemplo n.º 2
0
        private VirtualTreeItemInfo GetItemInfo(ref ITEMPOSITION pos, int column, bool setFlags, bool ignoreMultiColumn, bool lastSubItem)
        {
            var info = new VirtualTreeItemInfo(pos.ParentNode.Branch, pos.Index, column, pos.Level);
            var blankItem = ignoreMultiColumn ? false : pos.IsBlank(column);
            info.Blank = blankItem;

            if (setFlags)
            {
                if (!ignoreMultiColumn && MultiColumnSupport)
                {
                    TREENODE tnChild;
                    if (blankItem)
                    {
                        if (column >= pos.ParentNode.GetColumnCount(pos.Index))
                        {
                            // If the item is after all supported columns then
                            // just let it draw blank by leaving all flags clear.
                            info.ClearLevel();
                        }
                        else
                        {
                            Debug.Assert(pos.SubItemOffset > 0);
                            tnChild = pos.ParentNode.GetChildNode(pos.Index);
                            Debug.Assert(tnChild != null); // Can't get a subitem offset without a node
                            if (column == 0)
                            {
                                // A blank item in the first column
                                info.TrailingItem = pos.SubItemOffset == tnChild.ImmedSubItemGain;
                                info.LastBranchItem = (pos.Index + 1) == pos.ParentNode.ImmedCount;
                                info.FirstBranchItem = pos.Index == 0;
                                info.Expanded = tnChild.Expanded && (tnChild.ImmedCount > 0);
                                    // Required information to draw lines down to expanded item
                            }
                            else
                            {
                                // A blank item in subitem column
                                info.ClearLevel();
                                info.TrailingItem = pos.SubItemOffset == tnChild.ImmedSubItemGain;
                            }
                        }
                    } // if (blankItem)
                    else if (!pos.ParentNode.MultiColumn)
                    {
                        info.Expanded = pos.IsExpanded(column);
                        info.Expandable = info.Expanded || pos.IsExpandable(column);
                        info.FirstBranchItem = pos.Index == 0;
                        info.LastBranchItem = pos.ParentNode.Branch.VisibleItemCount == (pos.Index + 1);
                        if (pos.ParentNode.InSubItemColumn)
                        {
                            info.LeadingItem = info.FirstBranchItem && pos.ParentNode.ComplexSubItem;
                            info.TrailingItem = lastSubItem;
                            info.SimpleCell = info.Level == 0 && pos.ParentNode.NoChildExpansion;
                        }
                        else
                        {
                            info.TrailingItem = info.LeadingItem = true;
                        }
                    }
                    else if (column == 0)
                    {
                        info.LeadingItem = true;
                        info.FirstBranchItem = pos.Index == 0;
                        info.LastBranchItem = (pos.Index + 1) == pos.ParentNode.ImmedCount;
                        tnChild = pos.ParentNode.GetChildNode(pos.Index);
                        if (tnChild == null)
                        {
                            info.TrailingItem = true;
                            info.Expandable = pos.IsExpandable(0); //column == 0
                        }
                        else
                        {
                            info.TrailingItem = tnChild.ImmedSubItemGain == 0;
                            info.Expanded = pos.IsExpanded(0); // column == 0
                            info.Expandable = info.Expanded || pos.IsExpandable(0);
                        }
                        info.SimpleCell = info.Level == 0 && pos.ParentNode.NoChildExpansion;
                    } // else if (column == 0)
                    else
                    {
                        info.LeadingItem = info.FirstBranchItem = true;
                        info.LastBranchItem = true;
                        tnChild = pos.ParentNode.GetChildNode(pos.Index);
                        if (tnChild != null)
                        {
                            info.TrailingItem = tnChild.ImmedSubItemGain == 0;
                        }
                        else
                        {
                            info.TrailingItem = true;
                        }
                        info.Expanded = pos.IsExpanded(column);
                        info.Expandable = info.Expanded || pos.IsExpandable(column);
                        info.SimpleCell = info.Level == 0 && !info.Expandable;
                    } // else
                } // if (MultiColumnSupport)
                else
                {
                    Debug.Assert(column == 0);
                    if (!blankItem)
                    {
                        info.Expanded = pos.IsExpanded(column);
                        info.Expandable = info.Expanded ? true : pos.IsExpandable(column);
                    }
                    info.FirstBranchItem = pos.Index == 0;
                    info.LastBranchItem = pos.ParentNode.Branch.VisibleItemCount == (pos.Index + 1);
                    info.LeadingItem = info.TrailingItem = true;
                } // else
            }
            return info;
        }
Exemplo n.º 3
0
 // TrackRow functions are called for  a root node (either the tree root
 // or a subitem root) to get the position information for the given offset. The 
 // IgnoreOffsets functions can be used to provide position information that
 // enables a multi-column tree to be represented simultaneously as a single-column
 // tree.
 public ITEMPOSITION TrackRowIgnoreOffsets(int absRow)
 {
     if (absRow > FullCount)
     {
         throw new ArgumentOutOfRangeException("absRow");
     }
     TREENODE tn1;
     TREENODE tn2;
     var curIndex = 0;
     var pos = new ITEMPOSITION();
     pos.ParentNode = tn2 = this;
     pos.ParentAbsolute = VirtualTreeConstant.NullIndex;
     tn2 = NextExpanded(tn2.FirstChild);
     if (tn2 != null)
     {
         for (;;)
         {
             curIndex += tn2.Index;
             if (curIndex >= absRow)
             {
                 pos.Index = tn2.Index + absRow - curIndex;
                 break;
             }
             else if (curIndex + tn2.FullCount >= absRow)
             {
                 absRow -= ++curIndex;
                 pos.ParentAbsolute += curIndex;
                 curIndex = 0;
                 tn1 = tn2;
                 tn2 = NextExpanded(tn1.FirstChild);
                 pos.ParentNode = tn1;
                 ++pos.Level;
                 if (tn2 == null)
                 {
                     pos.Index = absRow;
                     break;
                 }
             }
             else
             {
                 curIndex += tn2.FullCount - tn2.Index;
                 tn1 = NextExpanded(tn2.NextSibling);
                 if (tn1 != null)
                 {
                     tn2 = tn1;
                 }
                 else
                 {
                     pos.Index = absRow - curIndex;
                     break;
                 }
             }
         } //for(;;)
     }
     else
     {
         pos.Index = absRow;
     }
     return pos;
 }