walt 0.1
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/.gitignore +14 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +61 -0
- data/LICENSE +26 -0
- data/README.md +193 -0
- data/Rakefile +17 -0
- data/app/app_delegate.rb +71 -0
- data/examples/Apple/.gitignore +13 -0
- data/examples/Apple/Rakefile +14 -0
- data/examples/Apple/app/app_delegate.rb +99 -0
- data/examples/Apple/spec/main_spec.rb +9 -0
- data/examples/Apple/vendor/Podfile.lock +11 -0
- data/examples/Bouncing/.gitignore +13 -0
- data/examples/Bouncing/Rakefile +14 -0
- data/examples/Bouncing/app/app_delegate.rb +49 -0
- data/examples/Bouncing/spec/main_spec.rb +9 -0
- data/examples/Bouncing/vendor/Podfile.lock +11 -0
- data/lib/walt.rb +27 -0
- data/lib/walt/animation.rb +124 -0
- data/lib/walt/animation_set.rb +64 -0
- data/lib/walt/asset/asset.rb +79 -0
- data/lib/walt/asset/image.rb +48 -0
- data/lib/walt/asset/text.rb +64 -0
- data/lib/walt/operation/base.rb +60 -0
- data/lib/walt/operation/fade.rb +35 -0
- data/lib/walt/operation/move.rb +73 -0
- data/lib/walt/operation/rotate.rb +41 -0
- data/lib/walt/operation/scale.rb +41 -0
- data/lib/walt/patch/ui_color.rb +5 -0
- data/lib/walt/support/attr_default.rb +16 -0
- data/lib/walt/support/const_get.rb +60 -0
- data/lib/walt/support/font.rb +87 -0
- data/lib/walt/version.rb +3 -0
- data/lib/walt/walt.rb +53 -0
- data/spec/animation_set_spec.rb +49 -0
- data/spec/animation_spec.rb +128 -0
- data/spec/asset/image_spec.rb +16 -0
- data/spec/asset/text_spec.rb +24 -0
- data/spec/asset_spec.rb +11 -0
- data/spec/main_spec.rb +9 -0
- data/spec/operation/fade_spec.rb +25 -0
- data/spec/operation/move_spec.rb +43 -0
- data/spec/operation_spec.rb +26 -0
- data/spec/support_spec.rb +46 -0
- data/vendor/Podfile.lock +11 -0
- data/walt.gemspec +21 -0
- metadata +172 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
$:.unshift("/Library/RubyMotion/lib")
|
3
|
+
require 'motion/project'
|
4
|
+
$:.unshift("../../lib")
|
5
|
+
require '../../lib/walt'
|
6
|
+
|
7
|
+
Motion::Project::App.setup do |app|
|
8
|
+
# Use `rake config' to see complete project settings.
|
9
|
+
app.name = 'Bouncing'
|
10
|
+
|
11
|
+
app.pods do
|
12
|
+
pod "AFNetworking"
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class AppDelegate
|
2
|
+
def application(application, didFinishLaunchingWithOptions:launchOptions)
|
3
|
+
@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
|
4
|
+
|
5
|
+
@window.makeKeyAndVisible
|
6
|
+
|
7
|
+
url = "http://upload.wikimedia.org/wikipedia/commons/7/7a/Basketball.png"
|
8
|
+
assets = (0..4).collect {|i| {
|
9
|
+
id: "ball_#{i}",
|
10
|
+
url: url,
|
11
|
+
size: [50, 50],
|
12
|
+
position: [i*50 + i*10, 0]
|
13
|
+
} }
|
14
|
+
|
15
|
+
height = UIScreen.mainScreen.bounds.size.height
|
16
|
+
points = [height - 50, height - 150, height - 50, height - 100, height - 50]
|
17
|
+
|
18
|
+
make_point_animation = lambda {|id, index|
|
19
|
+
after = (index < (points.length - 1)) ? make_point_animation.call(id, index+1) : nil
|
20
|
+
h = {
|
21
|
+
duration: 0.5 / (index + 1).to_f + rand(),
|
22
|
+
operations: [{
|
23
|
+
move: id,
|
24
|
+
to: points[index],
|
25
|
+
axis: :y
|
26
|
+
}, {
|
27
|
+
rotate: id,
|
28
|
+
to: rand() * 90
|
29
|
+
}],
|
30
|
+
after: after
|
31
|
+
}
|
32
|
+
h.delete(:after) if after.nil?
|
33
|
+
h
|
34
|
+
}
|
35
|
+
|
36
|
+
animations = []
|
37
|
+
assets.each_with_index do |asset, i|
|
38
|
+
animations << make_point_animation.call(asset[:id], 0)
|
39
|
+
end
|
40
|
+
|
41
|
+
Walt.animate(
|
42
|
+
assets: assets,
|
43
|
+
animations: animations,
|
44
|
+
in: @window
|
45
|
+
)
|
46
|
+
|
47
|
+
true
|
48
|
+
end
|
49
|
+
end
|
data/lib/walt.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require "walt/version"
|
2
|
+
require 'bubble-wrap/core'
|
3
|
+
require 'motion-cocoapods'
|
4
|
+
|
5
|
+
BW.require File.expand_path('../walt/support/**/*.rb', __FILE__) do
|
6
|
+
end
|
7
|
+
|
8
|
+
BW.require File.expand_path('../walt/**/*.rb', __FILE__) do
|
9
|
+
end
|
10
|
+
|
11
|
+
Motion::Project::App.setup do |app|
|
12
|
+
depends = {}
|
13
|
+
|
14
|
+
['fade','move'].each {|file|
|
15
|
+
_f = File.expand_path("../walt/operation/#{file}.rb", __FILE__)
|
16
|
+
depends[_f] ||= []
|
17
|
+
depends[_f] << File.expand_path("../walt/operation/base.rb", __FILE__)
|
18
|
+
}
|
19
|
+
|
20
|
+
['image'].each {|file|
|
21
|
+
_f = File.expand_path("../walt/asset/#{file}.rb", __FILE__)
|
22
|
+
depends[_f] ||= []
|
23
|
+
depends[_f] << File.expand_path("../walt/asset/asset.rb", __FILE__)
|
24
|
+
}
|
25
|
+
|
26
|
+
app.files_dependencies depends
|
27
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
=begin
|
2
|
+
{
|
3
|
+
delay: 0.5,
|
4
|
+
duration: 2.5,
|
5
|
+
# array of integers or symbols corresponding to UIViewAnimationOptions
|
6
|
+
options: [:curve_ease_in, :autoreverse]
|
7
|
+
operations: [{
|
8
|
+
# see operation/base.rb
|
9
|
+
type: :move,
|
10
|
+
from: 0,
|
11
|
+
to: 40,
|
12
|
+
id: :one
|
13
|
+
}],
|
14
|
+
after: {
|
15
|
+
# another animation object
|
16
|
+
}
|
17
|
+
}
|
18
|
+
=end
|
19
|
+
|
20
|
+
module Walt
|
21
|
+
class Animation
|
22
|
+
extend Walt::Support::AttrDefault
|
23
|
+
|
24
|
+
PROPERTIES = [:delay, :duration, :after, :operations, :options]
|
25
|
+
attr_accessor *PROPERTIES
|
26
|
+
|
27
|
+
def initialize(params = {})
|
28
|
+
params.each do |key, value|
|
29
|
+
if PROPERTIES.include?(key.to_sym)
|
30
|
+
self.send("#{key}=", value)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def after=(after)
|
36
|
+
_after = after
|
37
|
+
case after
|
38
|
+
when Walt::Animation
|
39
|
+
when NSDictionary
|
40
|
+
_after = Walt::Animation.new(after)
|
41
|
+
else
|
42
|
+
raise "Invalid class for after animation #{after.inspect}"
|
43
|
+
end
|
44
|
+
|
45
|
+
@after = _after
|
46
|
+
end
|
47
|
+
|
48
|
+
attr_default :operations, []
|
49
|
+
def operations=(operations)
|
50
|
+
_operations = []
|
51
|
+
operations.each do |op|
|
52
|
+
case op
|
53
|
+
when Walt::Operation::Base
|
54
|
+
_operations << op
|
55
|
+
when NSDictionary
|
56
|
+
_operations << Walt::Operation.for(op)
|
57
|
+
else
|
58
|
+
raise "Invalid class for operation #{op.inspect}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
@operations = _operations
|
62
|
+
end
|
63
|
+
|
64
|
+
attr_default :assets, {}
|
65
|
+
def assets=(assets)
|
66
|
+
_assets = {}
|
67
|
+
case assets
|
68
|
+
when NSArray
|
69
|
+
assets.each do |asset|
|
70
|
+
_asset = (asset.is_a?(Walt::Asset) ? asset : Walt::Asset.for(asset))
|
71
|
+
_assets[_asset.id] = _asset
|
72
|
+
end
|
73
|
+
when NSDictionary
|
74
|
+
assets.each do |key, value|
|
75
|
+
asset = value
|
76
|
+
_asset = (asset.is_a?(Walt::Asset) ? asset : Walt::Asset.for(asset))
|
77
|
+
_assets[_asset.id] = _asset
|
78
|
+
end
|
79
|
+
else
|
80
|
+
raise "Not a valid class for assets: #{assets.inspect}"
|
81
|
+
end
|
82
|
+
@assets = _assets
|
83
|
+
end
|
84
|
+
|
85
|
+
attr_default :options, [UIViewAnimationOptionCurveEaseInOut]
|
86
|
+
def options=(options)
|
87
|
+
_options = options.is_a?(NSArray) ? options : [options]
|
88
|
+
@options = _options
|
89
|
+
end
|
90
|
+
|
91
|
+
def animation_options
|
92
|
+
int = 0
|
93
|
+
self.options.each { |i| int = int | Walt::Support.constant("UIViewAnimationOption", i)}
|
94
|
+
int
|
95
|
+
end
|
96
|
+
|
97
|
+
def animate
|
98
|
+
@operations_completed = 0
|
99
|
+
self.operations.each do |operation|
|
100
|
+
asset = self.assets[operation.id]
|
101
|
+
if !asset
|
102
|
+
raise "No asset found for operation #{operation} id #{operation.id}"
|
103
|
+
end
|
104
|
+
|
105
|
+
operation.setup(asset.view, self)
|
106
|
+
|
107
|
+
UIView.animateWithDuration(self.duration,
|
108
|
+
delay:self.delay.to_f,
|
109
|
+
options:self.animation_options,
|
110
|
+
animations:lambda {
|
111
|
+
operation.finalize(asset.view, self)
|
112
|
+
},
|
113
|
+
completion:lambda { |completed|
|
114
|
+
@operations_completed += 1
|
115
|
+
if @operations_completed == self.operations.count && self.after
|
116
|
+
self.after.assets = self.assets
|
117
|
+
self.after.animate
|
118
|
+
end
|
119
|
+
}
|
120
|
+
)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
=begin
|
2
|
+
{
|
3
|
+
# array of assets (see asset/asset.rb) or UIViews
|
4
|
+
assets: [{...}],
|
5
|
+
# array of animations (see animation.rb)
|
6
|
+
animations: [{...}]
|
7
|
+
}
|
8
|
+
=end
|
9
|
+
module Walt
|
10
|
+
class AnimationSet
|
11
|
+
extend Walt::Support::AttrDefault
|
12
|
+
|
13
|
+
PROPERTIES = [:animations, :assets]
|
14
|
+
attr_accessor *PROPERTIES
|
15
|
+
|
16
|
+
def initialize(params = {})
|
17
|
+
params.each do |key, value|
|
18
|
+
if PROPERTIES.include?(key.to_sym)
|
19
|
+
self.send("#{key}=", value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_default :animations, []
|
25
|
+
def animations=(animations)
|
26
|
+
_animations = animations && animations.collect do |animation|
|
27
|
+
case animation
|
28
|
+
when Walt::Animation
|
29
|
+
animation
|
30
|
+
when NSDictionary
|
31
|
+
Walt::Animation.new(animation)
|
32
|
+
else
|
33
|
+
raise "Invalid class for animation #{animation.inspect}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
@animations = _animations
|
37
|
+
end
|
38
|
+
|
39
|
+
attr_default :assets, []
|
40
|
+
def assets=(assets)
|
41
|
+
_assets = assets && assets.collect do |asset|
|
42
|
+
case asset
|
43
|
+
when Walt::Asset
|
44
|
+
asset
|
45
|
+
when NSDictionary
|
46
|
+
Walt::Asset.for(asset)
|
47
|
+
when UIView
|
48
|
+
Walt::Asset.for(asset)
|
49
|
+
else
|
50
|
+
raise "Invalid class for asset #{asset.inspect}"
|
51
|
+
end
|
52
|
+
asset
|
53
|
+
end
|
54
|
+
@assets = _assets
|
55
|
+
end
|
56
|
+
|
57
|
+
def animate
|
58
|
+
self.animations.each do |animation|
|
59
|
+
animation.assets = self.assets
|
60
|
+
animation.animate
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
=begin
|
2
|
+
{
|
3
|
+
id: :one,
|
4
|
+
size: [100,100],
|
5
|
+
position: [10, 10],
|
6
|
+
# array of integers or symbols corresponding to UIViewContentMode
|
7
|
+
content_mode: [:scale_to_fill, :top],
|
8
|
+
clips_to_bounds: true,
|
9
|
+
background_color: "0088ff"
|
10
|
+
}
|
11
|
+
=end
|
12
|
+
|
13
|
+
module Walt
|
14
|
+
class Asset
|
15
|
+
extend Walt::Support::AttrDefault
|
16
|
+
|
17
|
+
PROPERTIES = [:id, :position, :size, :view, :content_mode, :clips_to_bounds, :background_color]
|
18
|
+
attr_accessor *PROPERTIES
|
19
|
+
|
20
|
+
def self.for(params = {})
|
21
|
+
if params.is_a?(NSDictionary) && params[:url]
|
22
|
+
Walt::ImageAsset.new(params)
|
23
|
+
elsif params.is_a?(NSDictionary) && params[:text]
|
24
|
+
Walt::TextAsset.new(params)
|
25
|
+
else
|
26
|
+
self.new(params)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(params = {})
|
31
|
+
case params
|
32
|
+
when UIView
|
33
|
+
self.view = params
|
34
|
+
when NSDictionary
|
35
|
+
params.each do |key, value|
|
36
|
+
if PROPERTIES.include?(key.to_sym)
|
37
|
+
self.send("#{key}=", value)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
attr_default :clips_to_bounds, false
|
44
|
+
|
45
|
+
attr_default :content_mode, [UIViewContentModeScaleToFill]
|
46
|
+
def content_mode=(content_mode)
|
47
|
+
_content_mode = content_mode.is_a?(NSArray) ? content_mode : [content_mode]
|
48
|
+
@content_mode = _content_mode
|
49
|
+
end
|
50
|
+
|
51
|
+
def view_content_mode
|
52
|
+
int = 0
|
53
|
+
self.content_mode.each { |i| int = int | Walt::Support.constant("UIViewContentMode", i)}
|
54
|
+
int
|
55
|
+
end
|
56
|
+
|
57
|
+
def view
|
58
|
+
@view ||= UIView.alloc.initWithFrame(CGRectZero).tap do |view|
|
59
|
+
view.frame = [self.position || CGPointZero, self.size || CGSizeZero]
|
60
|
+
view.backgroundColor = self.background_color.to_color if self.background_color
|
61
|
+
view.contentMode = self.view_content_mode
|
62
|
+
view.clipsToBounds = self.clips_to_bounds
|
63
|
+
Dispatch::Queue.main.async do
|
64
|
+
self.on_ready(true)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def on_ready(trigger = false, &callback)
|
70
|
+
@on_ready_callbacks ||= []
|
71
|
+
if callback
|
72
|
+
@on_ready_callbacks << callback
|
73
|
+
elsif trigger
|
74
|
+
@on_ready_callbacks.each {|c| c.call(self)}
|
75
|
+
@on_ready_callbacks = []
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
=begin
|
2
|
+
{
|
3
|
+
url: "http://mysite.com/pic.jpg"
|
4
|
+
}
|
5
|
+
=end
|
6
|
+
|
7
|
+
module Walt
|
8
|
+
class ImageAsset < Asset
|
9
|
+
PROPERTIES = [:url]
|
10
|
+
attr_accessor *PROPERTIES
|
11
|
+
|
12
|
+
def initialize(params = {})
|
13
|
+
super
|
14
|
+
|
15
|
+
params.is_a?(NSDictionary) && params.each do |key, value|
|
16
|
+
if PROPERTIES.include?(key.to_sym)
|
17
|
+
self.send("#{key}=", value)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def view
|
23
|
+
if !@view
|
24
|
+
@view = UIImageView.alloc.initWithFrame(CGRectZero)
|
25
|
+
@view.frame = [self.position || CGPointZero, self.size || CGSizeZero]
|
26
|
+
@view.contentMode = self.view_content_mode
|
27
|
+
@view.clipsToBounds = self.clips_to_bounds
|
28
|
+
url = NSURL.URLWithString(self.url)
|
29
|
+
@view.setImageWithURLRequest(NSURLRequest.requestWithURL(url),
|
30
|
+
placeholderImage:nil,
|
31
|
+
success: lambda {|request, response, image|
|
32
|
+
@view.image = image
|
33
|
+
if !self.size
|
34
|
+
@view.sizeToFit
|
35
|
+
end
|
36
|
+
Dispatch::Queue.main.async do
|
37
|
+
self.on_ready(true)
|
38
|
+
end
|
39
|
+
},
|
40
|
+
failure: lambda {|request, response, error|
|
41
|
+
|
42
|
+
})
|
43
|
+
@view
|
44
|
+
end
|
45
|
+
@view
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|