1
14 package demo.view.flowchart.painters;
15
16 import y.view.AbstractCustomNodePainter;
17 import y.view.NodeRealizer;
18 import y.view.GenericNodeRealizer;
19 import y.view.Graph2D;
20 import y.base.Node;
21 import y.view.YRenderingHints;
22
23 import java.awt.Graphics2D;
24 import java.awt.Color;
25 import java.awt.BasicStroke;
26 import java.awt.GradientPaint;
27 import java.awt.geom.GeneralPath;
28 import java.awt.geom.Point2D;
29 import java.awt.geom.Rectangle2D;
30
31
34 public class FlowchartAnnotationPainter extends AbstractCustomNodePainter implements GenericNodeRealizer.ContainsTest, FlowchartRealizerConstants {
35 private GeneralPath shape;
36 private Rectangle2D outline;
37
38
39 public FlowchartAnnotationPainter() {
40 outline = new Rectangle2D.Double();
41 shape = new GeneralPath();
42 }
43
44
50 protected void paintNode(NodeRealizer context, Graphics2D graphics, boolean sloppy) {
51 updateShape(context);
52 updateOutline(context);
53
54 final boolean useSelectionStyle = useSelectionStyle(context, graphics);
55 graphics.setStroke(getLineStroke(context, useSelectionStyle));
56
57 Color fillColor1 = getFillColor(context, useSelectionStyle);
58 Color fillColor2 = getFillColor2(context, useSelectionStyle);
59 Color lineColor = getLineColor(context, useSelectionStyle);
60
61 if (fillColor1 != null) {
62 if (fillColor2 != null && useGradientStyle(graphics)) {
63 double x = context.getX();
64 double y = context.getY();
65 double width = context.getWidth();
66 double height = context.getHeight();
67 GradientPaint gp = new GradientPaint((float) x, (float) y, fillColor1, (float) x + (float) width,
68 (float) y + (float) height, fillColor2);
69 graphics.setPaint(gp);
70 } else {
71 graphics.setColor(fillColor1);
72 }
73 graphics.fill(outline);
74
75 if (lineColor != null) {
76 graphics.setColor(lineColor);
77 graphics.setStroke(new BasicStroke(2));
78 graphics.draw(shape);
79 }
80 }
81 }
82
83 static boolean useGradientStyle( final Graphics2D graphics ) {
84 return YRenderingHints.isGradientPaintingEnabled(graphics);
85 }
86
87 static boolean useSelectionStyle( final NodeRealizer context, final Graphics2D gfx ) {
88 return context.isSelected() && YRenderingHints.isSelectionPaintingEnabled(gfx);
89 }
90
91
95 protected void updateOutline(NodeRealizer context) {
96 double x = context.getX();
97 double y = context.getY();
98 double width = context.getWidth();
99 double height = context.getHeight();
100 outline.setFrame(x, y, width, height);
101 }
102
103
107 protected void updateShape(NodeRealizer context) {
108 shape.reset();
109
110 byte orientation;
111 GenericNodeRealizer gnr = (GenericNodeRealizer) context;
112 if (gnr.getStyleProperty(PROPERTY_ORIENTATION) != null) {
113 orientation = ((Byte) gnr.getStyleProperty(PROPERTY_ORIENTATION)).byteValue();
114 } else {
115 orientation = PROPERTY_ORIENTATION_VALUE_LEFT;
116 }
117 if (orientation == PROPERTY_ORIENTATION_VALUE_AUTO) {
118 orientation = determineBracketOrientation(context);
119 }
120 switch (orientation) {
121 case PROPERTY_ORIENTATION_VALUE_DOWN: {
122 createDownBracket(gnr.getX(), gnr.getY(), gnr.getWidth(), gnr.getHeight());
123 break;
124 }
125 case PROPERTY_ORIENTATION_VALUE_RIGHT: {
126 createRightBracket(gnr.getX(), gnr.getY(), gnr.getWidth(), gnr.getHeight());
127 break;
128 }
129 case PROPERTY_ORIENTATION_VALUE_TOP: {
130 createTopBracket(gnr.getX(), gnr.getY(), gnr.getWidth(), gnr.getHeight());
131 break;
132 }
133 case PROPERTY_ORIENTATION_VALUE_LEFT: {
134 createLeftBracket(gnr.getX(), gnr.getY(), gnr.getWidth(), gnr.getHeight());
135 break;
136 }
137 default: {
138 createLeftBracket(gnr.getX(), gnr.getY(), gnr.getWidth(), gnr.getHeight());
139 }
140 }
141 }
142
143 private void createLeftBracket( double x, double y, double width, double height ) {
144 shape.moveTo((float)(x + 0.125 * width), (float) y);
145 shape.lineTo((float)x, (float)y);
146 shape.lineTo((float)x, (float)(y + height));
147 shape.lineTo((float)(x + 0.125 * width), (float)(y + height));
148 }
149
150 private void createRightBracket( double x, double y, double width, double height ) {
151 shape.moveTo((float)(x + 0.875 * width),(float) y);
152 shape.lineTo((float)(x + width), (float)y);
153 shape.lineTo((float)(x + width), (float)(y + height));
154 shape.lineTo((float)(x + 0.875 * width), (float)(y + height));
155 }
156
157 private void createTopBracket( double x, double y, double width, double height ) {
158 shape.moveTo((float)x, (float)(y + 0.125 * height));
159 shape.lineTo((float)x, (float)y);
160 shape.lineTo((float)(x + width), (float)y);
161 shape.lineTo((float)(x + width), (float)(y + 0.125 * height));
162 }
163
164 private void createDownBracket( double x, double y, double width, double height ) {
165 shape.moveTo((float)x, (float)(y + 0.875 * height));
166 shape.lineTo((float)x, (float)(y + height));
167 shape.lineTo((float)(x + width), (float)(y + height));
168 shape.lineTo((float)(x + width), (float)(y + 0.875 * height));
169 }
170
171
186 private byte determineBracketOrientation(NodeRealizer context) {
187 final Node node = context.getNode();
188 if (node != null && node.degree() == 1) {
189 final Graph2D graph = (Graph2D) node.getGraph();
190
191 final Point2D intersection =
192 node.inDegree() == 1
193 ? graph.getRealizer(node.firstInEdge()).getTargetIntersection()
194 : graph.getRealizer(node.firstOutEdge()).getSourceIntersection();
195
196 final double x = intersection.getX();
197 final double y = intersection.getY();
198
199 final double epsilon = 0.1;
200
201 final double minX = context.getX();
202 if ((x + epsilon) > minX && (x - epsilon) < minX) {
203 return PROPERTY_ORIENTATION_VALUE_LEFT;
204 } else {
205 final double maxX = minX + context.getWidth();
206 if (((x + epsilon) > maxX && ((x - epsilon) < maxX))) {
207 return PROPERTY_ORIENTATION_VALUE_RIGHT;
208 } else {
209 final double minY = context.getY();
210 if ((y + epsilon) > minY && (y - epsilon) < minY) {
211 return PROPERTY_ORIENTATION_VALUE_TOP;
212 } else {
213 final double maxY = minY + context.getHeight();
214 if (((y + epsilon) > maxY && ((y - epsilon) < maxY))) {
215 return PROPERTY_ORIENTATION_VALUE_DOWN;
216 }
217 }
218 }
219 }
220 }
221
222 return PROPERTY_ORIENTATION_VALUE_LEFT;
223 }
224
225 public boolean contains(NodeRealizer context, double x, double y) {
226 updateOutline(context);
227 return outline != null && outline.contains(x, y);
228 }
229 }
230