예제 #1
0
        /**
         *
         *  Arrange the Viewport and scrollbars conventionally within
         *  the specified width and height: vertical scrollbar on the
         *  right, horizontal scrollbar along the bottom.
         *
         *  Scrollbars for which the corresponding scrollPolicy=auto
         *  are made visible if the Viewport's content size is bigger
         *  than the actual size.   This introduces the possibility of
         *  validateSize,DisplayList() looping because the measure()
         *  method computes the size of the Viewport and the currently
         *  visible scrollbars.
         *
         */
        override internal void UpdateDisplayList(float w, float h)
        {
            //Debug.Log("UpdateDisplayList: " + w + ", " + h);

            Scroller scroller = GetScroller();

            if (null == scroller)
            {
                return;
            }

            IViewport     viewport         = scroller.Viewport;
            ScrollBarBase hsb              = scroller.HorizontalScrollBar;
            ScrollBarBase vsb              = scroller.VerticalScrollBar;
            float         minViewportInset = scroller.MinViewportInset;

            float contentW = 0;
            float contentH = 0;

            if (null != viewport)
            {
                Point contentSize = GetLayoutContentSize(viewport);
                contentW = contentSize.X;
                contentH = contentSize.Y;
            }

            // If the Viewport's size has been explicitly set (not typical) then use it
            // The initial values for viewportW,H are only used to decide if auto scrollbars
            // should be shown.

            Component viewportUIC = viewport as Component;
            //Debug.Log("viewportUIC: " + viewportUIC);
            //Debug.Log("viewportUIC.ExplicitWidth: " + viewportUIC.ExplicitWidth);
            float?explicitViewportW = null != viewportUIC ? viewportUIC.ExplicitWidth : null;
            float?explicitViewportH = null != viewportUIC ? viewportUIC.ExplicitHeight : null;

            //Debug.Log("explicitViewportW: " + explicitViewportW + "; explicitViewportH: " + explicitViewportH);

            float?viewportW = (null == explicitViewportW) ? (w - (minViewportInset * 2)) : explicitViewportW;              // TODO: 0?
            float?viewportH = (null == explicitViewportH) ? (h - (minViewportInset * 2)) : explicitViewportH;              // TODO: 0?

            //Debug.Log("viewportW: " + viewportW + "; viewportH: " + viewportH);

            // Decide which scrollbars will be visible based on the Viewport's content size
            // and the scroller's scroll policies.  A scrollbar is shown if the content size
            // greater than the Viewport's size by at least SDT.

            bool oldShowHSB = HsbVisible;
            bool oldShowVSB = VsbVisible;

            bool hAuto = false;

            //bool hsbTakeUpSpace = true; // if visible
            switch ((ScrollPolicy)scroller.GetStyle("horizontalScrollPolicy"))
            {
            case ScrollPolicy.On:
                //_canScrollHorizontally = true;
                HsbVisible = true;
                break;

            case ScrollPolicy.Auto:
                if (null != hsb && null != viewport)
                {
                    hAuto = true;
                    // = (contentW >= (viewportW + SDT));
                    //HsbVisible = (null != hsb && _canScrollHorizontally);
                    HsbVisible = (contentW >= (viewportW + SDT));
                }
                break;

            default:
                //_canScrollHorizontally = false;
                HsbVisible = false;
                break;
            }

            bool vAuto = false;

            //bool vsbTakeUpSpace = true; // if visible
            switch ((ScrollPolicy)scroller.GetStyle("verticalScrollPolicy"))
            {
            case ScrollPolicy.On:
                //_canScrollVertically = true;
                VsbVisible = true;
                break;

            case ScrollPolicy.Auto:
                if (null != vsb && null != viewport)
                {
                    vAuto = true;
                    //_canScrollVertically = (contentH >= (viewportH + SDT));
                    //VsbVisible = (null != vsb && _canScrollVertically);
                    VsbVisible = (contentH >= (viewportH + SDT));
                }
                break;

            default:
                //_canScrollVertically = false;
                VsbVisible = false;
                break;
            }

//            // if in touch mode, only show scrollbars if a scroll is currently in progress
//            if ((InteractionMode)scroller.GetStyle("interactionMode") == InteractionMode.Touch)
//            {
//                hsbTakeUpSpace = false;
//                HsbVisible = scroller.horizontalScrollInProgress;
//
//                vsbTakeUpSpace = false;
//                VsbVisible = scroller.verticalScrollInProgress;
//            }

            // Reset the Viewport's width,height to account for the visible scrollbars, unless
            // the Viewport's size was explicitly set, then we just use that.

            if (null == explicitViewportW)             // || 0 == explicitViewportW) // TODO: 0? // if (null == explicitViewportW)
            {
                viewportW = w - ((VsbVisible) ? (minViewportInset + VsbRequiredWidth()) : (minViewportInset * 2));
            }
            else
            {
                viewportW = explicitViewportW;
            }

            //Debug.Log("w: " + w);
            //Debug.Log("viewportW: " + viewportW);

            if (null == explicitViewportH)             // || 0 == explicitViewportH) // TODO: 0? // if (null == explicitViewportH)
            {
                viewportH = h - ((HsbVisible) ? (minViewportInset + HsbRequiredHeight()) : (minViewportInset * 2));
            }
            else
            {
                viewportH = explicitViewportH;
            }

            //Debug.Log("h: " + h);
            //Debug.Log("viewportH: " + viewportH);

            // If the scrollBarPolicy is auto, and we're only showing one scrollbar,
            // the Viewport may have shrunk enough to require showing the other one.

            bool hsbIsDependent = false;
            bool vsbIsDependent = false;

            if (VsbVisible && !HsbVisible && hAuto && (contentW >= (viewportW + SDT)))
            {
                HsbVisible = hsbIsDependent = true;
            }
            else if (!VsbVisible && HsbVisible && vAuto && (contentH >= (viewportH + SDT)))
            {
                VsbVisible = vsbIsDependent = true;
            }

            // If the HSB doesn't fit, hide it and give the space back.   Likewise for VSB.
            // If both scrollbars are supposed to be visible but they don't both fit,
            // then prefer to show the "non-dependent" auto scrollbar if we added the second
            // "dependent" auto scrollbar because of the space consumed by the first.

            if (HsbVisible && VsbVisible)
            {
                if (HsbFits(w, h, true) && VsbFits(w, h, true))
                {
                    // Both scrollbars fit, we're done.
                }
                else if (!HsbFits(w, h, false) && !VsbFits(w, h, false))
                {
                    // Neither scrollbar would fit, even if the other scrollbar wasn't visible.
                    HsbVisible = false;
                    VsbVisible = false;
                }
                else
                {
                    // Only one of the scrollbars will fit.  If we're showing a second "dependent"
                    // auto scrollbar because the first scrollbar consumed enough space to
                    // require it, if the first scrollbar doesn't fit, don't show either of them.

                    if (hsbIsDependent)
                    {
                        if (VsbFits(w, h, false))                          // VSB will fit if HSB isn't shown
                        {
                            HsbVisible = false;
                        }
                        else
                        {
                            VsbVisible = HsbVisible = false;
                        }
                    }
                    else if (vsbIsDependent)
                    {
                        if (HsbFits(w, h, false))                         // HSB will fit if VSB isn't shown
                        {
                            VsbVisible = false;
                        }
                        else
                        {
                            HsbVisible = VsbVisible = false;
                        }
                    }
                    else if (VsbFits(w, h, false))                     // VSB will fit if HSB isn't shown
                    {
                        HsbVisible = false;
                    }
                    else                     // HsbFits(w, h, false)   // HSB will fit if VSB isn't shown
                    {
                        VsbVisible = false;
                    }
                }
            }
            else if (HsbVisible && !HsbFits(w, h, true))              // just trying to show HSB, but it doesn't fit
            {
                HsbVisible = false;
            }
            else if (VsbVisible && !VsbFits(w, h, true))              // just trying to show VSB, but it doesn't fit
            {
                VsbVisible = false;
            }

            // Reset the Viewport's width,height to account for the visible scrollbars, unless
            // the Viewport's size was explicitly set, then we just use that.

            if (null == explicitViewportW)             // || 0 == explicitViewportW) // TODO: 0? // if (null == explicitViewportW)
            {
                viewportW = w - ((VsbVisible) ? (minViewportInset + VsbRequiredWidth()) : (minViewportInset * 2));
            }
            else
            {
                viewportW = explicitViewportW;
            }

            if (null == explicitViewportH)             // || 0 == explicitViewportH) // TODO: 0? // if (null == explicitViewportH)
            {
                viewportH = h - ((HsbVisible) ? (minViewportInset + HsbRequiredHeight()) : (minViewportInset * 2));
            }
            else
            {
                viewportH = explicitViewportH;
            }

            // Layout the Viewport and scrollbars.

            if (null != viewport)
            {
                //Debug.Log("Setting Viewport size: " + viewportW + ", " + viewportH);
                LayoutUtil.SetLayoutBoundsSize((InvalidationManagerClient)viewport, viewportW, viewportH);                  //null, null); // 20131026
                //Debug.Log("Setting Viewport position: " + minViewportInset + ", " + minViewportInset);
                LayoutUtil.SetLayoutBoundsPosition((InvalidationManagerClient)viewport, minViewportInset, minViewportInset);

                // TODO: examine why this doesn't work without going explicit!
                //((Component)viewport).Width = (float)viewportW; //TEMP
                //((Component) viewport).Height = (float) viewportH; //TEMP
                //((Component)viewport).Transform.Apply();
            }

            if (HsbVisible)
            {
                float hsbW = (VsbVisible) ? w - LayoutUtil.GetPreferredBoundsWidth(vsb) : w;
                float hsbH = LayoutUtil.GetPreferredBoundsHeight(hsb);
                LayoutUtil.SetLayoutBoundsSize(hsb, Math.Max(LayoutUtil.GetMinBoundsWidth(hsb), hsbW), hsbH);
                LayoutUtil.SetLayoutBoundsPosition(hsb, 0, h - hsbH);
            }

            if (VsbVisible)
            {
                float vsbW = LayoutUtil.GetPreferredBoundsWidth(vsb);
                float vsbH = (HsbVisible) ? h - LayoutUtil.GetPreferredBoundsHeight(hsb) : h;
                LayoutUtil.SetLayoutBoundsSize(vsb, vsbW, Math.Max(LayoutUtil.GetMinBoundsHeight(vsb), vsbH));
                LayoutUtil.SetLayoutBoundsPosition(vsb, w - vsbW, 0);
            }

            // If we've added an auto scrollbar, then the measured size is likely to have been wrong.
            // There's a risk of looping here, so we count.
            if ((_invalidationCount < 2) && (((VsbVisible != oldShowVSB) && vAuto) || ((HsbVisible != oldShowHSB) && hAuto)))
            {
                Target.InvalidateSize();

                // If the Viewport's layout is virtual, it's possible that its
                // measured size changed as a consequence of laying it out,
                // so we invalidate its size as well.
                GroupBase viewportGroup = viewport as GroupBase;
                //if (null != viewportGroup && null != viewportGroup.Layout && viewportGroup.Layout.UseVirtualLayout)
                //    viewportGroup.InvalidateSize();

                _invalidationCount += 1;
            }
            else
            {
                _invalidationCount = 0;
            }

            Target.SetContentSize(w, h);
        }