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