private void ApplyLengthCorrection(
            List <SplitPanel> panels,
            int correction,
            float measuredLength)
        {
            int num1  = Math.Sign(correction);
            int val2  = correction;
            int index = 0;

            while (panels.Count > 0 && (num1 >= 0 || val2 < 0) && (num1 <= 0 || val2 > 0))
            {
                if (index > panels.Count - 1)
                {
                    index = 0;
                }
                SplitPanelSizeInfo sizeInfo = panels[index].SizeInfo;
                int val1      = (int)((double)((float)(sizeInfo.MeasuredLength - this.GetLength(sizeInfo.SplitterCorrection)) / measuredLength) * (double)correction + 0.5 * (double)num1);
                int num2      = num1 >= 0 ? Math.Max(1, Math.Min(val1, val2)) : Math.Min(-1, Math.Max(val1, val2));
                int num3      = sizeInfo.MeasuredLength + num2;
                int minLength = sizeInfo.minLength;
                if (num3 < minLength)
                {
                    num3 = minLength;
                    panels.RemoveAt(index--);
                }
                val2 += sizeInfo.MeasuredLength - num3;
                sizeInfo.MeasuredLength = num3;
                ++index;
            }
        }
        /// <summary>
        /// Updates the layout info for a pending layout operation.
        /// </summary>
        /// <param name="container"></param>
        protected virtual void UpdateLayoutInfo(RadSplitContainer container)
        {
            this.layoutInfo.contentRect     = container.ContentRectangle;
            this.layoutInfo.orientation     = container.Orientation;
            this.layoutInfo.availableLength = this.GetLength(this.layoutInfo.contentRect.Size);
            this.layoutInfo.autoSizeLength  = this.layoutInfo.availableLength;
            this.layoutInfo.splitterLength  = container.SplitterWidth;

            //collect layout targets
            int count = container.SplitPanels.Count;

            for (int i = 0; i < count; i++)
            {
                SplitPanel panel = container.SplitPanels[i];
                if (panel.Collapsed)
                {
                    continue;
                }

                this.layoutInfo.layoutTargets.Add(panel);

                SplitPanelSizeInfo sizeInfo = panel.SizeInfo;
                sizeInfo.minLength              = this.GetLength(this.GetMinimumSize(panel));
                this.layoutInfo.totalMinLength += sizeInfo.minLength;


                switch (sizeInfo.SizeMode)
                {
                case SplitPanelSizeMode.Absolute:
                    int length = this.GetLength(sizeInfo.AbsoluteSize);
                    if (length > 0)
                    {
                        this.layoutInfo.autoSizeLength -= length;
                        this.layoutInfo.absoluteSizeTargets.Add(panel);
                    }
                    else
                    {
                        this.layoutInfo.autoSizeTargets.Add(panel);
                    }
                    break;

                case SplitPanelSizeMode.Auto:
                case SplitPanelSizeMode.Relative:
                    this.layoutInfo.autoSizeTargets.Add(panel);
                    break;
                }
            }

            if (this.layoutInfo.layoutTargets.Count > 0)
            {
                this.layoutInfo.totalSplitterLength = (this.layoutInfo.layoutTargets.Count - 1) * this.layoutInfo.splitterLength;
            }

            if (this.layoutInfo.autoSizeTargets.Count > 0)
            {
                this.layoutInfo.autoSizeCountFactor = 1F / this.layoutInfo.autoSizeTargets.Count;
                this.layoutInfo.autoSizeLength     -= (this.layoutInfo.autoSizeTargets.Count - 1) * this.layoutInfo.splitterLength;
            }
        }
        /// <summary>
        /// Special measure logic, used when there is at least one fill panel in the layout info.
        /// </summary>
        private void MeasureWithFillPanel()
        {
            int        remaining = this.layoutInfo.availableLength;
            SplitPanel panel;

            //calculate the desired size of all non-fill panels
            int desiredNonFillLength = 0;

            int count = this.layoutInfo.layoutTargets.Count;

            for (int i = 0; i < count; i++)
            {
                panel = this.layoutInfo.layoutTargets[i];
                if (panel == this.layoutInfo.fillPanel)
                {
                    continue;
                }

                desiredNonFillLength += this.GetLength(panel.SizeInfo.AbsoluteSize);
            }

            SplitPanelSizeInfo fillInfo = this.layoutInfo.fillPanel.SizeInfo;
            //calculate the correction that needs to be applied
            int layoutableLength  = this.layoutInfo.availableLength - this.layoutInfo.totalSplitterLength;
            int correction        = 0;
            int desiredFillLength = fillInfo.minLength;

            if (desiredNonFillLength + desiredFillLength > layoutableLength)
            {
                correction = (desiredNonFillLength + desiredFillLength) - layoutableLength;
            }

            int remainingCorrection = correction;

            for (int i = 0; i < this.layoutInfo.layoutTargets.Count; i++)
            {
                panel = this.layoutInfo.layoutTargets[i];
                if (panel == this.layoutInfo.fillPanel)
                {
                    continue;
                }

                int length = this.GetLength(panel.SizeInfo.AbsoluteSize);
                if (remainingCorrection > 0 && panel.SizeInfo.SizeMode != SplitPanelSizeMode.Absolute)
                {
                    float factor          = (float)length / desiredNonFillLength;
                    int   panelCorrection = Math.Max(1, (int)(factor * correction));
                    remainingCorrection -= panelCorrection;
                    length -= panelCorrection;
                }

                panel.SizeInfo.measuredLength = length;
                remaining -= (panel.SizeInfo.measuredLength + this.layoutInfo.splitterLength);
            }

            //finally update fill panel
            this.layoutInfo.fillPanel.SizeInfo.measuredLength = remaining;
        }
        /// <summary>
        /// Applies a correction in both of the specified panels, after a successful spliter drag operation.
        /// </summary>
        /// <param name="left">The panel left (top) on the splitter.</param>
        /// <param name="right">The panel right (bottom) on the splitter.</param>
        /// <param name="dragLength">The dragged distance.</param>
        public virtual void ApplySplitterCorrection(SplitPanel left, SplitPanel right, int dragLength)
        {
            this.ApplySplitterCorrection(left, dragLength, true);
            this.ApplySplitterCorrection(right, dragLength, false);

            //update all panels' auto-size scale factor
            foreach (SplitPanel panel in this.layoutInfo.layoutTargets)
            {
                //left, right anf fill panels do not need update
                if (panel == left || panel == right || panel == layoutInfo.fillPanel)
                {
                    continue;
                }

                //only auto-sizable panels should be updated
                SplitPanelSizeInfo info = panel.SizeInfo;
                if (info.SizeMode != SplitPanelSizeMode.Auto)
                {
                    continue;
                }

                if (this.layoutInfo.fillPanel != null)
                {
                    Size absolute = panel.SizeInfo.AbsoluteSize;
                    switch (this.layoutInfo.orientation)
                    {
                    case Orientation.Horizontal:
                        absolute.Height = panel.Height;
                        break;

                    case Orientation.Vertical:
                        absolute.Width = panel.Width;
                        break;
                    }
                    info.AbsoluteSize = absolute;
                }
                else
                {
                    SizeF scale = info.AutoSizeScale;
                    float ratio;
                    switch (this.layoutInfo.Orientation)
                    {
                    case Orientation.Vertical:
                        ratio       = (float)panel.Width / this.layoutInfo.autoSizeLength;
                        scale.Width = ratio - this.layoutInfo.autoSizeCountFactor;
                        break;

                    case Orientation.Horizontal:
                        ratio        = (float)panel.Height / this.layoutInfo.autoSizeLength;
                        scale.Height = ratio - this.layoutInfo.autoSizeCountFactor;
                        break;
                    }
                    info.AutoSizeScale = scale;
                }
            }
        }
        private void ApplyLengthCorrection(List <SplitPanel> panels, int correction, float measuredLength)
        {
            int        sign = Math.Sign(correction);
            int        remainingCorrection = correction;
            int        counter             = 0;
            SplitPanel panel;

            while (panels.Count > 0)
            {
                if (sign < 0 && remainingCorrection >= 0)
                {
                    break;
                }
                if (sign > 0 && remainingCorrection <= 0)
                {
                    break;
                }
                if (counter > panels.Count - 1)
                {
                    counter = 0;
                }

                panel = panels[counter];
                SplitPanelSizeInfo info = panel.SizeInfo;

                float factor          = (info.measuredLength - this.GetLength(info.SplitterCorrection)) / measuredLength;
                int   panelCorrection = (int)(factor * correction + (.5F * sign));

                if (sign < 0)
                {
                    panelCorrection = Math.Max(panelCorrection, remainingCorrection);
                    panelCorrection = Math.Min(-1, panelCorrection);
                }
                else
                {
                    panelCorrection = Math.Min(panelCorrection, remainingCorrection);
                    panelCorrection = Math.Max(1, panelCorrection);
                }

                int finalLength = info.measuredLength + panelCorrection;
                int minLength   = info.minLength;
                if (finalLength < minLength)
                {
                    finalLength = minLength;
                    panels.RemoveAt(counter--);
                }

                remainingCorrection += (info.measuredLength - finalLength);
                info.measuredLength  = finalLength;

                counter++;
            }
        }
        protected virtual void UpdateLayoutInfo(RadSplitContainer container)
        {
            this.layoutInfo.contentRect     = container.ContentRectangle;
            this.layoutInfo.orientation     = container.Orientation;
            this.layoutInfo.availableLength = this.GetLength(this.layoutInfo.contentRect.Size);
            this.layoutInfo.autoSizeLength  = this.layoutInfo.availableLength;
            this.layoutInfo.splitterLength  = container.SplitterWidth;
            int count = container.SplitPanels.Count;

            for (int index = 0; index < count; ++index)
            {
                SplitPanel splitPanel = container.SplitPanels[index];
                if (!splitPanel.Collapsed)
                {
                    this.layoutInfo.layoutTargets.Add(splitPanel);
                    SplitPanelSizeInfo sizeInfo = splitPanel.SizeInfo;
                    sizeInfo.minLength              = this.GetLength(this.GetMinimumSize(splitPanel));
                    this.layoutInfo.totalMinLength += sizeInfo.minLength;
                    switch (sizeInfo.SizeMode)
                    {
                    case SplitPanelSizeMode.Auto:
                    case SplitPanelSizeMode.Relative:
                        this.layoutInfo.autoSizeTargets.Add(splitPanel);
                        continue;

                    case SplitPanelSizeMode.Absolute:
                        int length = this.GetLength(sizeInfo.AbsoluteSize);
                        if (length > 0)
                        {
                            this.layoutInfo.autoSizeLength -= length;
                            this.layoutInfo.absoluteSizeTargets.Add(splitPanel);
                            continue;
                        }
                        this.layoutInfo.autoSizeTargets.Add(splitPanel);
                        continue;

                    default:
                        continue;
                    }
                }
            }
            if (this.layoutInfo.layoutTargets.Count > 0)
            {
                this.layoutInfo.totalSplitterLength = (this.layoutInfo.layoutTargets.Count - 1) * this.layoutInfo.splitterLength;
            }
            if (this.layoutInfo.autoSizeTargets.Count <= 0)
            {
                return;
            }
            this.layoutInfo.autoSizeCountFactor = 1f / (float)this.layoutInfo.autoSizeTargets.Count;
            this.layoutInfo.autoSizeLength     -= (this.layoutInfo.autoSizeTargets.Count - 1) * this.layoutInfo.splitterLength;
        }
Пример #7
0
 public void Copy(SplitPanelSizeInfo source)
 {
     this.relativeRatio      = source.relativeRatio;
     this.absoluteSize       = source.absoluteSize;
     this.splitterCorrection = source.splitterCorrection;
     this.autoSizeScale      = source.autoSizeScale;
     this.minimumSize        = source.minimumSize;
     if (source.sizeMode == SplitPanelSizeMode.Fill || this.sizeMode == SplitPanelSizeMode.Fill)
     {
         return;
     }
     this.sizeMode = source.sizeMode;
 }
Пример #8
0
        public void Copy(SplitPanelSizeInfo source)
        {
            this.relativeRatio      = source.relativeRatio;
            this.absoluteSize       = source.absoluteSize;
            this.splitterCorrection = source.splitterCorrection;
            this.autoSizeScale      = source.autoSizeScale;
            this.minimumSize        = source.minimumSize;

            //fill is special mode and does not need to be copied when splittig layout
            if (source.sizeMode != SplitPanelSizeMode.Fill &&
                this.sizeMode != SplitPanelSizeMode.Fill)
            {
                this.sizeMode = source.sizeMode;
            }
        }
        public virtual void ApplySplitterCorrection(SplitPanel left, SplitPanel right, int dragLength)
        {
            this.ApplySplitterCorrection(left, dragLength, true);
            this.ApplySplitterCorrection(right, dragLength, false);
            foreach (SplitPanel layoutTarget in this.layoutInfo.layoutTargets)
            {
                if (layoutTarget != left && layoutTarget != right && layoutTarget != this.layoutInfo.fillPanel)
                {
                    SplitPanelSizeInfo sizeInfo = layoutTarget.SizeInfo;
                    if (sizeInfo.SizeMode == SplitPanelSizeMode.Auto)
                    {
                        if (this.layoutInfo.fillPanel != null)
                        {
                            Size absoluteSize = layoutTarget.SizeInfo.AbsoluteSize;
                            switch (this.layoutInfo.orientation)
                            {
                            case Orientation.Horizontal:
                                absoluteSize.Height = layoutTarget.Height;
                                break;

                            case Orientation.Vertical:
                                absoluteSize.Width = layoutTarget.Width;
                                break;
                            }
                            sizeInfo.AbsoluteSize = absoluteSize;
                        }
                        else
                        {
                            SizeF autoSizeScale = sizeInfo.AutoSizeScale;
                            switch (this.layoutInfo.Orientation)
                            {
                            case Orientation.Horizontal:
                                float num1 = (float)layoutTarget.Height / (float)this.layoutInfo.autoSizeLength;
                                autoSizeScale.Height = num1 - this.layoutInfo.autoSizeCountFactor;
                                break;

                            case Orientation.Vertical:
                                float num2 = (float)layoutTarget.Width / (float)this.layoutInfo.autoSizeLength;
                                autoSizeScale.Width = num2 - this.layoutInfo.autoSizeCountFactor;
                                break;
                            }
                            sizeInfo.AutoSizeScale = autoSizeScale;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Performs the core layout logic. Updates each panel's bounds, keeping in mind restrictions like Minimum and Maximum size.
        /// </summary>
        /// <param name="container"></param>
        protected virtual void Layout(RadSplitContainer container)
        {
            SplitPanel panel;
            Rectangle  panelBounds;
            Rectangle  splitterBounds;

            int length    = 0;
            int offset    = this.GetLayoutOffset();
            int remaining = this.layoutInfo.availableLength;

            int count = this.layoutInfo.LayoutTargets.Count;

            for (int i = 0; i < count; i++)
            {
                panel = this.layoutInfo.LayoutTargets[i];
                SplitPanelSizeInfo sizeInfo = panel.SizeInfo;
                length = sizeInfo.measuredLength;
                if (i == count - 1)
                {
                    length = remaining;
                }

                switch (this.layoutInfo.Orientation)
                {
                case Orientation.Vertical:
                    panelBounds    = new Rectangle(offset, this.layoutInfo.contentRect.Top, length, this.layoutInfo.contentRect.Height);
                    splitterBounds = new Rectangle(panelBounds.Left - this.layoutInfo.splitterLength, panelBounds.Top, this.layoutInfo.splitterLength, panelBounds.Height);
                    break;

                default:
                    panelBounds    = new Rectangle(this.layoutInfo.contentRect.Left, offset, this.layoutInfo.contentRect.Width, length);
                    splitterBounds = new Rectangle(panelBounds.Left, panelBounds.Top - this.layoutInfo.splitterLength, panelBounds.Width, this.layoutInfo.splitterLength);
                    break;
                }

                panel.Bounds = panelBounds;
                offset      += (length + this.layoutInfo.splitterLength);
                remaining   -= (length + this.layoutInfo.splitterLength);

                if (i > 0)
                {
                    container.UpdateSplitter(this.layoutInfo, i, splitterBounds);
                }
            }
        }
        private void MeasureWithFillPanel()
        {
            int availableLength = this.layoutInfo.availableLength;
            int num1            = 0;
            int count           = this.layoutInfo.layoutTargets.Count;

            for (int index = 0; index < count; ++index)
            {
                SplitPanel layoutTarget = this.layoutInfo.layoutTargets[index];
                if (layoutTarget != this.layoutInfo.fillPanel)
                {
                    num1 += this.GetLength(layoutTarget.SizeInfo.AbsoluteSize);
                }
            }
            SplitPanelSizeInfo sizeInfo = this.layoutInfo.fillPanel.SizeInfo;
            int num2      = this.layoutInfo.availableLength - this.layoutInfo.totalSplitterLength;
            int num3      = 0;
            int minLength = sizeInfo.minLength;

            if (num1 + minLength > num2)
            {
                num3 = num1 + minLength - num2;
            }
            int num4 = num3;

            for (int index = 0; index < this.layoutInfo.layoutTargets.Count; ++index)
            {
                SplitPanel layoutTarget = this.layoutInfo.layoutTargets[index];
                if (layoutTarget != this.layoutInfo.fillPanel)
                {
                    int length = this.GetLength(TelerikDpiHelper.ScaleSize(layoutTarget.SizeInfo.AbsoluteSize, new SizeF(1f / layoutTarget.SplitPanelElement.DpiScaleFactor.Width, 1f / layoutTarget.SplitPanelElement.DpiScaleFactor.Height)));
                    if (num4 > 0 && layoutTarget.SizeInfo.SizeMode != SplitPanelSizeMode.Absolute)
                    {
                        int num5 = Math.Max(1, (int)((double)((float)length / (float)num1) * (double)num3));
                        num4   -= num5;
                        length -= num5;
                    }
                    layoutTarget.SizeInfo.MeasuredLength = length;
                    availableLength -= layoutTarget.SizeInfo.MeasuredLength + this.layoutInfo.splitterLength;
                }
            }
            this.layoutInfo.fillPanel.SizeInfo.MeasuredLength = availableLength;
        }
Пример #12
0
 public SplitPanelSizeInfo(SplitPanelSizeInfo source)
 {
     this.Copy(source);
 }