/** * Sets the scroll offset so the specified rectangle is fully in view, if possible. Coordinates * are in the scroll pane widget's coordinate system. */ public void scrollTo(float x, float y, float width, float height) { float amountX = this.amountX; if (x + width > amountX + areaWidth) amountX = x + width - areaWidth; if (x < amountX) amountX = x; scrollX(MathUtils.clamp(amountX, 0, maxX)); float amountY = this.amountY; if (amountY > maxY - y - height + areaHeight) amountY = maxY - y - height + areaHeight; if (amountY < maxY - y) amountY = maxY - y; scrollY(MathUtils.clamp(amountY, 0, maxY)); }
/** * Sets the scroll offset so the specified rectangle is fully in view and centered vertically in * the scroll pane, if possible. Coordinates are in the scroll pane widget's coordinate system. */ public void scrollToCenter(float x, float y, float width, float height) { float amountX = this.amountX; if (x + width > amountX + areaWidth) amountX = x + width - areaWidth; if (x < amountX) amountX = x; scrollX(MathUtils.clamp(amountX, 0, maxX)); float amountY = this.amountY; float centerY = maxY - y + areaHeight / 2 - height / 2; if (amountY < centerY - areaHeight / 4 || amountY > centerY + areaHeight / 4) amountY = centerY; scrollY(MathUtils.clamp(amountY, 0, maxY)); }
void clamp() { if (!clamp) return; scrollX( overscrollX ? MathUtils.clamp(amountX, -overscrollDistance, maxX + overscrollDistance) : MathUtils.clamp(amountX, 0, maxX)); scrollY( overscrollY ? MathUtils.clamp(amountY, -overscrollDistance, maxY + overscrollDistance) : MathUtils.clamp(amountY, 0, maxY)); }
public void setScrollPercentX(float percentX) { scrollX(maxX * MathUtils.clamp(percentX, 0, 1)); }
public void setScrollX(float pixels) { scrollX(MathUtils.clamp(pixels, 0, maxX)); }
public void layout() { final Drawable bg = style.background; final Drawable hScrollKnob = style.hScrollKnob; final Drawable vScrollKnob = style.vScrollKnob; float bgLeftWidth = 0, bgRightWidth = 0, bgTopHeight = 0, bgBottomHeight = 0; if (bg != null) { bgLeftWidth = bg.getLeftWidth(); bgRightWidth = bg.getRightWidth(); bgTopHeight = bg.getTopHeight(); bgBottomHeight = bg.getBottomHeight(); } float width = getWidth(); float height = getHeight(); float scrollbarHeight = 0; if (hScrollKnob != null) scrollbarHeight = hScrollKnob.getMinHeight(); if (style.hScroll != null) scrollbarHeight = Math.max(scrollbarHeight, style.hScroll.getMinHeight()); float scrollbarWidth = 0; if (vScrollKnob != null) scrollbarWidth = vScrollKnob.getMinWidth(); if (style.vScroll != null) scrollbarWidth = Math.max(scrollbarWidth, style.vScroll.getMinWidth()); // Get available space size by subtracting background's padded area. areaWidth = width - bgLeftWidth - bgRightWidth; areaHeight = height - bgTopHeight - bgBottomHeight; if (widget == null) return; // Get widget's desired width. float widgetWidth, widgetHeight; if (widget instanceof Layout) { Layout layout = (Layout) widget; widgetWidth = layout.getPrefWidth(); widgetHeight = layout.getPrefHeight(); } else { widgetWidth = widget.getWidth(); widgetHeight = widget.getHeight(); } // Determine if horizontal/vertical scrollbars are needed. scrollX = forceScrollX || (widgetWidth > areaWidth && !disableX); scrollY = forceScrollY || (widgetHeight > areaHeight && !disableY); boolean fade = fadeScrollBars; if (!fade) { // Check again, now taking into account the area that's taken up by any enabled scrollbars. if (scrollY) { areaWidth -= scrollbarWidth; if (!scrollX && widgetWidth > areaWidth && !disableX) { scrollX = true; } } if (scrollX) { areaHeight -= scrollbarHeight; if (!scrollY && widgetHeight > areaHeight && !disableY) { scrollY = true; areaWidth -= scrollbarWidth; } } } // Set the widget area bounds. widgetAreaBounds.set(bgLeftWidth, bgBottomHeight, areaWidth, areaHeight); if (fade) { // Make sure widget is drawn under fading scrollbars. if (scrollX) areaHeight -= scrollbarHeight; if (scrollY) areaWidth -= scrollbarWidth; } else { if (scrollbarsOnTop) { // Make sure widget is drawn under non-fading scrollbars. if (scrollX) widgetAreaBounds.height += scrollbarHeight; if (scrollY) widgetAreaBounds.width += scrollbarWidth; } else { // Offset widget area y for horizontal scrollbar. if (scrollX) { if (hScrollOnBottom) { widgetAreaBounds.y += scrollbarHeight; } else { widgetAreaBounds.y = 0; } } // Offset widget area x for vertical scrollbar. if (scrollY) { if (vScrollOnRight) { widgetAreaBounds.x = 0; } else { widgetAreaBounds.x += scrollbarWidth; } } } } // If the widget is smaller than the available space, make it take up the available space. widgetWidth = disableX ? width : Math.max(areaWidth, widgetWidth); widgetHeight = disableY ? height : Math.max(areaHeight, widgetHeight); maxX = widgetWidth - areaWidth; maxY = widgetHeight - areaHeight; if (fade) { // Make sure widget is drawn under fading scrollbars. if (scrollX) maxY -= scrollbarHeight; if (scrollY) maxX -= scrollbarWidth; } scrollX(MathUtils.clamp(amountX, 0, maxX)); scrollY(MathUtils.clamp(amountY, 0, maxY)); // Set the bounds and scroll knob sizes if scrollbars are needed. if (scrollX) { if (hScrollKnob != null) { float hScrollHeight = style.hScroll != null ? style.hScroll.getMinHeight() : hScrollKnob.getMinHeight(); // the small gap where the two scroll bars intersect might have to flip from right to left float boundsX, boundsY; if (vScrollOnRight) { boundsX = bgLeftWidth; } else { boundsX = bgLeftWidth + scrollbarWidth; } // bar on the top or bottom if (hScrollOnBottom) { boundsY = bgBottomHeight; } else { boundsY = height - bgTopHeight - hScrollHeight; } hScrollBounds.set(boundsX, boundsY, areaWidth, hScrollHeight); hKnobBounds.width = Math.max( hScrollKnob.getMinWidth(), (int) (hScrollBounds.width * areaWidth / widgetWidth)); hKnobBounds.height = hScrollKnob.getMinHeight(); hKnobBounds.x = hScrollBounds.x + (int) ((hScrollBounds.width - hKnobBounds.width) * getScrollPercentX()); hKnobBounds.y = hScrollBounds.y; } else { hScrollBounds.set(0, 0, 0, 0); hKnobBounds.set(0, 0, 0, 0); } } if (scrollY) { if (vScrollKnob != null) { float vScrollWidth = style.vScroll != null ? style.vScroll.getMinWidth() : vScrollKnob.getMinWidth(); // the small gap where the two scroll bars intersect might have to flip from bottom to top float boundsX, boundsY; if (hScrollOnBottom) { boundsY = height - bgTopHeight - areaHeight; } else { boundsY = bgBottomHeight; } // bar on the left or right if (vScrollOnRight) { boundsX = width - bgRightWidth - vScrollWidth; } else { boundsX = bgLeftWidth; } vScrollBounds.set(boundsX, boundsY, vScrollWidth, areaHeight); vKnobBounds.width = vScrollKnob.getMinWidth(); vKnobBounds.height = Math.max( vScrollKnob.getMinHeight(), (int) (vScrollBounds.height * areaHeight / widgetHeight)); if (vScrollOnRight) { vKnobBounds.x = width - bgRightWidth - vScrollKnob.getMinWidth(); } else { vKnobBounds.x = bgLeftWidth; } vKnobBounds.y = vScrollBounds.y + (int) ((vScrollBounds.height - vKnobBounds.height) * (1 - getScrollPercentY())); } else { vScrollBounds.set(0, 0, 0, 0); vKnobBounds.set(0, 0, 0, 0); } } widget.setSize(widgetWidth, widgetHeight); if (widget instanceof Layout) ((Layout) widget).validate(); }
public void act(float delta) { super.act(delta); boolean panning = flickScrollListener.getGestureDetector().isPanning(); if (fadeAlpha > 0 && fadeScrollBars && !panning && !touchScrollH && !touchScrollV) { fadeDelay -= delta; if (fadeDelay <= 0) fadeAlpha = Math.max(0, fadeAlpha - delta); } if (flingTimer > 0) { resetFade(); float alpha = flingTimer / flingTime; amountX -= velocityX * alpha * delta; amountY -= velocityY * alpha * delta; clamp(); // Stop fling if hit overscroll distance. if (amountX == -overscrollDistance) velocityX = 0; if (amountX >= maxX + overscrollDistance) velocityX = 0; if (amountY == -overscrollDistance) velocityY = 0; if (amountY >= maxY + overscrollDistance) velocityY = 0; flingTimer -= delta; if (flingTimer <= 0) { velocityX = 0; velocityY = 0; } } if (smoothScrolling && flingTimer <= 0 && !touchScrollH && !touchScrollV && !panning) { if (visualAmountX != amountX) { if (visualAmountX < amountX) visualScrollX( Math.min( amountX, visualAmountX + Math.max(150 * delta, (amountX - visualAmountX) * 5 * delta))); else visualScrollX( Math.max( amountX, visualAmountX - Math.max(150 * delta, (visualAmountX - amountX) * 5 * delta))); } if (visualAmountY != amountY) { if (visualAmountY < amountY) visualScrollY( Math.min( amountY, visualAmountY + Math.max(150 * delta, (amountY - visualAmountY) * 5 * delta))); else visualScrollY( Math.max( amountY, visualAmountY - Math.max(150 * delta, (visualAmountY - amountY) * 5 * delta))); } } else { if (visualAmountX != amountX) visualScrollX(amountX); if (visualAmountY != amountY) visualScrollY(amountY); } if (!panning) { if (overscrollX && scrollX) { if (amountX < 0) { resetFade(); amountX += (overscrollSpeedMin + (overscrollSpeedMax - overscrollSpeedMin) * -amountX / overscrollDistance) * delta; if (amountX > 0) scrollX(0); } else if (amountX > maxX) { resetFade(); amountX -= (overscrollSpeedMin + (overscrollSpeedMax - overscrollSpeedMin) * -(maxX - amountX) / overscrollDistance) * delta; if (amountX < maxX) scrollX(maxX); } } if (overscrollY && scrollY) { if (amountY < 0) { resetFade(); amountY += (overscrollSpeedMin + (overscrollSpeedMax - overscrollSpeedMin) * -amountY / overscrollDistance) * delta; if (amountY > 0) scrollY(0); } else if (amountY > maxY) { resetFade(); amountY -= (overscrollSpeedMin + (overscrollSpeedMax - overscrollSpeedMin) * -(maxY - amountY) / overscrollDistance) * delta; if (amountY < maxY) scrollY(maxY); } } } }