sproutcore 0.9.3 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +19 -0
- data/Manifest.txt +15 -1
- data/clients/view_builder/builders/builder.js +339 -0
- data/clients/view_builder/builders/button.js +81 -0
- data/clients/view_builder/controllers/document.js +21 -0
- data/clients/view_builder/core.js +19 -0
- data/clients/view_builder/english.lproj/body.css +77 -0
- data/clients/view_builder/english.lproj/body.rhtml +39 -0
- data/clients/view_builder/english.lproj/controls.css +0 -0
- data/clients/view_builder/english.lproj/strings.js +14 -0
- data/clients/view_builder/main.js +38 -0
- data/clients/view_builder/mixins/design_mode.js +92 -0
- data/clients/view_builder/tests/controllers/document.rhtml +20 -0
- data/clients/view_builder/tests/views/builder.rhtml +20 -0
- data/clients/view_builder/tests/views/palette.rhtml +21 -0
- data/clients/view_builder/views/builder.js +26 -0
- data/clients/view_builder/views/palette.js +30 -0
- data/frameworks/sproutcore/Core.js +6 -4
- data/frameworks/sproutcore/README +1 -3
- data/frameworks/sproutcore/controllers/array.js +5 -5
- data/frameworks/sproutcore/drag/drag.js +2 -0
- data/frameworks/sproutcore/english.lproj/panes.css +16 -35
- data/frameworks/sproutcore/foundation/application.js +29 -8
- data/frameworks/sproutcore/foundation/object.js +5 -1
- data/frameworks/sproutcore/foundation/run_loop.js +65 -2
- data/frameworks/sproutcore/foundation/timer.js +1 -0
- data/frameworks/sproutcore/globals/window.js +23 -18
- data/frameworks/sproutcore/mixins/array.js +2 -2
- data/frameworks/sproutcore/mixins/observable.js +127 -52
- data/frameworks/sproutcore/panes/dialog.js +1 -1
- data/frameworks/sproutcore/panes/overlay.js +6 -2
- data/frameworks/sproutcore/panes/pane.js +27 -0
- data/frameworks/sproutcore/views/collection/collection.js +1 -1
- data/frameworks/sproutcore/views/collection/grid.js +3 -15
- data/frameworks/sproutcore/views/collection/source_list.js +10 -5
- data/frameworks/sproutcore/views/field/select_field.js +11 -2
- data/frameworks/sproutcore/views/field/text_field.js +1 -1
- data/frameworks/sproutcore/views/label.js +2 -7
- data/frameworks/sproutcore/views/view.js +254 -213
- data/generators/client/README +2 -2
- data/generators/client/USAGE +2 -2
- data/lib/sproutcore/build_tools/html_builder.rb +2 -2
- data/lib/sproutcore/bundle_manifest.rb +28 -22
- data/lib/sproutcore/merb/bundle_controller.rb +4 -3
- data/lib/sproutcore/version.rb +1 -1
- metadata +17 -3
- data/frameworks/sproutcore/animation/animation.js +0 -411
data/generators/client/README
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
Your new SproutCore client application has been created. To access your application, just start
|
1
|
+
Your new SproutCore client application has been created. To access your application, just start sc-sever and visit your client name in the web browser.
|
2
2
|
|
3
|
-
If you want to change the deployment settings for
|
3
|
+
If you want to change the deployment settings for your application edit the sc-config.rb file to get started.
|
data/generators/client/USAGE
CHANGED
@@ -2,11 +2,11 @@ client - Generates a new SproutCore client
|
|
2
2
|
|
3
3
|
USAGE:
|
4
4
|
|
5
|
-
|
5
|
+
sc-gen client client_name
|
6
6
|
|
7
7
|
DISCUSSION:
|
8
8
|
|
9
9
|
This generator will create a new SproutCore-based JavaScript application. After the generator completes, you will be able to begin work immediately.
|
10
10
|
|
11
|
-
The code created by this generator will appear in a /clients directory. To add models, views, and controllers, you can use the additional generators
|
11
|
+
The code created by this generator will appear in a /clients directory. To add models, views, and controllers, you can use the additional generators model, controller, and view.
|
12
12
|
|
@@ -45,8 +45,8 @@ module SproutCore
|
|
45
45
|
end
|
46
46
|
|
47
47
|
# Clean out any composites we might have collected. They have already
|
48
|
-
# been expanded.
|
49
|
-
@entries.reject! { |entry| entry.composite? }
|
48
|
+
# been expanded. Also clean out any non-localized rhtml files.
|
49
|
+
@entries.reject! { |entry| entry.composite? || (entry.type == :html && !entry.localized?) }
|
50
50
|
|
51
51
|
# Load any helpers before we continue
|
52
52
|
puts "*************REQUIRE"
|
@@ -51,17 +51,19 @@ module SproutCore
|
|
51
51
|
# Builds a manifest for the bundle and the specified language
|
52
52
|
def build!
|
53
53
|
|
54
|
-
# STEP 1: Catalog all of the files in the project, including the target
|
55
|
-
# and the default language. This will filter out resources not
|
54
|
+
# STEP 1: Catalog all of the files in the project, including the target
|
55
|
+
# language and the default language. This will filter out resources not
|
56
|
+
# used in this language.
|
56
57
|
entries = catalog_entries
|
57
58
|
|
58
|
-
# STEP 2: Combine the HTML file paths into a single entry, unless this
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
59
|
+
# STEP 2: Combine the HTML file paths into a single entry, unless this
|
60
|
+
# is a framework
|
61
|
+
working = entries[:html] ||= []
|
62
|
+
|
63
|
+
if bundle.can_have_html?
|
64
|
+
working << build_entry_for('index.html', :html, working)
|
65
|
+
else
|
66
|
+
working.each { |x| x.hidden = true }
|
65
67
|
end
|
66
68
|
|
67
69
|
# STEP 3: If in development build mode:
|
@@ -148,7 +150,7 @@ module SproutCore
|
|
148
150
|
if current_lproj = src_path.match(/^([^\/]+\.lproj)\//).to_a[1]
|
149
151
|
next if (current_lproj != default_lproj) && (current_lproj != target_lproj)
|
150
152
|
end
|
151
|
-
|
153
|
+
|
152
154
|
# OK, pass all of our validations. Go ahead and build an entry for this
|
153
155
|
# Add entry to list of entries for appropriate lproj if localized
|
154
156
|
entry = build_entry_for(src_path, src_type)
|
@@ -158,6 +160,8 @@ module SproutCore
|
|
158
160
|
when target_lproj
|
159
161
|
target_lproj_entries[entry.filename] = entry
|
160
162
|
else
|
163
|
+
|
164
|
+
# Be sure to mark any
|
161
165
|
entries[entry.filename] = entry
|
162
166
|
end
|
163
167
|
end
|
@@ -198,17 +202,17 @@ module SproutCore
|
|
198
202
|
case src_path
|
199
203
|
when /^tests\/.+/
|
200
204
|
:test
|
201
|
-
when /^fixtures
|
205
|
+
when /^fixtures\/.+\.js$/
|
202
206
|
:fixture
|
203
|
-
when
|
207
|
+
when /\.html$/
|
204
208
|
:html
|
205
|
-
when
|
209
|
+
when /\.rhtml$/
|
206
210
|
:html
|
207
|
-
when
|
211
|
+
when /\.html.erb$/
|
208
212
|
:html
|
209
|
-
when
|
213
|
+
when /\.css$/
|
210
214
|
:stylesheet
|
211
|
-
when
|
215
|
+
when /\.js$/
|
212
216
|
:javascript
|
213
217
|
when /\.lproj\/.+/
|
214
218
|
:resource
|
@@ -234,9 +238,10 @@ module SproutCore
|
|
234
238
|
# the source path is just the combine source root + the path
|
235
239
|
ret.source_path = (composite.nil?) ? File.join(bundle.source_root, src_path) : nil
|
236
240
|
|
237
|
-
# set the composite property. The passed in array should contain other
|
238
|
-
# if hide_composite is true, then hide the composite items as
|
239
|
-
|
241
|
+
# set the composite property. The passed in array should contain other
|
242
|
+
# entries if hide_composite is true, then hide the composite items as
|
243
|
+
# well
|
244
|
+
unless composite.nil?
|
240
245
|
composite.each { |x| x.hidden = true } if hide_composite
|
241
246
|
ret.composite = composite.map { |x| x.filename }
|
242
247
|
end
|
@@ -295,8 +300,7 @@ module SproutCore
|
|
295
300
|
# hidden:: if true, this entry is needed internally, but otherwise should not be used
|
296
301
|
# use_symlink:: if true, then this entry should be handled via the build symlink
|
297
302
|
# language:: the language in use when this entry was created
|
298
|
-
# composite:: If set, this will contain the filenames of other resources that should be
|
299
|
-
# combined to form this resource.
|
303
|
+
# composite:: If set, this will contain the filenames of other resources that should be combined to form this resource.
|
300
304
|
#
|
301
305
|
class ManifestEntry < Struct.new(:filename, :ext, :source_path, :url, :build_path, :type, :original_path, :hidden, :use_symlink, :language, :composite)
|
302
306
|
def to_hash
|
@@ -309,7 +313,9 @@ module SproutCore
|
|
309
313
|
def use_symlink?; !!use_symlink; end
|
310
314
|
def composite?; !!composite; end
|
311
315
|
|
312
|
-
|
316
|
+
def localized?; !!source_path.match(/\.lproj/); end
|
317
|
+
|
318
|
+
# Returns true if this entry can be cached even in development mode. Composite resources
|
313
319
|
# and tests need to be regenerated whenever you get this.
|
314
320
|
def cacheable?
|
315
321
|
!composite? && (type != :test)
|
@@ -21,9 +21,10 @@ module SproutCore
|
|
21
21
|
# the request path to determine which bundle should handle the request.
|
22
22
|
def main
|
23
23
|
|
24
|
-
# Before we do anything, set the build_mode for the bundles. This
|
25
|
-
# during execution, but if we set this during the
|
26
|
-
# is sometimes not ready yet.
|
24
|
+
# Before we do anything, set the build_mode for the bundles. This
|
25
|
+
# shouldn't change during execution, but if we set this during the
|
26
|
+
# router call, the Merb.environment is sometimes not ready yet.
|
27
|
+
#
|
27
28
|
if ::Merb.environment.to_sym == :production
|
28
29
|
Bundle.build_mode = :production
|
29
30
|
else
|
data/lib/sproutcore/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sproutcore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charles Jolley
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-05-05 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -106,10 +106,24 @@ files:
|
|
106
106
|
- clients/sc_test_runner/models/test.js
|
107
107
|
- clients/sc_test_runner/views/runner_frame.js
|
108
108
|
- clients/sc_test_runner/views/test_label.js
|
109
|
+
- clients/view_builder/builders/builder.js
|
110
|
+
- clients/view_builder/builders/button.js
|
111
|
+
- clients/view_builder/controllers/document.js
|
112
|
+
- clients/view_builder/core.js
|
113
|
+
- clients/view_builder/english.lproj/body.css
|
114
|
+
- clients/view_builder/english.lproj/body.rhtml
|
115
|
+
- clients/view_builder/english.lproj/controls.css
|
116
|
+
- clients/view_builder/english.lproj/strings.js
|
117
|
+
- clients/view_builder/main.js
|
118
|
+
- clients/view_builder/mixins/design_mode.js
|
119
|
+
- clients/view_builder/tests/controllers/document.rhtml
|
120
|
+
- clients/view_builder/tests/views/builder.rhtml
|
121
|
+
- clients/view_builder/tests/views/palette.rhtml
|
122
|
+
- clients/view_builder/views/builder.js
|
123
|
+
- clients/view_builder/views/palette.js
|
109
124
|
- config/hoe.rb
|
110
125
|
- config/requirements.rb
|
111
126
|
- frameworks/prototype/prototype.js
|
112
|
-
- frameworks/sproutcore/animation/animation.js
|
113
127
|
- frameworks/sproutcore/controllers/array.js
|
114
128
|
- frameworks/sproutcore/controllers/collection.js
|
115
129
|
- frameworks/sproutcore/controllers/controller.js
|
@@ -1,411 +0,0 @@
|
|
1
|
-
// ========================================================================
|
2
|
-
// SproutCore
|
3
|
-
// copyright 2006-2008 Sprout Systems, Inc.
|
4
|
-
// ========================================================================
|
5
|
-
|
6
|
-
require('Core') ;
|
7
|
-
require('foundation/timer') ;
|
8
|
-
|
9
|
-
/**
|
10
|
-
@class
|
11
|
-
|
12
|
-
An animator is a special timer that will transition its value property from
|
13
|
-
0 to 1 according to a transform function you define. You can also specify
|
14
|
-
one or more "subjects" that will be invoked whenever the animation value
|
15
|
-
changes, which can apply the animation to any target you like.
|
16
|
-
|
17
|
-
This class and its related classes are based on Bernie's Better Animator
|
18
|
-
class.
|
19
|
-
|
20
|
-
Use Cases:
|
21
|
-
|
22
|
-
1. I just want to transition from x=0 -> x=20.
|
23
|
-
v.transitionTo('styleLeft', 20) ;
|
24
|
-
-> creates an animation for styleLeft. If you add a new animation for
|
25
|
-
the same effect, it will cancel the old one automatically.
|
26
|
-
|
27
|
-
2. I want to have an 'animation behavior' attached to some property.
|
28
|
-
whenever I change it, it should automatically transition the property
|
29
|
-
instead of just updating it. i.e. a "Tracker".
|
30
|
-
|
31
|
-
-> I may want the tracker to update several things at once. But that
|
32
|
-
could be done through changing one property which will in turn
|
33
|
-
update everything else. Better idea.
|
34
|
-
|
35
|
-
Tracker simply stores some animation properties and calls transitionTo
|
36
|
-
whenever your target value changes.
|
37
|
-
|
38
|
-
3. I want to have some property animating on its own. For example a
|
39
|
-
throbbing button
|
40
|
-
|
41
|
-
a = v.addAnimation('opacity', {
|
42
|
-
repeatCount: ,
|
43
|
-
autoreverses: YES,
|
44
|
-
end: 1.0,
|
45
|
-
start: 0.0,
|
46
|
-
property: 'opacity'
|
47
|
-
}) ;
|
48
|
-
|
49
|
-
a.set('isPaused', YES) ;
|
50
|
-
v.removeAnimation('opacity');
|
51
|
-
|
52
|
-
--
|
53
|
-
We will need an animation builder. It would be nice if I could have a
|
54
|
-
complete timeline for an animation setup and you just tell it to run. Set
|
55
|
-
the timecode to anytime that you want, tell it to start or stop.
|
56
|
-
|
57
|
-
@extends SC.Timer
|
58
|
-
@author Charles Jolley
|
59
|
-
@since SproutCore 1.0
|
60
|
-
*/
|
61
|
-
SC.Animation = SC.Timer.extend(
|
62
|
-
/** @scope SC.Animation.prototype */ {
|
63
|
-
|
64
|
-
/**
|
65
|
-
The target frame rate. This is used to determine the interval of the
|
66
|
-
timer.
|
67
|
-
|
68
|
-
@type {Number}
|
69
|
-
@field
|
70
|
-
*/
|
71
|
-
frameRate: 60,
|
72
|
-
|
73
|
-
/**
|
74
|
-
The interval between frames. Calculated automatically from the frameRate.
|
75
|
-
This property is read only.
|
76
|
-
|
77
|
-
@type {Number}
|
78
|
-
@field
|
79
|
-
*/
|
80
|
-
interval: function() {
|
81
|
-
return 1000 / this.get('frameRate') ;
|
82
|
-
}.property('frameRate'),
|
83
|
-
|
84
|
-
/**
|
85
|
-
The total amount of time in msec you want to take for the animation to
|
86
|
-
go from 0-1.
|
87
|
-
*/
|
88
|
-
duration: 0,
|
89
|
-
|
90
|
-
/**
|
91
|
-
The speed at which the timecode for the animation will progress. 1.0
|
92
|
-
means it will progress in real time, 2.0 means twice as fast, etc.
|
93
|
-
*/
|
94
|
-
speed: 1.0,
|
95
|
-
|
96
|
-
/**
|
97
|
-
The total number of times you want the animation to repeat.
|
98
|
-
|
99
|
-
This can be any number, including partial numbers. If you set this
|
100
|
-
value you must not set repeatDuration as well. This will be ignored
|
101
|
-
if the value is 0, which is the default.
|
102
|
-
|
103
|
-
If you set this property to -1, then the animation will repeat
|
104
|
-
indefinitely.
|
105
|
-
|
106
|
-
Setting this property will update the targetTimecode.
|
107
|
-
|
108
|
-
@type {Number}
|
109
|
-
@field
|
110
|
-
*/
|
111
|
-
repeatCount: 0,
|
112
|
-
|
113
|
-
/**
|
114
|
-
The total amount of time the animation should run, repeating itself, in
|
115
|
-
msec.
|
116
|
-
|
117
|
-
If you set this value you must not set repeatCount as well. This will
|
118
|
-
be ignored if the value is 0, which is the default.
|
119
|
-
|
120
|
-
Setting this property will update the targetTimecode.
|
121
|
-
|
122
|
-
@type {Number}
|
123
|
-
@field
|
124
|
-
*/
|
125
|
-
repeatDuration: 0,
|
126
|
-
|
127
|
-
/**
|
128
|
-
If YES, then the animation will automatically reverse itself on each
|
129
|
-
repeat.
|
130
|
-
|
131
|
-
@type {Boolean}
|
132
|
-
@field
|
133
|
-
*/
|
134
|
-
autoreverses: NO,
|
135
|
-
|
136
|
-
/**
|
137
|
-
A transition function. This is used to convert the progress into a
|
138
|
-
state value. You can supply your own transition function to provide
|
139
|
-
varied behaviors such as ease in, ease out, etc.
|
140
|
-
|
141
|
-
The function must have a signature like:
|
142
|
-
|
143
|
-
transition: function(value, animator)
|
144
|
-
|
145
|
-
It must accept a value from 0-1 indicating the current animation progress
|
146
|
-
and return a value from 0-1 indication the current transition progress.
|
147
|
-
|
148
|
-
@type {Function}
|
149
|
-
@field
|
150
|
-
*/
|
151
|
-
transition: null,
|
152
|
-
|
153
|
-
/**
|
154
|
-
This is the current timecode for the animation, in msec. You can set
|
155
|
-
this to any value that you want and the animation to compute the current
|
156
|
-
transition value from it.
|
157
|
-
|
158
|
-
To move instantly to any part of your animation, you can simply set this
|
159
|
-
timecode or use jumpTo().
|
160
|
-
|
161
|
-
@type {Number}
|
162
|
-
@field
|
163
|
-
*/
|
164
|
-
currentTimecode: 0,
|
165
|
-
|
166
|
-
/**
|
167
|
-
This is the target timecode. Whenever the target timecode and the
|
168
|
-
current timecode do not match, the animation will animate until it
|
169
|
-
reaches the target timecode.
|
170
|
-
|
171
|
-
To transition the animation to a new state, set the timecode to any
|
172
|
-
value that you want.
|
173
|
-
|
174
|
-
@type {Number}
|
175
|
-
*/
|
176
|
-
targetTimecode: 0,
|
177
|
-
|
178
|
-
/**
|
179
|
-
The current animation progress.
|
180
|
-
|
181
|
-
This value will loop from 0-1 based on the current timecode and the
|
182
|
-
setting of autoreverses. You generally do not want to use this value.
|
183
|
-
Instead use the value property to compute the current transition.
|
184
|
-
|
185
|
-
@type {Number}
|
186
|
-
@field
|
187
|
-
*/
|
188
|
-
progress: function() {
|
189
|
-
|
190
|
-
// current progress is calculated from the currentTimecode by dividing
|
191
|
-
// it by the animation duration and autoreverses.
|
192
|
-
var currentTimecode = this.get('currentTimecode') ;
|
193
|
-
var duration = this.get('duration') ;
|
194
|
-
var reverses = this.get('autoreverses') ;
|
195
|
-
|
196
|
-
// find the progress through the current cycle.
|
197
|
-
var cycle = Math.floor(currentTimecode / duration) ;
|
198
|
-
var progress = (currentTimecode - (duration * cycle)) / duration;
|
199
|
-
|
200
|
-
// if we autoreverse and the cycle is odd numbered, invert.
|
201
|
-
if (reverses && (cycle % 2) > 0) progress = 1 - progress ;
|
202
|
-
return progress ;
|
203
|
-
}.property('currentTimecode', 'duration', 'autoreverses'),
|
204
|
-
|
205
|
-
/**
|
206
|
-
The current animation value. Transform functions can observe this
|
207
|
-
property and update the target object accordingly.
|
208
|
-
|
209
|
-
@type {Number}
|
210
|
-
@field
|
211
|
-
*/
|
212
|
-
value: function() {
|
213
|
-
var value = this.get('progress');
|
214
|
-
if (this.transition) value = this.transition(value, this) ;
|
215
|
-
return value ;
|
216
|
-
}.property('progress'),
|
217
|
-
|
218
|
-
/**
|
219
|
-
The target object of the animation. This is often used by transform
|
220
|
-
functions as the target of their change. It is not strictly required.
|
221
|
-
|
222
|
-
@type {Object}
|
223
|
-
@field
|
224
|
-
*/
|
225
|
-
target: null,
|
226
|
-
|
227
|
-
|
228
|
-
/**
|
229
|
-
This method must be called once when the animation is created to schedule
|
230
|
-
it with the run loop. Once animation has been started, you should can
|
231
|
-
pause it to remove it from the runloop temporarily.
|
232
|
-
|
233
|
-
@returns {void}
|
234
|
-
*/
|
235
|
-
play: function() {
|
236
|
-
this.beginPropertyChanges() ;
|
237
|
-
if (!this.get('isScheduled')) {
|
238
|
-
this.schedule() ;
|
239
|
-
this._lastActionTime = SC.runLoop.get('startTime') ;
|
240
|
-
}
|
241
|
-
|
242
|
-
if (this.get('isPaused')) this.set('isPaused', NO) ;
|
243
|
-
this.endPropertyChanges() ;
|
244
|
-
},
|
245
|
-
|
246
|
-
/**
|
247
|
-
Once an animation has been started, you can pause it anytime with this
|
248
|
-
method. Call start() to restart it or set isPaused to NO.
|
249
|
-
|
250
|
-
@returns {void}
|
251
|
-
*/
|
252
|
-
pause: function() {
|
253
|
-
this.set('isPaused', YES) ;
|
254
|
-
},
|
255
|
-
|
256
|
-
/**
|
257
|
-
Immediately changes the currentTimecode to reflect the requested amount
|
258
|
-
of progress through a single cycle of the animation.
|
259
|
-
|
260
|
-
@param progress {Number} a progress value from 0 to 1.
|
261
|
-
@returns {void}
|
262
|
-
*/
|
263
|
-
jumpTo: function(progress) {
|
264
|
-
// get the current progress.
|
265
|
-
var cur = this.get('progress') ;
|
266
|
-
var diff = progress - cur ;
|
267
|
-
var duration = this.get('duration') ;
|
268
|
-
diff *= duration ;
|
269
|
-
|
270
|
-
var timecode = this.get('currentTimecode') ;
|
271
|
-
if (diff !== 0) this.set('currentTimecode', timecode + diff) ;
|
272
|
-
},
|
273
|
-
|
274
|
-
/**
|
275
|
-
Changes the targetTimecode to reflect the request amount of progress
|
276
|
-
through the current cycle of the animation. If the animation is in
|
277
|
-
reverse, this could move the timecode in the opposite direction.
|
278
|
-
|
279
|
-
@param progress {Number} a progress value from 0 to 1.
|
280
|
-
@returns {void}
|
281
|
-
*/
|
282
|
-
seekTo: function(progress) {
|
283
|
-
// get the current progress.
|
284
|
-
var cur = this.get('progress') ;
|
285
|
-
var diff = progress - cur ;
|
286
|
-
var duration = this.get('duration') ;
|
287
|
-
diff *= duration ;
|
288
|
-
|
289
|
-
var timecode = this.get('currentTimecode') ;
|
290
|
-
if (diff !== 0) this.set('targetTimecode', timecode + diff) ;
|
291
|
-
},
|
292
|
-
|
293
|
-
/**
|
294
|
-
Changes the currentTimecode and targetTimecode to reflect the requested
|
295
|
-
amount of progress through the current cycle of the animation. If the
|
296
|
-
animation is in reverse, this could move the timecode in the opposite
|
297
|
-
direction.
|
298
|
-
|
299
|
-
@param fromProgress {Number} a progress value from 0 to 1
|
300
|
-
@param toProgress {Number} a progress value from 0 to 1
|
301
|
-
@returns {void}
|
302
|
-
*/
|
303
|
-
seekFromTo: function(fromProgress, toProgress) {
|
304
|
-
// get the current progress.
|
305
|
-
var timecode = this.get('currentTimecode') ;
|
306
|
-
var cur = this.get('progress') ;
|
307
|
-
var duration = this.get('duration') ;
|
308
|
-
|
309
|
-
this.beginPropertyChanges() ;
|
310
|
-
|
311
|
-
var diff = fromProgress - cur ;
|
312
|
-
diff *= duration ;
|
313
|
-
if (diff !== 0) this.set('currentTimecode', timecode + diff) ;
|
314
|
-
|
315
|
-
diff = toProgress - cur ;
|
316
|
-
diff *= duration ;
|
317
|
-
if (diff !== 0) this.set('targetTimecode', timecode + diff) ;
|
318
|
-
|
319
|
-
this.endPropertyChanges() ;
|
320
|
-
},
|
321
|
-
|
322
|
-
/**
|
323
|
-
Changes the targetTimecode to invert the direction of the animation.
|
324
|
-
If the progress value is currently headed towards 1.0, it will be instead
|
325
|
-
headed to 0.
|
326
|
-
|
327
|
-
@returns {Number} the new progress
|
328
|
-
*/
|
329
|
-
toggle: function() {
|
330
|
-
throw "toggle not yet implemented" ;
|
331
|
-
},
|
332
|
-
|
333
|
-
/**
|
334
|
-
The core action executed by the timer.
|
335
|
-
*/
|
336
|
-
performAction: function() {
|
337
|
-
|
338
|
-
// if timecodes match, then we suspend the animation and return, there
|
339
|
-
// is nothing more to do.
|
340
|
-
var cur = this.get('currentTimecode') ;
|
341
|
-
var target = this.get('targetTimecode') ;
|
342
|
-
if (cur == target) {
|
343
|
-
this.set('isPaused', YES) ;
|
344
|
-
return ;
|
345
|
-
}
|
346
|
-
|
347
|
-
// determine the amount of time that has elapsed since the last time
|
348
|
-
// we were called.
|
349
|
-
var curTime = SC.runLoop.get('startTime') ;
|
350
|
-
var lapsed = (curTime - this._lastActionTime) * this.get('speed') ;
|
351
|
-
this._lastActionTime = curTime ;
|
352
|
-
|
353
|
-
// update the current timecode. Moving in the direction of the target
|
354
|
-
// timecode. If timecodes match, there is nothing to do.
|
355
|
-
if (target > cur) {
|
356
|
-
cur += lapsed ;
|
357
|
-
if (cur > target) cur = target ;
|
358
|
-
} else {
|
359
|
-
cur -= lapsed ;
|
360
|
-
if (cur < target) cur = target ;
|
361
|
-
}
|
362
|
-
|
363
|
-
// now set the new timecode, this should trigger other observers to
|
364
|
-
// update.
|
365
|
-
this.set('currentTimecode', cur) ;
|
366
|
-
},
|
367
|
-
|
368
|
-
// ......................................
|
369
|
-
// INTERNAL METHODS
|
370
|
-
//
|
371
|
-
|
372
|
-
/** @private
|
373
|
-
Observes changes to repeatCount; updates the targetTimecode.
|
374
|
-
*/
|
375
|
-
_repeatCountObserver: function() {
|
376
|
-
var repeatCount = this.get('repeatCount') ;
|
377
|
-
var target ;
|
378
|
-
if (repeatCount < 0) {
|
379
|
-
target = Date.now() * 2 ;
|
380
|
-
} else if (repeatCount > 0) {
|
381
|
-
target = this.get('duration') * repeatCount ;
|
382
|
-
} else return ; // nothing to do.
|
383
|
-
this.set('targetTimecode', target) ;
|
384
|
-
}.observes('repeatCount'),
|
385
|
-
|
386
|
-
/** @private
|
387
|
-
Observes changes to the repeatDuration; updates the targetTimecode.
|
388
|
-
*/
|
389
|
-
_repeatDurationObserver: function() {
|
390
|
-
var dur = this.get('repeatDuration') ;
|
391
|
-
if (dur < 0) {
|
392
|
-
dur = Date.now() * 2 ;
|
393
|
-
} else if (dur == 0) return; // nothing to do
|
394
|
-
this.set('targetTimecode', dur) ;
|
395
|
-
}.observes('repeatDuration'),
|
396
|
-
|
397
|
-
init: function() {
|
398
|
-
arguments.callee.base.call(this) ;
|
399
|
-
|
400
|
-
this.targetTimecode = this.get('duration') ;
|
401
|
-
this._repeatDurationObserver() ;
|
402
|
-
this._repeatCountObserver() ;
|
403
|
-
},
|
404
|
-
|
405
|
-
repeats: YES, // for timer
|
406
|
-
|
407
|
-
_logValueObserver: function() {
|
408
|
-
console.log('value did change to: %@'.fmt(this.get('value')));
|
409
|
-
}.observes('value')
|
410
|
-
|
411
|
-
});
|