Source code: com/arranger/jarl/widget/container/EchoCollection.java
1 package com.arranger.jarl.widget.container;
2
3 import com.arranger.jarl.base.IContext;
4 import com.arranger.jarl.base.Time;
5 import com.arranger.jarl.base.IJarlObjectInfo;
6 import com.arranger.jarl.stroke.BaseStroke;
7 import com.arranger.jarl.trait.base.GradientColor;
8 import com.arranger.jarl.util.*;
9 import com.arranger.jarl.widget.ContainerWidget;
10 import com.arranger.jarl.widget.IWidget;
11 import com.jhlabs.image.Gradient;
12
13 import java.awt.*;
14 import java.util.Iterator;
15
16 /**
17 * EchoCollection creates an echo of widgets
18 *
19 * @widgetAttribute alpha ## xs:string ## the echos will fade to this transparency (between 0 & 1)
20 * @widgetAttribute numEchos ## xs:integer ## the number of echos to perform
21 * @widgetAttribute fadeColor ## xs:string ## the color to fade to (red, white, etc...)
22 * @widgetAttribute fadeColorData ## xs:string ## the colorData to fade to
23 */
24 public class EchoCollection extends ContainerWidget {
25
26 //config params
27 protected float m_alpha = 1.0f;
28 protected Time m_numEchos;
29 protected Color m_fadeColor;
30
31 //runtime params
32 protected Time m_normalizedTotalTime;
33 protected FadeStroke m_fadeStroke;
34 protected double m_fadePct;
35
36 public Time getNumEchos() {
37 return m_numEchos;
38 }
39
40 /**
41 * The main paint routine
42 * @param graphics2D should be cast to a {@link Graphics2D}
43 * @param context the current context
44 */
45 public void paint(IContext context, Graphics2D graphics2D) {
46 if (!m_initChildren) {
47 initializeChildren();
48 m_initChildren = true;
49 }
50
51 Composite composite = graphics2D.getComposite();
52
53 //back up in time
54 Time currentTime = context.getTime();
55 Time controlTime = (Time) currentTime.clone();
56 Time relativeTime = WidgetUtil.getRelativeTime(this, currentTime);
57 Time normalizedTime = getNormalizedTotalTime();
58 Time echoTime;
59
60 int backup = 0;
61 if (relativeTime.getFrame() <= m_numEchos.getFrame()) {
62 backup = relativeTime.getFrame();
63 } else {
64 backup = m_numEchos.getFrame();
65 }
66
67 if (relativeTime.isGreater(normalizedTime)) {
68 int extendedTime = relativeTime.getFrame() - normalizedTime.getFrame();
69 backup -= extendedTime;
70 controlTime = new Time(getStartTime().getFrame() + getNormalizedTotalTime().getFrame());
71 }
72 echoTime = new Time(controlTime.getFrame() - backup);
73
74 while (echoTime.isLess(controlTime) || echoTime.equals(controlTime)) {
75 //adjust for alpha now
76 float alpha = (float) InterpolateUtil.interpolate(0,
77 m_numEchos.getFrame(),
78 1.0f,
79 m_alpha,
80 controlTime.getFrame() - echoTime.getFrame());
81
82 if (m_fadeStroke != null) {
83 m_fadePct = InterpolateUtil.interpolate(0,
84 m_numEchos.getFrame(),
85 0,
86 1,
87 controlTime.getFrame() - echoTime.getFrame());
88 }
89
90 context.setTime(echoTime);
91 graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
92 super.paint(context, graphics2D);
93 echoTime.increment();
94 }
95
96 //restore
97 context.setTime(currentTime);
98 graphics2D.setComposite(composite);
99 }
100
101 protected void initializeChildren() {
102 if (m_fadeColor != null) {
103 m_fadeStroke = new FadeStroke(this);
104 getStrokes().add(m_fadeStroke);
105 }
106
107 super.initializeChildren();
108 Time endTime = new Time(getEndTime().getFrame() - m_numEchos.getFrame()); //see initAttributes
109 Time startTime = getStartTime();
110 for (Iterator it = m_children.iterator(); it.hasNext();) {
111 IWidget widget = (IWidget) it.next();
112 widget.setStartTime(startTime);
113 widget.setEndTime(endTime);
114 }
115 }
116
117 protected Time getNormalizedTotalTime() {
118 if (m_normalizedTotalTime == null) {
119 m_normalizedTotalTime = new Time(getTotalTime().getFrame() - m_numEchos.getFrame());
120 }
121 return m_normalizedTotalTime;
122 }
123
124
125 /**
126 * Always remember some attrs might not be there
127 * @param context
128 */
129 protected void initAttributes(IContext context) {
130 super.initAttributes(context);
131
132 ObjectUtil.initializeField("numEchos", m_configElement, this, ObjectUtil.TIME_CONVERSION);
133 ObjectUtil.initializeField("alpha", m_configElement, this, ObjectUtil.NORMALIZING_CONVERSION);
134 ObjectUtil.initializeField("fadeColor", m_configElement, this, ObjectUtil.COLOR_CONVERSION);
135
136 if (m_endTime != null && m_endTime.getFrame() != -1 && m_numEchos.getFrame() > 0) {
137 m_endTime = new Time(m_endTime.getFrame() + m_numEchos.getFrame()); //see initializeChildren
138 }
139 }
140
141 protected void addJarlObjectInfo(IJarlObjectInfo jarlObjectInfo) {
142 super.addJarlObjectInfo(jarlObjectInfo);
143 populateInfo(jarlObjectInfo, "numEchos", "Number of Echos", JarlInfoUtil.TIME_DISPLAY);
144 populateInfo(jarlObjectInfo, "alpha", "Alpha Level", JarlInfoUtil.PCT_DISPLAY);
145 populateInfo(jarlObjectInfo, "fadeColor", "Fading Color", JarlInfoUtil.COLOR_DISPLAY);
146 }
147
148 protected class FadeStroke extends BaseStroke {
149
150 protected EchoCollection m_echoCollection;
151 protected Paint m_storedPaint;
152
153 public FadeStroke(EchoCollection echoCollection) {
154 m_echoCollection = echoCollection;
155 }
156
157 /**
158 * This will perform custom drawing of the shape
159 * onto the graphics on behalf of the widget
160 *
161 * @param widget
162 * @param context
163 * @param graphics2D
164 * @param shape
165 */
166 public Shape processShape(IWidget widget,
167 IContext context,
168 Graphics2D graphics2D,
169 Shape shape) {
170 return shape;
171 }
172
173 /**
174 * Prior to the {@link IWidget#paint} the trait can perform some work
175 * @param widget the widget that is being painted
176 * @param context the current context
177 * @param graphics2D the current graphics object
178 * @return the new graphics, or the same
179 */
180 public Graphics2D prePaint(IWidget widget, IContext context, Graphics2D graphics2D, Shape shape) {
181 m_storedPaint = graphics2D.getPaint();
182
183 //set new paint
184 if (m_storedPaint instanceof Color) {
185 Color newColor = PaintUtil.interpolatePaint((Color) m_storedPaint, m_echoCollection.m_fadeColor, m_echoCollection.m_fadePct);
186 graphics2D.setPaint(newColor);
187 } else if (m_storedPaint instanceof GradientColor) {
188 Gradient gradient = ((GradientColor)m_storedPaint).getGradient();
189 gradient = context.getGradientManager().interpolate(gradient, m_echoCollection.m_fadeColor, m_echoCollection.m_fadePct);
190 graphics2D.setPaint(new GradientColor(gradient));
191 }
192
193 return super.prePaint(widget, context, graphics2D, shape);
194 }
195
196 /**
197 * After the call to {@link IWidget#paint} is called
198 * the trait can restore some state
199 * @param widget the widget that is being painted
200 * @param context the current context
201 * @param graphics2D the current graphics object
202 * @return the new graphics, or the same
203 */
204 public Graphics2D postPaint(IWidget widget, IContext context, Graphics2D graphics2D, Shape shape) {
205 graphics2D.setPaint(m_storedPaint);
206 return super.postPaint(widget, context, graphics2D, shape);
207 }
208 }
209 }