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; }
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; }
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; }
public SplitPanelSizeInfo(SplitPanelSizeInfo source) { this.Copy(source); }