UpdateMarginTopCollapse() public method

Gets the result of collapsing the vertical margins of the two boxes
public UpdateMarginTopCollapse ( CssBox upperSibling ) : float
upperSibling CssBox the previous box under the same parent
return float
Ejemplo n.º 1
0
        public static void PerformContentLayout(CssBox box, LayoutVisitor lay)
        {
            //recursive

            //this box has its own  container property
            //this box may use...
            // 1) line formatting context  , or
            // 2) block formatting context 

            CssBox myContainingBlock = lay.LatestContainingBlock;
            CssBox prevSibling = lay.LatestSiblingBox;
            if (box.CssDisplay != Css.CssDisplay.TableCell)
            {
                //-------------------------------------------
                if (box.CssDisplay != Css.CssDisplay.Table)
                {
                    float availableWidth = myContainingBlock.GetClientWidth();
                    // Console.WriteLine(availableWidth.ToString());

                    if (!box.Width.IsEmptyOrAuto)
                    {
                        float w = CssValueParser.ConvertToPx(box.Width, availableWidth, box);
                        //specific width
                        box.SetCssBoxWidth(w);
                    }
                    else
                    {
                        box.SetCssBoxFromContainerAvailableWidth(availableWidth);
                    }
                }
                //-------------------------------------------

                float localLeft = myContainingBlock.GetClientLeft() + box.ActualMarginLeft;
                float localTop = 0;
                if (prevSibling == null)
                {
                    //this is first child of parent
                    if (box.ParentBox != null)
                    {
                        localTop = myContainingBlock.GetClientTop();
                    }
                }
                else
                {
                    localTop = prevSibling.LocalVisualBottom;
                }

                //if (box.Float != CssFloat.None)
                //{
                //    //float box 
                //    //find context floating c
                //    if (lay.HasFloatBoxInContext)
                //    {


                //    }
                //}


                localTop += box.UpdateMarginTopCollapse(prevSibling);
                box.SetLocation(localLeft, localTop);
                box.SetHeightToZero();
            }
            //--------------------------------------------------------------------------

            switch (box.CssDisplay)
            {
                case Css.CssDisplay.Table:
                case Css.CssDisplay.InlineTable:
                    {
                        //If we're talking about a table here..

                        lay.PushContaingBlock(box);
                        var currentLevelLatestSibling = lay.LatestSiblingBox;
                        lay.LatestSiblingBox = null;//reset
                        CssTableLayoutEngine.PerformLayout(box, myContainingBlock.GetClientWidth(), lay);
                        lay.LatestSiblingBox = currentLevelLatestSibling;
                        lay.PopContainingBlock();
                        //TODO: check if this can have absolute layer? 
                    }
                    break;
                default:
                    {
                        //formatting context for...
                        //1. line formatting context
                        //2. block formatting context 
                        if (box.IsCustomCssBox)
                        {
                            //has custom layout method
                            box.ReEvaluateComputedValues(lay.SampleIFonts, lay.LatestContainingBlock);
                            box.CustomRecomputedValue(lay.LatestContainingBlock);
                        }
                        else
                        {
                            if (ContainsInlinesOnly(box))
                            {
                                //This will automatically set the bottom of this block 
                                LinesFormattingEngine.DoLayoutLinesContext(box, lay);
                            }
                            else if (box.ChildCount > 0)
                            {
                                DoLayoutBlocksContext(box, lay);
                            }

                            if (box.HasAbsoluteLayer)
                            {
                                LayoutContentInAbsoluteLayer(lay, box);
                            }
                        }
                        //---------------------
                        //again!
                        switch (box.CssDisplay)
                        {
                            case CssDisplay.Flex:
                            case CssDisplay.InlineFlex:
                                {
                                    //------------------------------------------------
                                    RearrangeWithFlexContext(box, lay);
                                    //------------------------------------------------
                                }
                                break;
                            default:
                                {    //TODO: review here again
                                    //if (box.Float != CssFloat.None)
                                    //{
                                    //    var iw = box.InnerContentWidth;
                                    //    var ew = box.VisualWidth;
                                    //    box.SetVisualSize(box.InnerContentWidth, box.InnerContentHeight);
                                    //    //float to specific position 
                                    //    //box.SetVisualSize(iw, box.VisualHeight);
                                    //}
                                }
                                break;
                        }
                        //---------------------
                    }
                    break;
            }


            switch (box.Float)
            {
                case CssFloat.Left:
                    {
#if DEBUG
                        CssBox a = box;
#endif

                        //place it to floating context
                        CssBox currentFloatOwner = lay.GetFloatingContextStack().CurrentTopOwner;
                        CssBox recentLeftFloatBox = lay.LatestLeftFloatBox;
                        CssBox recentRightFloatBox = lay.LatestRightFloatBox;
                        float availableWidth2 = myContainingBlock.GetClientWidth();
                        if (recentRightFloatBox != null)
                        {
                            availableWidth2 -= recentRightFloatBox.LocalX;
                        }

                        float sx = myContainingBlock.GetClientLeft();
                        //--------------------------------------------------------------------
                        float sy = 0;
                        if (myContainingBlock.LineBoxCount > 0)
                        {
                            //line context
                            sy = myContainingBlock.GetClientTop();
                        }
                        else
                        {
                            var prevNode = box.GetPrevNode();
                            if (prevNode != null)
                            {
                                if (prevNode.Float != CssFloat.None)
                                {
                                    //float left/right 
                                    //TODO: review inherit here
                                    if (box.VisualWidth < availableWidth2)
                                    {
                                        sy = prevNode.LocalY;
                                    }
                                    else
                                    {
                                        sy = prevNode.LocalVisualBottom;
                                    }
                                }
                                else
                                {
                                    sy = prevNode.LocalVisualBottom;
                                }
                            }
                            else
                            {
                                sy = myContainingBlock.GetClientTop();
                            }
                        }

                        if (recentLeftFloatBox != null)
                        {
                            availableWidth2 -= recentLeftFloatBox.LocalVisualRight;
                            //TODO: review here again
                            sx = recentLeftFloatBox.LocalVisualRight + recentLeftFloatBox.ActualMarginRight;
                            sy = recentLeftFloatBox.LocalY;
                        }

                        if (box.VisualWidth > availableWidth2)
                        {
                            //start newline
                            sx = myContainingBlock.GetClientLeft();
                            float sy1 = 0;
                            float sy2 = 0;
                            sy1 = sy2 = myContainingBlock.GetClientTop();
                            if (recentLeftFloatBox != null)
                            {
                                sy1 = recentLeftFloatBox.LocalVisualBottom + recentLeftFloatBox.ActualMarginBottom;
                            }
                            if (recentRightFloatBox != null)
                            {
                                sy2 = recentRightFloatBox.LocalVisualBottom + recentRightFloatBox.ActualMarginBottom;
                            }

                            sy = (sy1 > sy2) ? sy1 : sy2;
                        }
                        sx += box.ActualMarginLeft;
                        sy += box.ActualMarginTop;
                        box.SetLocation(sx, sy);
                        lay.AddFloatBox(box);
                    }
                    break;
                case CssFloat.Right:
                    {
                        CssBox recentLeftFloatBox = lay.LatestLeftFloatBox;
                        CssBox recentRightFloatBox = lay.LatestRightFloatBox;
                        float availableWidth2 = myContainingBlock.GetClientWidth();
                        if (recentLeftFloatBox != null)
                        {
                            availableWidth2 -= recentLeftFloatBox.LocalVisualRight;
                        }


                        float sx = myContainingBlock.GetClientRight() - (box.VisualWidth + box.ActualMarginLeft + box.ActualMarginRight);
                        //--------------------------------------------------------------------

                        float sy = 0;
                        if (myContainingBlock.LineBoxCount > 0)
                        {
                            //line context
                            sy = myContainingBlock.GetClientTop();
                        }
                        else
                        {
                            var prevNode = box.GetPrevNode();
                            if (prevNode != null)
                            {
                                if (prevNode.Float != CssFloat.None)
                                {
                                    //float left/right 
                                    //TODO: review inherit here
                                    if (box.VisualWidth < availableWidth2)
                                    {
                                        sy = prevNode.LocalY;
                                    }
                                    else
                                    {
                                        sy = prevNode.LocalVisualBottom;
                                    }
                                }
                                else
                                {
                                    sy = prevNode.LocalVisualBottom;
                                }
                            }
                            else
                            {
                                sy = myContainingBlock.GetClientTop();
                            }
                        }
                        //--------------------------------------------------------------------
                        if (recentRightFloatBox != null)
                        {
                            availableWidth2 -= recentRightFloatBox.LocalX;
                            sx = recentRightFloatBox.LocalX - box.VisualWidth;
                            sy = recentRightFloatBox.LocalY;
                        }

                        if (box.VisualWidth > availableWidth2)
                        {
                            //start newline
                            sx = myContainingBlock.GetClientRight() - (box.VisualWidth + box.ActualMarginLeft + box.ActualMarginRight);
                            float sy1 = 0;
                            float sy2 = 0;
                            sy1 = sy2 = myContainingBlock.GetClientTop();
                            //if (recentLeftFloatBox != null)
                            //{
                            //    sy1 = recentLeftFloatBox.LocalY + recentLeftFloatBox.InnerContentHeight +
                            //      recentLeftFloatBox.ActualPaddingBottom +
                            //      recentLeftFloatBox.ActualMarginBottom;
                            //}
                            //if (recentRightFloatBox != null)
                            //{
                            //    sy2 = recentRightFloatBox.LocalY + recentRightFloatBox.InnerContentHeight +
                            //       recentRightFloatBox.ActualPaddingBottom +
                            //       recentRightFloatBox.ActualMarginBottom;
                            //}
                            if (recentLeftFloatBox != null)
                            {
                                sy1 = recentLeftFloatBox.LocalVisualBottom + recentLeftFloatBox.ActualMarginBottom;
                            }
                            if (recentRightFloatBox != null)
                            {
                                sy2 = recentRightFloatBox.LocalVisualBottom + recentRightFloatBox.ActualMarginBottom;
                            }
                            sy = (sy1 > sy2) ? sy1 : sy2;
                        }

                        sx += box.ActualMarginLeft;
                        sy += box.ActualMarginTop;
                        box.SetLocation(sx, sy);
                        lay.AddFloatBox(box);
                    }
                    break;
                case CssFloat.None:
                default:
                    {
                        //review here for inherit property

                    }
                    break;
            }
        }