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