001package squidpony.squidgrid.gui.gdx;
002
003import com.badlogic.gdx.Gdx;
004import com.badlogic.gdx.InputAdapter;
005import com.badlogic.gdx.InputProcessor;
006import com.badlogic.gdx.math.MathUtils;
007
008/**
009 * This mouse processor allows for easy conversion to a grid based system. This
010 * class covers all aspects of mouse movement and clicking, passing those off
011 * to a given InputProcessor after converting to cell-based grid coordinates
012 * instead of pixel-based screen coordinates. It also passes off scroll events
013 * to the InputProcessor without additional changes.
014 *
015 * This class is meant to be used as a wrapper to your own mouse InputProcessor,
016 * it simply converts the coordinates from UI Component x,y to Grid based x,y
017 *
018 * @author Eben Howard - http://squidpony.com - howard@squidpony.com
019 * @author Tommy Ettinger
020 */
021public class SquidMouse extends InputAdapter {
022
023        protected float cellWidth, cellHeight, gridWidth, gridHeight;
024    protected int  offsetX, offsetY;
025    protected InputProcessor processor;
026
027    /**
028     * Sets the size of the cell so that all mouse input can be evaluated as
029     * relative to the grid. All input is passed to the provided InputProcessor once
030     * it has had its coordinates translated to grid coordinates.
031     *
032     * Offsets are initialized to 0 here, and the grid is assumed to take up the
033     * full game window.
034     *
035     * @param cellWidth
036     * @param cellHeight
037     * @param processor an InputProcessor that implements some of touchUp(), touchDown(), touchDragged(), mouseMoved(), or scrolled().
038     */
039    public SquidMouse(float cellWidth, float cellHeight, InputProcessor processor) {
040        this.cellWidth = cellWidth;
041        this.cellHeight = cellHeight;
042        this.processor = processor;
043        this.offsetX = 0;
044        this.offsetY = 0;
045        this.gridWidth = Gdx.graphics.getWidth() / cellWidth;
046        this.gridHeight = Gdx.graphics.getHeight() / cellHeight;
047    }
048
049    /**
050     * Sets the size of the cell so that all mouse input can be evaluated as
051     * relative to the grid. Offsets can be specified for x and y if the grid
052     * is displayed at a position other than the full screen. Instead of
053     * specifying an offset from the bottom and right edges, specify the
054     * width and height in grid cells of the area to receive input. All input
055     * is passed to the provided InputProcessor once it's had its coordinates
056     * translated to grid coordinates.
057     *
058     * If the input is not within the bounds of the grid as determined by
059     * gridWidth, gridHeight, offsetX, and offsetY, the input will be clamped.
060     *
061     * @param cellWidth
062     * @param cellHeight
063     * @param gridWidth
064     * @param gridHeight
065     * @param offsetX
066     * @param offsetY
067     * @param processor an InputProcessor that implements some of touchUp(), touchDown(), touchDragged(), mouseMoved(), or scrolled().
068     */
069    public SquidMouse(float cellWidth, float cellHeight, float gridWidth, float gridHeight, int offsetX, int offsetY, InputProcessor processor) {
070        this.cellWidth = cellWidth;
071        this.cellHeight = cellHeight;
072        this.processor = processor;
073        this.offsetX = offsetX;
074        this.offsetY = offsetY;
075        this.gridWidth = gridWidth;
076        this.gridHeight = gridHeight;
077    }
078
079    public float getCellWidth() {
080        return cellWidth;
081    }
082
083    public float getCellHeight() {
084        return cellHeight;
085    }
086
087    public int getOffsetX() {
088        return offsetX;
089    }
090
091    public int getOffsetY() {
092        return offsetY;
093    }
094
095    public float getGridWidth() {
096        return gridWidth;
097    }
098
099    public float getGridHeight() {
100        return gridHeight;
101    }
102
103    public void setCellWidth(float cellWidth) {
104        this.cellWidth = cellWidth;
105    }
106
107    public void setCellHeight(float cellHeight) {
108        this.cellHeight = cellHeight;
109    }
110
111    public void setOffsetX(int offsetX) {
112        this.offsetX = offsetX;
113    }
114
115    public void setOffsetY(int offsetY) {
116        this.offsetY = offsetY;
117    }
118
119    public void setGridWidth(float gridWidth) {
120        this.gridWidth = gridWidth;
121    }
122
123    public void setGridHeight(float gridHeight) {
124        this.gridHeight = gridHeight;
125    }
126
127
128    public void reinitialize(float cellWidth, float cellHeight)
129    {
130        this.cellWidth = cellWidth;
131        this.cellHeight = cellHeight;
132        this.offsetX = 0;
133        this.offsetY = 0;
134        this.gridWidth = Gdx.graphics.getWidth() / cellWidth;
135        this.gridHeight = Gdx.graphics.getHeight() / cellHeight;
136    }
137    public void reinitialize(float cellWidth, float cellHeight, float gridWidth, float gridHeight, int offsetX, int offsetY)
138    {
139        this.cellWidth = cellWidth;
140        this.cellHeight = cellHeight;
141        this.offsetX = offsetX;
142        this.offsetY = offsetY;
143        this.gridWidth = gridWidth;
144        this.gridHeight = gridHeight;
145    }
146
147    /**
148     * Gets the InputProcessor this object uses to handle mouse input.
149     * @return the wrapped InputProcessor.
150     */
151    public InputProcessor getProcessor() {
152        return processor;
153    }
154
155    /**
156     * Sets the InputProcessor this object uses to handle mouse input.
157     * @param processor an InputProcessor that implements some of touchUp(), touchDown(), touchDragged(), mouseMoved(), or scrolled().
158     */
159    public void setProcessor(InputProcessor processor) {
160        this.processor = processor;
161    }
162
163        protected int translateX(int screenX) {
164                return MathUtils.floor(MathUtils.clamp((screenX - offsetX) / cellWidth, 0.0f, gridWidth - 1.0f));
165        }
166
167        protected int translateY(int screenY) {
168                return MathUtils.floor(MathUtils.clamp((screenY - offsetY) / cellHeight, 0.0f, gridHeight - 1.0f));
169        }
170
171    @Override
172    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
173        return processor.touchDown(translateX(screenX), translateY(screenY), pointer, button);
174    }
175
176    @Override
177    public boolean touchUp(int screenX, int screenY, int pointer, int button) {
178        return processor.touchUp(translateX(screenX), translateY(screenY), pointer, button);
179    }
180
181    @Override
182    public boolean touchDragged(int screenX, int screenY, int pointer) {
183        return processor.touchDragged(translateX(screenX), translateY(screenY), pointer);
184    }
185
186    @Override
187    public boolean mouseMoved(int screenX, int screenY) {
188        return processor.mouseMoved(translateX(screenX), translateY(screenY));
189    }
190
191    @Override
192    public boolean scrolled(int amount) {
193        return processor.scrolled(amount);
194    }
195}