Example #1
0
        public override void SizeAllocate(Gdk.Rectangle newAlloc)
        {
            Gdk.Rectangle oldAlloc = Allocation;
            base.SizeAllocate(newAlloc);

            if (type == DockGroupType.Tabbed)
            {
                if (boundTabStrip != null)
                {
                    int tabsHeight = boundTabStrip.SizeRequest().Height;
                    boundTabStrip.SizeAllocate(new Gdk.Rectangle(newAlloc.X, newAlloc.Bottom - tabsHeight, newAlloc.Width, tabsHeight));
                }
                if (allocStatus == AllocStatus.Valid && newAlloc == oldAlloc)
                {
                    // Even if allocation has not changed, SizeAllocation has to be called on all items to avoid redrawing issues.
                    foreach (DockObject ob in VisibleObjects)
                    {
                        ob.SizeAllocate(ob.Allocation);
                    }
                    return;
                }
                if (VisibleObjects.Count > 1 && boundTabStrip != null)
                {
                    int tabsHeight = boundTabStrip.SizeRequest().Height;
                    newAlloc.Height -= tabsHeight;
                    boundTabStrip.QueueDraw();
                }
                else if (VisibleObjects.Count != 0)
                {
                    ((DockGroupItem)VisibleObjects [0]).Item.Widget.Show();
                }
                allocStatus = AllocStatus.Valid;
                foreach (DockObject ob in VisibleObjects)
                {
                    ob.Size = ob.PrefSize = -1;
                    ob.SizeAllocate(newAlloc);
                }
                return;
            }

            bool horiz = type == DockGroupType.Horizontal;
            int  pos   = horiz ? Allocation.Left : Allocation.Top;

            if (allocStatus == AllocStatus.Valid && newAlloc == oldAlloc)
            {
                // The layout of this group (as a whole) has not changed, but the layout
                // of child items may have changed. Assign the new sizes.

                if (CheckMinSizes())
                {
                    allocStatus = AllocStatus.NewSizeRequest;
                }
                else
                {
                    foreach (DockObject ob in VisibleObjects)
                    {
                        Gdk.Rectangle rect;
                        int           ins = ob.AllocSize;
                        if (horiz)
                        {
                            rect = new Gdk.Rectangle(pos, Allocation.Y, ins, Allocation.Height);
                        }
                        else
                        {
                            rect = new Gdk.Rectangle(Allocation.X, pos, Allocation.Width, ins);
                        }
                        ob.SizeAllocate(rect);
                        pos += ins + Frame.TotalHandleSize;
                    }
                    return;
                }
            }

            // This is the space available for the child items (excluding size
            // required for the resize handles)
            int realSize = GetRealSize(VisibleObjects);

            if (allocStatus == AllocStatus.NotSet /* || allocStatus == AllocStatus.RestorePending*/)
            {
                // It is the first size allocation. Calculate all sizes.
                CalcNewSizes();
            }
            else if (allocStatus != AllocStatus.NewSizeRequest)
            {
                // Available space has changed, so the size of the items must be changed.
                // First of all, get the change fraction
                double change;
                if (horiz)
                {
                    change = (double)newAlloc.Width / (double)oldAlloc.Width;
                }
                else
                {
                    change = (double)newAlloc.Height / (double)oldAlloc.Height;
                }

                // Get the old total size of the visible objects. Used to calculate the
                // proportion of size of each item.
                double tsize = 0;
                double rsize = 0;
                foreach (DockObject ob in VisibleObjects)
                {
                    tsize += ob.PrefSize;
                    rsize += ob.Size;
                }

                foreach (DockObject ob in dockObjects)
                {
                    if (ob.Visible)
                    {
                        // Proportionally spread the new available space among all visible objects
                        ob.Size = ob.PrefSize = (ob.PrefSize / tsize) * (double)realSize;
                    }
                    else
                    {
                        // For non-visible objects, change the size by the same grow fraction. In this
                        // way, when the item is shown again, it size will have the correct proportions.
                        ob.Size     = ob.Size * change;
                        ob.PrefSize = ob.PrefSize * change;
                    }
                    ob.DefaultSize = ob.DefaultSize * change;
                }
                CheckMinSizes();
            }

            allocStatus = AllocStatus.Valid;

            // Sizes for all items have been set.
            // Sizes are real numbers to ensure that the values are not degradated when resizing
            // pixel by pixel. Now those have to be converted to integers, that is, actual allocated sizes.

            int ts = 0;

            for (int n = 0; n < VisibleObjects.Count; n++)
            {
                DockObject ob = VisibleObjects [n];

                int ins = (int)Math.Truncate(ob.Size);

                if (n == VisibleObjects.Count - 1)
                {
                    ins = realSize - ts;
                }

                ts += ins;

                if (ins < 0)
                {
                    ins = 0;
                }

                ob.AllocSize = ins;

                if (horiz)
                {
                    ob.SizeAllocate(new Gdk.Rectangle(pos, Allocation.Y, ins, Allocation.Height));
                }
                else
                {
                    ob.SizeAllocate(new Gdk.Rectangle(Allocation.X, pos, Allocation.Width, ins));
                }

                pos += ins + Frame.TotalHandleSize;
            }
        }