1   
28  package demo.view.uml;
29  
30  import y.geom.YDimension;
31  import y.view.GenericNodeRealizer;
32  import y.view.NodeLabel;
33  import y.view.NodeRealizer;
34  import y.view.SmartNodeLabelModel;
35  
36  import java.awt.Color;
37  import java.awt.Font;
38  import java.awt.Insets;
39  import java.awt.geom.Rectangle2D;
40  import java.util.List;
41  
42  
58  class UmlClassLabelSupport {
59  
60    
61    public static final double SECTION_GAP = 5;
62  
63    private UmlClassLabelSupport() {
64    }
65  
66    
69    public static void updateAllLabels(final NodeRealizer context) {
70      removeAllLabels(context);
71      createAllLabels(context);
72    }
73  
74    
77    private static void removeAllLabels(final NodeRealizer context) {
78      for (int i = context.labelCount() - 1; i >= 0; i--) {
79        context.removeLabel(i);
80      }
81    }
82  
83    
86    private static void createAllLabels(final NodeRealizer context) {
87      final UmlClassModel model = getModel(context);
88      double yOffset = 0d;
89  
90          final NodeLabel nameLabel = createNameLabel(context);
92      configureLabelModel(nameLabel, false, 20d, yOffset);
93      context.addLabel(nameLabel);
94      yOffset += nameLabel.getHeight() + 5;
95  
96      if (model.areSectionsVisible()) {
97              final NodeLabel attributeHeadingLabel = createCaptionLabel("Attributes");
99        configureLabelModel(attributeHeadingLabel, false, 20d, yOffset);
100       context.addLabel(attributeHeadingLabel);
101       yOffset += attributeHeadingLabel.getHeight();
102 
103             final NodeLabel operationHeadingLabel = createCaptionLabel("Operations");
105       context.addLabel(operationHeadingLabel);
106 
107             if (model.areAttributesVisible()) {
109         final List attributes = model.getAttributes();
110         for (java.util.Iterator it = attributes.iterator(); it.hasNext(); ) {
111           final String text = (String) it.next();
112           final NodeLabel attributeLabel = createLabelByText(text);
113           configureLabelModel(attributeLabel, false, 30d, yOffset);
114           context.addLabel(attributeLabel);
115           yOffset += attributeLabel.getHeight();
116         }
117       }
118 
119             yOffset += SECTION_GAP;
121       configureLabelModel(operationHeadingLabel, false, 20d, yOffset);
122       yOffset += operationHeadingLabel.getHeight();
123 
124             if (model.areOperationsVisible()) {
126         final List operations = model.getOperations();
127         for (java.util.Iterator it = operations.iterator(); it.hasNext(); ) {
128           final String text = (String) it.next();
129           final NodeLabel operationLabel = createLabelByText(text);
130           configureLabelModel(operationLabel, false, 30d, yOffset);
131           context.addLabel(operationLabel);
132           yOffset += operationLabel.getHeight();
133         }
134       }
135     }
136   }
137 
138   
141   static UmlClassModel getModel(final NodeRealizer context) {
142     final GenericNodeRealizer gnr = (GenericNodeRealizer) context;
143     return (UmlClassModel) gnr.getUserData();
144   }
145 
146   
149   private static NodeLabel createNameLabel(final NodeRealizer context) {
150     final NodeLabel label = new NodeLabel();
151     final UmlClassModel model = getModel(context);
152     label.setText(model.getClassName());
153     label.setConfiguration(UmlRealizerFactory.LABEL_CONFIG_NAME);
154     label.setFontSize(16);
155     label.setFontStyle(Font.BOLD);
156     label.setTextColor(Color.WHITE);
157     label.setInsets(new Insets(10, 0, 15, 0));
158     return label;
159   }
160 
161   
164   private static NodeLabel createCaptionLabel(final String text) {
165     final NodeLabel label = new NodeLabel();
166     label.setConfiguration(UmlRealizerFactory.LABEL_CONFIG_NAME);
167     label.setText(text);
168     label.setFontSize(14);
169     label.setTextColor(Color.WHITE);
170     return label;
171   }
172 
173   private static NodeLabel createLabelByText(final String text) {
174     final NodeLabel label = new NodeLabel();
175     label.setConfiguration(UmlRealizerFactory.LABEL_CONFIG_NAME);
176     label.setText(text);
177     label.setFontSize(14);
178     label.setTextColor(Color.DARK_GRAY);
179     return label;
180   }
181 
182   
185   private static void configureLabelModel(
186       final NodeLabel label,
187       final boolean isCenter,
188       final double xOffset,
189       final double yOffset
190   ) {
191     final SmartNodeLabelModel model = new SmartNodeLabelModel();
192     if (isCenter) {
193       label.setLabelModel(model, model.createSpecificModelParameter(0, -0.5, 0, -0.5, xOffset, yOffset, 0, -1));
194     } else {
195       label.setLabelModel(model, model.createSpecificModelParameter(-0.5, -0.5, -0.5, -0.5, xOffset, yOffset, 0, -1));
196     }
197   }
198 
199   
202   public static void removeSelectedLabel(final NodeRealizer context) {
203     final NodeLabel label = getSelectedLabel(context);
204     if (label != null) {
205       int labelIndex = indexOfLabel(context, label);
206       updateSelection(context, labelIndex);
207       removeLabelFromModel(context, labelIndex);
208       updateAllLabels(context);
209       updateRealizerSize(context);
210     }
211   }
212 
213   
216   private static void updateSelection(final NodeRealizer context, final int labelIndexToRemove) {
217                 final int modelListIndex = modelListIndexOf(context, labelIndexToRemove);
221     final List modelList = getModelList(context, labelIndexToRemove);
222     if (modelListIndex == modelList.size() - 1) {
223       getModel(context).setSelectedListIndex(modelList.size() - 2);
224     } else if (modelList.size() == 1) {
225       getModel(context).setSelectedListIndex(UmlClassModel.LIST_INDEX_NONE);
226     }
227   }
228 
229   
232   private static void removeLabelFromModel(final NodeRealizer context, final int labelIndex) {
233     final List modelList = getModelList(context, labelIndex);
234     final int modelListIndex = modelListIndexOf(context, labelIndex);
235     modelList.remove(modelListIndex);
236   }
237 
238   
241   private static List getModelList(final NodeRealizer context, final int labelIndex) {
242     final UmlClassModel model = getModel(context);
243     if (getModel(context).areAttributesVisible()) {
244       final int attributeCount = model.getAttributes().size();
245       if (labelIndex < attributeCount + 3) {
246                 return model.getAttributes();
248       }
249     }
250     return model.getOperations();
251   }
252 
253   
256   private static int modelListIndexOf(final NodeRealizer context, final int labelIndex) {
257     final UmlClassModel model = getModel(context);
258     if (getModel(context).areAttributesVisible()) {
259       final int attributeCount = model.getAttributes().size();
260             if (labelIndex >= attributeCount + 3) {
262         return labelIndex - 3 - attributeCount;
263       }
264     }
265     return labelIndex - 3;
266   }
267 
268   
271   private static int indexOfLabel(final NodeRealizer context, final NodeLabel label) {
272     int labelIndex = -1;
273     for (int i = 0; i < context.labelCount(); i++) {
274       if (label == context.getLabel(i)) {
275         labelIndex = i;
276         break;
277       }
278     }
279     return labelIndex;
280   }
281 
282   
285   public static NodeLabel addAttribute(final NodeRealizer context) {
286     addAttributeToModel(context, "attribute");
287     updateAllLabels(context);
288     updateRealizerSize(context);
289     final int index = indexOfLastAttributeLabel(context);
290     selectLabel(context, index);
291     return context.getLabel(index);
292   }
293 
294   
297   private static void addAttributeToModel(final NodeRealizer context, final String text) {
298     final UmlClassModel model = getModel(context);
299     model.getAttributes().add(text);
300   }
301 
302   
305   private static int indexOfLastAttributeLabel(final NodeRealizer context) {
306     final UmlClassModel model = getModel(context);
307     return model.getAttributes().size() + 2;
308   }
309 
310   
313   public static NodeLabel addOperation(final NodeRealizer context) {
314     addOperationToModel(context, "operation");
315     updateAllLabels(context);
316     updateRealizerSize(context);
317     final int index = indexOfLastOperationLabel(context);
318     selectLabel(context, index);
319     return context.getLabel(index);
320   }
321 
322   
325   private static void addOperationToModel(final NodeRealizer context, final String text) {
326     final UmlClassModel model = getModel(context);
327     model.getOperations().add(text);
328   }
329 
330   
333   private static int indexOfLastOperationLabel(final NodeRealizer context) {
334     final UmlClassModel model = getModel(context);
335     if (getModel(context).areAttributesVisible()) {
336       return model.getAttributes().size() + model.getOperations().size() + 2;
337     } else
338       return model.getOperations().size() + 2;
339   }
340 
341   
344   public static void updateLabelText(final NodeRealizer context, final NodeLabel label) {
345     final String text = label.getText();
346     final int labelIndex = indexOfLabel(context, label);
347     updateLabelTextInModel(context, labelIndex, text);
348   }
349 
350   
353   private static void updateLabelTextInModel(final NodeRealizer context, final int labelIndex, final String text) {
354     if (labelIndex == 0) {
355       final UmlClassModel model = getModel(context);
356       model.setClassName(text);
357     } else {
358       final List modelList = getModelList(context, labelIndex);
359       final int modelListIndex = modelListIndexOf(context, labelIndex);
360       modelList.set(modelListIndex, text);
361     }
362   }
363 
364   
367   public static void updateRealizerSize(final NodeRealizer context) {
368     final double x = context.getX();
369     final double y = context.getY();
370     final YDimension minimumSize = context.getSizeConstraintProvider().getMinimumSize();
371     final double width = Math.max(context.getWidth(), minimumSize.getWidth());
372     context.setSize(width, minimumSize.getHeight());
373     context.setLocation(x, y);
374   }
375 
376   
379   public static boolean selectListItemAt(final NodeRealizer context, final double x, final double y) {
380     if (!UmlClassLabelSupport.getModel(context).areSectionsVisible()) {
381       return false;
382     }
383 
384     final int labelIndex = indexOfLabelAt(context, x, y);
385     if (labelIndex > 2) {
386       selectLabel(context, labelIndex);
387       return true;
388     }
389     return false;
390   }
391 
392   
395   private static int indexOfLabelAt(final NodeRealizer context, final double x, final double y) {
396     for (int i = 3; i < context.labelCount(); i++) {
397       final NodeLabel label = context.getLabel(i);
398       if (labelContains(context, label, x, y)) {
399         return i;
400       }
401     }
402     return -1;
403   }
404 
405   
408   private static void selectLabel(final NodeRealizer context, final int labelIndex) {
409     final UmlClassModel model = getModel(context);
410     if (model.getAttributes() == getModelList(context, labelIndex)) {
411       getModel(context).setSelectedList(UmlClassModel.LIST_ATTRIBUTES);
412     } else {
413       getModel(context).setSelectedList(UmlClassModel.LIST_OPERATIONS);
414     }
415     getModel(context).setSelectedListIndex(modelListIndexOf(context, labelIndex));
416   }
417 
418   
421   public static void selectLabel(final NodeRealizer context, final NodeLabel label) {
422     final int labelIndex = indexOfLabel(context, label);
423     selectLabel(context, labelIndex);
424   }
425 
426   
429   private static boolean labelContains(final NodeRealizer context, final NodeLabel label, final double x, final double y) {
430    final double lx = context.getX();
431    final double ly = label.getLocation().getY();
432    final double lw = context.getWidth();
433    final double lh = label.getHeight();
434     return x >= lx && x <= lx + lw &&
435            y >= ly && y <= ly + lh;
436   }
437 
438   
441   public static void getLabelArea(final NodeRealizer context, final NodeLabel label, final Rectangle2D rect) {
442     rect.setFrame(
443         context.getX(),
444         label.getLocation().getY(),
445         context.getWidth(),
446         label.getHeight());
447   }
448 
449   
452   public static NodeLabel getSelectedLabel(final NodeRealizer context) {
453     final int listIndex = getModel(context).getSelectedListIndex();
454     if (listIndex < 0 || !isSelectedSectionVisible(context)) {
455       return null;
456     }
457 
458     final int list = getModel(context).getSelectedList();
459     final int labelIndex = indexOfLabel(context, list, listIndex);
460     return context.getLabel(labelIndex);
461   }
462 
463   
466   private static int indexOfLabel(final NodeRealizer context, final int list, final int index) {
467     if ((list == UmlClassModel.LIST_ATTRIBUTES) || !getModel(context).areAttributesVisible()) {
468       return index + 3;
469     } else {
470       final UmlClassModel model = getModel(context);
471       return model.getAttributes().size() + index + 3;
472     }
473   }
474 
475   
478   private static boolean isSelectedSectionVisible(final NodeRealizer context) {
479     final int list = getModel(context).getSelectedList();
480     return UmlClassLabelSupport.getModel(context).areSectionsVisible() &&
481            (getModel(context).areAttributesVisible() && (list == UmlClassModel.LIST_ATTRIBUTES)) ||
482            (getModel(context).areOperationsVisible() && (list == UmlClassModel.LIST_OPERATIONS));
483   }
484 
485   
488   public static boolean isAttributeSelected(final NodeRealizer context) {
489     return (getModel(context).getSelectedList() == UmlClassModel.LIST_ATTRIBUTES) &&
490            getModel(context).getSelectedListIndex() >= 0;
491 
492   }
493 
494   
497   public static boolean isOperationSelected(final NodeRealizer context) {
498     return (getModel(context).getSelectedList() == UmlClassModel.LIST_OPERATIONS) &&
499            getModel(context).getSelectedListIndex() >= 0;
500 
501   }
502 
503   
506   static NodeLabel getNameLabel(final NodeRealizer context) {
507     return context.getLabel(0);
508   }
509 
510   
513   static NodeLabel getAttributeCaptionLabel(final NodeRealizer context) {
514     return context.getLabel(1);
515   }
516 
517   
520   static NodeLabel getOperationCaptionLabel(final NodeRealizer context) {
521     return context.getLabel(2);
522   }
523 
524   
527   static boolean isCaptionLabel(final NodeLabel label) {
528     final int labelIndex = indexOfLabel(label.getRealizer(), label);
529     return (labelIndex == 1) || (labelIndex == 2);
530   }
531 }
532