private ActorGestureListener flickScrollListener;\r
\r
boolean scrollX, scrollY;\r
+ boolean vScrollOnRight = true;\r
+ boolean hScrollOnBottom = true;\r
float amountX, amountY;\r
float visualAmountX, visualAmountY;\r
float maxX, maxY;\r
if (scrollY) widgetAreaBounds.width += scrollbarWidth;\r
} else {\r
// Offset widget area y for horizontal scrollbar.\r
- if (scrollX) widgetAreaBounds.y += scrollbarHeight;\r
+ if (scrollX) {\r
+ if (hScrollOnBottom) {\r
+ widgetAreaBounds.y += scrollbarHeight;\r
+ } else {\r
+ widgetAreaBounds.y = 0;\r
+ }\r
+ }\r
+ // Offset widget area x for vertical scrollbar.\r
+ if (scrollY) {\r
+ if (vScrollOnRight) {\r
+ widgetAreaBounds.x = 0;\r
+ } else {\r
+ widgetAreaBounds.x += scrollbarWidth;\r
+ }\r
+ }\r
}\r
}\r
\r
if (scrollX) {\r
if (hScrollKnob != null) {\r
float hScrollHeight = style.hScroll != null ? style.hScroll.getMinHeight() : hScrollKnob.getMinHeight();\r
- hScrollBounds.set(bgLeftWidth, bgBottomHeight, areaWidth, hScrollHeight);\r
+ // the small gap where the two scroll bars intersect might have to flip from right to left\r
+ float boundsX, boundsY;\r
+ if (vScrollOnRight) {\r
+ boundsX = bgLeftWidth;\r
+ } else {\r
+ boundsX = bgLeftWidth + scrollbarWidth;\r
+ }\r
+ // bar on the top or bottom\r
+ if (hScrollOnBottom) {\r
+ boundsY = bgBottomHeight;\r
+ } else {\r
+ System.out.println("height: " + height);\r
+ System.out.println("areaHeight: " + areaHeight);\r
+ System.out.println("bgBottomHeight: " + bgBottomHeight);\r
+ System.out.println("bgTopHeight: " + bgTopHeight); \r
+ boundsY = height - bgTopHeight - hScrollHeight;\r
+ }\r
+ hScrollBounds.set(boundsX, boundsY, areaWidth, hScrollHeight);\r
hKnobBounds.width = Math.max(hScrollKnob.getMinWidth(), (int)(hScrollBounds.width * areaWidth / widgetWidth));\r
hKnobBounds.height = hScrollKnob.getMinHeight();\r
hKnobBounds.x = hScrollBounds.x + (int)((hScrollBounds.width - hKnobBounds.width) * getScrollPercentX());\r
if (scrollY) {\r
if (vScrollKnob != null) {\r
float vScrollWidth = style.vScroll != null ? style.vScroll.getMinWidth() : vScrollKnob.getMinWidth();\r
- vScrollBounds.set(width - bgRightWidth - vScrollWidth, height - bgTopHeight - areaHeight, vScrollWidth, areaHeight);\r
+ // the small gap where the two scroll bars intersect might have to flip from bottom to top\r
+ float boundsX, boundsY;\r
+ if (hScrollOnBottom) {\r
+ boundsY = height - bgTopHeight - areaHeight;\r
+ } else {\r
+ boundsY = bgBottomHeight;\r
+ }\r
+ // bar on the left or right\r
+ if (vScrollOnRight) {\r
+ boundsX = width - bgRightWidth - vScrollWidth;\r
+ } else {\r
+ boundsX = bgLeftWidth;\r
+ }\r
+ vScrollBounds.set(boundsX, boundsY, vScrollWidth, areaHeight);\r
vKnobBounds.width = vScrollKnob.getMinWidth();\r
vKnobBounds.height = Math.max(vScrollKnob.getMinHeight(), (int)(vScrollBounds.height * areaHeight / widgetHeight));\r
- vKnobBounds.x = width - bgRightWidth - vScrollKnob.getMinWidth();\r
+ if (vScrollOnRight) {\r
+ vKnobBounds.x = width - bgRightWidth - vScrollKnob.getMinWidth();\r
+ } else {\r
+ vKnobBounds.x = 0;\r
+ }\r
vKnobBounds.y = vScrollBounds.y + (int)((vScrollBounds.height - vKnobBounds.height) * (1 - getScrollPercentY()));\r
} else {\r
vScrollBounds.set(0, 0, 0, 0);\r
this.clamp = clamp;\r
}\r
\r
+ /** Put the vertical scroll bar and knob on the left or right side of the ScrollPane\r
+ * @param atRight set to true to draw on the right, false to draw on the left (default : right)\r
+ */\r
+ public void setVScrollBarAtRight(boolean atRight) {\r
+ vScrollOnRight = atRight;\r
+ }\r
+\r
+ /** Put the vertical scroll bar and knob on the top (y coords, not draw order) or bottom of the ScrollPane\r
+ * @param atBottom set to true to draw on the bottom, false to draw on the top (default : bottom)\r
+ */\r
+ public void setHScrollBarAtBottom(boolean atBottom) {\r
+ hScrollOnBottom = atBottom;\r
+ }\r
+\r
/** When true the scroll bars fade out after some time of not being used. */\r
public void setFadeScrollBars (boolean fadeScrollBars) {\r
if (this.fadeScrollBars == fadeScrollBars) return;\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright 2011 See AUTHORS file.\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ ******************************************************************************/\r
+\r
+package com.badlogic.gdx.tests;\r
+\r
+import com.badlogic.gdx.Gdx;\r
+import com.badlogic.gdx.graphics.GL10;\r
+import com.badlogic.gdx.scenes.scene2d.Stage;\r
+import com.badlogic.gdx.scenes.scene2d.ui.Label;\r
+import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;\r
+import com.badlogic.gdx.scenes.scene2d.ui.Skin;\r
+import com.badlogic.gdx.scenes.scene2d.ui.Table;\r
+import com.badlogic.gdx.tests.utils.GdxTest;\r
+\r
+/**\r
+ * Test switch of scroll bars + knobs from right to left, and bottom to top\r
+ */\r
+public class ScrollPaneScrollBarsTest extends GdxTest {\r
+ private Stage stage;\r
+ private Table bottomLeft, bottomRight, topLeft, topRight,\r
+ horizOnlyTop, horizOnlyBottom, vertOnlyLeft, vertOnlyRight;\r
+\r
+ public void create () {\r
+ stage = new Stage(0, 0, false);\r
+ Skin skin = new Skin(Gdx.files.internal("data/uiskin.json"));\r
+ Gdx.input.setInputProcessor(stage);\r
+\r
+ // Gdx.graphics.setVSync(false);\r
+\r
+ float width = Gdx.graphics.getWidth();\r
+ float height = Gdx.graphics.getHeight();\r
+ float gap = 8;\r
+ float x = gap;\r
+ float y = gap;\r
+ float contWidth = width / 2 - gap * 1.5f;\r
+ float contHeight = height / 4 - gap * 1.25f;\r
+\r
+ bottomLeft = new Table();\r
+ bottomLeft.setPosition(x, y);\r
+ bottomLeft.setSize(contWidth, contHeight);\r
+ stage.addActor(bottomLeft);\r
+ \r
+ bottomRight = new Table();\r
+ bottomRight.setSize(contWidth, contHeight);\r
+ x = bottomLeft.getX() + bottomLeft.getWidth() + gap;\r
+ bottomRight.setPosition(x, y);\r
+ stage.addActor(bottomRight);\r
+\r
+ topLeft = new Table();\r
+ topLeft.setSize(contWidth, contHeight);\r
+ x = bottomLeft.getX();\r
+ y = bottomLeft.getY() + bottomLeft.getHeight() + gap;\r
+ topLeft.setPosition(x, y);\r
+ stage.addActor(topLeft);\r
+\r
+ topRight = new Table();\r
+ topRight.setSize(contWidth, contHeight);\r
+ x = bottomRight.getX();\r
+ y = topLeft.getY();\r
+ topRight.setPosition(x, y);\r
+ stage.addActor(topRight);\r
+ \r
+ horizOnlyTop = new Table();\r
+ horizOnlyTop.setSize(contWidth, contHeight);\r
+ x = topRight.getX();\r
+ y = topRight.getY() + topRight.getHeight() + gap;\r
+ horizOnlyTop.setPosition(x, y);\r
+ stage.addActor(horizOnlyTop);\r
+ \r
+ horizOnlyBottom = new Table();\r
+ horizOnlyBottom.setSize(contWidth, contHeight);\r
+ x = topLeft.getX();\r
+ y = topLeft.getY() + topLeft.getHeight() + gap;\r
+ horizOnlyBottom.setPosition(x, y);\r
+ stage.addActor(horizOnlyBottom);\r
+\r
+ vertOnlyLeft = new Table();\r
+ vertOnlyLeft.setSize(contWidth, contHeight);\r
+ x = horizOnlyBottom.getX();\r
+ y = horizOnlyBottom.getY() + horizOnlyBottom.getHeight() + gap;\r
+ vertOnlyLeft.setPosition(x, y);\r
+ stage.addActor(vertOnlyLeft);\r
+\r
+ vertOnlyRight = new Table();\r
+ vertOnlyRight.setSize(contWidth, contHeight);\r
+ x = horizOnlyTop.getX();\r
+ y = horizOnlyTop.getY() + horizOnlyTop.getHeight() + gap;\r
+ vertOnlyRight.setPosition(x, y);\r
+ stage.addActor(vertOnlyRight);\r
+\r
+ Table bottomLeftTable = new Table();\r
+ Table bottomRightTable = new Table();\r
+ Table topLeftTable = new Table();\r
+ Table topRightTable = new Table();\r
+ Table horizOnlyTopTable = new Table();\r
+ Table horizOnlyBottomTable = new Table();\r
+ Table vertOnlyLeftTable = new Table();\r
+ Table vertOnlyRightTable = new Table();\r
+\r
+ final ScrollPane bottomLeftScroll = new ScrollPane(bottomLeftTable, skin);\r
+ bottomLeftScroll.setVScrollBarAtRight(false);\r
+ bottomLeftScroll.setHScrollBarAtBottom(true);\r
+\r
+ final ScrollPane bottomRightScroll = new ScrollPane(bottomRightTable, skin);\r
+ bottomRightScroll.setVScrollBarAtRight(true);\r
+ bottomRightScroll.setHScrollBarAtBottom(true);\r
+\r
+ final ScrollPane topLeftScroll = new ScrollPane(topLeftTable, skin);\r
+ topLeftScroll.setVScrollBarAtRight(false);\r
+ topLeftScroll.setHScrollBarAtBottom(false);\r
+\r
+ final ScrollPane topRightScroll = new ScrollPane(topRightTable, skin);\r
+ topRightScroll.setVScrollBarAtRight(true);\r
+ topRightScroll.setHScrollBarAtBottom(false);\r
+ \r
+ final ScrollPane horizOnlyTopScroll = new ScrollPane(horizOnlyTopTable, skin);\r
+ horizOnlyTopScroll.setHScrollBarAtBottom(false);\r
+ \r
+ final ScrollPane horizOnlyBottomScroll = new ScrollPane(horizOnlyBottomTable, skin);\r
+ horizOnlyBottomScroll.setHScrollBarAtBottom(true);\r
+\r
+ final ScrollPane vertOnlyLeftScroll = new ScrollPane(vertOnlyLeftTable, skin);\r
+ vertOnlyLeftScroll.setVScrollBarAtRight(false);\r
+\r
+ final ScrollPane vertOnlyRightScroll = new ScrollPane(vertOnlyRightTable, skin);\r
+ vertOnlyRightScroll.setVScrollBarAtRight(true);\r
+ \r
+ ScrollPane[] scrollPanes = new ScrollPane[] {bottomLeftScroll, bottomRightScroll, topLeftScroll, topRightScroll,\r
+ horizOnlyTopScroll, horizOnlyBottomScroll };\r
+ // want to see all scroll bars all the time\r
+ for (ScrollPane pane : scrollPanes) {\r
+ pane.setFadeScrollBars(false);\r
+ }\r
+\r
+ Table[] tables = new Table[] { bottomLeftTable, bottomRightTable, topLeftTable, topRightTable,\r
+ horizOnlyTopTable, horizOnlyBottomTable};\r
+ for (Table t : tables) {\r
+ t.pad(10).defaults().expandX().space(4);\r
+ }\r
+ \r
+ horizOnlyTopTable.add(new Label("HORIZONTAL-ONLY-TOP verify HORIZONTAL scroll bar is on the TOP and properly aligned", skin));\r
+ horizOnlyBottomTable.add(new Label("HORIZONTAL-ONLY-BOTTOM verify HORIZONTAL scroll bar is on the BOTTOM and properly aligned", skin));\r
+ \r
+ for (int i = 0; i < 12; i++) {\r
+ bottomLeftTable.row();\r
+ bottomRightTable.row();\r
+ topLeftTable.row();\r
+ topRightTable.row(); \r
+\r
+ bottomLeftTable.add(new Label(i + " BOTTOM-LEFT verify scroll bars are on the BOTTOM and the LEFT, and are properly aligned", skin));\r
+ bottomRightTable.add(new Label(i + " BOTTOM-RIGHT verify scroll bars are on the BOTTOM and the RIGHT, and are properly aligned", skin));\r
+ topLeftTable.add(new Label(i + " TOP-LEFT verify scroll bars are on the TOP and the LEFT, and are properly aligned", skin));\r
+ topRightTable.add(new Label(i + " TOP-RIGHT verify scroll bars are on the TOP and the RIGHT, and are properly aligned", skin));\r
+\r
+ vertOnlyLeftTable.row();\r
+ vertOnlyRightTable.row();\r
+\r
+ vertOnlyLeftTable.add(new Label("VERT-ONLY-LEFT", skin));\r
+ vertOnlyRightTable.add(new Label("VERT-ONLY-RIGHT", skin));\r
+ } \r
+\r
+ bottomLeft.add(bottomLeftScroll).expand().fill().colspan(4);\r
+ bottomRight.add(bottomRightScroll).expand().fill().colspan(4);\r
+ topLeft.add(topLeftScroll).expand().fill().colspan(4);\r
+ topRight.add(topRightScroll).expand().fill().colspan(4);\r
+ horizOnlyTop.add(horizOnlyTopScroll).expand().fill().colspan(4);\r
+ horizOnlyBottom.add(horizOnlyBottomScroll).expand().fill().colspan(4);\r
+ vertOnlyLeft.add(vertOnlyLeftScroll).expand().fill().colspan(4);\r
+ vertOnlyRight.add(vertOnlyRightScroll).expand().fill().colspan(4);\r
+ }\r
+\r
+ public void render () {\r
+ Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);\r
+ stage.act(Gdx.graphics.getDeltaTime());\r
+ stage.draw();\r
+ Table.drawDebug(stage);\r
+ }\r
+\r
+ public void resize (int width, int height) {\r
+ stage.setViewport(width, height, false);\r
+ // Gdx.gl.glViewport(100, 100, width - 200, height - 200);\r
+ // stage.setViewport(800, 600, false, 100, 100, width - 200, height - 200);\r
+ }\r
+\r
+ public void dispose () {\r
+ stage.dispose();\r
+ }\r
+\r
+ public boolean needsGL20 () {\r
+ return false;\r
+ }\r
+}\r