X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scenegraph%2Fsrc%2Forg%2Fsimantics%2Fscenegraph%2Fg2d%2Fnodes%2FRulerNode.java;h=785c246b4e20679396f5cf9b5282e100d512455f;hp=ef6f2fc7cdefd62c39a0395dc5044c0563467adf;hb=bc195f999a0a3f4571ff45342327223b4b480750;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/RulerNode.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/RulerNode.java index ef6f2fc7c..785c246b4 100644 --- a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/RulerNode.java +++ b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/RulerNode.java @@ -1,63 +1,66 @@ -/******************************************************************************* - * 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 - *******************************************************************************/ +/******************************************************************************* + * 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.scenegraph.g2d.nodes; -import java.awt.AlphaComposite; -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.util.Locale; - -import org.simantics.scenegraph.g2d.G2DNode; -import org.simantics.scenegraph.utils.GridUtils; +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.util.Locale; + +import org.simantics.scenegraph.g2d.G2DNode; +import org.simantics.scenegraph.utils.DPIUtil; +import org.simantics.scenegraph.utils.GridUtils; public class RulerNode extends G2DNode { /** * */ - private static final long serialVersionUID = 2490944880914577411L; - - /** - * FIXME: this is a hack for the map UI that has to be solved some other way. - */ - private static final boolean MAP_Y_SCALING = false; - - private static final Color GRAY = new Color(100, 100, 100); - - protected Boolean enabled = true; - - protected double gridSize = 1.0; - - @SyncField("enabled") - public void setEnabled(Boolean enabled) { - this.enabled = enabled; - } - - @SyncField("gridSize") - public void setGridSize(double gridSize) { - if (gridSize < 1e-6) - gridSize = 1e-6; - this.gridSize = gridSize; - } - + private static final long serialVersionUID = 2490944880914577411L; + + private static final Color GRAY = new Color(100, 100, 100); + + protected Boolean enabled = true; + + protected double gridSize = 1.0; + + protected double rulerSize = 20; + + @SyncField("enabled") + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + @SyncField("gridSize") + public void setGridSize(double gridSize) { + if (gridSize < 1e-6) + gridSize = 1e-6; + this.gridSize = gridSize; + } + + @SyncField("rulerSize") + public void setRulerSize(double rulerSize) { + this.rulerSize = rulerSize; + } + @Override public void render(Graphics2D g) { - if (!enabled) - return; - + if (!enabled) + return; + AffineTransform tr = g.getTransform(); double scaleX = Math.abs(tr.getScaleX()); double scaleY = Math.abs(tr.getScaleY()); @@ -69,7 +72,7 @@ public class RulerNode extends G2DNode { double offsetY = tr.getTranslateY(); g.setTransform(new AffineTransform()); - Font rulerFont = new Font("Tahoma", Font.PLAIN, 9); + Font rulerFont = new Font("Tahoma", Font.PLAIN, DPIUtil.upscale(9)); //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setStroke(new BasicStroke(1)); @@ -80,37 +83,44 @@ public class RulerNode extends G2DNode { g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f)); - Rectangle2D vertical = new Rectangle2D.Double(bounds.getMinX(), bounds.getMinY(), bounds.getMaxX(), bounds.getMinY()+20); + int rulerPixelSize = (int) DPIUtil.upscale(rulerSize); + int u7 = DPIUtil.upscale(7); + int u4 = DPIUtil.upscale(4); + int u2 = DPIUtil.upscale(2); + + Rectangle2D vertical = new Rectangle2D.Double(bounds.getMinX(), bounds.getMinY(), bounds.getMaxX(), bounds.getMinY()+rulerPixelSize); g.fill(vertical); - Rectangle2D horizontal = new Rectangle2D.Double(bounds.getMinX(), bounds.getMinY()+20, bounds.getMinX()+20, bounds.getMaxY()); + Rectangle2D horizontal = new Rectangle2D.Double(bounds.getMinX(), bounds.getMinY()+rulerPixelSize, bounds.getMinX()+rulerPixelSize, bounds.getMaxY()); g.fill(horizontal); // stepX and stepY should be something between 50 and 100 double stepX = 50; double stepY = 50; - - stepX = GridUtils.limitedEvenGridSpacing(stepX, scaleX, 100, gridSize, true); - stepY = GridUtils.limitedEvenGridSpacing(stepY, scaleY, 100, gridSize, true); + + stepX = GridUtils.limitedEvenGridSpacing(stepX, scaleX, 100, gridSize, true); + stepY = GridUtils.limitedEvenGridSpacing(stepY, scaleY, 100, gridSize, true); //while(stepX * scaleX > 100) stepX /= 2; //while(stepY * scaleY > 100) stepY /= 2; while(stepX * scaleX < 50) stepX *= 2; while(stepY * scaleY < 50) stepY *= 2; - + stepX *= scaleX; stepY *= scaleY; g.setColor(GRAY); g.setFont(rulerFont); + FontMetrics fm = g.getFontMetrics(); double previousText = -100; // Vertical ruler - for(double x = offsetX%stepX-stepX; x < bounds.getMaxX(); x+=stepX) { - if(x > 20) { - String str = formatValue((x-offsetX)/scaleX); - FontMetrics fm = g.getFontMetrics(); + for(double x = offsetX%stepX-stepX; x < bounds.getMaxX(); x+=stepX) { + if(x > rulerPixelSize) { + double val = (x-offsetX)/scaleX / getTransform().getScaleX(); + double modifiedValue = modifyHorizontalValue(val); + String str = formatValue(modifiedValue, getMaxDigits()); Rectangle2D r = fm.getStringBounds(str, g); if((x-r.getWidth()/2) > previousText) { g.setColor(Color.BLACK); @@ -119,32 +129,29 @@ public class RulerNode extends G2DNode { } g.setColor(GRAY); - g.drawLine((int)x, (int)bounds.getMinY()+12, (int)x, (int)bounds.getMinY()+19); + g.drawLine((int)x, (int)bounds.getMinY()+rulerPixelSize-1-u7, (int)x, (int)bounds.getMinY()+rulerPixelSize-1); } if(stepX/5 > 2) { for(double x2 = x+stepX/5; x2 < x+stepX; x2+=stepX/5) { - if(x2 > 20) { - g.drawLine((int)x2, (int)bounds.getMinY()+15, (int)x2, (int)bounds.getMinY()+19); + if(x2 > rulerPixelSize) { + g.drawLine((int)x2, (int)bounds.getMinY()+rulerPixelSize-1-u4, (int)x2, (int)bounds.getMinY()+rulerPixelSize-1); } } for(double x2 = x+stepX/10; x2 < x+stepX; x2+=stepX/5) { - if(x2 > 20) { - g.drawLine((int)x2, (int)bounds.getMinY()+17, (int)x2, (int)bounds.getMinY()+19); + if(x2 > rulerPixelSize) { + g.drawLine((int)x2, (int)bounds.getMinY()+rulerPixelSize-1-u2, (int)x2, (int)bounds.getMinY()+rulerPixelSize-1); } } - } } - + // Horizontal ruler previousText = -100; - for(double y = offsetY%stepY-stepY; y < bounds.getMaxY(); y+=stepY) { - if(y > 20) { - double val = (y-offsetY)/scaleY; - if (MAP_Y_SCALING) - val = Math.toDegrees(Math.atan(Math.sinh(Math.toRadians(val)))); - String str = formatValue(val); - FontMetrics fm = g.getFontMetrics(); + for(double y = offsetY%stepY-stepY; y < bounds.getMaxY(); y+=stepY) { + if(y > rulerPixelSize) { + double val = (y-offsetY)/scaleY / getTransform().getScaleY(); + double modifiedValue = modifyVerticalValue(val); + String str = formatValue(modifiedValue, getMaxDigits()); Rectangle2D r = fm.getStringBounds(str, g); if(y-1+r.getHeight()/2 > previousText) { g.setColor(Color.BLACK); @@ -156,24 +163,44 @@ public class RulerNode extends G2DNode { previousText = y-1+r.getHeight(); } g.setColor(GRAY); - g.drawLine((int)bounds.getMinX()+12, (int)y, (int)bounds.getMinX()+19, (int)y); + g.drawLine((int)bounds.getMinX()+rulerPixelSize-1-u7, (int)y, (int)bounds.getMinX()+rulerPixelSize-1, (int)y); } if(stepY/5 > 2) { for(double y2 = y+stepY/5; y2 < y+stepY; y2+=stepY/5) { - if(y2 > 20) { - g.drawLine((int)bounds.getMinX()+15, (int)y2, (int)bounds.getMinX()+19, (int)y2); + if(y2 > rulerPixelSize) { + g.drawLine((int)bounds.getMinX()+rulerPixelSize-1-u4, (int)y2, (int)bounds.getMinX()+rulerPixelSize-1, (int)y2); } } for(double y2 = y+stepY/10; y2 < y+stepY; y2+=stepY/5) { - if(y2 > 20) { - g.drawLine((int)bounds.getMinX()+17, (int)y2, (int)bounds.getMinX()+19, (int)y2); + if(y2 > rulerPixelSize) { + g.drawLine((int)bounds.getMinX()+rulerPixelSize-1-u2, (int)y2, (int)bounds.getMinX()+rulerPixelSize-1, (int)y2); } } } } g.setTransform(tr); - } + } + + /** + * A method for subclasses to alter the actual X-value of the ruler + * + * @param value + * @return possibly modified X-value + */ + protected double modifyHorizontalValue(double value) { + return value; + } + + /** + * A method for subclasses to alter the actual Y-value of the ruler + * + * @param value + * @return possibly modified Y-value + */ + protected double modifyVerticalValue(double value) { + return value; + } private static final transient int MAX_DIGITS = 5; private static final transient double EPSILON = 0.01; @@ -181,11 +208,15 @@ public class RulerNode extends G2DNode { private static final transient String[] SI_UNIT_LARGE_PREFIXES = { "k", "M", "G", "T", "P", "E", "Z", "Y" }; + + protected int getMaxDigits() { + return MAX_DIGITS; + } - public static String formatValue(double value) { + public static String formatValue(double value, int maxDigits) { int magnitude = (int) Math.round(Math.log10(value)); //System.out.println("magnitude: " + magnitude + ", " + value); - int allowedDecimals = MAX_DIGITS; + int allowedDecimals = maxDigits; allowedDecimals -= Math.abs(magnitude); if (allowedDecimals < 0) allowedDecimals = 0;