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