fiore@0: /* fiore@0: CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool fiore@0: fiore@0: Copyright (C) 2002 Cay S. Horstmann (http://horstmann.com) fiore@0: Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/) fiore@0: fiore@0: This program is free software: you can redistribute it and/or modify fiore@0: it under the terms of the GNU General Public License as published by fiore@0: the Free Software Foundation, either version 3 of the License, or fiore@0: (at your option) any later version. fiore@0: fiore@0: This program is distributed in the hope that it will be useful, fiore@0: but WITHOUT ANY WARRANTY; without even the implied warranty of fiore@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the fiore@0: GNU General Public License for more details. fiore@0: fiore@0: You should have received a copy of the GNU General Public License fiore@0: along with this program. If not, see . fiore@0: */ fiore@0: fiore@0: package uk.ac.qmul.eecs.ccmi.gui; fiore@0: fiore@0: import java.awt.Color; fiore@0: import java.awt.Graphics2D; fiore@0: import java.awt.Stroke; fiore@0: import java.awt.geom.Line2D; fiore@0: import java.awt.geom.Point2D; fiore@0: import java.awt.geom.Rectangle2D; fiore@0: import java.awt.geom.RectangularShape; fiore@0: fiore@0: /** fiore@0: A grid to which nodes can be "snapped". The fiore@0: snapping operation moves a point to the nearest grid point. fiore@0: */ fiore@0: public class Grid fiore@0: { fiore@0: /** fiore@0: Constructs a grid with no grid points. fiore@0: */ fiore@0: public Grid() fiore@0: { fiore@0: setGrid(0, 0); fiore@0: } fiore@0: fiore@0: /** fiore@0: Sets the grid point distances in x- and y-direction fiore@0: @param x the grid point distance in x-direction fiore@0: @param y the grid point distance in y-direction fiore@0: */ fiore@0: public void setGrid(double x, double y) fiore@0: { fiore@0: gridx = x; fiore@0: gridy = y; fiore@0: } fiore@0: fiore@0: /** fiore@0: Draws this grid inside a rectangle. fiore@0: @param g2 the graphics context fiore@0: @param bounds the bounding rectangle fiore@0: */ fiore@0: public void draw(Graphics2D g2, Rectangle2D bounds) fiore@0: { fiore@0: Color PALE_BLUE = new Color(0.9F, 0.8F, 0.9F); fiore@0: Color oldColor = g2.getColor(); fiore@0: g2.setColor(PALE_BLUE); fiore@0: Stroke oldStroke = g2.getStroke(); fiore@0: for (double x = bounds.getX(); x < bounds.getMaxX(); x += gridx) fiore@0: g2.draw(new Line2D.Double(x, bounds.getY(), x, bounds.getMaxY())); fiore@0: for (double y = bounds.getY(); y < bounds.getMaxY(); y += gridy) fiore@0: g2.draw(new Line2D.Double(bounds.getX(), y, bounds.getMaxX(), y)); fiore@0: g2.setStroke(oldStroke); fiore@0: g2.setColor(oldColor); fiore@0: } fiore@0: fiore@0: /** fiore@0: Snaps a point to the nearest grid point fiore@0: @param p the point to snap. After the call, the fiore@0: coordinates of p are changed so that p falls on the grid. fiore@0: */ fiore@0: public void snap(Point2D p) fiore@0: { fiore@0: double x; fiore@0: if (gridx == 0) fiore@0: x = p.getX(); fiore@0: else fiore@0: x = Math.round(p.getX() / gridx) * gridx; fiore@0: double y; fiore@0: if (gridy == 0) fiore@0: y = p.getY(); fiore@0: else fiore@0: y = Math.round(p.getY() / gridy) * gridy; fiore@0: fiore@0: p.setLocation(x, y); fiore@0: } fiore@0: fiore@0: /** fiore@0: Snaps a rectangle to the nearest grid points fiore@0: @param r the rectangle to snap. After the call, the fiore@0: coordinates of r are changed so that all of its corners fiore@0: falls on the grid. fiore@0: */ fiore@0: public void snap(RectangularShape r) fiore@0: { fiore@0: double x; fiore@0: double w; fiore@0: w = r.getWidth(); fiore@0: if (gridx == 0) fiore@0: { fiore@0: x = r.getX(); fiore@0: } fiore@0: else fiore@0: { fiore@0: x = Math.round(r.getX() / gridx) * gridx; fiore@0: // w = Math.ceil(r.getWidth() / (2 * gridx)) * (2 * gridx); fiore@0: } fiore@0: double y; fiore@0: double h; fiore@0: h = r.getHeight(); fiore@0: if (gridy == 0) fiore@0: { fiore@0: y = r.getY(); fiore@0: } fiore@0: else fiore@0: { fiore@0: y = Math.round(r.getY() / gridy) * gridy; fiore@0: // h = Math.ceil(r.getHeight() / (2 * gridy)) * (2 * gridy); fiore@0: } fiore@0: fiore@0: r.setFrame(x, y, w, h); fiore@0: } fiore@0: fiore@0: private double gridx; fiore@0: private double gridy; fiore@0: }