1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.dishevelled.piccolo.identify;
25
26 import java.awt.Color;
27 import java.awt.Shape;
28
29 import java.awt.geom.Point2D;
30 import java.awt.geom.RoundRectangle2D;
31
32 import java.beans.PropertyChangeEvent;
33 import java.beans.PropertyChangeListener;
34
35 import javax.swing.UIManager;
36
37 import org.piccolo2d.nodes.PPath;
38
39 import org.piccolo2d.util.PBounds;
40
41 import org.piccolo2d.extras.nodes.PShadow;
42
43 import org.dishevelled.iconbundle.IconSize;
44 import org.dishevelled.iconbundle.IconState;
45
46
47
48
49
50
51
52 public final class NautilusIdNode
53 extends AbstractIdNode
54 {
55
56 private PPath textSelection;
57
58
59 private PShadow textShadow;
60
61
62 private final double iconTextGap = DEFAULT_ICON_TEXT_GAP;
63
64
65 private static final int BLUR_RADIUS = 4;
66
67
68 private static final double TEXT_SHADOW_OFFSET = 0.5d;
69
70
71 private static final double DEFAULT_ICON_TEXT_GAP = 2.0d;
72
73
74
75
76
77 public NautilusIdNode()
78 {
79 this(null);
80 }
81
82
83
84
85
86
87 public NautilusIdNode(final Object value)
88 {
89 super(value);
90 createNodes();
91 resetStateMachine();
92 }
93
94
95
96
97
98
99
100 public NautilusIdNode(final Object value, final IconSize iconSize)
101 {
102 super(value);
103 setIconSize(iconSize);
104 createNodes();
105 resetStateMachine();
106 }
107
108
109
110
111
112 private void createNodes()
113 {
114 textSelection = new PPath.Double();
115 textShadow = new PShadow(getNameTextNode().toImage(), Color.BLACK, BLUR_RADIUS);
116 addChild(textShadow);
117 addChild(textSelection);
118 addChild(getIconBundleImageNode());
119 addChild(getNameTextNode());
120
121
122 PropertyChangeListener listener = new PropertyChangeListener()
123 {
124 @Override
125 public void propertyChange(final PropertyChangeEvent event)
126 {
127 updateTextShadow();
128 }
129 };
130 getNameTextNode().addPropertyChangeListener("font", listener);
131 getNameTextNode().addPropertyChangeListener("text", listener);
132 }
133
134
135
136
137 private void normal()
138 {
139 setIconState(IconState.NORMAL);
140 getNameTextNode().setTextPaint(Color.BLACK);
141 textSelection.setVisible(false);
142 textShadow.setVisible(false);
143 }
144
145
146
147
148 private void reverseNormal()
149 {
150 setIconState(IconState.NORMAL);
151 getNameTextNode().setTextPaint(Color.WHITE);
152 textSelection.setVisible(false);
153 textShadow.setVisible(true);
154 }
155
156
157
158
159 private void mouseover()
160 {
161 setIconState(IconState.MOUSEOVER);
162 getNameTextNode().setTextPaint(Color.BLACK);
163 textSelection.setVisible(false);
164 textShadow.setVisible(false);
165 }
166
167
168
169
170 private void reverseMouseover()
171 {
172 setIconState(IconState.MOUSEOVER);
173 getNameTextNode().setTextPaint(Color.WHITE);
174 textSelection.setVisible(false);
175 textShadow.setVisible(true);
176 }
177
178
179
180
181 private void selected()
182 {
183 setIconState(IconState.SELECTED);
184 getNameTextNode().setTextPaint(Color.WHITE);
185 textSelection.setPaint(UIManager.getColor("List.selectionBackground"));
186 textSelection.setStrokePaint(UIManager.getColor("List.selectionBackground"));
187 textSelection.setVisible(true);
188 textShadow.setVisible(false);
189 }
190
191
192
193
194 private void selectedMouseover()
195 {
196 setIconState(IconState.SELECTED_MOUSEOVER);
197 getNameTextNode().setTextPaint(Color.WHITE);
198 textSelection.setPaint(UIManager.getColor("List.selectionBackground"));
199 textSelection.setStrokePaint(UIManager.getColor("List.selectionBackground"));
200 textSelection.setVisible(true);
201 textShadow.setVisible(false);
202 }
203
204
205
206
207 private void reverseSelected()
208 {
209 selected();
210 }
211
212
213
214
215 private void reverseSelectedMouseover()
216 {
217 selectedMouseover();
218 }
219
220
221
222
223 private void dragging()
224 {
225 setIconState(IconState.NORMAL);
226 getNameTextNode().setTextPaint(Color.WHITE);
227 textSelection.setPaint(UIManager.getColor("List.selectionBackground"));
228 textSelection.setStrokePaint(UIManager.getColor("List.selectionBackground"));
229 textSelection.setVisible(true);
230 textShadow.setVisible(false);
231 }
232
233
234
235
236 private void reverseDragging()
237 {
238 setIconState(IconState.NORMAL);
239 getNameTextNode().setTextPaint(Color.WHITE);
240 textSelection.setPaint(UIManager.getColor("List.selectionBackground"));
241 textSelection.setStrokePaint(UIManager.getColor("List.selectionBackground"));
242 textSelection.setVisible(true);
243 textShadow.setVisible(false);
244 }
245
246
247
248
249 private void updateTextShadow()
250 {
251 removeChild(textShadow);
252 boolean visible = textShadow.getVisible();
253 textShadow = new PShadow(getNameTextNode().toImage(), Color.BLACK, BLUR_RADIUS);
254 textShadow.setVisible(visible);
255 addChild(0, textShadow);
256 }
257
258 @Override
259 protected void layoutChildren()
260 {
261 PBounds iconBounds = getIconBundleImageNode().getBoundsReference();
262 Point2D iconCenter = iconBounds.getCenter2D();
263 getIconBundleImageNode().setOffset(-iconCenter.getX(), -iconCenter.getY());
264
265 PBounds textBounds = getNameTextNode().getBoundsReference();
266 Point2D textCenter = textBounds.getCenter2D();
267
268 double textSelectionWidthMargin = 4.0d;
269 double textSelectionHeightMargin = 1.0d;
270
271 Shape textSelectionRect = new RoundRectangle2D.Double(0.0d, 0.0d,
272 textBounds.getWidth() + 2.0d * textSelectionWidthMargin, textBounds.getHeight() + 2.0d * textSelectionHeightMargin,
273 6.0d, 6.0d);
274 textSelection.reset();
275 textSelection.append(textSelectionRect, false);
276 PBounds textSelectionBounds = textSelection.getBoundsReference();
277 Point2D textSelectionCenter = textSelectionBounds.getCenter2D();
278 textSelection.setOffset(-textSelectionCenter.getX(), iconCenter.getY() + iconTextGap - textSelectionHeightMargin);
279 getNameTextNode().setOffset(-textCenter.getX(), iconCenter.getY() + iconTextGap);
280 textShadow.setOffset(-textCenter.getX() - (2 * BLUR_RADIUS) + TEXT_SHADOW_OFFSET,
281 iconCenter.getY() + iconTextGap + textSelectionHeightMargin - (2 * BLUR_RADIUS) + TEXT_SHADOW_OFFSET);
282 }
283 }