/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.kie.workbench.common.stunner.lienzo.grid; import java.util.Iterator; import java.util.NoSuchElementException; import com.ait.lienzo.shared.core.types.Direction; public class Grid implements Iterable<Grid.Point> { private int padding; private int iconSize; private int rows; private int cols; public Grid(final int padding, final int iconSize, final int rows, final int cols) { if (padding < 0 || iconSize < 0 || rows < 1 || cols < 1) { throw new IllegalArgumentException("Not possible to instantiate grid."); } this.padding = padding; this.iconSize = iconSize; this.rows = rows; this.cols = cols; } public Point findPosition(final Point anchorPoint, final Direction direction) { int width = getWidth(); int height = getHeight(); int x = anchorPoint.getX(); int y = anchorPoint.getY(); switch (direction) { case NORTH: x -= width / 2; y -= height; break; case SOUTH: x -= width / 2; break; case EAST: y -= height / 2; break; case WEST: x -= width; y -= height / 2; break; case NONE: x -= width / 2; y -= height / 2; break; case NORTH_EAST: y -= height; break; case SOUTH_EAST: break; case SOUTH_WEST: x -= width; break; case NORTH_WEST: x -= width; y -= height; break; default: throw new UnsupportedOperationException(); } return new Point(x, y); } public Point findPosition(final int row, final int col) { if (!isInRange(row, getRows())) { throw new IllegalArgumentException( row + " is incorrect row value. Value have to be from 0 to " + (getRows() - 1) ); } if (!isInRange(col, getCols())) { throw new IllegalArgumentException( col + " is incorrect col value. Value have to be from 0 to " + (getCols() - 1) ); } int x = calculateDistance(col); int y = calculateDistance(row); return new Point(x, y); } private int calculateDistance(final int position) { return padding + (position * (padding + iconSize)); } private boolean isInRange(final int value, final int max) { return value >= 0 && value < max; } @Override public Iterator<Point> iterator() { return new GridIterator(this); } public int getRows() { return rows; } public int getCols() { return cols; } public int size() { return getRows() * getCols(); } public int getWidth() { return calculateDistance(getCols()); } public int getHeight() { return calculateDistance(getRows()); } public static class Point { private final int x; private final int y; public Point(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public int getY() { return y; } } protected static class GridIterator implements Iterator<Point> { private final Grid grid; private int currentRow = 0; private int currentColumn = 0; public GridIterator(Grid grid) { this.grid = grid; } @Override public boolean hasNext() { return currentColumn <= lastColumn() && currentRow <= lastRow(); } private int lastColumn() { return this.grid.getCols() - 1; } private int lastRow() { return this.grid.getRows() - 1; } @Override public Point next() { if (!hasNext()) { throw new NoSuchElementException(); } int column = currentColumn; int row = currentRow; if (currentColumn == (this.grid.getCols() - 1)) { currentColumn = 0; currentRow++; } else { currentColumn++; } return this.grid.findPosition(row, column); } @Override public void remove() { throw new UnsupportedOperationException(); } } }