394 lines
19 KiB
C#
394 lines
19 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Drawing;
|
|
using DevComponents.DotNetBar;
|
|
|
|
namespace DevComponents.AdvTree.Layout
|
|
{
|
|
internal class CellTileLayout : CellLayout
|
|
{
|
|
/// <summary>
|
|
/// Initializes a new instance of the CellTileLayout class.
|
|
/// </summary>
|
|
public CellTileLayout(LayoutSettings layoutSettings) : base(layoutSettings)
|
|
{
|
|
|
|
}
|
|
public override Size LayoutCells(NodeLayoutContextInfo layoutInfo, int x, int y)
|
|
{
|
|
eCellLayout layout = layoutInfo.CellLayout;
|
|
if (layoutInfo.ContextNode.CellLayout != layoutInfo.CellLayout && layoutInfo.ContextNode.CellLayout != eCellLayout.Default)
|
|
layout = layoutInfo.ContextNode.CellLayout;
|
|
if (layout == eCellLayout.Default && !(layoutInfo.ContextNode.HasChildNodes && layoutInfo.IsViewGroupping) && layoutInfo.ContextNode.ImageAlignment == eCellPartAlignment.Default)
|
|
{
|
|
return TileLayout(layoutInfo, x, y);
|
|
}
|
|
else
|
|
return base.LayoutCells(layoutInfo, x, y);
|
|
|
|
}
|
|
private Size TileLayout(NodeLayoutContextInfo layoutInfo, int x, int y)
|
|
{
|
|
Node node = layoutInfo.ContextNode;
|
|
int height = 0, width = 0, realHeight = 0;
|
|
//eHorizontalAlign align = eHorizontalAlign.Left;
|
|
Size tileSize = layoutInfo.TileSize;
|
|
int iVisibleCells = 0;
|
|
int cellCount = node.Cells.Count;
|
|
bool isVerticalOverflow = false;
|
|
for (int i = 0; i < cellCount; i++)
|
|
{
|
|
Cell cell = node.Cells[i];
|
|
|
|
bool bCellVisible = isVerticalOverflow ? false : true;
|
|
|
|
// Setup cell layout helper class
|
|
LayoutCellInfo cellLayout = this.GetLayoutCellInfo();
|
|
cellLayout.Top = y;
|
|
cellLayout.Left = x;
|
|
cellLayout.CellWidth = tileSize.Width;
|
|
cellLayout.ContextCell = cell;
|
|
cellLayout.Graphics = layoutInfo.Graphics;
|
|
cellLayout.LeftToRight = layoutInfo.LeftToRight;
|
|
cellLayout.Font = layoutInfo.DefaultFont;
|
|
cellLayout.View = layoutInfo.View;
|
|
cellLayout.CellIndex = i;
|
|
if (cell.Layout != eCellPartLayout.Default)
|
|
cellLayout.VerticalPartAlignment = (cell.Layout == eCellPartLayout.Vertical);
|
|
else if (layoutInfo.CellPartLayout != eCellPartLayout.Default)
|
|
cellLayout.VerticalPartAlignment = (layoutInfo.CellPartLayout == eCellPartLayout.Vertical);
|
|
|
|
// Prepare union style
|
|
if (cell.StyleNormal != null)
|
|
cellLayout.LayoutStyle = cell.StyleNormal;
|
|
else
|
|
cellLayout.LayoutStyle = layoutInfo.DefaultCellStyle;
|
|
|
|
this.LayoutSingleTileCell(cellLayout);
|
|
if (bCellVisible && y + cell.BoundsRelative.Height > tileSize.Height && i > 0)
|
|
{
|
|
isVerticalOverflow = true;
|
|
bCellVisible = false;
|
|
}
|
|
cell.SetVisible(bCellVisible);
|
|
|
|
if (bCellVisible)
|
|
{
|
|
iVisibleCells++;
|
|
y += cell.BoundsRelative.Height;
|
|
height += cell.BoundsRelative.Height;
|
|
if (cell.BoundsRelative.Height > 0)
|
|
{
|
|
y += this.CellVerticalSpacing;
|
|
height += this.CellVerticalSpacing;
|
|
}
|
|
if (cell.BoundsRelative.Width > width)
|
|
width = cell.BoundsRelative.Width;
|
|
if (i == 0)
|
|
{
|
|
realHeight += cell.BoundsRelative.Height;
|
|
if (cell.BoundsRelative.Height > 0)
|
|
realHeight += this.CellVerticalSpacing;
|
|
}
|
|
else
|
|
realHeight = Math.Max(realHeight, height);
|
|
|
|
// Align other cells under the text of the first cell and to the right of the image, if any
|
|
if (i == 0 && !cell.Images.LargestImageSize.IsEmpty && cellCount > 1)
|
|
{
|
|
Size largestImageSize = Dpi.ImageSize(cell.Images.LargestImageSize);
|
|
if (cell.TextContentBounds.IsEmpty)
|
|
x += largestImageSize.Width + this.ImageTextSpacing;
|
|
else
|
|
x += (cell.TextContentBounds.X - x);
|
|
tileSize.Width = cell.TextContentBounds.Width;
|
|
height -= cell.BoundsRelative.Height;
|
|
height += cell.TextContentBounds.Height;
|
|
y -= cell.BoundsRelative.Height;
|
|
y += cell.TextContentBounds.Height;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Take last added spacing off
|
|
y -= this.CellVerticalSpacing;
|
|
height -= this.CellVerticalSpacing;
|
|
realHeight -= this.CellVerticalSpacing;
|
|
|
|
if (node.Cells[0].BoundsRelative.Height > height && !node.Cells[0].Images.LargestImageSize.IsEmpty)
|
|
{
|
|
int textOffset = ((realHeight - height) / iVisibleCells) / 2;
|
|
if (textOffset > 0)
|
|
{
|
|
foreach (Cell cell in node.Cells)
|
|
{
|
|
if (!cell.IsVisible) continue;
|
|
cell.TextContentBounds = new Rectangle(cell.TextContentBounds.X, cell.TextContentBounds.Y + textOffset, cell.TextContentBounds.Width, cell.TextContentBounds.Height);
|
|
}
|
|
}
|
|
}
|
|
else if(iVisibleCells == 1)
|
|
{
|
|
Rectangle rtc = node.Cells[0].TextContentBounds;
|
|
node.Cells[0].TextContentBounds = new Rectangle(rtc.X, rtc.Y, rtc.Width, node.Cells[0].BoundsRelative.Height);
|
|
}
|
|
|
|
// Additional pass needed if horizontal alignment is other than left and there is more than one cell visible
|
|
//if (align != eHorizontalAlign.Left && iVisibleCells > 1)
|
|
//{
|
|
// foreach (Cell cell in node.Cells)
|
|
// {
|
|
// if (!cell.IsVisible)
|
|
// continue;
|
|
// if (align == eHorizontalAlign.Center)
|
|
// this.Offset(cell, (width - cell.BoundsRelative.Width) / 2, 0);
|
|
// else // Right aligned cells
|
|
// this.Offset(cell, width - cell.BoundsRelative.Width, 0);
|
|
// }
|
|
//}
|
|
if (width < layoutInfo.TileSize.Width)
|
|
width = layoutInfo.TileSize.Width;
|
|
if (realHeight < layoutInfo.TileSize.Height)
|
|
realHeight = layoutInfo.TileSize.Height;
|
|
return new Size(width, realHeight);
|
|
}
|
|
|
|
protected virtual void LayoutSingleTileCell(LayoutCellInfo info)
|
|
{
|
|
Size textSize = Size.Empty;
|
|
Font font = info.Font;
|
|
int fontHeight = info.FontHeight;
|
|
int height = 0;
|
|
if (info.LayoutStyle.Font != null)
|
|
{
|
|
font = info.LayoutStyle.Font;
|
|
fontHeight = font.Height;
|
|
}
|
|
|
|
info.ContextCell.OnLayoutCell();
|
|
|
|
Size largestImageSize = info.ContextCell.Images.LargestImageSize;
|
|
if (largestImageSize.IsEmpty && HasImage(info.ContextCell))
|
|
info.ContextCell.Images.RefreshLargestImageSize();
|
|
largestImageSize = Dpi.ImageSize(info.ContextCell.Images.LargestImageSize);
|
|
|
|
if (info.ContextCell.HostedControl != null)
|
|
{
|
|
Size controlSize = info.ContextCell.HostedControl.Size;
|
|
if (!info.ContextCell.HostedControlSize.IsEmpty)
|
|
controlSize = info.ContextCell.HostedControlSize;
|
|
if (info.CellWidth == 0)
|
|
textSize = new Size(controlSize.Width, controlSize.Height);
|
|
else
|
|
{
|
|
int availTextWidth = info.CellWidth -
|
|
ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
|
|
textSize = new Size(availTextWidth, controlSize.Height);
|
|
}
|
|
}
|
|
else if (info.ContextCell.HostedItem != null)
|
|
{
|
|
if (info.CellWidth != 0) info.ContextCell.HostedItem.WidthInternal = info.CellWidth;
|
|
info.ContextCell.HostedItem.RecalcSize();
|
|
|
|
Size controlSize = info.ContextCell.HostedItem.Size;
|
|
if (info.CellWidth == 0)
|
|
textSize = new Size(controlSize.Width, controlSize.Height);
|
|
else
|
|
{
|
|
int availTextWidth = info.CellWidth -
|
|
ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
|
|
textSize = new Size(availTextWidth, controlSize.Height);
|
|
info.ContextCell.HostedItem.WidthInternal = availTextWidth;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Calculate Text Width and Height
|
|
if (info.CellWidth == 0)
|
|
{
|
|
if (info.ContextCell.TextMarkupBody == null)
|
|
{
|
|
string text = info.ContextCell.DisplayText;
|
|
if (text != "")
|
|
{
|
|
if (info.LayoutStyle.WordWrap && info.LayoutStyle.MaximumWidth > 0)
|
|
textSize = TextDrawing.MeasureString(info.Graphics, text, font, info.LayoutStyle.MaximumWidth);
|
|
else if (info.ContextCell.Parent != null && info.ContextCell.Parent.Style != null && info.ContextCell.Parent.Style.WordWrap && info.ContextCell.Parent.Style.MaximumWidth > 0)
|
|
textSize = TextDrawing.MeasureString(info.Graphics, text, font, info.ContextCell.Parent.Style.MaximumWidth);
|
|
else
|
|
textSize = TextDrawing.MeasureString(info.Graphics, text, font, 0, eTextFormat.Left | eTextFormat.LeftAndRightPadding | eTextFormat.GlyphOverhangPadding | eTextFormat.NoPrefix);
|
|
#if (FRAMEWORK20)
|
|
if (!BarFunctions.IsVista && BarUtilities.UseTextRenderer) textSize.Width += 4;
|
|
#endif
|
|
}
|
|
else if (largestImageSize.IsEmpty && !info.ContextCell.CheckBoxVisible)
|
|
{
|
|
textSize = new Size(5, fontHeight);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Size availSize = new Size(1600, 1);
|
|
if (info.LayoutStyle.WordWrap && info.LayoutStyle.MaximumWidth > 0)
|
|
availSize.Width = info.LayoutStyle.MaximumWidth;
|
|
else if (info.ContextCell.Parent != null && info.ContextCell.Parent.Style != null && info.ContextCell.Parent.Style.WordWrap && info.ContextCell.Parent.Style.MaximumWidth > 0)
|
|
availSize.Width = info.ContextCell.Parent.Style.MaximumWidth;
|
|
|
|
DevComponents.DotNetBar.TextMarkup.MarkupDrawContext d = new DevComponents.DotNetBar.TextMarkup.MarkupDrawContext(info.Graphics, font, Color.Empty, false);
|
|
info.ContextCell.TextMarkupBody.Measure(availSize, d);
|
|
availSize = info.ContextCell.TextMarkupBody.Bounds.Size;
|
|
d.RightToLeft = !info.LeftToRight;
|
|
info.ContextCell.TextMarkupBody.Arrange(new Rectangle(0, 0, availSize.Width, availSize.Height), d);
|
|
|
|
textSize = info.ContextCell.TextMarkupBody.Bounds.Size;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int availTextWidth = info.CellWidth -
|
|
ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
|
|
|
|
availTextWidth -= largestImageSize.Width +
|
|
(largestImageSize.Width > 0 ? ImageTextSpacing * 2 : 0);
|
|
|
|
if (info.ContextCell.CheckBoxVisible)
|
|
availTextWidth -= CheckBoxSize.Width + ImageTextSpacing * 2;
|
|
|
|
int cellHeight = fontHeight;
|
|
|
|
if (info.LayoutStyle.WordWrap || info.ContextCell.TextMarkupBody != null)
|
|
{
|
|
cellHeight = info.LayoutStyle.MaximumHeight - info.LayoutStyle.MarginTop -
|
|
info.LayoutStyle.MarginBottom - info.LayoutStyle.PaddingTop - info.LayoutStyle.PaddingBottom;
|
|
|
|
if (info.ContextCell.TextMarkupBody == null)
|
|
{
|
|
if (availTextWidth > 0)
|
|
{
|
|
if (cellHeight > 0)
|
|
textSize = TextDrawing.MeasureString(info.Graphics, info.ContextCell.DisplayText, font, new Size(availTextWidth, cellHeight), info.LayoutStyle.TextFormat);
|
|
else
|
|
textSize = TextDrawing.MeasureString(info.Graphics, info.ContextCell.DisplayText, font, availTextWidth, info.LayoutStyle.TextFormat);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Size availSize = new Size(availTextWidth, 1);
|
|
DevComponents.DotNetBar.TextMarkup.MarkupDrawContext d = new DevComponents.DotNetBar.TextMarkup.MarkupDrawContext(info.Graphics, font, Color.Empty, false);
|
|
info.ContextCell.TextMarkupBody.Measure(availSize, d);
|
|
availSize = info.ContextCell.TextMarkupBody.Bounds.Size;
|
|
availSize.Width = availTextWidth;
|
|
d.RightToLeft = !info.LeftToRight;
|
|
info.ContextCell.TextMarkupBody.Arrange(new Rectangle(0, 0, availSize.Width, availSize.Height), d);
|
|
|
|
textSize = info.ContextCell.TextMarkupBody.Bounds.Size;
|
|
}
|
|
}
|
|
else
|
|
textSize = new Size(availTextWidth, cellHeight);
|
|
}
|
|
}
|
|
|
|
if (info.LayoutStyle.WordWrap)
|
|
info.ContextCell.WordWrap = true;
|
|
else
|
|
info.ContextCell.WordWrap = false;
|
|
|
|
height = (int)Math.Max(height, Math.Ceiling((double)textSize.Height));
|
|
if (info.VerticalPartAlignment)
|
|
{
|
|
if (largestImageSize.Height > 0)
|
|
height += largestImageSize.Height + this.ImageTextSpacing;
|
|
if (info.ContextCell.CheckBoxVisible)
|
|
height += CheckBoxSize.Height + this.ImageCheckBoxSpacing;
|
|
}
|
|
else
|
|
{
|
|
if (largestImageSize.Height > height)
|
|
height = largestImageSize.Height;
|
|
if (info.ContextCell.CheckBoxVisible && CheckBoxSize.Height > height)
|
|
height = CheckBoxSize.Height;
|
|
}
|
|
|
|
Rectangle r = new Rectangle(info.Left + ElementStyleLayout.LeftWhiteSpace(info.LayoutStyle),
|
|
info.Top + ElementStyleLayout.TopWhiteSpace(info.LayoutStyle)
|
|
, info.CellWidth, height);
|
|
|
|
if (r.Width == 0)
|
|
{
|
|
if (info.VerticalPartAlignment)
|
|
{
|
|
r.Width = (int)Math.Ceiling((double)textSize.Width);
|
|
if (largestImageSize.Width > r.Width)
|
|
r.Width = (largestImageSize.Width + this.ImageTextSpacing);
|
|
if (info.ContextCell.CheckBoxVisible && CheckBoxSize.Width > r.Width)
|
|
r.Width += (CheckBoxSize.Width + this.ImageTextSpacing);
|
|
}
|
|
else
|
|
{
|
|
r.Width = (int)Math.Ceiling((double)textSize.Width);
|
|
if (largestImageSize.Width > 0)
|
|
r.Width += (largestImageSize.Width + this.ImageTextSpacing);
|
|
if (info.ContextCell.CheckBoxVisible)
|
|
r.Width += (CheckBoxSize.Width + this.ImageTextSpacing);
|
|
}
|
|
}
|
|
|
|
// Now that we have cell bounds store them
|
|
Rectangle rCellBounds = new Rectangle(info.Left, info.Top, info.CellWidth, r.Height + info.LayoutStyle.MarginTop + info.LayoutStyle.MarginBottom + info.LayoutStyle.PaddingTop + info.LayoutStyle.PaddingBottom);
|
|
if (rCellBounds.Width == 0)
|
|
rCellBounds.Width = r.Width + ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
|
|
info.ContextCell.SetBounds(rCellBounds);
|
|
|
|
// Set position of the check box
|
|
if (info.ContextCell.CheckBoxVisible && rCellBounds.Width >= this.CheckBoxSize.Width)
|
|
{
|
|
eVerticalAlign va = GetCheckBoxVerticalAlign(info.ContextCell.CheckBoxAlignment, info.View);
|
|
eHorizontalAlign ha = GetCheckBoxHorizontalAlign(info.ContextCell.CheckBoxAlignment, info.LeftToRight, info.View);
|
|
if (ha == eHorizontalAlign.Center && (!string.IsNullOrEmpty(info.ContextCell.Text) || !largestImageSize.IsEmpty))
|
|
ha = eHorizontalAlign.Left;
|
|
|
|
if (info.VerticalPartAlignment)
|
|
info.ContextCell.SetCheckBoxBounds(AlignContentVertical(this.CheckBoxSize, ref r, ha, va, this.ImageTextSpacing));
|
|
else
|
|
info.ContextCell.SetCheckBoxBounds(AlignContent(this.CheckBoxSize, ref r, ha, va, this.ImageTextSpacing));
|
|
}
|
|
else
|
|
info.ContextCell.SetCheckBoxBounds(Rectangle.Empty);
|
|
|
|
// Set Position of the image
|
|
if (!largestImageSize.IsEmpty && rCellBounds.Width >= largestImageSize.Width)
|
|
{
|
|
eVerticalAlign va = GetVerticalAlign(info.ContextCell.ImageAlignment, info.View);
|
|
eHorizontalAlign ha = GetHorizontalAlign(info.ContextCell.ImageAlignment, info.LeftToRight, info.View);
|
|
if (ha == eHorizontalAlign.Center && (!string.IsNullOrEmpty(info.ContextCell.Text) || info.ContextCell.CheckBoxVisible))
|
|
ha = eHorizontalAlign.Left;
|
|
|
|
if (info.VerticalPartAlignment)
|
|
info.ContextCell.SetImageBounds(AlignContentVertical(largestImageSize, ref r, ha, va, this.ImageTextSpacing));
|
|
else
|
|
info.ContextCell.SetImageBounds(AlignContent(largestImageSize, ref r, ha, va, this.ImageTextSpacing));
|
|
}
|
|
else
|
|
info.ContextCell.SetImageBounds(Rectangle.Empty);
|
|
|
|
// Set position of the text
|
|
//info.ContextCell.SetTextBounds(Rectangle.Empty);
|
|
if (!textSize.IsEmpty)
|
|
{
|
|
if (info.CellWidth > 0)
|
|
r.Width -= 2;
|
|
if (info.View == eView.Tile && info.CellIndex == 0)
|
|
info.ContextCell.TextContentBounds = new Rectangle(r.X, r.Y, textSize.Width, textSize.Height + 1);
|
|
else
|
|
info.ContextCell.TextContentBounds = r;
|
|
}
|
|
else
|
|
info.ContextCell.TextContentBounds = Rectangle.Empty;
|
|
|
|
}
|
|
}
|
|
}
|