Example #1
0
        /// <summary>Positions this element and all it's children relative to their parent.</summary>
        public void PositionLocally()
        {
            // This is the first pass of layout requests.
            // It locates elements locally whilst also finding their width and height.
            ComputedStyle computed = Style.Computed;

            if (computed.Display == DisplayType.None)
            {
                // Don't draw this element or it's kids.
                return;
            }

            if (!IsRebuildingChildren)
            {
                // Update child nodes (thread safety):
                KidsToRender = ChildNodes;
            }

            float depth             = Document.Renderer.Depth;
            float maxDepth          = Document.Renderer.MaxDepth;
            bool  elementPositioned = false;

            if (!computed.FixedDepth)
            {
                elementPositioned = (computed.IsOffset() || computed.Position != PositionType.Relative);

                if (elementPositioned)
                {
                    // This element has been positioned - make sure it's ontop of the current highest element:
                    Document.Renderer.Depth = Document.Renderer.MaxDepth;

                    if (Document.Renderer.DepthUsed)
                    {
                        Document.Renderer.IncreaseDepth();
                    }
                    else
                    {
                        Document.Renderer.DepthUsed = true;
                    }

                    computed.ZIndex = Document.Renderer.Depth;
                }
                else
                {
                    computed.ZIndex = depth;
                }
            }
            else
            {
                computed.ZIndex = computed.FixedZIndex;
            }

            if (KidsToRender != null || HScrollbar || VScrollbar)
            {
                if (computed.FixedDepth)
                {
                    // Set the depth buffer to this element so it's kids are at the right height; restore it after.

                    // Offset by the document's depth if we're in a document in a document (e.g. iframe):
                    Element documentParent = Document.html.parentNode;

                    if (documentParent != null && documentParent != this)
                    {
                        computed.ZIndex += documentParent.Style.Computed.ZIndex;
                    }

                    Document.Renderer.Depth = computed.ZIndex;

                    if (computed.ZIndex > Document.Renderer.MaxDepth)
                    {
                        Document.Renderer.MaxDepth = Document.Renderer.Depth;
                    }
                }
                else if (computed.BGImage != null || computed.BGColour != null)
                {
                    // Only increase the depth if the element has a background image/colour to get it's kids away from.
                    Document.Renderer.IncreaseDepth();
                }
            }

            if (KidsToRender != null)
            {
                for (int i = 0; i < KidsToRender.Count; i++)
                {
                    KidsToRender[i].PositionLocally();
                }
            }

            if (HScrollbar)
            {
                HorizontalScrollbar.Element.PositionLocally();
            }

            if (VScrollbar)
            {
                VerticalScrollbar.Element.PositionLocally();
            }

            // Restore the depth:
            if (elementPositioned)
            {
                // This element has been positioned - everything after it must be ontop of it and all it's kids.
                Document.Renderer.Depth = Document.Renderer.MaxDepth;
                Document.Renderer.IncreaseDepth();
            }
            else if (computed.FixedDepth)
            {
                Document.Renderer.Depth    = depth;
                Document.Renderer.MaxDepth = maxDepth;
            }

            if (computed.Display == Css.DisplayType.Inline && computed.Position == Css.PositionType.Relative)
            {
                // Relative Inline - The kids will be packed onto the next element up's lines (this is done internally by the PackOnLine function).
                // Fixed or absolute pack their own lines.

                if (computed.BGImage == null && computed.BGColour == null && computed.Border == null)
                {
                    // Only occurs though if the element has no background or border - if it does, it should act like an inline-block element.
                    return;
                }
            }

            Document.Renderer.BeginLinePack(this);

            if (KidsToRender != null || HScrollbar || VScrollbar)
            {
                if (KidsToRender != null)
                {
                    for (int i = 0; i < KidsToRender.Count; i++)
                    {
                        Document.Renderer.PackOnLine(KidsToRender[i]);
                    }
                }

                if (HScrollbar)
                {
                    Document.Renderer.PackOnLine(HorizontalScrollbar.Element);
                }

                if (VScrollbar)
                {
                    Document.Renderer.PackOnLine(VerticalScrollbar.Element);
                }
            }

            Document.Renderer.EndLinePack(this);
        }