/// <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;

			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
                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);    
			}

			blocksBounds=AlignResizeBlocks(containerBounds, blocksBounds, lines);

            if (m_RightToLeft)
                blocksBounds = MirrorContent(containerBounds, blocksBounds, contentBlocks);

            blocksBounds = blockLayout.FinalizeLayout(containerBounds, blocksBounds, lines);

			return blocksBounds;
		}
Esempio n. 2
0
		/// <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 override Rectangle Layout(Rectangle containerBounds,IBlock[] contentBlocks,BlockLayoutManager blockLayout)
		{
			if(contentBlocks.Length==0)
				return Rectangle.Empty;

			if(m_MouseOverIndex==-1)
			{
				return base.Layout(containerBounds,contentBlocks,blockLayout);
			}

			BubbleButton[] buttons=new BubbleButton[contentBlocks.Length];
			contentBlocks.CopyTo(buttons,0);

			int x=0,y=0;
			if(this.ContentOrientation==eContentOrientation.Horizontal)
			{
				buttons[m_MouseOverIndex].SetMagnifiedDisplayRectangle(new Rectangle(m_MouseOverPosition,GetY(containerBounds,m_BubbleSize.Height),m_BubbleSize.Width,m_BubbleSize.Height));
				x=m_MouseOverPosition;
			}
			else
			{
				buttons[m_MouseOverIndex].SetMagnifiedDisplayRectangle(new Rectangle(GetX(containerBounds,m_BubbleSize.Width),m_MouseOverPosition,m_BubbleSize.Width,m_BubbleSize.Height));
				y=m_MouseOverPosition;
			}

			int growthWidth=m_BubbleSize.Width-contentBlocks[0].Bounds.Width;
			int growthHeight=m_BubbleSize.Height-contentBlocks[0].Bounds.Height;

			// Apply factor 2
			int index=GetPreviousButtonIndex(buttons,m_MouseOverIndex);
			if(index>=0)
				SetFactorPrevious(containerBounds,buttons[index],growthWidth,growthHeight,m_Factor2,ref x, ref y);
			
			// Apply factor 1
			index=GetPreviousButtonIndex(buttons,index);
			if(index>=0)
				SetFactorPrevious(containerBounds,buttons[index],growthWidth,growthHeight,m_Factor1,ref x, ref y);

			if(this.ContentOrientation==eContentOrientation.Horizontal)
			{
				while(index>=0)
				{
					index=GetPreviousButtonIndex(buttons,index);
					if(index>=0)
					{
						x-=(buttons[index].DisplayRectangle.Width+this.BlockSpacing);
						buttons[index].SetMagnifiedDisplayRectangle(new Rectangle(x,buttons[index].DisplayRectangle.Y,buttons[index].DisplayRectangle.Width,buttons[index].DisplayRectangle.Height));	
					}
				}
				x=m_MouseOverPosition+m_BubbleSize.Width+this.BlockSpacing;
			}
			else
			{
				while(index>=0)
				{
					index=GetPreviousButtonIndex(buttons,index);
					if(index>=0)
					{
						y-=(buttons[index].DisplayRectangle.Height+this.BlockSpacing);
						buttons[index].SetMagnifiedDisplayRectangle(new Rectangle(buttons[index].DisplayRectangle.X,y,buttons[index].DisplayRectangle.Width,buttons[index].DisplayRectangle.Height));
					}
				}

				y=m_MouseOverPosition+m_BubbleSize.Height+this.BlockSpacing;
			}
			
			// Apply factor 3
			index=GetNextButtonIndex(buttons,m_MouseOverIndex);
			if(index>=0)
				SetFactorNext(containerBounds,buttons[index],growthWidth,growthHeight,m_Factor3,ref x, ref y);

			// Apply factor 4
			if(index==-1) index=m_MouseOverIndex;
			index=GetNextButtonIndex(buttons,index);
			if(index>=0)
				SetFactorNext(containerBounds,buttons[index],growthWidth,growthHeight,m_Factor4,ref x, ref y);
			
			if(this.ContentOrientation==eContentOrientation.Horizontal)
			{
				while(index>=0)
				{
					index=GetNextButtonIndex(buttons,index);
					if(index>=0)
					{
						buttons[index].SetMagnifiedDisplayRectangle(new Rectangle(x,buttons[index].DisplayRectangle.Y,buttons[index].DisplayRectangle.Width,buttons[index].DisplayRectangle.Height));
						x+=(buttons[index].DisplayRectangle.Width+this.BlockSpacing);
					}
				}
			}
			else
			{
				while(index>=0)
				{
					index=GetNextButtonIndex(buttons,index);
					if(index>=0)
					{
						buttons[index].SetMagnifiedDisplayRectangle(new Rectangle(buttons[index].DisplayRectangle.X,y,buttons[index].DisplayRectangle.Width,buttons[index].DisplayRectangle.Height));
						y+=(buttons[index].DisplayRectangle.Height+this.BlockSpacing);
					}
				}
			}

			if(buttons.Length==1)
				return buttons[0].MagnifiedDisplayRectangle;
			
			return Rectangle.Union(buttons[0].MagnifiedDisplayRectangle,buttons[buttons.Length-1].MagnifiedDisplayRectangle);
		}