1   /****************************************************************************
2    **
3    ** This file is part of yFiles-2.9. 
4    ** 
5    ** yWorks proprietary/confidential. Use is subject to license terms.
6    **
7    ** Redistribution of this file or of an unauthorized byte-code version
8    ** of this file is strictly forbidden.
9    **
10   ** Copyright (c) 2000-2011 by yWorks GmbH, Vor dem Kreuzberg 28, 
11   ** 72070 Tuebingen, Germany. All rights reserved.
12   **
13   ***************************************************************************/
14  package demo.view.entityrelationship.painters;
15  
16  import y.geom.OrientedRectangle;
17  import y.view.NodeLabel;
18  import y.view.YLabel;
19  
20  import java.awt.Graphics2D;
21  import java.awt.font.FontRenderContext;
22  import java.util.Map;
23  
24  /**
25   * This configuration paints ERD attribute labels for detailed entities.
26   *
27   * The label uses the whole space of the lower compartment. So the size is retrieved from
28   * the oriented box instead of the content box. Also the the contains test is using this size.
29   */
30  public class ErdAttributesLabelConfiguration implements YLabel.Layout, YLabel.Painter {
31    private final YLabel.Layout layout;
32    private final YLabel.Painter painter;
33  
34    public ErdAttributesLabelConfiguration() {
35      this(defaultLayout(), ErdNameLabelPainter.defaultPainter());
36    }
37  
38    /**
39     * Creates a new <code>ErdAttributesLabelConfiguration</code>.
40     * @param layout the layout of the label
41     * @param painter the painter of the label
42     */
43    public ErdAttributesLabelConfiguration(
44            final YLabel.Layout layout,
45            final YLabel.Painter painter
46    ) {
47      this.layout = layout;
48      this.painter = painter;
49    }
50  
51    /**
52     * Paints the ERD attributes label.
53     * @param label the label context
54     * @param gfx the graphics object
55     */
56    public void paint( final YLabel label, final Graphics2D gfx ) {
57      if (painter != null) {
58        final OrientedRectangle cb = label.getContentBox();
59        if (cb.getUpY() == -1) {
60          // Use the oriented box size to paint the box,
61          // so the label is as wide as the node
62          final OrientedRectangle ob = label.getOrientedBox();
63          final double h = ob.getHeight();
64          final double x = ob.getAnchorX();
65          final double y = ob.getAnchorY() - h;
66          paintBox(label, gfx, x, y, ob.getWidth(), h);
67          paintContent(label, gfx, x, y, cb.getWidth(), cb.getHeight());
68        } else {
69          painter.paint(label, gfx);
70        }
71      }
72    }
73  
74    /**
75     * Draws the content of the attributes label. In this case it is a string containing the attributes.
76     * @param label the label context
77     * @param gfx the graphics object
78     * @param x the x-coordinate of the label
79     * @param y the y-coordinate of the label
80     * @param width the width of the label
81     * @param height the height of the label
82     */
83    public void paintContent(
84            final YLabel label,
85            final Graphics2D gfx,
86            final double x,
87            final double y,
88            final double width,
89            final double height
90    ) {
91      if (painter != null) {
92        painter.paintContent(label, gfx, x, y, width, height);
93      }
94    }
95  
96    /**
97     * Paints the background of the attributes label.
98     * @param label the label context
99     * @param gfx the graphics object
100    * @param x the x-coordinate of the label
101    * @param y the y-coordinate of the label
102    * @param width the width of the label
103    * @param height the height of the label
104    */
105   public void paintBox(
106           final YLabel label,
107           final Graphics2D gfx,
108           final double x,
109           final double y,
110           final double width,
111           final double height
112   ) {
113     if (painter != null) {
114       painter.paintBox(label, gfx, x, y, width, height);
115     }
116   }
117 
118   /**
119    * Returns the text box of the current painter.
120    * @param label the label context
121    * @return a rectangle with the size and position of the text box
122    */
123   public OrientedRectangle getTextBox( final YLabel label ) {
124     if (painter != null) {
125       return painter.getTextBox(label);
126     } else {
127       return null;
128     }
129   }
130 
131   /**
132    * Returns the icon box of the current painter.
133    * @param label the label context
134    * @return a rectangle with the size and position of the icon box
135    */
136   public OrientedRectangle getIconBox( final YLabel label ) {
137     if (painter != null) {
138       return painter.getIconBox(label);
139     } else {
140       return null;
141     }
142   }
143 
144   /**
145    * Calculates the size of the label content.
146    * @param label the label context
147    * @param frc the font render context.
148    */
149   public void calculateContentSize(
150           final YLabel label,
151           final FontRenderContext frc
152   ) {
153     if (layout != null) {
154       layout.calculateContentSize(label, frc);
155     }
156   }
157 
158   /**
159    * Determines if the coordinates <code>(x,y)</code> lie within the label box.
160    * @param label the label context.
161    * @param x x-coordinate
162    * @param y y-coordinate
163    * @return <code>true</code> if the label box contains the coordinates (x,y), <code>false</code> otherwise
164    */
165   public boolean contains(
166           final YLabel label,
167           final double x,
168           final double y
169   ) {
170     // Use the oriented box instead of the content box, so one can
171     // click on the whole compartment to select the label
172     return label.getOrientedBox().contains(x, y, true);
173   }
174 
175 
176   /**
177    * Retrieves a suitable default layout for this configuration.
178    * @return the default layout or <code>null</code> if no default layout is set
179    */
180   static YLabel.Layout defaultLayout() {
181     final YLabel.Factory factory = NodeLabel.getFactory();
182     final Map c = factory.createDefaultConfigurationMap();
183     final Object layout = c.get(YLabel.Layout.class);
184     if (layout instanceof YLabel.Layout) {
185       return (YLabel.Layout) layout;
186     } else {
187       return null;
188     }
189   }
190 }
191 
192