walt 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/.gitignore +14 -0
  2. data/CHANGELOG.md +3 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +61 -0
  5. data/LICENSE +26 -0
  6. data/README.md +193 -0
  7. data/Rakefile +17 -0
  8. data/app/app_delegate.rb +71 -0
  9. data/examples/Apple/.gitignore +13 -0
  10. data/examples/Apple/Rakefile +14 -0
  11. data/examples/Apple/app/app_delegate.rb +99 -0
  12. data/examples/Apple/spec/main_spec.rb +9 -0
  13. data/examples/Apple/vendor/Podfile.lock +11 -0
  14. data/examples/Bouncing/.gitignore +13 -0
  15. data/examples/Bouncing/Rakefile +14 -0
  16. data/examples/Bouncing/app/app_delegate.rb +49 -0
  17. data/examples/Bouncing/spec/main_spec.rb +9 -0
  18. data/examples/Bouncing/vendor/Podfile.lock +11 -0
  19. data/lib/walt.rb +27 -0
  20. data/lib/walt/animation.rb +124 -0
  21. data/lib/walt/animation_set.rb +64 -0
  22. data/lib/walt/asset/asset.rb +79 -0
  23. data/lib/walt/asset/image.rb +48 -0
  24. data/lib/walt/asset/text.rb +64 -0
  25. data/lib/walt/operation/base.rb +60 -0
  26. data/lib/walt/operation/fade.rb +35 -0
  27. data/lib/walt/operation/move.rb +73 -0
  28. data/lib/walt/operation/rotate.rb +41 -0
  29. data/lib/walt/operation/scale.rb +41 -0
  30. data/lib/walt/patch/ui_color.rb +5 -0
  31. data/lib/walt/support/attr_default.rb +16 -0
  32. data/lib/walt/support/const_get.rb +60 -0
  33. data/lib/walt/support/font.rb +87 -0
  34. data/lib/walt/version.rb +3 -0
  35. data/lib/walt/walt.rb +53 -0
  36. data/spec/animation_set_spec.rb +49 -0
  37. data/spec/animation_spec.rb +128 -0
  38. data/spec/asset/image_spec.rb +16 -0
  39. data/spec/asset/text_spec.rb +24 -0
  40. data/spec/asset_spec.rb +11 -0
  41. data/spec/main_spec.rb +9 -0
  42. data/spec/operation/fade_spec.rb +25 -0
  43. data/spec/operation/move_spec.rb +43 -0
  44. data/spec/operation_spec.rb +26 -0
  45. data/spec/support_spec.rb +46 -0
  46. data/vendor/Podfile.lock +11 -0
  47. data/walt.gemspec +21 -0
  48. metadata +172 -0
@@ -0,0 +1,9 @@
1
+ describe "Application 'Apple'" do
2
+ before do
3
+ @app = UIApplication.sharedApplication
4
+ end
5
+
6
+ it "has one window" do
7
+ @app.windows.size.should == 1
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+
2
+ PODS:
3
+ - AFNetworking (1.1.0)
4
+
5
+ DEPENDENCIES:
6
+ - AFNetworking
7
+
8
+ SPEC CHECKSUMS:
9
+ AFNetworking: 761a418233d280c1e0580bcb76ff9cb4c3073d17
10
+
11
+ COCOAPODS: 0.16.0
@@ -0,0 +1,13 @@
1
+ .repl_history
2
+ build
3
+ tags
4
+ resources/*.nib
5
+ resources/*.momd
6
+ resources/*.storyboardc
7
+ .DS_Store
8
+ nbproject
9
+ .redcar
10
+ #*#
11
+ *~
12
+ *.sw[po]
13
+ .eprj
@@ -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
@@ -0,0 +1,9 @@
1
+ describe "Application 'Bouncing'" do
2
+ before do
3
+ @app = UIApplication.sharedApplication
4
+ end
5
+
6
+ it "has one window" do
7
+ @app.windows.size.should == 1
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+
2
+ PODS:
3
+ - AFNetworking (1.1.0)
4
+
5
+ DEPENDENCIES:
6
+ - AFNetworking
7
+
8
+ SPEC CHECKSUMS:
9
+ AFNetworking: 761a418233d280c1e0580bcb76ff9cb4c3073d17
10
+
11
+ COCOAPODS: 0.16.0
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