private void Remove(OutlineState rur)
        {
            if (rur.button != null)
            {
                Controls.Remove(rur.button);
                rur.button.Dispose();
            }

            Outlines.Remove(rur);
        }
        public Outline Find(int rowstart, int rowend)
        {
            OutlineState rur = FindEntry(rowstart, rowend);

            if (rur != null)
            {
                rur.r.expanded = dgv.Rows[rowstart].Visible;
            }

            return(rur?.r);
        }
 // Add an set of outline areas, areas must be unique but can overlap
 public void Add(IEnumerable <Outline> outlinelist)
 {
     foreach (var e in outlinelist)
     {
         OutlineState rup = new OutlineState();
         rup.r = e;
         Outlines.Add(rup);
     }
     RollUpListChanged();
     UpdateOutlines();
 }
        public bool Remove(int rowstart, int rowend)        // remove an outline
        {
            OutlineState r = FindEntry(rowstart, rowend);

            if (r != null)
            {
                Remove(r);
                RollUpListChanged();
                UpdateOutlines();
                Invalidate();   // ensure in case we have gone to zero rollups
                return(true);
            }
            else
            {
                return(false);
            }
        }
        // Add/remove does not affect DGV - you need to do that yourself
        // areas must be unique
        // no update means you must call UpdateAfterAdd.
        public bool Add(int rowstart, int rowend, bool expandedout = true, bool noupdate = false)
        {
            if (FindEntry(rowstart, rowend) == null)
            {
                OutlineState rup = new OutlineState();
                rup.r = new Outline()
                {
                    start = rowstart, end = rowend, expanded = expandedout
                };
                Outlines.Add(rup);

                if (!noupdate)
                {
                    RollUpListChanged();
                    UpdateOutlines();
                }
                return(true);
            }
            else
            {
                return(false);
            }
        }
        private void Button_Click(object sender, EventArgs e)
        {
            ExtButtonDrawn but = sender as ExtButtonDrawn;
            OutlineState   rur = but.Tag as OutlineState;

            if (Parent is ExtPanelDataGridViewScroll)   // this implements an efficient visibility change system
            {
                rur.r.expanded = !rur.r.expanded;

                if (rur.r.expanded == false)       // off is easy - hide everything
                {
                    (Parent as ExtPanelDataGridViewScroll).ChangeVisibility(rur.r.start, rur.r.end - KeepLastEntriesVisibleOnRollUp, rur.r.expanded);
                }
                else
                {
                    BaseUtils.IntRangeList irl = new BaseUtils.IntRangeList();
                    irl.Add(rur.r.start, rur.r.end);
                    Vis(Outlines.IndexOf(rur), irl);         // remove visibility of any children marked hidden
                    irl.Sort();
                    (Parent as ExtPanelDataGridViewScroll).ChangeVisibility(rur.r.start, rur.r.end, irl);
                }
            }
        }
        public bool Remove(int rowstart, int rowend)        // remove it
        {
            OutlineState r = FindEntry(rowstart, rowend);

            if (r != null)
            {
                if (r.button != null)
                {
                    Controls.Remove(r.button);
                    r.button.Dispose();
                }

                Outlines.Remove(r);

                RollUpListChanged();
                UpdateOutlines();
                Invalidate();   // ensure in case we have gone to zero rollups
                return(true);
            }
            else
            {
                return(false);
            }
        }
 public bool Overlapped(OutlineState other)
 {
     return((r.start >= other.r.start && r.start <= other.r.end) || (r.end >= other.r.start && r.end <= other.r.end));
 }