1
28 package demo.view.isometry;
29
30 import y.view.GenericNodeRealizer;
31 import y.view.NodeRealizer;
32 import y.view.hierarchy.GroupFeature;
33
34 import java.awt.BasicStroke;
35 import java.awt.Color;
36 import java.awt.Font;
37 import java.awt.Graphics2D;
38 import java.awt.geom.AffineTransform;
39 import java.awt.geom.Line2D;
40
41
44 public class IsometryGroupPainter implements GenericNodeRealizer.Painter, GenericNodeRealizer.ContainsTest {
45 static final int ICON_GAP = 2;
46 static final int ICON_HEIGHT = 16;
47 static final int ICON_WIDTH = 16;
48
49 private final IsometryNodePainter painterDelegate;
50
51 public IsometryGroupPainter(IsometryNodePainter painter) {
52 painterDelegate = painter;
53 }
54
55 public void paint(NodeRealizer context, Graphics2D graphics) {
56 painterDelegate.paint(context, graphics);
58
59 final AffineTransform oldTransform = graphics.getTransform();
62 final Font oldFont = graphics.getFont();
63 final Color oldColor = graphics.getColor();
64
65 final double[] corners = new double[16];
67 final IsometryData isometryData = IsometryRealizerFactory.getIsometryData(context);
68 isometryData.calculateCorners(corners);
69 IsometryData.moveTo(context.getX(), context.getY(), corners);
70
71 final double anchorX = corners[IsometryData.C3_X];
73 final double anchorY = corners[IsometryData.C3_Y];
74
75 graphics.translate(anchorX, anchorY);
77 graphics.transform(new AffineTransform(
78 new double[]{
79 IsometryData.M_TO_VIEW_11,
80 IsometryData.M_TO_VIEW_21,
81 IsometryData.M_TO_VIEW_12,
82 IsometryData.M_TO_VIEW_22}));
83 graphics.translate(-anchorX, -anchorY);
84
85 final int x = (int) anchorX + ICON_GAP;
87 final int y = (int) (anchorY - ICON_HEIGHT - ICON_GAP);
88
89 graphics.setStroke(new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER));
91 graphics.setColor(Color.WHITE);
92 graphics.fillRect(x, y, ICON_WIDTH, ICON_HEIGHT);
93 graphics.setColor(Color.BLACK);
94 graphics.drawRect(x, y, ICON_WIDTH, ICON_HEIGHT);
95
96 final Line2D line = new Line2D.Double(x + ICON_WIDTH * 0.25, y + ICON_HEIGHT * 0.5,
98 x + ICON_WIDTH * 0.75, y + ICON_HEIGHT * 0.5);
99 graphics.draw(line);
100 if (context instanceof GroupFeature && ((GroupFeature) context).isGroupClosed()) {
101 line.setLine(x + ICON_WIDTH * 0.5, y + ICON_HEIGHT * 0.25,
102 x + ICON_WIDTH * 0.5, y + ICON_HEIGHT * 0.75);
103 graphics.draw(line);
104 }
105
106 graphics.setTransform(oldTransform);
108 graphics.setFont(oldFont);
109 graphics.setColor(oldColor);
110 }
111
112 public void paintSloppy(NodeRealizer context, Graphics2D graphics) {
113 painterDelegate.paintSloppy(context, graphics);
114 }
115
116 public boolean contains(NodeRealizer context, double x, double y) {
117 return painterDelegate.contains(context, x, y);
118 }
119
120
123 public static boolean hitsGroupStateIcon(NodeRealizer context, double x, double y) {
124 final double[] corners = new double[16];
126 final IsometryData isometryData = IsometryRealizerFactory.getIsometryData(context);
127 isometryData.calculateCorners(corners);
128 IsometryData.moveTo(context.getX(), context.getY(), corners);
129
130 final double anchorX = corners[IsometryData.C3_X];
132 final double anchorY = corners[IsometryData.C3_Y];
133
134 final double mouseX = IsometryData.toLayoutX(x - anchorX, y - anchorY);
137 final double mouseY = IsometryData.toLayoutY(x - anchorX, y - anchorY);
138
139 return mouseX > ICON_GAP && mouseX < ICON_WIDTH + ICON_GAP
141 && mouseY < -ICON_GAP && mouseY > -ICON_HEIGHT - ICON_GAP;
142 }
143 }
144