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 the width of one cell in screen coordinates, usually pixels
036     * @param cellHeight the height of one cell in screen coordinates, usually pixels
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        offsetX = 0;
044        offsetY = 0;
045        gridWidth = Gdx.graphics.getWidth() / cellWidth;
046        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. Specify the
053     * width and height in grid cells of the area to receive input, as well as
054     * the offsets from the bottom and left edges also measured in screen
055     * coordinates, which are often pixels but may be stretched or shrunk.
056     * All input is passed to the provided InputProcessor once it's had its
057     * coordinates translated to grid coordinates.
058     *
059     * If the input is not within the bounds of the grid as determined by
060     * gridWidth, gridHeight, offsetX, and offsetY, the input will be clamped.
061     *
062     * @param cellWidth the width of one cell in screen coordinates, usually pixels
063     * @param cellHeight the height of one cell in screen coordinates, usually pixels
064     * @param gridWidth in number of cells horizontally on the grid
065     * @param gridHeight in number of cells vertically on the grid
066     * @param offsetX the horizontal offset in screen coordinates, usually pixels
067     * @param offsetY the vertical offset in screen coordinates, usually pixels
068     * @param processor an InputProcessor that implements some of touchUp(), touchDown(), touchDragged(), mouseMoved(), or scrolled().
069     */
070    public SquidMouse(float cellWidth, float cellHeight, float gridWidth, float gridHeight, int offsetX, int offsetY, InputProcessor processor) {
071        this.cellWidth = cellWidth;
072        this.cellHeight = cellHeight;
073        this.processor = processor;
074        this.offsetX = offsetX;
075        this.offsetY = offsetY;
076        this.gridWidth = gridWidth;
077        this.gridHeight = gridHeight;
078    }
079
080    public float getCellWidth() {
081        return cellWidth;
082    }
083
084    public float getCellHeight() {
085        return cellHeight;
086    }
087
088    public int getOffsetX() {
089        return offsetX;
090    }
091
092    public int getOffsetY() {
093        return offsetY;
094    }
095
096    public float getGridWidth() {
097        return gridWidth;
098    }
099
100    public float getGridHeight() {
101        return gridHeight;
102    }
103
104    public void setCellWidth(float cellWidth) {
105        this.cellWidth = cellWidth;
106    }
107
108    public void setCellHeight(float cellHeight) {
109        this.cellHeight = cellHeight;
110    }
111
112    public void setOffsetX(int offsetX) {
113        this.offsetX = offsetX;
114    }
115
116    public void setOffsetY(int offsetY) {
117        this.offsetY = offsetY;
118    }
119
120    public void setGridWidth(float gridWidth) {
121        this.gridWidth = gridWidth;
122    }
123
124    public void setGridHeight(float gridHeight) {
125        this.gridHeight = gridHeight;
126    }
127
128
129    public void reinitialize(float cellWidth, float cellHeight)
130    {
131        this.cellWidth = cellWidth;
132        this.cellHeight = cellHeight;
133        offsetX = 0;
134        offsetY = 0;
135        gridWidth = Gdx.graphics.getWidth() / cellWidth;
136        gridHeight = Gdx.graphics.getHeight() / cellHeight;
137    }
138    public void reinitialize(float cellWidth, float cellHeight, float gridWidth, float gridHeight, int offsetX, int offsetY)
139    {
140        this.cellWidth = cellWidth;
141        this.cellHeight = cellHeight;
142        this.offsetX = offsetX;
143        this.offsetY = offsetY;
144        this.gridWidth = gridWidth;
145        this.gridHeight = gridHeight;
146    }
147
148    /**
149     * Gets the InputProcessor this object uses to handle mouse input.
150     * @return the wrapped InputProcessor.
151     */
152    public InputProcessor getProcessor() {
153        return processor;
154    }
155
156    /**
157     * Sets the InputProcessor this object uses to handle mouse input.
158     * @param processor an InputProcessor that implements some of touchUp(), touchDown(), touchDragged(), mouseMoved(), or scrolled().
159     */
160    public void setProcessor(InputProcessor processor) {
161        this.processor = processor;
162    }
163
164        protected int translateX(int screenX) {
165                return MathUtils.floor((screenX + offsetX) / cellWidth);
166        }
167
168        protected int translateY(int screenY) {
169                return MathUtils.floor((screenY + offsetY) / cellHeight);
170        }
171
172    public boolean onGrid(int screenX, int screenY)
173    {
174        return screenX >= 0 && screenX < gridWidth && screenY >= 0 && screenY < gridHeight;
175    }
176
177    @Override
178    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
179        if(onGrid(screenX = translateX(screenX), screenY = translateY(screenY)))
180            return processor.touchDown(screenX, screenY, pointer, button);
181        return false;
182    }
183
184    @Override
185    public boolean touchUp(int screenX, int screenY, int pointer, int button) {
186        if(onGrid(screenX = translateX(screenX), screenY = translateY(screenY)))
187            return processor.touchUp(screenX, screenY, pointer, button);
188        return false;
189    }
190
191    @Override
192    public boolean touchDragged(int screenX, int screenY, int pointer) {
193        if(onGrid(screenX = translateX(screenX), screenY = translateY(screenY)))
194            return processor.touchDragged(screenX, screenY, pointer);
195        return false;
196    }
197
198    @Override
199    public boolean mouseMoved(int screenX, int screenY) {
200        if(onGrid(screenX = translateX(screenX), screenY = translateY(screenY)))
201            return processor.mouseMoved(screenX, screenY);
202        return false;
203    }
204
205    @Override
206    public boolean scrolled(int amount) {
207        return processor.scrolled(amount);
208    }
209}