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        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 grid cells.
055     * All input is passed to the provided InputProcessor once it's had its
056     * coordinates 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        offsetX = 0;
133        offsetY = 0;
134        gridWidth = Gdx.graphics.getWidth() / cellWidth;
135        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.clamp(MathUtils.floor((screenX + offsetX) / cellWidth), 0, (int)(gridWidth - 1)); //MathUtils.floor((offsetX * 0f) / cellWidth)
165        }
166
167        protected int translateY(int screenY) {
168                return MathUtils.clamp(MathUtils.floor((screenY + offsetY) / cellHeight), 0, (int)(gridHeight - 1)); //MathUtils.floor((offsetY * 0f) / cellHeight)
169        }
170
171    public boolean onGrid(int screenX, int screenY)
172    {
173        int tmp = MathUtils.floor((screenX + offsetX) / cellWidth);
174        if(tmp < 0 || tmp >= gridWidth)
175            return false;
176        tmp = MathUtils.floor((screenY + offsetY) / cellHeight);
177        return tmp >= 0 && tmp < gridHeight;
178    }
179
180    @Override
181    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
182        return processor.touchDown(translateX(screenX), translateY(screenY), pointer, button);
183    }
184
185    @Override
186    public boolean touchUp(int screenX, int screenY, int pointer, int button) {
187        return processor.touchUp(translateX(screenX), translateY(screenY), pointer, button);
188    }
189
190    @Override
191    public boolean touchDragged(int screenX, int screenY, int pointer) {
192        return processor.touchDragged(translateX(screenX), translateY(screenY), pointer);
193    }
194
195    @Override
196    public boolean mouseMoved(int screenX, int screenY) {
197        return processor.mouseMoved(translateX(screenX), translateY(screenY));
198    }
199
200    @Override
201    public boolean scrolled(int amount) {
202        return processor.scrolled(amount);
203    }
204}