Source code: com/arranger/jarl/trait/base/Position.java
1 package com.arranger.jarl.trait.base;
2
3 import com.arranger.jarl.base.IContext;
4 import com.arranger.jarl.base.IJarlObjectInfo;
5 import com.arranger.jarl.trait.BaseSegmentTrait;
6 import com.arranger.jarl.util.*;
7 import com.arranger.jarl.widget.IWidget;
8 import org.w3c.dom.Element;
9
10 import java.awt.*;
11 import java.awt.geom.Point2D;
12
13 /**
14 * Position
15 * Required params are either:
16 * pos: x%, y% (eg 5%, 7%)
17 * or
18 * startPos, endPos
19 *
20 * For example:
21 * <traitDef name="upperLeft" class="Position" pos="7%, 5%" />
22 *
23 * @traitAttribute pos ## xs:string ## the Starting position (relative to the screen). For example: (50%, 50%) would be in the center of the screen
24 * @traitAttribute startPos ## xs:string ## the starting position
25 * @traitAttribute endPos ## xs:string ## the ending position
26 */
27 public class Position extends BaseSegmentTrait {
28
29 protected Point2D m_pos;
30 protected Point2D m_startPos;
31 protected Point2D m_endPos;
32
33 /**
34 * Prior to the {@link IWidget#paint} the trait can perform some work
35 * @param widget the widget that is being painted
36 * @param context the current context
37 * @param graphics2D the current graphics object
38 * @return the new graphics, or the same
39 */
40 public Graphics2D prePaint(IWidget widget, IContext context, Graphics2D graphics2D) {
41 //get and store transform
42 graphics2D = initGraphicsTransform(graphics2D);
43
44 double x = 0.0;
45 double y = 0.0;
46 if (m_pos != null) {
47 x = m_pos.getX();
48 y = m_pos.getY();
49 } else if (m_startPos != null && m_endPos != null) {
50 //interpolate
51 x = InterpolateUtil.interpolate(widget.getStartTime(),
52 widget.getEndTime(),
53 m_startPos.getX(),
54 m_endPos.getX(),
55 context.getTime());
56 y = InterpolateUtil.interpolate(widget.getStartTime(),
57 widget.getEndTime(),
58 m_startPos.getY(),
59 m_endPos.getY(),
60 context.getTime());
61 } else {
62
63 //get the current position segment and the pct relative to that segment
64 PositionConfigSegment positionSegment = (PositionConfigSegment) getCurrentSegment(widget, context);
65 double currentTimePct = getCurrentSegmentTimePct(widget, context, positionSegment);
66
67 x = InterpolateUtil.interpolate(0,
68 1,
69 positionSegment.getStartPos().getX(),
70 positionSegment.getEndPos().getX(),
71 currentTimePct);
72
73 y = InterpolateUtil.interpolate(0,
74 1,
75 positionSegment.getStartPos().getY(),
76 positionSegment.getEndPos().getY(),
77 currentTimePct);
78 }
79
80 translate(graphics2D, context, x, y);
81 return graphics2D;
82 }
83
84 /**
85 * do the actual translation
86 *
87 * @param graphics2D
88 * @param context
89 * @param x
90 * @param y
91 */
92 protected void translate(Graphics2D graphics2D, IContext context, double x, double y) {
93 graphics2D.translate(
94 (context.getWidth() * x) - context.getWidth() / 2,
95 (context.getHeight() * y) - context.getHeight() / 2);
96 }
97
98 /**
99 * After the call to {@link IWidget#paint} is called
100 * the trait can restore some state
101 * @param widget the widget that is being painted
102 * @param context the current context
103 * @param graphics2D the current graphics object
104 * @return the new graphics, or the same
105 */
106 public Graphics2D postPaint(IWidget widget, IContext context, Graphics2D graphics2D) {
107 restoreTransform(graphics2D);
108 return graphics2D;
109 }
110
111 /**
112 * Always remember some attrs might not be there
113 * @param context
114 */
115 protected void initAttributes(IContext context) {
116 super.initAttributes(context);
117
118 ObjectUtil.initializeField("pos", m_configElement, this, ObjectUtil.POINT2D_CONVERSION);
119 ObjectUtil.initializeField("startPos", m_configElement, this, ObjectUtil.POINT2D_CONVERSION);
120 ObjectUtil.initializeField("endPos", m_configElement, this, ObjectUtil.POINT2D_CONVERSION);
121 }
122
123 /**
124 * Override this, and for every field that you're using, call {@link #populateInfo}
125 * for example:
126 * <code>
127 * populateInfo(jarlObjectInfo, "zOrder", "Z-Order", JarlInfoUtil.PRIMITIVE_DISPLAY);
128 * </code>
129 *
130 * @param jarlObjectInfo
131 *
132 * @see JarlInfoUtil#PRIMITIVE_DISPLAY
133 * @see #populateInfo
134 * @see ObjectUtil#initializeField
135 */
136 protected void addJarlObjectInfo(IJarlObjectInfo jarlObjectInfo) {
137 super.addJarlObjectInfo(jarlObjectInfo);
138 populateInfo(jarlObjectInfo, "pos", "Position", JarlInfoUtil.POINT2D_DISPLAY);
139 populateInfo(jarlObjectInfo, "startPos", "Start Position", JarlInfoUtil.POINT2D_DISPLAY);
140 populateInfo(jarlObjectInfo, "endPos", "End Position", JarlInfoUtil.POINT2D_DISPLAY);
141 }
142
143 /**
144 * Create a concrete {@link WidgetConfigSegment} based on this element
145 * @param element
146 * @return a specific {@link WidgetConfigSegment}
147 */
148 public WidgetConfigSegment createSegment(Element element) {
149 return new PositionConfigSegment(element);
150 }
151
152 protected static class PositionConfigSegment extends WidgetConfigSegment {
153
154 protected Point2D m_startPos;
155 protected Point2D m_endPos;
156
157 public PositionConfigSegment(Element element) {
158 super(element);
159 ObjectUtil.initializeFieldStrict("startPos", element, this, ObjectUtil.POINT2D_CONVERSION);
160 ObjectUtil.initializeFieldStrict("endPos", element, this, ObjectUtil.POINT2D_CONVERSION);
161 }
162
163 protected void addJarlObjectInfo(IJarlObjectInfo jarlObjectInfo) {
164 super.addJarlObjectInfo(jarlObjectInfo);
165 populateInfo(jarlObjectInfo, "startPos", "Start Position", JarlInfoUtil.POINT2D_DISPLAY);
166 populateInfo(jarlObjectInfo, "endPos", "End Position", JarlInfoUtil.POINT2D_DISPLAY);
167 }
168
169 public Point2D getStartPos() {
170 return m_startPos;
171 }
172
173 public Point2D getEndPos() {
174 return m_endPos;
175 }
176 }
177 }