1
28 package demo.layout.labeling;
29
30 import y.view.DefaultLabelConfiguration;
31 import y.view.EdgeLabel;
32 import y.view.YLabel;
33 import y.view.YRenderingHints;
34
35 import java.awt.BasicStroke;
36 import java.awt.Color;
37 import java.awt.Font;
38 import java.awt.Graphics2D;
39 import java.awt.Stroke;
40 import java.awt.geom.Ellipse2D;
41 import java.awt.geom.Line2D;
42 import java.awt.geom.Rectangle2D;
43
44
48 class VisualizingBoundsLabelConfiguration extends DefaultLabelConfiguration {
49
50 private static final Color COLOR_HEIGHT_INDICATOR = new Color(51, 102, 153);
51 private static final Color COLOR_WIDTH_INDICATOR = new Color(102, 204, 51);
52 private static final Color COLOR_UP_VECTOR = new Color(204, 153, 51);
53 private static final Color COLOR_ANCHOR_POINT = new Color(153, 51, 51);
54 private static final Color COLOR_LABEL_BACKGROUND = new Color(210, 210, 210);
55 private static final Color COLOR_LABEL_SELECTED = Color.RED;
56
57 private static final Stroke STROKE_UNSELECTED = new BasicStroke(0.5f);
58 private static final Stroke STROKE_SELECTED = new BasicStroke(1f);
59
60 private static final double DIAGONAL_THIN_STROKE_OFFSET = Math.sqrt(2) * 0.25;
61
62 private static Font tinyFont;
63
64
65 public void paintContent(YLabel label, Graphics2D gfx, double x, double y, double width, double height) {
66 }
68
69 public void paintBox(YLabel label, Graphics2D gfx, double x, double y, double width, double height) {
70 if (label instanceof EdgeLabel) {
71 final Stroke oldStroke = gfx.getStroke();
72 final Color oldColor = gfx.getColor();
73 final Font oldFont = gfx.getFont();
74
75 try {
76 final double x2 = x + width;
77 final double y2 = y + height;
78 final double cx = x + width / 2;
79
80 final boolean flipVerticalText = label.getOrientedBox().getUpX() < 0;
83 final boolean flipHorizontalText = label.getOrientedBox().getUpY() > 0;
84
85 gfx.setColor(COLOR_LABEL_BACKGROUND);
87 gfx.fill(new Rectangle2D.Double(x, y, width, height));
88
89 gfx.setStroke(STROKE_UNSELECTED);
90 gfx.setFont(getTinyFont(gfx));
91
92 gfx.setColor(COLOR_UP_VECTOR);
94 gfx.draw(new Line2D.Double(x, y + 0.5, x, y2 - 0.25));
95 gfx.draw(new Line2D.Double(x, y + DIAGONAL_THIN_STROKE_OFFSET, x - 2, y + 2 + DIAGONAL_THIN_STROKE_OFFSET));
96 gfx.draw(new Line2D.Double(x, y + DIAGONAL_THIN_STROKE_OFFSET, x + 2, y + 2 + DIAGONAL_THIN_STROKE_OFFSET));
97
98 gfx.setColor(COLOR_ANCHOR_POINT);
100 gfx.fill(new Ellipse2D.Double(x - 1, y2 - 1, 2, 2));
101
102 gfx.setColor(COLOR_HEIGHT_INDICATOR);
104 gfx.draw(new Line2D.Double(cx, y + 0.5, cx, y2 - 0.5));
105
106 gfx.draw(new Line2D.Double(cx, y + DIAGONAL_THIN_STROKE_OFFSET, cx - 2, y + 2 + DIAGONAL_THIN_STROKE_OFFSET));
107 gfx.draw(new Line2D.Double(cx, y + DIAGONAL_THIN_STROKE_OFFSET, cx + 2, y + 2 + DIAGONAL_THIN_STROKE_OFFSET));
108
109 gfx.draw(new Line2D.Double(cx, y2 - DIAGONAL_THIN_STROKE_OFFSET, cx - 2, y2 - 2 - DIAGONAL_THIN_STROKE_OFFSET));
110 gfx.draw(new Line2D.Double(cx, y2 - DIAGONAL_THIN_STROKE_OFFSET, cx + 2, y2 - 2 - DIAGONAL_THIN_STROKE_OFFSET));
111
112 if (flipVerticalText) {
113 gfx.rotate(Math.PI / 2, x, y);
114 gfx.drawString("height", (float) (x + 3), (float) (y - width / 2 + 4));
115 gfx.rotate(-Math.PI / 2, x, y);
116
117 } else {
118 gfx.rotate(-Math.PI / 2, x, y);
119 gfx.drawString("height", (float) (x - height + 4), (float) (y + width / 2 - 2));
120 gfx.rotate(Math.PI / 2, x, y);
121 }
122
123 gfx.setColor(COLOR_WIDTH_INDICATOR);
125 gfx.draw(new Line2D.Double(x + 0.5, y2, x2 - 0.5, y2));
126
127 gfx.draw(new Line2D.Double(x + DIAGONAL_THIN_STROKE_OFFSET, y2, x + 2 + DIAGONAL_THIN_STROKE_OFFSET, y2 - 2));
128 gfx.draw(new Line2D.Double(x + DIAGONAL_THIN_STROKE_OFFSET, y2, x + 2 + DIAGONAL_THIN_STROKE_OFFSET, y2 + 2));
129
130 gfx.draw(new Line2D.Double(x2 - DIAGONAL_THIN_STROKE_OFFSET, y2, x2 - 2 - DIAGONAL_THIN_STROKE_OFFSET, y2 - 2));
131 gfx.draw(new Line2D.Double(x2 - DIAGONAL_THIN_STROKE_OFFSET, y2, x2 - 2 - DIAGONAL_THIN_STROKE_OFFSET, y2 + 2));
132
133 if (flipHorizontalText) {
134 gfx.rotate(-Math.PI, x + width / 2, y + height);
135 gfx.drawString("width", (float) (x + width / 2 - 5), (float) (y + height));
136 gfx.rotate(Math.PI, x + width / 2, y + height);
137 } else {
138 gfx.drawString("width", (float) (x + width / 2 - 5), (float) (y + height + 3));
139 }
140
141 if (useSelectionStyle(label, gfx)) {
143 gfx.setStroke(STROKE_SELECTED);
144 gfx.setColor(COLOR_LABEL_SELECTED);
145 gfx.draw(new Rectangle2D.Double(x, y, width, height));
146 }
147 } finally {
148 gfx.setFont(oldFont);
149 gfx.setStroke(oldStroke);
150 gfx.setColor(oldColor);
151 }
152 }
153 }
154
155 private boolean useSelectionStyle(final YLabel label, final Graphics2D gfx) {
156 return label.isSelected() && YRenderingHints.isSelectionPaintingEnabled(gfx);
157 }
158
159 private static Font getTinyFont(final Graphics2D gfx) {
160 if (tinyFont == null) {
161 final Font font = gfx.getFont();
162 tinyFont = new Font(font.getName(), font.getStyle(), 4);
163 }
164 return tinyFont;
165 }
166 }
167