1   
28  package demo.view.uml;
29  
30  import y.base.NodeList;
31  import y.geom.YDimension;
32  import y.view.Graph2D;
33  import y.view.Graph2DView;
34  import y.view.LineType;
35  import y.view.NodeLabel;
36  import y.view.NodeRealizer;
37  
38  import java.awt.Color;
39  import java.awt.Graphics2D;
40  import java.awt.Shape;
41  import java.awt.geom.GeneralPath;
42  import java.awt.geom.Rectangle2D;
43  
44  
47  class UmlClassOpenCloseClassButton extends UmlClassButton {
48    public static final double ICON_SIZE = 16;
49    public static final double ICON_GAP = 5;
50  
51    
54    protected boolean isVisible(final NodeRealizer context) {
55      return true;
56    }
57  
58    
61    public void paint(final NodeRealizer context, final Graphics2D graphics) {
62      if (isVisible(context)) {
63        final Rectangle2D area = getButtonArea(context);
64        paintButton(context, graphics, area);
65        paintIcon(context, graphics, area);
66      }
67    }
68  
69    
72    protected Rectangle2D getButtonArea(final NodeRealizer context) {
73      return new Rectangle2D.Double(
74          context.getX() + context.getWidth() - ICON_SIZE - ICON_GAP,
75          context.getY() + ICON_GAP,
76          ICON_SIZE,
77          ICON_SIZE);
78    }
79  
80    
83    private void paintButton(final NodeRealizer context, final Graphics2D graphics, final Rectangle2D area) {
84      final Color color = getButtonColor(context);
85      graphics.setColor(color);
86      graphics.fill(area);
87    }
88  
89    
92    private Color getButtonColor(final NodeRealizer context) {
93      return isMouseOverButton(context) ?
94          UmlRealizerFactory.COLOR_BUTTON_BACKGROUND_ACTIVE :
95          UmlRealizerFactory.COLOR_BUTTON_BACKGROUND_BLANK;
96    }
97  
98    
102   private boolean isMouseOverButton(final NodeRealizer context) {
103     return UmlRealizerFactory.getMouseOverButton(context) == UmlRealizerFactory.BUTTON_OPEN_CLOSE_CLASS_SECTIONS;
104   }
105 
106   
109   private void paintIcon(final NodeRealizer context, final Graphics2D graphics, final Rectangle2D area) {
110     final Shape shape = getIconShape(context, area);
111     graphics.setColor(UmlRealizerFactory.COLOR_BUTTON_FOREGROUND_ENABLED);
112     graphics.setStroke(LineType.LINE_1);
113     graphics.draw(shape);
114   }
115 
116   
119   private Shape getIconShape(final NodeRealizer context, final Rectangle2D area) {
120     if (UmlClassLabelSupport.getModel(context).areSectionsVisible()) {
121       return getCloseShape(area);
122     } else {
123       return getOpenShape(area);
124     }
125   }
126 
127   
130   private Shape getCloseShape(final Rectangle2D area) {
131     final float minX = (float) (area.getX() + area.getWidth() * 0.25);
132     final float midX = (float) (area.getX() + area.getWidth() * 0.5);
133     final float maxX = (float) (area.getX() + area.getWidth() * 0.75);
134     final float minY = (float) (area.getY() + area.getHeight() * 0.25);
135     final float midY = (float) (area.getY() + area.getHeight() * 0.5);
136     final float maxY = (float) (area.getY() + area.getHeight() * 0.75);
137 
138     final GeneralPath icon = new GeneralPath();
139     icon.moveTo(minX, midY);
140     icon.lineTo(midX, minY);
141     icon.lineTo(maxX, midY);
142     icon.moveTo(minX, maxY);
143     icon.lineTo(midX, midY);
144     icon.lineTo(maxX, maxY);
145 
146     return icon;
147   }
148 
149   
152   private Shape getOpenShape(final Rectangle2D area) {
153     final float minX = (float) (area.getX() + area.getWidth() * 0.25);
154     final float midX = (float) (area.getX() + area.getWidth() * 0.5);
155     final float maxX = (float) (area.getX() + area.getWidth() * 0.75);
156     final float minY = (float) (area.getY() + area.getHeight() * 0.25);
157     final float midY = (float) (area.getY() + area.getHeight() * 0.5);
158     final float maxY = (float) (area.getY() + area.getHeight() * 0.75);
159 
160     final GeneralPath icon = new GeneralPath();
161     icon.moveTo(minX, minY);
162     icon.lineTo(midX, midY);
163     icon.lineTo(maxX, minY);
164     icon.moveTo(minX, midY);
165     icon.lineTo(midX, maxY);
166     icon.lineTo(maxX, midY);
167     return icon;
168   }
169 
170   
173   protected void buttonClicked(final NodeRealizer context, final Graph2DView view) {
174     final Graph2D graph = view.getGraph2D();
175     graph.firePreEvent();
176     try {
177       graph.backupRealizers(new NodeList(context.getNode()).nodes());
178       graph.backupRealizers(context.getNode().edges());
179       final boolean isOpened = UmlClassLabelSupport.getModel(context).areSectionsVisible();
180       final UmlClassAnimation animation = new OpenCloseClassAnimation(view, context, isOpened);
181       animation.play();
182     } finally {
183       graph.firePostEvent();
184     }
185   }
186 
187   
190   protected void buttonEntered(final NodeRealizer context, final Graph2DView view) {
191     UmlRealizerFactory.setMouseOverButton(context, UmlRealizerFactory.BUTTON_OPEN_CLOSE_CLASS_SECTIONS);
192     view.updateView();
193   }
194 
195   
198   private static class OpenCloseClassAnimation extends UmlClassAnimation  {
199     private OpenCloseClassAnimation(final Graph2DView view, final NodeRealizer context, final boolean isClosing) {
200       super(view, context, isClosing);
201     }
202 
203     
206     protected void close() {
207       UmlClassLabelSupport.getModel(context).setSectionsVisible(false);
208       UmlClassLabelSupport.updateAllLabels(context);
209       UmlClassLabelSupport.updateRealizerSize(context);
210     }
211 
212     
215     protected void open() {
216       UmlClassLabelSupport.getModel(context).setSectionsVisible(true);
217       UmlClassLabelSupport.updateAllLabels(context);
218       UmlClassLabelSupport.updateRealizerSize(context);
219     }
220 
221     
224     protected YDimension getClosedSize() {
225       final boolean isVisible = UmlClassLabelSupport.getModel(context).areSectionsVisible();
226       UmlClassLabelSupport.getModel(context).setSectionsVisible(false);
227       UmlClassLabelSupport.updateAllLabels(context);
228       UmlClassLabelSupport.updateRealizerSize(context);
229 
230       final YDimension dimension = new YDimension(context.getWidth(), context.getHeight());
231       UmlClassLabelSupport.getModel(context).setSectionsVisible(isVisible);
232       UmlClassLabelSupport.updateAllLabels(context);
233       UmlClassLabelSupport.updateRealizerSize(context);
234       return dimension;
235     }
236 
237     
240     protected double getFixedY() {
241       final NodeLabel nameLabel = UmlClassLabelSupport.getNameLabel(context);
242       return nameLabel.getLocation().getY() + nameLabel.getHeight();
243     }
244 
245     
248     protected double getMovingY() {
249       double fixedY = getFixedY();
250       for (int i = 0; i < context.labelCount(); i++) {
251         final NodeLabel label = context.getLabel(i);
252         fixedY = Math.max(fixedY, label.getLocation().getY() + label.getHeight());
253       }
254       return fixedY;
255     }
256   }
257 }
258