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.AlphaComposite;
39  import java.awt.Color;
40  import java.awt.Composite;
41  import java.awt.Graphics2D;
42  import java.awt.RenderingHints;
43  import java.awt.Shape;
44  import java.awt.geom.Ellipse2D;
45  import java.awt.geom.GeneralPath;
46  import java.awt.geom.Rectangle2D;
47  
48  
51  class UmlClassRemoveItemButton extends UmlClassButton {
52    public static final double ICON_SIZE = 12;
53    public static final double ICON_GAP = 5;
54  
55    private final boolean isAttributeSection;
56  
57    
60    public UmlClassRemoveItemButton(final boolean attributeSection) {
61      isAttributeSection = attributeSection;
62    }
63  
64    
67    public void paint(final NodeRealizer context, final Graphics2D graphics) {
68      if (isVisible(context)) {
69              final Composite orgComposite = graphics.getComposite();
71        final AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getButtonOpacity(context));
72        graphics.setComposite(composite);
73  
74        final Rectangle2D area = getButtonArea(context);
75        paintBackground(context, graphics, area);
76        paintIcon(context, graphics, area);
77  
78        graphics.setComposite(orgComposite);
79      }
80    }
81  
82    
86    protected boolean isVisible(final NodeRealizer context) {
87      final boolean areClassDetailsVisible = UmlClassLabelSupport.getModel(context).areSectionsVisible();
88      final boolean isSectionVisible =
89          isAttributeSection && UmlClassLabelSupport.getModel(context).areAttributesVisible() ||
90          !isAttributeSection && UmlClassLabelSupport.getModel(context).areOperationsVisible();
91      return isSectionVisible && areClassDetailsVisible;
92    }
93  
94    
97    protected Rectangle2D getButtonArea(final NodeRealizer context) {
98      final NodeLabel label = getCaptionLabel(context);
99      return new Rectangle2D.Double(
100         context.getX() + context.getWidth() - ICON_SIZE - ICON_GAP,
101         label.getLocation().getY() + (label.getHeight() - ICON_SIZE) * 0.5,
102         ICON_SIZE,
103         ICON_SIZE);
104   }
105 
106   
107   private NodeLabel getCaptionLabel(final NodeRealizer context) {
108     if (isAttributeSection) {
109       return UmlClassLabelSupport.getAttributeCaptionLabel(context);
110     } else {
111       return UmlClassLabelSupport.getOperationCaptionLabel(context);
112     }
113   }
114 
115   
118   private void paintBackground(final NodeRealizer context, final Graphics2D graphics, final Rectangle2D area) {
119     final Color color = isMouseOverButton(context) && isEnabled(context) ?
120         UmlRealizerFactory.COLOR_BUTTON_BACKGROUND_ACTIVE :
121         UmlRealizerFactory.COLOR_BUTTON_BACKGROUND_BLANK;
122     final Shape shape = new Ellipse2D.Double(area.getX(), area.getY(), area.getWidth(), area.getHeight());
123     graphics.setColor(color);
124     graphics.fill(shape);
125   }
126 
127   
128   private float getButtonOpacity(final NodeRealizer context) {
129     if (isAttributeSection) {
130       return UmlRealizerFactory.getAttributeButtonOpacity(context);
131     } else {
132       return UmlRealizerFactory.getOperationButtonOpacity(context);
133     }
134   }
135 
136   
140   private boolean isMouseOverButton(final NodeRealizer context) {
141     final int button = UmlRealizerFactory.getMouseOverButton(context);
142     return ((button == UmlRealizerFactory.BUTTON_SUB_ATTRIBUTE) && isAttributeSection) ||
143            ((button == UmlRealizerFactory.BUTTON_SUB_OPERATION) && !isAttributeSection);
144   }
145 
146   
149   private void paintIcon(final NodeRealizer context, final Graphics2D graphics, final Rectangle2D area) {
150     final Object orgRenderingHint = graphics.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
151     graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
152     try {
153       final Shape shape = getIconShape(area);
154       final Color color = isEnabled(context) ?
155           UmlRealizerFactory.COLOR_BUTTON_FOREGROUND_ENABLED :
156           UmlRealizerFactory.COLOR_BUTTON_FOREGROUND_DISABLED;
157       graphics.setColor(color);
158       graphics.setStroke(LineType.LINE_1);
159       graphics.draw(shape);
160     } finally {
161       graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, orgRenderingHint);
162     }
163   }
164 
165   
169   private boolean isEnabled(final NodeRealizer context) {
170     return (isAttributeSection && UmlClassLabelSupport.isAttributeSelected(context)) ||
171            (!isAttributeSection && UmlClassLabelSupport.isOperationSelected(context));
172   }
173 
174   
177   private Shape getIconShape(final Rectangle2D area) {
178     final float minX = (float) (area.getX() + area.getWidth() * 0.25);
179     final float maxX = (float) (area.getX() + area.getWidth() * 0.75);
180     final float midY = (float) (area.getY() + area.getHeight() * 0.5);
181 
182     final GeneralPath icon = new GeneralPath();
183     icon.moveTo(minX, midY);
184     icon.lineTo(maxX, midY);
185     return icon;
186   }
187 
188   
191   protected void buttonClicked(final NodeRealizer context, final Graph2DView view) {
192     if (isEnabled(context) && getButtonOpacity(context) == UmlRealizerFactory.OPAQUE) {
193       final Graph2D graph = view.getGraph2D();
194       graph.firePreEvent();
195       try {
196         graph.backupRealizers(new NodeList(context.getNode()).nodes());
197         graph.backupRealizers(context.getNode().edges());
198         final UmlClassAnimation animation = new RemoveItemAnimation(view, context, true);
199         animation.play();
200       } finally {
201         graph.firePostEvent();
202       }
203       view.updateView();
204     }
205   }
206 
207   
208   protected void buttonEntered(final NodeRealizer context, final Graph2DView view) {
209     if (isAttributeSection) {
210       UmlRealizerFactory.setMouseOverButton(context, UmlRealizerFactory.BUTTON_SUB_ATTRIBUTE);
211     } else {
212       UmlRealizerFactory.setMouseOverButton(context, UmlRealizerFactory.BUTTON_SUB_OPERATION);
213     }
214     view.updateView(getButtonArea(context));
215   }
216 
217   
220   static class RemoveItemAnimation extends UmlClassAnimation  {
221 
222     RemoveItemAnimation(final Graph2DView view, final NodeRealizer context, final boolean isClosing) {
223       super(view, context, isClosing);
224     }
225 
226     
229     protected void open() {
230     }
231 
232     
235     protected void close() {
236       UmlClassLabelSupport.removeSelectedLabel(context);
237     }
238 
239     
242     protected YDimension getClosedSize() {
243       final NodeLabel selectedLabel = UmlClassLabelSupport.getSelectedLabel(context);
244       return new YDimension(context.getWidth(), context.getHeight() - selectedLabel.getHeight());
245     }
246 
247     
250     protected double getFixedY() {
251       final NodeLabel label = UmlClassLabelSupport.getSelectedLabel(context);
252       return label.getLocation().getY();
253     }
254 
255     
258     protected double getMovingY() {
259       final NodeLabel label = UmlClassLabelSupport.getSelectedLabel(context);
260       return label.getLocation().getY() + label.getHeight();
261     }
262   }
263 }
264