DotNet 4.8.1 build of DotNetBar
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
using System.Collections;
|
||||
using System.Drawing;
|
||||
|
||||
#if AdvTree
|
||||
namespace DevComponents.Tree.TextMarkup
|
||||
#elif DOTNETBAR
|
||||
namespace DevComponents.UI.ContentManager
|
||||
#elif SUPERGRID
|
||||
namespace DevComponents.SuperGrid.TextMarkup
|
||||
#elif LAYOUT
|
||||
namespace DevComponents.DotNetBar.Layout.TextMarkup
|
||||
#endif
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents block layout manager responsible for sizing the content blocks.
|
||||
/// </summary>
|
||||
public abstract class BlockLayoutManager
|
||||
{
|
||||
private Graphics m_Graphics;
|
||||
|
||||
/// <summary>
|
||||
/// Resizes the content block and sets it's Bounds property to reflect new size.
|
||||
/// </summary>
|
||||
/// <param name="block">Content block to resize.</param>
|
||||
/// <param name="availableSize">Content size available for the block in the given line.</param>
|
||||
public abstract void Layout(IBlock block, Size availableSize);
|
||||
|
||||
/// <summary>
|
||||
/// Performs layout finalization
|
||||
/// </summary>
|
||||
/// <param name="containerBounds"></param>
|
||||
/// <param name="blocksBounds"></param>
|
||||
/// <param name="lines"></param>
|
||||
/// <returns></returns>
|
||||
public abstract Rectangle FinalizeLayout(Rectangle containerBounds, Rectangle blocksBounds, ArrayList lines);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the graphics object used by layout manager.
|
||||
/// </summary>
|
||||
public System.Drawing.Graphics Graphics
|
||||
{
|
||||
get {return m_Graphics;}
|
||||
set {m_Graphics=value;}
|
||||
}
|
||||
}
|
||||
}
|
66
PROMS/DotNetBar Source Code/ContentManager/Enums.cs
Normal file
66
PROMS/DotNetBar Source Code/ContentManager/Enums.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
|
||||
#if AdvTree
|
||||
namespace DevComponents.Tree.TextMarkup
|
||||
#elif DOTNETBAR
|
||||
namespace DevComponents.UI.ContentManager
|
||||
#elif SUPERGRID
|
||||
namespace DevComponents.SuperGrid.TextMarkup
|
||||
#elif LAYOUT
|
||||
namespace DevComponents.DotNetBar.Layout.TextMarkup
|
||||
#endif
|
||||
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies orientation of content.
|
||||
/// </summary>
|
||||
public enum eContentOrientation
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates Horizontal orientation of the content.
|
||||
/// </summary>
|
||||
Horizontal,
|
||||
/// <summary>
|
||||
/// Indicates Vertical orientation of the content.
|
||||
/// </summary>
|
||||
Vertical
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies content horizontal alignment.
|
||||
/// </summary>
|
||||
public enum eContentAlignment
|
||||
{
|
||||
/// <summary>
|
||||
/// Content is left aligned.UI
|
||||
/// </summary>
|
||||
Left,
|
||||
/// <summary>
|
||||
/// Content is right aligned.
|
||||
/// </summary>
|
||||
Right,
|
||||
/// <summary>
|
||||
/// Content is centered.
|
||||
/// </summary>
|
||||
Center
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies content vertical alignment.
|
||||
/// </summary>
|
||||
public enum eContentVerticalAlignment
|
||||
{
|
||||
/// <summary>
|
||||
/// Content is top aligned.
|
||||
/// </summary>
|
||||
Top,
|
||||
/// <summary>
|
||||
/// Content is bottom aligned.
|
||||
/// </summary>
|
||||
Bottom,
|
||||
/// <summary>
|
||||
/// Content is in the middle.
|
||||
/// </summary>
|
||||
Middle
|
||||
}
|
||||
}
|
34
PROMS/DotNetBar Source Code/ContentManager/IBlock.cs
Normal file
34
PROMS/DotNetBar Source Code/ContentManager/IBlock.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using DevComponents.DotNetBar;
|
||||
|
||||
#if AdvTree
|
||||
namespace DevComponents.Tree.TextMarkup
|
||||
#elif DOTNETBAR
|
||||
namespace DevComponents.UI.ContentManager
|
||||
#elif SUPERGRID
|
||||
namespace DevComponents.SuperGrid.TextMarkup
|
||||
#elif LAYOUT
|
||||
namespace DevComponents.DotNetBar.Layout.TextMarkup
|
||||
#endif
|
||||
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a content block interface.
|
||||
/// </summary>
|
||||
public interface IBlock
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the bounds of the content block.
|
||||
/// </summary>
|
||||
Rectangle Bounds {get;set;}
|
||||
/// <summary>
|
||||
/// Gets or sets whether content block is visible.
|
||||
/// </summary>
|
||||
bool Visible {get;set;}
|
||||
/// <summary>
|
||||
/// Gets or sets the block margins.
|
||||
/// </summary>
|
||||
DevComponents.DotNetBar.Padding Margin { get;set;}
|
||||
}
|
||||
}
|
28
PROMS/DotNetBar Source Code/ContentManager/IBlockExtended.cs
Normal file
28
PROMS/DotNetBar Source Code/ContentManager/IBlockExtended.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
#if AdvTree
|
||||
namespace DevComponents.Tree.TextMarkup
|
||||
#elif DOTNETBAR
|
||||
namespace DevComponents.UI.ContentManager
|
||||
#elif SUPERGRID
|
||||
namespace DevComponents.SuperGrid.TextMarkup
|
||||
#elif LAYOUT
|
||||
namespace DevComponents.DotNetBar.Layout.TextMarkup
|
||||
#endif
|
||||
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a extended content block interface for advanced layout information.
|
||||
/// </summary>
|
||||
public interface IBlockExtended : IBlock
|
||||
{
|
||||
bool IsBlockElement { get;}
|
||||
bool IsNewLineAfterElement { get;}
|
||||
bool CanStartNewLine { get; }
|
||||
/// <summary>
|
||||
/// Returns whether element is an container so it receives full available size of parent control for layout.
|
||||
/// </summary>
|
||||
bool IsBlockContainer { get; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
#if AdvTree
|
||||
namespace DevComponents.Tree.TextMarkup
|
||||
#elif DOTNETBAR
|
||||
namespace DevComponents.UI.ContentManager
|
||||
#elif SUPERGRID
|
||||
namespace DevComponents.SuperGrid.TextMarkup
|
||||
#elif LAYOUT
|
||||
namespace DevComponents.DotNetBar.Layout.TextMarkup
|
||||
#endif
|
||||
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents interface for block layout.
|
||||
/// </summary>
|
||||
public interface IContentLayout
|
||||
{
|
||||
/// <summary>
|
||||
/// Performs layout of the content block.
|
||||
/// </summary>
|
||||
/// <param name="containerBounds">Container bounds to layout content blocks in.</param>
|
||||
/// <param name="contentBlocks">Content blocks to layout.</param>
|
||||
/// <param name="blockLayout">Block layout manager that resizes the content blocks.</param>
|
||||
/// <returns>The bounds of the content blocks within the container bounds.</returns>
|
||||
Rectangle Layout(Rectangle containerBounds, IBlock[] contentBlocks, BlockLayoutManager blockLayout);
|
||||
}
|
||||
}
|
@@ -0,0 +1,742 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Drawing;
|
||||
|
||||
#if AdvTree
|
||||
namespace DevComponents.Tree.TextMarkup
|
||||
#elif DOTNETBAR
|
||||
namespace DevComponents.UI.ContentManager
|
||||
#elif SUPERGRID
|
||||
namespace DevComponents.SuperGrid.TextMarkup
|
||||
#elif LAYOUT
|
||||
namespace DevComponents.DotNetBar.Layout.TextMarkup
|
||||
#endif
|
||||
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the serial content layout manager that arranges content blocks in series next to each other.
|
||||
/// </summary>
|
||||
public class SerialContentLayoutManager:IContentLayout
|
||||
{
|
||||
#region Events
|
||||
/// <summary>
|
||||
/// Occurs when X, Y position of next block is calcualted.
|
||||
/// </summary>
|
||||
public event LayoutManagerPositionEventHandler NextPosition;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before new block is layed out.
|
||||
/// </summary>
|
||||
public event LayoutManagerLayoutEventHandler BeforeNewBlockLayout;
|
||||
#endregion
|
||||
|
||||
#region Private Variables
|
||||
private int m_BlockSpacing=0;
|
||||
private bool m_FitContainerOversize=false;
|
||||
private bool m_FitContainer = false;
|
||||
private bool m_VerticalFitContainerWidth = false;
|
||||
private bool m_HorizontalFitContainerHeight = false;
|
||||
private eContentOrientation m_ContentOrientation=eContentOrientation.Horizontal;
|
||||
private eContentAlignment m_ContentAlignment=eContentAlignment.Left;
|
||||
private eContentVerticalAlignment m_ContentVerticalAlignment=eContentVerticalAlignment.Middle;
|
||||
private eContentVerticalAlignment m_BlockLineAlignment = eContentVerticalAlignment.Middle;
|
||||
private bool m_EvenHeight=false;
|
||||
private bool m_MultiLine=false;
|
||||
private bool m_RightToLeft = false;
|
||||
private bool m_OversizeDistribute = false;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Creates new instance of the class.
|
||||
/// </summary>
|
||||
public SerialContentLayoutManager()
|
||||
{
|
||||
}
|
||||
|
||||
#region IContentLayout Members
|
||||
/// <summary>
|
||||
/// Performs layout of the content block.
|
||||
/// </summary>
|
||||
/// <param name="containerBounds">Container bounds to layout content blocks in.</param>
|
||||
/// <param name="contentBlocks">Content blocks to layout.</param>
|
||||
/// <param name="blockLayout">Block layout manager that resizes the content blocks.</param>
|
||||
/// <returns>The bounds of the content blocks within the container bounds.</returns>
|
||||
public virtual Rectangle Layout(Rectangle containerBounds, IBlock[] contentBlocks, BlockLayoutManager blockLayout)
|
||||
{
|
||||
Rectangle blocksBounds=Rectangle.Empty;
|
||||
Point position=containerBounds.Location;
|
||||
ArrayList lines=new ArrayList();
|
||||
lines.Add(new BlockLineInfo());
|
||||
BlockLineInfo currentLine=lines[0] as BlockLineInfo;
|
||||
bool switchToNewLine = false;
|
||||
bool canStartOnNewLine = true;
|
||||
int visibleIndex = 0;
|
||||
bool callLayout = true;
|
||||
|
||||
if (_EqualItemSize)
|
||||
{
|
||||
Size largestItemSize = Size.Empty;
|
||||
foreach (IBlock block in contentBlocks)
|
||||
{
|
||||
if (!block.Visible)
|
||||
{
|
||||
block.Bounds = Rectangle.Empty;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (BeforeNewBlockLayout != null)
|
||||
{
|
||||
LayoutManagerLayoutEventArgs e = new LayoutManagerLayoutEventArgs(block, position, visibleIndex);
|
||||
BeforeNewBlockLayout(this, e);
|
||||
position = e.CurrentPosition;
|
||||
if (e.CancelLayout)
|
||||
continue;
|
||||
}
|
||||
visibleIndex++;
|
||||
|
||||
Size availableSize = containerBounds.Size;
|
||||
blockLayout.Layout(block, availableSize);
|
||||
if (block.Bounds.Width > largestItemSize.Width)
|
||||
largestItemSize.Width = block.Bounds.Width;
|
||||
if (block.Bounds.Height > largestItemSize.Height)
|
||||
largestItemSize.Height = block.Bounds.Height;
|
||||
}
|
||||
|
||||
foreach (IBlock block in contentBlocks)
|
||||
{
|
||||
if (!block.Visible)
|
||||
continue;
|
||||
block.Bounds=new Rectangle(block.Bounds.Location, largestItemSize);
|
||||
|
||||
}
|
||||
callLayout = false;
|
||||
}
|
||||
|
||||
foreach(IBlock block in contentBlocks)
|
||||
{
|
||||
if(!block.Visible)
|
||||
{
|
||||
block.Bounds = Rectangle.Empty;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (BeforeNewBlockLayout != null)
|
||||
{
|
||||
LayoutManagerLayoutEventArgs e = new LayoutManagerLayoutEventArgs(block, position, visibleIndex);
|
||||
BeforeNewBlockLayout(this, e);
|
||||
position = e.CurrentPosition;
|
||||
if (e.CancelLayout)
|
||||
continue;
|
||||
}
|
||||
visibleIndex++;
|
||||
|
||||
Size availableSize = containerBounds.Size;
|
||||
bool isBlockElement = false;
|
||||
bool isNewLineTriggger = false;
|
||||
bool isContainer = false;
|
||||
if (block is IBlockExtended)
|
||||
{
|
||||
IBlockExtended ex = block as IBlockExtended;
|
||||
isBlockElement = ex.IsBlockElement;
|
||||
isNewLineTriggger = ex.IsNewLineAfterElement;
|
||||
canStartOnNewLine = ex.CanStartNewLine;
|
||||
isContainer = ex.IsBlockContainer;
|
||||
}
|
||||
else
|
||||
canStartOnNewLine = true;
|
||||
|
||||
if (!isBlockElement && !isContainer)
|
||||
{
|
||||
if (m_ContentOrientation == eContentOrientation.Horizontal)
|
||||
availableSize.Width = (containerBounds.Right - position.X);
|
||||
else
|
||||
availableSize.Height = (containerBounds.Bottom - position.Y);
|
||||
}
|
||||
|
||||
// Resize the content block
|
||||
if(callLayout)
|
||||
blockLayout.Layout(block, availableSize);
|
||||
|
||||
if(m_MultiLine && currentLine.Blocks.Count > 0)
|
||||
{
|
||||
if (m_ContentOrientation == eContentOrientation.Horizontal && (position.X + block.Bounds.Width > containerBounds.Right && canStartOnNewLine || isBlockElement || switchToNewLine))
|
||||
{
|
||||
position.X=containerBounds.X;
|
||||
position.Y+=(currentLine.LineSize.Height+m_BlockSpacing);
|
||||
currentLine=new BlockLineInfo();
|
||||
currentLine.Line=lines.Count;
|
||||
lines.Add(currentLine);
|
||||
}
|
||||
else if (m_ContentOrientation == eContentOrientation.Vertical && (position.Y + block.Bounds.Height > containerBounds.Bottom && canStartOnNewLine || isBlockElement || switchToNewLine))
|
||||
{
|
||||
position.Y=containerBounds.Y;
|
||||
position.X+=(currentLine.LineSize.Width+m_BlockSpacing);
|
||||
currentLine=new BlockLineInfo();
|
||||
currentLine.Line=lines.Count;
|
||||
lines.Add(currentLine);
|
||||
}
|
||||
}
|
||||
|
||||
if(m_ContentOrientation==eContentOrientation.Horizontal)
|
||||
{
|
||||
if(block.Bounds.Height>currentLine.LineSize.Height)
|
||||
currentLine.LineSize.Height=block.Bounds.Height;
|
||||
currentLine.LineSize.Width=position.X+block.Bounds.Width-containerBounds.X;
|
||||
}
|
||||
else if(m_ContentOrientation==eContentOrientation.Vertical)
|
||||
{
|
||||
if(block.Bounds.Width>currentLine.LineSize.Width)
|
||||
currentLine.LineSize.Width=block.Bounds.Width;
|
||||
currentLine.LineSize.Height=position.Y+block.Bounds.Height-containerBounds.Y;
|
||||
}
|
||||
|
||||
currentLine.Blocks.Add(block);
|
||||
if (block.Visible) currentLine.VisibleItemsCount++;
|
||||
Rectangle r = new Rectangle(position, block.Bounds.Size);
|
||||
r.X += block.Margin.Left;
|
||||
r.Y += block.Margin.Top;
|
||||
block.Bounds = r;
|
||||
|
||||
if (blocksBounds.IsEmpty)
|
||||
{
|
||||
r = block.Bounds; // Make sure that blocks bounds take in account any margin
|
||||
r.X -= block.Margin.Left;
|
||||
r.Y -= block.Margin.Top;
|
||||
r.Width += block.Margin.Horizontal;
|
||||
r.Height += block.Margin.Vertical;
|
||||
blocksBounds = r;
|
||||
}
|
||||
else
|
||||
blocksBounds = Rectangle.Union(blocksBounds, block.Bounds);
|
||||
|
||||
switchToNewLine = isBlockElement | isNewLineTriggger;
|
||||
|
||||
position = GetNextPosition(block, position, ref switchToNewLine);
|
||||
}
|
||||
|
||||
blocksBounds=AlignResizeBlocks(containerBounds, blocksBounds, lines);
|
||||
|
||||
if (m_RightToLeft)
|
||||
blocksBounds = MirrorContent(containerBounds, blocksBounds, contentBlocks);
|
||||
|
||||
blocksBounds = blockLayout.FinalizeLayout(containerBounds, blocksBounds, lines);
|
||||
|
||||
return blocksBounds;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internals
|
||||
private struct SizeExtended
|
||||
{
|
||||
public int Width;
|
||||
public int Height;
|
||||
public float WidthReduction;
|
||||
public float HeightReduction;
|
||||
public bool UseAbsoluteWidth;
|
||||
}
|
||||
|
||||
private Rectangle AlignResizeBlocks(Rectangle containerBounds,Rectangle blocksBounds,ArrayList lines)
|
||||
{
|
||||
Rectangle newBounds=Rectangle.Empty;
|
||||
if(containerBounds.IsEmpty || blocksBounds.IsEmpty || ((BlockLineInfo)lines[0]).Blocks.Count==0)
|
||||
return newBounds;
|
||||
|
||||
//Reverting to EventHeight property check so the buttons on RibbonBar are properly stretched so they consume same height.
|
||||
// Be very careful when changing this code!
|
||||
if (m_ContentAlignment == eContentAlignment.Left && m_ContentVerticalAlignment == eContentVerticalAlignment.Top &&
|
||||
!m_FitContainer && !m_FitContainerOversize && !m_EvenHeight && m_BlockLineAlignment == eContentVerticalAlignment.Top &&
|
||||
(!(m_ContentOrientation == eContentOrientation.Vertical && (m_VerticalFitContainerWidth || m_EvenHeight)) || m_MultiLine))
|
||||
return blocksBounds;
|
||||
|
||||
Point[] offset=new Point[lines.Count];
|
||||
SizeExtended[] sizeOffset = new SizeExtended[lines.Count];
|
||||
foreach(BlockLineInfo lineInfo in lines)
|
||||
{
|
||||
if(m_ContentOrientation==eContentOrientation.Horizontal)
|
||||
{
|
||||
if(m_FitContainer && containerBounds.Width>lineInfo.LineSize.Width ||
|
||||
m_FitContainerOversize && lineInfo.LineSize.Width>containerBounds.Width)
|
||||
{
|
||||
if (m_OversizeDistribute && containerBounds.Width < lineInfo.LineSize.Width * .75)
|
||||
{
|
||||
sizeOffset[lineInfo.Line].Width = (int)Math.Floor((float)(containerBounds.Width - lineInfo.VisibleItemsCount * m_BlockSpacing) / (float)lineInfo.VisibleItemsCount);
|
||||
sizeOffset[lineInfo.Line].UseAbsoluteWidth = true;
|
||||
}
|
||||
else
|
||||
sizeOffset[lineInfo.Line].Width = ((containerBounds.Width - lineInfo.VisibleItemsCount * m_BlockSpacing) - lineInfo.LineSize.Width) / lineInfo.VisibleItemsCount;
|
||||
sizeOffset[lineInfo.Line].WidthReduction = (float)(containerBounds.Width - lineInfo.VisibleItemsCount * m_BlockSpacing) / (float)lineInfo.LineSize.Width;
|
||||
blocksBounds.Width=containerBounds.Width;
|
||||
}
|
||||
|
||||
if (m_HorizontalFitContainerHeight && containerBounds.Height > blocksBounds.Height && lines.Count == 1)
|
||||
sizeOffset[lineInfo.Line].Height = (containerBounds.Height - lineInfo.LineSize.Height) / lines.Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_FitContainer && containerBounds.Height>lineInfo.LineSize.Height ||
|
||||
m_FitContainerOversize && lineInfo.LineSize.Height>containerBounds.Height)
|
||||
{
|
||||
if (m_OversizeDistribute && containerBounds.Width < lineInfo.LineSize.Width * .75)
|
||||
{
|
||||
sizeOffset[lineInfo.Line].Height = (int)Math.Floor((float)(containerBounds.Height - lineInfo.VisibleItemsCount * m_BlockSpacing) / (float)lineInfo.VisibleItemsCount);
|
||||
sizeOffset[lineInfo.Line].UseAbsoluteWidth = true;
|
||||
}
|
||||
else
|
||||
sizeOffset[lineInfo.Line].Height = ((containerBounds.Height - lineInfo.VisibleItemsCount * m_BlockSpacing) - lineInfo.LineSize.Height) / lineInfo.VisibleItemsCount;
|
||||
sizeOffset[lineInfo.Line].HeightReduction = (float)(containerBounds.Height - lineInfo.VisibleItemsCount * m_BlockSpacing) / (float)lineInfo.LineSize.Height;
|
||||
blocksBounds.Height=containerBounds.Height;
|
||||
}
|
||||
|
||||
if (m_VerticalFitContainerWidth && containerBounds.Width > blocksBounds.Width && lines.Count==1)
|
||||
sizeOffset[lineInfo.Line].Width = (containerBounds.Width - lineInfo.LineSize.Width) / lines.Count;
|
||||
}
|
||||
|
||||
|
||||
if(m_ContentOrientation==eContentOrientation.Horizontal && !m_FitContainer)
|
||||
{
|
||||
if(containerBounds.Width>blocksBounds.Width && m_FitContainerOversize || !m_FitContainerOversize)
|
||||
{
|
||||
switch(m_ContentAlignment)
|
||||
{
|
||||
case eContentAlignment.Right:
|
||||
if (containerBounds.Width > lineInfo.LineSize.Width)
|
||||
offset[lineInfo.Line].X = containerBounds.Width - lineInfo.LineSize.Width;
|
||||
break;
|
||||
case eContentAlignment.Center:
|
||||
if (containerBounds.Width > lineInfo.LineSize.Width)
|
||||
offset[lineInfo.Line].X = (containerBounds.Width - lineInfo.LineSize.Width) / 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(m_ContentOrientation==eContentOrientation.Vertical && !m_FitContainer)
|
||||
{
|
||||
if(containerBounds.Height>blocksBounds.Height && m_FitContainerOversize || !m_FitContainerOversize)
|
||||
{
|
||||
switch(m_ContentVerticalAlignment)
|
||||
{
|
||||
case eContentVerticalAlignment.Bottom:
|
||||
if (containerBounds.Height > lineInfo.LineSize.Height)
|
||||
offset[lineInfo.Line].Y = containerBounds.Height - lineInfo.LineSize.Height;
|
||||
break;
|
||||
case eContentVerticalAlignment.Middle:
|
||||
if (containerBounds.Height > lineInfo.LineSize.Height)
|
||||
offset[lineInfo.Line].Y = (containerBounds.Height - lineInfo.LineSize.Height) / 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_VerticalFitContainerWidth && containerBounds.Width > blocksBounds.Width && m_ContentOrientation==eContentOrientation.Vertical)
|
||||
blocksBounds.Width = containerBounds.Width;
|
||||
else if(m_HorizontalFitContainerHeight && containerBounds.Height>blocksBounds.Height && m_ContentOrientation==eContentOrientation.Horizontal)
|
||||
blocksBounds.Height = containerBounds.Height;
|
||||
|
||||
if(m_ContentOrientation==eContentOrientation.Horizontal)
|
||||
{
|
||||
foreach(BlockLineInfo lineInfo in lines)
|
||||
{
|
||||
foreach(IBlock block in lineInfo.Blocks)
|
||||
{
|
||||
if(!block.Visible)
|
||||
continue;
|
||||
Rectangle r=block.Bounds;
|
||||
if(m_EvenHeight && lineInfo.LineSize.Height>0)
|
||||
r.Height=lineInfo.LineSize.Height;
|
||||
r.Offset(offset[lineInfo.Line]);
|
||||
|
||||
if(m_ContentVerticalAlignment==eContentVerticalAlignment.Middle)
|
||||
{
|
||||
// Takes care of offset rounding error when both content is vertically centered and blocks in line are centered
|
||||
if (m_BlockLineAlignment == eContentVerticalAlignment.Middle)
|
||||
r.Offset(0,((containerBounds.Height-blocksBounds.Height)+(lineInfo.LineSize.Height-r.Height))/2);
|
||||
else
|
||||
r.Offset(0,(containerBounds.Height-blocksBounds.Height)/2);
|
||||
|
||||
// Line alignment of the block
|
||||
if (m_BlockLineAlignment == eContentVerticalAlignment.Bottom)
|
||||
r.Offset(0, lineInfo.LineSize.Height - r.Height);
|
||||
}
|
||||
else if(m_ContentVerticalAlignment==eContentVerticalAlignment.Bottom)
|
||||
r.Offset(0,containerBounds.Height-blocksBounds.Height);
|
||||
|
||||
// To avoid rounding offset errors when dividing this is split see upper part
|
||||
if(m_ContentVerticalAlignment!=eContentVerticalAlignment.Middle)
|
||||
{
|
||||
// Line alignment of the block
|
||||
if (m_BlockLineAlignment == eContentVerticalAlignment.Middle)
|
||||
r.Offset(0, (lineInfo.LineSize.Height - r.Height) / 2);
|
||||
else if (m_BlockLineAlignment == eContentVerticalAlignment.Bottom)
|
||||
r.Offset(0, lineInfo.LineSize.Height - r.Height);
|
||||
}
|
||||
|
||||
if(sizeOffset[lineInfo.Line].Width!=0)
|
||||
{
|
||||
if (m_OversizeDistribute)
|
||||
{
|
||||
int nw = sizeOffset[lineInfo.Line].UseAbsoluteWidth ? sizeOffset[lineInfo.Line].Width : (int)Math.Floor(r.Width * sizeOffset[lineInfo.Line].WidthReduction);
|
||||
offset[lineInfo.Line].X += nw - r.Width;
|
||||
r.Width = nw;
|
||||
}
|
||||
else
|
||||
{
|
||||
r.Width += sizeOffset[lineInfo.Line].Width;
|
||||
offset[lineInfo.Line].X += sizeOffset[lineInfo.Line].Width;
|
||||
}
|
||||
}
|
||||
r.Height+=sizeOffset[lineInfo.Line].Height;
|
||||
block.Bounds=r;
|
||||
if(newBounds.IsEmpty)
|
||||
newBounds=block.Bounds;
|
||||
else
|
||||
newBounds=Rectangle.Union(newBounds,block.Bounds);
|
||||
}
|
||||
// Adjust for left-over size adjustment for odd difference between container width and the total block width
|
||||
if (!m_OversizeDistribute && sizeOffset[lineInfo.Line].Width != 0 && containerBounds.Width - (lineInfo.LineSize.Width + sizeOffset[lineInfo.Line].Width * lineInfo.Blocks.Count) != 0)
|
||||
{
|
||||
Rectangle r=((IBlock)lineInfo.Blocks[lineInfo.Blocks.Count-1]).Bounds;
|
||||
r.Width+=containerBounds.Width-(lineInfo.LineSize.Width+sizeOffset[lineInfo.Line].Width*lineInfo.Blocks.Count);
|
||||
((IBlock)lineInfo.Blocks[lineInfo.Blocks.Count-1]).Bounds=r;
|
||||
}
|
||||
if (!m_FitContainer && m_ContentAlignment != eContentAlignment.Left && _ReserveLeftSpace)
|
||||
{
|
||||
// For block elements they should consume the space available to the left otherwise
|
||||
// the parent is not aware that the space has been consumed
|
||||
newBounds.Width += (newBounds.X - containerBounds.X);
|
||||
newBounds.X = containerBounds.X;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach(BlockLineInfo lineInfo in lines)
|
||||
{
|
||||
foreach(IBlock block in lineInfo.Blocks)
|
||||
{
|
||||
if(!block.Visible)
|
||||
continue;
|
||||
Rectangle r=block.Bounds;
|
||||
if(m_EvenHeight && lineInfo.LineSize.Width>0)
|
||||
r.Width=lineInfo.LineSize.Width - block.Margin.Horizontal;
|
||||
r.Offset(offset[lineInfo.Line]);
|
||||
if(m_ContentAlignment==eContentAlignment.Center)
|
||||
r.Offset(((containerBounds.Width-blocksBounds.Width)+(lineInfo.LineSize.Width-r.Width))/2,0); //r.Offset((containerBounds.Width-blocksBounds.Width)/2+(lineInfo.LineSize.Width-r.Width)/2,0);
|
||||
else if(m_ContentAlignment==eContentAlignment.Right)
|
||||
r.Offset((containerBounds.Width-blocksBounds.Width)+lineInfo.LineSize.Width-r.Width,0);
|
||||
r.Width+=sizeOffset[lineInfo.Line].Width;
|
||||
if(sizeOffset[lineInfo.Line].Height!=0)
|
||||
{
|
||||
if (m_OversizeDistribute)
|
||||
{
|
||||
int nw = sizeOffset[lineInfo.Line].UseAbsoluteWidth ? sizeOffset[lineInfo.Line].Height : (int)Math.Floor(r.Height * sizeOffset[lineInfo.Line].HeightReduction);
|
||||
offset[lineInfo.Line].Y += nw - r.Height;
|
||||
r.Height = nw;
|
||||
}
|
||||
else
|
||||
{
|
||||
r.Height += sizeOffset[lineInfo.Line].Height;
|
||||
offset[lineInfo.Line].Y += sizeOffset[lineInfo.Line].Height;
|
||||
}
|
||||
}
|
||||
block.Bounds=r;
|
||||
if (newBounds.IsEmpty)
|
||||
{
|
||||
r.Y -= block.Margin.Top; // Account for any margin set on first element
|
||||
r.X -= block.Margin.Left;
|
||||
r.Width += block.Margin.Horizontal;
|
||||
r.Height += block.Margin.Vertical;
|
||||
newBounds = r;
|
||||
}
|
||||
else
|
||||
newBounds = Rectangle.Union(newBounds, block.Bounds);
|
||||
}
|
||||
if (!m_OversizeDistribute && sizeOffset[lineInfo.Line].Height != 0 && containerBounds.Height - (lineInfo.LineSize.Height + sizeOffset[lineInfo.Line].Height * lineInfo.Blocks.Count) != 0)
|
||||
{
|
||||
Rectangle r=((IBlock)lineInfo.Blocks[lineInfo.Blocks.Count-1]).Bounds;
|
||||
r.Height+=containerBounds.Height-(lineInfo.LineSize.Height+sizeOffset[lineInfo.Line].Height*lineInfo.Blocks.Count);
|
||||
((IBlock)lineInfo.Blocks[lineInfo.Blocks.Count-1]).Bounds=r;
|
||||
}
|
||||
}
|
||||
}
|
||||
return newBounds;
|
||||
}
|
||||
|
||||
private Point GetNextPosition(IBlock block, Point position, ref bool switchToNewLine)
|
||||
{
|
||||
if (NextPosition != null)
|
||||
{
|
||||
LayoutManagerPositionEventArgs e = new LayoutManagerPositionEventArgs();
|
||||
|
||||
e.Block = block;
|
||||
e.CurrentPosition = position;
|
||||
e.SwitchToNewLine = switchToNewLine;
|
||||
|
||||
NextPosition(this, e);
|
||||
|
||||
switchToNewLine = e.SwitchToNewLine;
|
||||
|
||||
if (e.Cancel)
|
||||
return e.NextPosition;
|
||||
}
|
||||
|
||||
if (m_ContentOrientation == eContentOrientation.Horizontal)
|
||||
position.X += block.Bounds.Width + m_BlockSpacing + block.Margin.Horizontal;
|
||||
else
|
||||
position.Y += block.Bounds.Height + m_BlockSpacing + block.Margin.Vertical;
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
internal class BlockLineInfo
|
||||
{
|
||||
public BlockLineInfo() {}
|
||||
public ArrayList Blocks=new ArrayList();
|
||||
public Size LineSize=Size.Empty;
|
||||
public int Line=0;
|
||||
public int VisibleItemsCount = 0;
|
||||
}
|
||||
|
||||
private Rectangle MirrorContent(Rectangle containerBounds, Rectangle blockBounds, IBlock[] contentBlocks)
|
||||
{
|
||||
int xOffset = (blockBounds.X - containerBounds.X);
|
||||
|
||||
if (blockBounds.Width < containerBounds.Width)
|
||||
blockBounds.X = containerBounds.Right - ((blockBounds.X - containerBounds.X) + blockBounds.Width);
|
||||
else if (blockBounds.Width > containerBounds.Width)
|
||||
containerBounds.Width = blockBounds.Width;
|
||||
foreach (IBlock block in contentBlocks)
|
||||
{
|
||||
if (!block.Visible)
|
||||
continue;
|
||||
Rectangle r = block.Bounds;
|
||||
block.Bounds = new Rectangle(containerBounds.Right - ((r.X - containerBounds.X) + r.Width), r.Y, r.Width, r.Height);
|
||||
}
|
||||
|
||||
return blockBounds;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
private bool _ReserveLeftSpace = false;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether space to the left of center and right aligned blocks is blocked out by stretching the block so it consumes that space.
|
||||
/// </summary>
|
||||
public bool ReserveLeftSpace
|
||||
{
|
||||
get { return _ReserveLeftSpace; }
|
||||
set { _ReserveLeftSpace = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the spacing in pixels between content blocks. Default value is 0.
|
||||
/// </summary>
|
||||
public virtual int BlockSpacing
|
||||
{
|
||||
get {return m_BlockSpacing;}
|
||||
set {m_BlockSpacing=value;}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether content blocks are forced to fit the container bounds if they
|
||||
/// occupy more space than it is available by container. Default value is false.
|
||||
/// </summary>
|
||||
public virtual bool FitContainerOversize
|
||||
{
|
||||
get {return m_FitContainerOversize;}
|
||||
set {m_FitContainerOversize=value;}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether content blocks are resized to fit the container bound if they
|
||||
/// occupy less space than it is available by container. Default value is false.
|
||||
/// </summary>
|
||||
public virtual bool FitContainer
|
||||
{
|
||||
get {return m_FitContainer;}
|
||||
set {m_FitContainer=value;}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether content blocks are resized (Width) to fit container bounds if they
|
||||
/// occupy less space than the actual container width. Applies to the Vertical orientation only. Default value is false.
|
||||
/// </summary>
|
||||
public virtual bool VerticalFitContainerWidth
|
||||
{
|
||||
get { return m_VerticalFitContainerWidth; }
|
||||
set { m_VerticalFitContainerWidth = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether content blocks are resized (Height) to fit container bounds if they
|
||||
/// occupy less space than the actual container height. Applies to the Horizontal orientation only. Default value is false.
|
||||
/// </summary>
|
||||
public virtual bool HorizontalFitContainerHeight
|
||||
{
|
||||
get { return m_HorizontalFitContainerHeight; }
|
||||
set { m_HorizontalFitContainerHeight = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content orientation. Default value is Horizontal.
|
||||
/// </summary>
|
||||
public virtual eContentOrientation ContentOrientation
|
||||
{
|
||||
get {return m_ContentOrientation;}
|
||||
set {m_ContentOrientation=value;}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content vertical alignment. Default value is Middle.
|
||||
/// </summary>
|
||||
public virtual eContentVerticalAlignment ContentVerticalAlignment
|
||||
{
|
||||
get {return m_ContentVerticalAlignment;}
|
||||
set {m_ContentVerticalAlignment=value;}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the block line vertical alignment. Default value is Middle.
|
||||
/// </summary>
|
||||
public virtual eContentVerticalAlignment BlockLineAlignment
|
||||
{
|
||||
get { return m_BlockLineAlignment; }
|
||||
set { m_BlockLineAlignment = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content horizontal alignment. Default value is Left.
|
||||
/// </summary>
|
||||
public virtual eContentAlignment ContentAlignment
|
||||
{
|
||||
get {return m_ContentAlignment;}
|
||||
set {m_ContentAlignment=value;}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether all content blocks are resized so they have same height which is height of the tallest content block. Default value is false.
|
||||
/// </summary>
|
||||
public virtual bool EvenHeight
|
||||
{
|
||||
get {return m_EvenHeight;}
|
||||
set {m_EvenHeight=value;}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether oversized blocks are resized based on the percentage reduction instead of based on equal pixel distribution. Default value is false.
|
||||
/// </summary>
|
||||
public virtual bool OversizeDistribute
|
||||
{
|
||||
get { return m_OversizeDistribute; }
|
||||
set { m_OversizeDistribute = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether content is wrapped into new line if it exceeds the width of the container.
|
||||
/// </summary>
|
||||
public bool MultiLine
|
||||
{
|
||||
get {return m_MultiLine;}
|
||||
set {m_MultiLine=value;}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether layout is right-to-left.
|
||||
/// </summary>
|
||||
public bool RightToLeft
|
||||
{
|
||||
get { return m_RightToLeft; }
|
||||
set { m_RightToLeft = value; }
|
||||
}
|
||||
|
||||
private bool _EqualItemSize = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether all items are equaly sized based on the size of the largest item in the list.
|
||||
/// </summary>
|
||||
public bool EqualItemSize
|
||||
{
|
||||
get { return _EqualItemSize; }
|
||||
set { _EqualItemSize = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents event arguments for SerialContentLayoutManager.NextPosition event.
|
||||
/// </summary>
|
||||
public class LayoutManagerPositionEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the block that is layed out.
|
||||
/// </summary>
|
||||
public IBlock Block = null;
|
||||
/// <summary>
|
||||
/// Gets or sets the current block position.
|
||||
/// </summary>
|
||||
public Point CurrentPosition = Point.Empty;
|
||||
/// <summary>
|
||||
/// Gets or sets the calculated next block position.
|
||||
/// </summary>
|
||||
public Point NextPosition = Point.Empty;
|
||||
/// <summary>
|
||||
/// Cancels default position calculation.
|
||||
/// </summary>
|
||||
public bool Cancel = false;
|
||||
|
||||
public bool SwitchToNewLine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents event arguments for the SerialContentLayoutManager layout events.
|
||||
/// </summary>
|
||||
public class LayoutManagerLayoutEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the reference block object.
|
||||
/// </summary>
|
||||
public IBlock Block = null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the position block will assume.
|
||||
/// </summary>
|
||||
public Point CurrentPosition = Point.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Cancel the layout of the block, applies only to BeforeXXX layout event.
|
||||
/// </summary>
|
||||
public bool CancelLayout = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the visibility index of the block.
|
||||
/// </summary>
|
||||
public int BlockVisibleIndex = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Creates new instance of the class and initializes it with default values.
|
||||
/// </summary>
|
||||
public LayoutManagerLayoutEventArgs(IBlock block, Point currentPosition, int visibleIndex)
|
||||
{
|
||||
this.Block = block;
|
||||
this.CurrentPosition = currentPosition;
|
||||
this.BlockVisibleIndex = visibleIndex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for SerialContentLayoutManager.NextPosition event.
|
||||
/// </summary>
|
||||
public delegate void LayoutManagerPositionEventHandler(object sender, LayoutManagerPositionEventArgs e);
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the SerialContentLayoutManager layout events.
|
||||
/// </summary>
|
||||
public delegate void LayoutManagerLayoutEventHandler(object sender, LayoutManagerLayoutEventArgs e);
|
||||
|
||||
|
||||
}
|
Reference in New Issue
Block a user