]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/participant/RulerPainter.java
HiDPI scaling for diagram ruler and model activity tracker
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / participant / RulerPainter.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 /*
13  *
14  * @author Toni Kalajainen
15  */
16 package org.simantics.g2d.participant;
17
18 import java.awt.AlphaComposite;
19 import java.awt.Color;
20 import java.awt.Composite;
21
22 import org.simantics.g2d.canvas.Hints;
23 import org.simantics.g2d.canvas.ICanvasContext;
24 import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;
25 import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup;
26 import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
27 import org.simantics.scenegraph.g2d.G2DParentNode;
28 import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
29 import org.simantics.scenegraph.g2d.events.command.CommandEvent;
30 import org.simantics.scenegraph.g2d.events.command.Commands;
31 import org.simantics.scenegraph.g2d.nodes.RulerNode;
32 import org.simantics.utils.datastructures.hints.HintListenerAdapter;
33 import org.simantics.utils.datastructures.hints.IHintListener;
34 import org.simantics.utils.datastructures.hints.IHintObservable;
35 import org.simantics.utils.datastructures.hints.IHintContext.Key;
36 import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
37 import org.simantics.utils.page.MarginUtils;
38 import org.simantics.utils.page.MarginUtils.Margin;
39 import org.simantics.utils.page.MarginUtils.Margins;
40
41
42 public class RulerPainter extends AbstractCanvasParticipant {
43
44     public static final int PAINT_PRIORITY = Integer.MAX_VALUE - 1000;
45
46     public static final double RULER_WIDTH = 20.0;
47
48     /** Ruler width + 5% */
49     public static final Margin RULER_MARGIN5 = MarginUtils.marginOf(5, RulerPainter.RULER_WIDTH, 0);
50     /** Ruler width + 2% */
51     public static final Margin RULER_MARGIN2 = MarginUtils.marginOf(2, RulerPainter.RULER_WIDTH, 0);
52     /** 5% margin + ruler */
53     public static final Margins RULER_MARINGS5 = new Margins(RULER_MARGIN5, MarginUtils.MARGIN5, RULER_MARGIN5, MarginUtils.MARGIN5);
54     /** 2% margin + ruler */
55     public static final Margins RULER_MARINGS2 = new Margins(RULER_MARGIN2, MarginUtils.MARGIN2, RULER_MARGIN2, MarginUtils.MARGIN2);
56
57     public static final Key KEY_RULER_ENABLED = new KeyOf(Boolean.class, "RULER_ENABLED");
58
59     /**
60      * Size of ruler in normalized (non-zoomed or 100% zoom) coordinates, not screen pixel coordinates.
61      */
62     public static final Key KEY_RULER_SIZE = new KeyOf(Double.class, "RULER_SIZE");
63
64     /** Background color */
65     public static final Key KEY_RULER_BACKGROUND_COLOR = new KeyOf(Color.class, "RULER_BACKGROUND_COLOR");
66
67     public static final Key KEY_RULER_TEXT_COLOR = new KeyOf(Color.class, "RULER_TEXT_COLOR");
68
69     public static Color DEFAULT_RULER_BACKGROUND_COLOR = new Color(192, 192, 192, 192);
70
71     public static Color DEFAULT_RULER_TEXT_COLOR = Color.BLACK;
72
73     IHintListener hintListener = new HintListenerAdapter() {
74         public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
75             ICanvasContext cc = getContext();
76             if (cc != null) {
77                 updateNode();
78                 cc.getContentContext().setDirty();
79             }
80         }
81     };
82
83     @Override
84     public void addedToContext(ICanvasContext ctx) {
85         super.addedToContext(ctx);
86
87         if (!hasHint(KEY_RULER_SIZE))
88             setHint(KEY_RULER_SIZE, RULER_WIDTH);
89
90         getHintStack().addKeyHintListener(getThread(), KEY_RULER_ENABLED, hintListener);
91         getHintStack().addKeyHintListener(getThread(), KEY_RULER_SIZE, hintListener);
92         getHintStack().addKeyHintListener(getThread(), KEY_RULER_BACKGROUND_COLOR, hintListener);
93         getHintStack().addKeyHintListener(getThread(), KEY_RULER_TEXT_COLOR, hintListener);
94         getHintStack().addKeyHintListener(getThread(), GridPainter.KEY_GRID_SIZE, hintListener);
95         getHintStack().addKeyHintListener(getThread(), Hints.KEY_DISABLE_PAINTING, hintListener);
96     }
97
98     @Override
99     public void removedFromContext(ICanvasContext ctx) {
100         getHintStack().removeKeyHintListener(getThread(), KEY_RULER_ENABLED, hintListener);
101         getHintStack().removeKeyHintListener(getThread(), KEY_RULER_SIZE, hintListener);
102         getHintStack().removeKeyHintListener(getThread(), KEY_RULER_BACKGROUND_COLOR, hintListener);
103         getHintStack().removeKeyHintListener(getThread(), KEY_RULER_TEXT_COLOR, hintListener);
104         getHintStack().removeKeyHintListener(getThread(), GridPainter.KEY_GRID_SIZE, hintListener);
105         getHintStack().removeKeyHintListener(getThread(), Hints.KEY_DISABLE_PAINTING, hintListener);
106         super.removedFromContext(ctx);
107     }
108
109     @SuppressWarnings("unused")
110     private final Composite transparency = AlphaComposite.SrcOver.derive(0.75f);
111
112     protected RulerNode node = null;
113
114     @SGInit
115     public void initSG(G2DParentNode parent) {
116         node = parent.addNode("ruler", getNodeClass());
117         node.setZIndex(PAINT_PRIORITY);
118         updateNode();
119     }
120
121     protected Class<? extends RulerNode> getNodeClass() {
122         return RulerNode.class;
123     }
124
125     @SGCleanup
126     public void cleanupSG() {
127         node.remove();
128     }
129
130     protected void updateNode() {
131         node.setEnabled(isPaintingEnabled());
132         node.setGridSize(getGridSize());
133         node.setRulerSize(getRulerSize());
134     }
135
136     private double getGridSize() {
137         Double d = getHint(GridPainter.KEY_GRID_SIZE);
138         return d != null ? d : 1.0;
139     }
140
141     boolean isPaintingEnabled()
142     {
143         boolean enabled = isEnabled();
144         Boolean globalDisable = getHint(Hints.KEY_DISABLE_PAINTING);
145         return enabled && !Boolean.TRUE.equals(globalDisable);
146     }
147
148     public boolean isEnabled()
149     {
150         Boolean b = getHint(KEY_RULER_ENABLED);
151         return !Boolean.FALSE.equals(b);
152     }
153
154     private double getRulerSize() {
155         Double d = getHint(KEY_RULER_SIZE);
156         return d != null ? d : RULER_WIDTH;
157     }
158
159     public Color getRulerTextColor()
160     {
161         Color c = getHint(KEY_RULER_TEXT_COLOR);
162         if (c!=null) return c;
163         return DEFAULT_RULER_TEXT_COLOR;
164     }
165
166     public Color getRulerBackgroundColor()
167     {
168         Color c = getHint(KEY_RULER_BACKGROUND_COLOR);
169         if (c!=null) return c;
170         return DEFAULT_RULER_BACKGROUND_COLOR;
171     }
172
173     public void setEnabled(boolean enabled)
174     {
175         node.setEnabled(enabled);
176         setHint(KEY_RULER_ENABLED, enabled);
177     }
178
179     public void setRulerTextColor(Color c)
180     {
181         setHint(KEY_RULER_TEXT_COLOR, c);
182     }
183
184     public void setRulerBackgroundColor(Color c)
185     {
186         setHint(KEY_RULER_BACKGROUND_COLOR, c);
187     }
188
189     @EventHandler(priority = 0)
190     public boolean handleKeyEvent(CommandEvent e) {
191         if (e.command.equals( Commands.RULER_ENABLE)) {
192             setEnabled(true);
193             return true;
194         } else if (e.command.equals( Commands.RULER_DISABLE)) {
195             setEnabled(false);
196             return true;
197         } else if (e.command.equals( Commands.RULER_TOGGLE)) {
198             setEnabled(!isEnabled());
199             return true;
200         }
201         return false;
202     }
203
204 }