OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | |
3 * | |
4 * This library is free software; you can redistribute it and/or | |
5 * modify it under the terms of the GNU Library General Public | |
6 * License as published by the Free Software Foundation; either | |
7 * version 2 of the License, or (at your option) any later version. | |
8 * | |
9 * This library is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 * Library General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU Library General Public License | |
15 * along with this library; see the file COPYING.LIB. If not, write to | |
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
17 * Boston, MA 02110-1301, USA. | |
18 */ | |
19 | |
20 #ifndef SVGAnimatedListPropertyTearOff_h | |
21 #define SVGAnimatedListPropertyTearOff_h | |
22 | |
23 #include "core/svg/properties/SVGAnimatedProperty.h" | |
24 #include "core/svg/properties/SVGListPropertyTearOff.h" | |
25 #include "core/svg/properties/SVGStaticListPropertyTearOff.h" | |
26 | |
27 namespace WebCore { | |
28 | |
29 template<typename PropertyType> | |
30 class SVGPropertyTearOff; | |
31 | |
32 template<typename PropertyType> | |
33 class SVGAnimatedListPropertyTearOff : public SVGAnimatedProperty { | |
34 public: | |
35 typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType; | |
36 typedef SVGPropertyTearOff<ListItemType> ListItemTearOff; | |
37 typedef Vector<RefPtr<ListItemTearOff> > ListWrapperCache; | |
38 typedef SVGListProperty<PropertyType> ListProperty; | |
39 typedef SVGListPropertyTearOff<PropertyType> ListPropertyTearOff; | |
40 typedef PropertyType ContentType; | |
41 | |
42 virtual ~SVGAnimatedListPropertyTearOff() | |
43 { | |
44 if (m_baseVal) | |
45 static_cast<ListPropertyTearOff*>(m_baseVal.get())->clearAnimatedPro
perty(); | |
46 if (m_animVal) | |
47 static_cast<ListPropertyTearOff*>(m_animVal.get())->clearAnimatedPro
perty(); | |
48 } | |
49 | |
50 virtual ListProperty* baseVal() | |
51 { | |
52 if (!m_baseVal) | |
53 m_baseVal = ListPropertyTearOff::create(this, BaseValRole, m_values,
m_wrappers); | |
54 return static_cast<ListProperty*>(m_baseVal.get()); | |
55 } | |
56 | |
57 virtual ListProperty* animVal() | |
58 { | |
59 if (!m_animVal) | |
60 m_animVal = ListPropertyTearOff::create(this, AnimValRole, m_values,
m_wrappers); | |
61 return static_cast<ListProperty*>(m_animVal.get()); | |
62 } | |
63 | |
64 virtual bool isAnimatedListTearOff() const { return true; } | |
65 | |
66 int findItem(SVGProperty* property) const | |
67 { | |
68 // This should ever be called for our baseVal, as animVal can't modify t
he list. | |
69 // It's safe to cast to ListPropertyTearOff here as all classes inheriti
ng from us supply their own removeItemFromList() method. | |
70 typedef SVGPropertyTearOff<typename SVGPropertyTraits<PropertyType>::Lis
tItemType> ListItemTearOff; | |
71 return static_cast<ListPropertyTearOff*>(m_baseVal.get())->findItem(stat
ic_cast<ListItemTearOff*>(property)); | |
72 } | |
73 | |
74 void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers) | |
75 { | |
76 // This should ever be called for our baseVal, as animVal can't modify t
he list. | |
77 // It's safe to cast to ListPropertyTearOff here as all classes inheriti
ng from us supply their own removeItemFromList() method. | |
78 static_cast<ListPropertyTearOff*>(m_baseVal.get())->removeItemFromList(i
temIndex, shouldSynchronizeWrappers); | |
79 } | |
80 | |
81 void detachListWrappers(unsigned newListSize) | |
82 { | |
83 ListProperty::detachListWrappersAndResize(&m_wrappers, newListSize); | |
84 } | |
85 | |
86 PropertyType& currentAnimatedValue() | |
87 { | |
88 ASSERT(m_isAnimating); | |
89 ASSERT(m_animVal); | |
90 return static_cast<ListProperty*>(m_animVal.get())->values(); | |
91 } | |
92 | |
93 const PropertyType& currentBaseValue() const | |
94 { | |
95 return m_values; | |
96 } | |
97 | |
98 void animationStarted(PropertyType* newAnimVal, bool shouldOwnValues = false
) | |
99 { | |
100 ASSERT(!m_isAnimating); | |
101 ASSERT(newAnimVal); | |
102 ASSERT(m_values.size() == m_wrappers.size()); | |
103 ASSERT(m_animatedWrappers.isEmpty()); | |
104 | |
105 // Switch to new passed in value type & new wrappers list. The new wrapp
ers list must be created for the new value. | |
106 if (!newAnimVal->isEmpty()) | |
107 m_animatedWrappers.fill(nullptr, newAnimVal->size()); | |
108 | |
109 ListProperty* animVal = static_cast<ListProperty*>(this->animVal()); | |
110 animVal->setValuesAndWrappers(newAnimVal, &m_animatedWrappers, shouldOwn
Values); | |
111 ASSERT(animVal->values().size() == animVal->wrappers().size()); | |
112 ASSERT(animVal->wrappers().size() == m_animatedWrappers.size()); | |
113 m_isAnimating = true; | |
114 } | |
115 | |
116 void animationEnded() | |
117 { | |
118 ASSERT(m_isAnimating); | |
119 ASSERT(m_animVal); | |
120 ASSERT(contextElement()); | |
121 ASSERT(m_values.size() == m_wrappers.size()); | |
122 | |
123 ListProperty* animVal = static_cast<ListProperty*>(m_animVal.get()); | |
124 ASSERT(animVal->values().size() == animVal->wrappers().size()); | |
125 ASSERT(animVal->wrappers().size() == m_animatedWrappers.size()); | |
126 | |
127 animVal->setValuesAndWrappers(&m_values, &m_wrappers, false); | |
128 ASSERT(animVal->values().size() == animVal->wrappers().size()); | |
129 ASSERT(animVal->wrappers().size() == m_wrappers.size()); | |
130 | |
131 m_animatedWrappers.clear(); | |
132 m_isAnimating = false; | |
133 } | |
134 | |
135 void synchronizeWrappersIfNeeded() | |
136 { | |
137 // Eventually the wrapper list needs synchronization because any SVGAnim
ateLengthList::calculateAnimatedValue() call may | |
138 // mutate the length of our values() list, and thus the wrapper() cache
needs synchronization, to have the same size. | |
139 // Also existing wrappers which point directly at elements in the existi
ng SVGLengthList have to be detached (so a copy | |
140 // of them is created, so existing animVal variables in JS are kept-aliv
e). If we'd detach them later the underlying | |
141 // SVGLengthList was already mutated, and our list item wrapper tear off
s would point nowhere. Assertions would fire. | |
142 ListProperty* animVal = static_cast<ListProperty*>(m_animVal.get()); | |
143 animVal->detachListWrappers(animVal->values().size()); | |
144 | |
145 ASSERT(animVal->values().size() == animVal->wrappers().size()); | |
146 ASSERT(animVal->wrappers().size() == m_animatedWrappers.size()); | |
147 } | |
148 | |
149 void animValWillChange() | |
150 { | |
151 ASSERT(m_isAnimating); | |
152 ASSERT(m_animVal); | |
153 ASSERT(m_values.size() == m_wrappers.size()); | |
154 synchronizeWrappersIfNeeded(); | |
155 } | |
156 | |
157 void animValDidChange() | |
158 { | |
159 ASSERT(m_isAnimating); | |
160 ASSERT(m_animVal); | |
161 ASSERT(m_values.size() == m_wrappers.size()); | |
162 synchronizeWrappersIfNeeded(); | |
163 } | |
164 | |
165 static PassRefPtr<SVGAnimatedListPropertyTearOff<PropertyType> > create(SVGE
lement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType
animatedPropertyType, PropertyType& values) | |
166 { | |
167 ASSERT(contextElement); | |
168 return adoptRef(new SVGAnimatedListPropertyTearOff<PropertyType>(context
Element, attributeName, animatedPropertyType, values)); | |
169 } | |
170 | |
171 protected: | |
172 SVGAnimatedListPropertyTearOff(SVGElement* contextElement, const QualifiedNa
me& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& valu
es) | |
173 : SVGAnimatedProperty(contextElement, attributeName, animatedPropertyTyp
e) | |
174 , m_values(values) | |
175 { | |
176 if (!values.isEmpty()) | |
177 m_wrappers.fill(nullptr, values.size()); | |
178 } | |
179 | |
180 PropertyType& m_values; | |
181 | |
182 ListWrapperCache m_wrappers; | |
183 ListWrapperCache m_animatedWrappers; | |
184 | |
185 RefPtr<SVGProperty> m_baseVal; | |
186 RefPtr<SVGProperty> m_animVal; | |
187 }; | |
188 | |
189 } | |
190 | |
191 #endif // SVGAnimatedListPropertyTearOff_h | |
OLD | NEW |