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