package org.terasology.rendering.gui.components; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.Display; import org.terasology.rendering.gui.framework.IScrollListener; import org.terasology.rendering.gui.framework.UIDisplayContainer; import javax.vecmath.Vector2f; import java.util.ArrayList; /* * A simple graphical ScrollBar * * @author Anton Kireev <adeon.k87@gmail.com> * @version 0.1 */ public class UIScrollBar extends UIDisplayContainer { //ScrollBarElements private UIScrollBarThumb _scrolBarThumb; //Scroll Listeners private final ArrayList<IScrollListener> _scrollListeners = new ArrayList<IScrollListener>(); //Options private float _max; private float _min; private float _step; private float _prevMousePos = -1; private ScrollType _scrollType = ScrollType.vertical; private boolean _scrolled = false; private boolean _wheelled = false; private float _containerLength = 0.0f; private float _contentLength = 0.0f; private float _value = 0.0f; private float _oldValue = 0.0f; public static enum ScrollType { vertical, horizontal } public UIScrollBar(Vector2f size, ScrollType scrollType) { setScrollType(scrollType); switch (_scrollType) { case vertical: setSize(new Vector2f(15f, size.y)); _scrolBarThumb = new UIScrollBarThumb(getSize(), ScrollType.vertical); break; case horizontal: setSize(new Vector2f(size.x, 15f)); _scrolBarThumb = new UIScrollBarThumb(getSize(), ScrollType.horizontal); break; } _scrolBarThumb.setVisible(true); addDisplayElement(_scrolBarThumb); } public void update() { updateThumb(); Vector2f mousePos = new Vector2f(Mouse.getX(), Display.getHeight() - Mouse.getY()); if (intersects(mousePos)) { if (_mouseDown) { _scrolled = true; if (_prevMousePos == -1) { if (_scrollType == ScrollType.vertical) { _prevMousePos = mousePos.y; } else { _prevMousePos = mousePos.x; } } } } if (_scrolled) { scrolled(calculateScrollFromMouse(_scrollType == ScrollType.vertical ? mousePos.y : mousePos.x)); } if (_wheelMoved != 0 && _wheelled) { scrolled(calculateScrollFromWheel(((-1) * _wheelMoved / 120) / _step)); } if (!_mouseDown || !_scrolled || _mouseUp) { _scrolled = false; _mouseDown = false; _prevMousePos = -1; _mouseUp = false; } super.update(); } public void scrolled(float scrollTo) { _scrolBarThumb.setThumbPosition((_scrolBarThumb.getThumbPosition() + scrollTo)); calculateValue(); for (int i = 0; i < _scrollListeners.size(); i++) { _scrollListeners.get(i).scrolled(this); } } private float calculateScrollFromMouse(float mousePos) { float scrollValue = 0; if (_max < (_scrolBarThumb.getThumbPosition() + mousePos - _prevMousePos + _scrolBarThumb.getThumbSize())) { mousePos = _max - _scrolBarThumb.getThumbSize() + _prevMousePos - _scrolBarThumb.getThumbPosition(); } else if (_min > (_scrolBarThumb.getThumbPosition() + mousePos - _prevMousePos)) { mousePos = _min + _prevMousePos - _scrolBarThumb.getThumbPosition(); } scrollValue = mousePos - _prevMousePos; _prevMousePos = mousePos; return scrollValue; } public float calculateScrollFromWheel(float wheelValue) { float scrollValue = wheelValue; if (_max < (_scrolBarThumb.getThumbPosition() + wheelValue + _scrolBarThumb.getThumbSize())) { scrollValue = _max - _scrolBarThumb.getThumbSize() - _scrolBarThumb.getThumbPosition(); } else if (_min > (_scrolBarThumb.getThumbPosition() + wheelValue)) { scrollValue = _min - _scrolBarThumb.getThumbPosition(); } return scrollValue; } public void addScrollListener(IScrollListener listener) { _scrollListeners.add(listener); } private void updateThumb() { float newScrollSize = _containerLength * _step; if (newScrollSize != _scrolBarThumb.getThumbSize()) { _scrolBarThumb.resize(newScrollSize); } if ((_scrolBarThumb.getThumbPosition() + _scrolBarThumb.getThumbSize() > _max)) { _prevMousePos = _scrolBarThumb.getThumbPosition(); scrolled((_scrolBarThumb.getThumbPosition() + _scrolBarThumb.getThumbSize()) - _max); } calculateValue(); } public void setScrollType(ScrollType scrollType) { _scrollType = scrollType; } private void calculateValue() { _value = _scrolBarThumb.getThumbPosition() / _step; } public void setMaxMin(float min, float max) { _min = min; _max = max; switch (_scrollType) { case vertical: setSize(new Vector2f(15f, max)); break; case horizontal: setSize(new Vector2f(max, 15f)); break; } } public boolean isScrolled() { return _scrolled; } public void setStep(float contentLength, float containerLength) { try { _step = containerLength / contentLength; if (_step > 1.0f) { _step = 1.0f; } } catch (ArithmeticException e) { _step = 1.0f; } _containerLength = containerLength; _contentLength = contentLength; } public float getValue() { return _value; } public float getOldValue() { return _oldValue; } public float getStep() { return _step; } public void setWheelled(boolean wheelled) { _wheelled = wheelled; } }