/* * Copyright (C) 2012 Jason Gedge <http://www.gedge.ca> * * This file is part of the OpGraph project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package ca.gedge.opgraph.app.components.canvas; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import javax.swing.JComponent; import ca.gedge.opgraph.app.util.GUIHelper; /** * A grid component intended for displaying on the background of a * {@link GraphCanvas} component. */ public class GridLayer extends JComponent { /** Grid line spacing */ public static final int DEFAULT_GRID_SPACING = 50; /** Snap distance */ public static final int DEFAULT_SNAP_DISTANCE = 5; /** * Constructs a viewport for the specified canvas. */ public GridLayer() { setOpaque(true); setBackground(Color.DARK_GRAY); } /** * Snaps a point to this grid. * * @param p the point which will be snapped * * @return the delta to apply to the given point to enforce snapping */ public Point snap(Point p) { final int mx = p.x % DEFAULT_GRID_SPACING; final int my = p.y % DEFAULT_GRID_SPACING; final Point snapped = new Point(); if(Math.abs(mx) <= DEFAULT_SNAP_DISTANCE) { snapped.x = -mx; } else if(Math.abs(DEFAULT_GRID_SPACING - mx) <= DEFAULT_SNAP_DISTANCE) { snapped.x = DEFAULT_GRID_SPACING - mx; } if(Math.abs(my) <= DEFAULT_SNAP_DISTANCE) { snapped.y = -my; } else if(Math.abs(DEFAULT_GRID_SPACING - my) <= DEFAULT_SNAP_DISTANCE) { snapped.y = DEFAULT_GRID_SPACING - my; } return snapped; } // // Overrides // @Override public Dimension getPreferredSize() { return null; } @Override protected void paintComponent(Graphics gfx) { Graphics2D g = (Graphics2D)gfx; //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); super.paintComponent(g); // Fill background g.setColor(getBackground()); g.fill(getVisibleRect()); // Draw grid lines final Rectangle view = getVisibleRect(); final int startx = ((view.x / DEFAULT_GRID_SPACING - 1) * DEFAULT_GRID_SPACING); final int starty = ((view.y / DEFAULT_GRID_SPACING - 1) * DEFAULT_GRID_SPACING); final int endx = view.x + view.width + 1; final int endy = view.y + view.height + 1; g.setColor(GUIHelper.highlightColor(getBackground())); for(int y = starty; y < endy; y += DEFAULT_GRID_SPACING) g.drawLine(view.x, y, endx, y); for(int x = startx; x < endx; x += DEFAULT_GRID_SPACING) g.drawLine(x, view.y, x, endy); } }