/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.g2d.participant; import java.awt.BasicStroke; import java.awt.Color; import org.simantics.g2d.canvas.Hints; import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant; import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup; import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit; import org.simantics.g2d.diagram.DiagramHints; import org.simantics.scenegraph.g2d.G2DParentNode; import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler; import org.simantics.scenegraph.g2d.events.command.CommandEvent; import org.simantics.scenegraph.g2d.events.command.Commands; import org.simantics.scenegraph.g2d.nodes.GridNode; import org.simantics.scenegraph.g2d.snap.ISnapAdvisor; import org.simantics.utils.datastructures.hints.HintListenerAdapter; import org.simantics.utils.datastructures.hints.IHintListener; import org.simantics.utils.datastructures.hints.IHintObservable; import org.simantics.utils.datastructures.hints.IHintContext.Key; import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; /** * GridPainter draws grid lines through the scene graph. * * This interactor has no dependencies to other participants. * * @author Toni Kalajainen * * @see GridNode */ public class GridPainter extends AbstractCanvasParticipant { /** * Grid enabled status. Default value is True */ public static final Key KEY_GRID_ENABLED = new KeyOf(Boolean.class, "GRID_ENABLED"); /** * Specifies the absolute diagram grid size, which is also the snapping grid * size. This painter will use {@link GridNode} to draw the grid in a * resolution that is no less than this value. The value is expected to be * defined in millimeters which is the standard diagram unit. */ public static final Key KEY_GRID_SIZE = new KeyOf(Double.class, "GRID_SIZE"); private static final double DEFAULT_GRID_SIZE = 1.0; public static final BasicStroke GRID_LINE_STROKE = new BasicStroke(0.1f, BasicStroke.CAP_SQUARE, BasicStroke.CAP_SQUARE, 10.0f, null, 0.0f); IHintListener gridListener = new HintListenerAdapter() { public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) { ICanvasContext cc = getContext(); if (cc != null) { updateNode(); cc.getContentContext().setDirty(); } } }; @Override public void addedToContext(ICanvasContext ctx) { super.addedToContext(ctx); getHintStack().addKeyHintListener(getThread(), KEY_GRID_ENABLED, gridListener); getHintStack().addKeyHintListener(getThread(), KEY_GRID_SIZE, gridListener); getHintStack().addKeyHintListener(getThread(), Hints.KEY_GRID_COLOR, gridListener); getHintStack().addKeyHintListener(getThread(), Hints.KEY_DISABLE_PAINTING, gridListener); getHintStack().addKeyHintListener(getThread(), DiagramHints.SNAP_ADVISOR, gridListener); } @Override public void removedFromContext(ICanvasContext ctx) { getHintStack().removeKeyHintListener(getThread(), KEY_GRID_ENABLED, gridListener); getHintStack().removeKeyHintListener(getThread(), KEY_GRID_SIZE, gridListener); getHintStack().removeKeyHintListener(getThread(), Hints.KEY_GRID_COLOR, gridListener); getHintStack().removeKeyHintListener(getThread(), Hints.KEY_DISABLE_PAINTING, gridListener); getHintStack().removeKeyHintListener(getThread(), DiagramHints.SNAP_ADVISOR, gridListener); super.removedFromContext(ctx); } @EventHandler(priority = 0) public boolean handleKeyEvent(CommandEvent e) { if (e.command.equals( Commands.GRID_ENABLE )) { setEnabled(true); updateNode(); setDirty(); return true; } else if (e.command.equals( Commands.GRID_DISABLE )) { setEnabled(false); updateNode(); setDirty(); return true; } else if (e.command.equals( Commands.GRID_TOGGLE )) { setEnabled(!isGridEnabled()); updateNode(); setDirty(); return true; } return false; } protected GridNode node = null; @SGInit public void initSG(G2DParentNode parent) { node = parent.addNode(GridNode.GRID_NODE_ID, GridNode.class); node.setLookupId(GridNode.GRID_NODE_ID); node.setZIndex(Integer.MIN_VALUE + 1000); updateNode(); } @SGCleanup public void cleanupSG() { node.remove(); } protected void updateNode() { node.setEnabled(isPaintingEnabled()); node.setGridColor(getGridColor()); node.setGridSize(getGridSize()); node.setSnapAdvisor( (ISnapAdvisor) getHint(DiagramHints.SNAP_ADVISOR) ); } boolean isPaintingEnabled() { boolean enabled = isGridEnabled(); Boolean globalDisable = getHint(Hints.KEY_DISABLE_PAINTING); return enabled && !Boolean.TRUE.equals(globalDisable); } public boolean isGridEnabled() { Boolean enabled = getHint(KEY_GRID_ENABLED); return !Boolean.FALSE.equals(enabled); } public void setEnabled(boolean enabled) { setHint(KEY_GRID_ENABLED, enabled); } public Color getGridColor() { return getHint(Hints.KEY_GRID_COLOR); } /** * Convenience method * @param r * @param g * @param b */ public void setGridColor(int r, int g, int b) { setGridColor(new Color(r, g, b)); } /** * Convenience method * @param c */ public void setGridColor(Color c) { setHint(Hints.KEY_GRID_COLOR, c); } public double getGridSize() { Double d = getHint(KEY_GRID_SIZE); return d == null ? DEFAULT_GRID_SIZE : d.doubleValue(); } public void setGridSize(double gridSize) { setHint(KEY_GRID_SIZE, gridSize); } }