/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * 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 com.bc.ceres.glayer.support; import com.bc.ceres.binding.Property; import com.bc.ceres.binding.PropertyContainer; import com.bc.ceres.binding.PropertySet; import com.bc.ceres.glayer.Layer; import com.bc.ceres.glayer.LayerContext; import com.bc.ceres.glayer.LayerType; import com.bc.ceres.glayer.LayerTypeRegistry; import com.bc.ceres.glayer.annotations.LayerTypeMetadata; import com.bc.ceres.grender.Rendering; import com.bc.ceres.grender.Viewport; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * A shape layer is used to draw {@link Shape}s. * * @author Norman Fomferra */ public class ShapeLayer extends Layer { private final List<Shape> shapeList; private final AffineTransform shapeToModelTransform; private final AffineTransform modelToShapeTransform; public ShapeLayer(Shape[] shapes, AffineTransform shapeToModelTransform) { this(LayerTypeRegistry.getLayerType(Type.class), Arrays.asList(shapes), shapeToModelTransform); } private ShapeLayer(Type layerType,List<Shape> shapes, AffineTransform shapeToModelTransform) { this(layerType, shapes, shapeToModelTransform, layerType.createLayerConfig(null)); } public ShapeLayer(Type layerType, List<Shape> shapes, AffineTransform shapeToModelTransform, PropertySet configuration) { super(layerType, configuration); this.shapeList = new ArrayList<Shape>(shapes); this.shapeToModelTransform = shapeToModelTransform; try { this.modelToShapeTransform = shapeToModelTransform.createInverse(); } catch (NoninvertibleTransformException e) { throw new IllegalArgumentException("shapeToModelTransform", e); } } public List<Shape> getShapeList() { return new ArrayList<Shape>(shapeList); } public void setShapeList(List<Shape> list) { shapeList.clear(); shapeList.addAll(list); } public AffineTransform getShapeToModelTransform() { return (AffineTransform) shapeToModelTransform.clone(); } public AffineTransform getModelToShapeTransform() { return (AffineTransform) modelToShapeTransform.clone(); } @Override protected Rectangle2D getLayerModelBounds() { Rectangle2D shapeBounds = null; for (Shape shape : shapeList) { if (shapeBounds == null) { shapeBounds = shape.getBounds2D(); } else { shapeBounds.add(shape.getBounds2D()); } } return shapeBounds != null ? shapeToModelTransform.createTransformedShape(shapeBounds).getBounds2D() : null; } @Override protected void renderLayer(Rendering rendering) { final Graphics2D g = rendering.getGraphics(); final Viewport vp = rendering.getViewport(); final AffineTransform transformSave = g.getTransform(); try { final AffineTransform transform = new AffineTransform(); transform.concatenate(vp.getModelToViewTransform()); transform.concatenate(shapeToModelTransform); g.setTransform(transform); for (Shape shape : shapeList) { g.setPaint(Color.WHITE); g.fill(shape); g.setPaint(Color.BLACK); g.draw(shape); } } finally { g.setTransform(transformSave); } } @LayerTypeMetadata(name = "ShapeLayerType", aliasNames = {"com.bc.ceres.glayer.support.ShapeLayer$Type"}) public static class Type extends LayerType { public static final String PROPERTY_SHAPE_LIST = "shapes"; public static final String PROPTERY_SHAPE_TO_MODEL_TRANSFORM = "shapeToModelTransform"; @Override public boolean isValidFor(LayerContext ctx) { return true; } @Override public Layer createLayer(LayerContext ctx, PropertySet configuration) { final List<Shape> shapeList = (List<Shape>) configuration.getValue(PROPERTY_SHAPE_LIST); final AffineTransform modelTransform = (AffineTransform) configuration.getValue( PROPTERY_SHAPE_TO_MODEL_TRANSFORM); return new ShapeLayer(this, shapeList, modelTransform, configuration); } @Override public PropertySet createLayerConfig(LayerContext ctx) { final PropertyContainer vc = new PropertyContainer(); final Property shapeList = Property.create(PROPERTY_SHAPE_LIST, List.class); shapeList.getDescriptor().setDefaultValue(new ArrayList<Shape>()); vc.addProperty(shapeList); final Property transform = Property.create(PROPTERY_SHAPE_TO_MODEL_TRANSFORM, AffineTransform.class, new AffineTransform(), true); vc.addProperty(transform); return vc; } } }