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.
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,64 @@
1
+ =begin
2
+ {
3
+ text: "This goes on the screen",
4
+ text_color: "ff0000",
5
+ background_color: "00ff00",
6
+ number_of_lines: 2,
7
+ text_alignment: :center,
8
+ font: "MarkerFelt" # see support/font.rb
9
+ attributes: {...} # see support/font.rb
10
+ }
11
+ =end
12
+ module Walt
13
+ class TextAsset < Asset
14
+ PROPERTIES = [:text, :text_color, :background_color, :number_of_lines, :font, :attributes, :text_alignment]
15
+ attr_accessor *PROPERTIES
16
+
17
+ attr_default :content_mode, [UIViewContentModeRedraw]
18
+ attr_default :text_color, UIColor.blackColor
19
+ attr_default :background_color, UIColor.clearColor
20
+ attr_default :number_of_lines, 1
21
+
22
+ def initialize(params = {})
23
+ super
24
+
25
+ params.is_a?(NSDictionary) && params.each do |key, value|
26
+ if PROPERTIES.include?(key.to_sym)
27
+ self.send("#{key}=", value)
28
+ end
29
+ end
30
+ end
31
+
32
+ def view
33
+ @view ||= UILabel.alloc.initWithFrame(CGRectZero).tap do |view|
34
+ view.frame = [self.position || CGPointZero, self.size || CGSizeZero]
35
+ view.contentMode = self.view_content_mode
36
+ view.clipsToBounds = self.clips_to_bounds
37
+ view.text = self.text
38
+ view.textColor = self.text_color.to_color
39
+ view.backgroundColor = self.background_color.to_color
40
+ view.numberOfLines = self.number_of_lines
41
+ view.font = Walt::Font.make(self.font) if self.font
42
+ view.textAlignment = Walt::Support.constant("UITextAlignment", self.text_alignment) if self.text_alignment
43
+
44
+ if self.attributes
45
+ attributes = Walt::Font.attributes(self.attributes)
46
+ view.font = attributes[UITextAttributeFont] if attributes[UITextAttributeFont]
47
+ view.textColor = attributes[UITextAttributeTextColor] if attributes[UITextAttributeTextColor]
48
+ view.shadowColor = attributes[UITextAttributeTextShadowColor] if attributes[UITextAttributeTextShadowColor]
49
+ if attributes[UITextAttributeTextShadowOffset]
50
+ view.shadowOffset = CGSizeMake(self.attributes[:shadow_offset][:x], self.attributes[:shadow_offset][:y])
51
+ end
52
+ end
53
+
54
+ if !self.size
55
+ view.sizeToFit
56
+ end
57
+
58
+ Dispatch::Queue.main.async do
59
+ self.on_ready(true)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,60 @@
1
+ =begin
2
+ {
3
+ type: :move,
4
+ id: :one
5
+ }
6
+ =end
7
+
8
+ module Walt
9
+ module Operation
10
+ class Base
11
+ extend Walt::Support::AttrDefault
12
+
13
+ PROPERTIES = [:id, :type]
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
+ def setup(view, animation)
25
+ # do initial before animation
26
+ end
27
+
28
+ def finalize(view, animation = nil)
29
+ # do whatever occurs during the animation
30
+ end
31
+ end
32
+
33
+ module_function
34
+ def for(hash)
35
+ # Check classes in module for corresponding operation
36
+ type = hash[:type] || hash["type"]
37
+
38
+ # Check for the form {operation_type: :id}
39
+ if !type
40
+ type = (hash.keys.map(&:to_s) | self.operation_types)[0]
41
+ hash[:id] = (hash[type] || hash[type.to_sym])
42
+ hash[:type] = type
43
+ end
44
+
45
+ if type.is_a?(Symbol) || type.is_a?(String)
46
+ string = "#{type.to_s.downcase}_operation".camelize
47
+ if not const_defined? string
48
+ raise "Invalid Operation value for operation #{hash.inspect}. Create a class called #{string}."
49
+ end
50
+ return Walt::Operation.const_get(string).new(hash)
51
+ end
52
+
53
+ self.new(hash)
54
+ end
55
+
56
+ def operation_types
57
+ Walt::Operation.constants(false).select { |constant_name| constant_name =~ /Operation$/ }.collect! { |op| op.to_s.gsub("Operation", "").underscore }
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,35 @@
1
+ =begin
2
+ {
3
+ from: 0.0,
4
+ to: 0.8
5
+ }
6
+ =end
7
+
8
+ module Walt
9
+ module Operation
10
+ class FadeOperation < Base
11
+ PROPERTIES = [:from, :to]
12
+ attr_accessor *PROPERTIES
13
+
14
+ def initialize(params = {})
15
+ super
16
+
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
+ def setup(view, animation)
25
+ if self.from
26
+ view.alpha = self.from
27
+ end
28
+ end
29
+
30
+ def finalize(view, animation)
31
+ view.alpha = self.to
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,73 @@
1
+ =begin
2
+ {
3
+ from: [0, 0],
4
+ to: [10, 20]
5
+ }
6
+
7
+ {
8
+ from: 100,
9
+ to: 200,
10
+ axis: :y
11
+ }
12
+ =end
13
+
14
+ module Walt
15
+ module Operation
16
+ class MoveOperation < Base
17
+ PROPERTIES = [:from, :to, :axis]
18
+ attr_accessor *PROPERTIES
19
+
20
+ attr_default :axis, :x
21
+
22
+ def initialize(params = {})
23
+ super
24
+
25
+ if axis = (params[:axis] || params["axis"])
26
+ self.axis = axis
27
+ end
28
+
29
+ params.each do |key, value|
30
+ if PROPERTIES.include?(key.to_sym)
31
+ self.send("#{key}=", value)
32
+ end
33
+ end
34
+ end
35
+
36
+ ["from", "to"].each do |point|
37
+ define_method("#{point}=") do |new_point|
38
+ _point = new_point
39
+ case new_point
40
+ when Numeric
41
+ if self.axis.to_sym == :x
42
+ _point = [new_point, nil]
43
+ else
44
+ _point = [nil, new_point]
45
+ end
46
+ when CGPoint
47
+ _point = [new_point.x, new_point.y]
48
+ when NSArray
49
+ else
50
+ raise "Invalid class for #{point}=: #{new_point.inspect}"
51
+ end
52
+ instance_variable_set("@#{point}", _point)
53
+ end
54
+ end
55
+
56
+ def setup(view, animation)
57
+ if self.from
58
+ origin = view.frame.origin
59
+ origin.x = (self.from[0] || origin.x)
60
+ origin.y = (self.from[1] || origin.y)
61
+ view.frame = [origin, view.frame.size]
62
+ end
63
+ end
64
+
65
+ def finalize(view, animation)
66
+ origin = view.frame.origin
67
+ origin.x = (self.to[0] || origin.x)
68
+ origin.y = (self.to[1] || origin.y)
69
+ view.frame = [origin, view.frame.size]
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,41 @@
1
+ =begin
2
+ {
3
+ from: 0,
4
+ to: 45
5
+ }
6
+ =end
7
+
8
+ module Walt
9
+ module Operation
10
+ class RotateOperation < Base
11
+ PROPERTIES = [:from, :to]
12
+ attr_accessor *PROPERTIES
13
+
14
+ def initialize(params = {})
15
+ super
16
+
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
+ def finalize(view, animation)
25
+ rotate = CABasicAnimation.animationWithKeyPath("transform.rotation")
26
+
27
+ from = self.from || view.instance_variable_get("@__last_rotation") || 0
28
+ rotate.fromValue = NSNumber.numberWithFloat(from)
29
+
30
+ rotate.toValue = NSNumber.numberWithFloat(self.to * Math::PI / 180)
31
+ view.instance_variable_set("@__last_rotation", rotate.toValue.to_f)
32
+
33
+ rotate.duration = animation.duration
34
+ rotate.removedOnCompletion = false
35
+ rotate.fillMode = KCAFillModeForwards
36
+
37
+ view.layer.addAnimation(rotate, forKey:nil)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,41 @@
1
+ =begin
2
+ {
3
+ from: 1.0,
4
+ to: 1.2
5
+ }
6
+ =end
7
+
8
+ module Walt
9
+ module Operation
10
+ class ScaleOperation < Base
11
+ PROPERTIES = [:from, :to]
12
+ attr_accessor *PROPERTIES
13
+
14
+ def initialize(params = {})
15
+ super
16
+
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
+ def finalize(view, animation)
25
+ scale = CABasicAnimation.animationWithKeyPath("transform.scale")
26
+
27
+ from = self.from || view.instance_variable_get("@__last_scale") || 1.0
28
+ scale.fromValue = NSNumber.numberWithFloat(from)
29
+
30
+ scale.toValue = NSNumber.numberWithFloat(self.to)
31
+ view.instance_variable_set("@__last_scale", scale.toValue.to_f)
32
+
33
+ scale.duration = animation.duration
34
+ scale.removedOnCompletion = false
35
+ scale.fillMode = KCAFillModeForwards
36
+
37
+ view.layer.addAnimation(scale, forKey:nil)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,5 @@
1
+ class UIColor
2
+ def to_color
3
+ self
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ module Walt
2
+ module Support
3
+ module AttrDefault
4
+ def attr_default(attribute, default)
5
+ attr_accessor attribute
6
+ define_method(attribute) do
7
+ ivar = "@#{attribute}"
8
+ if !instance_variable_defined?(ivar)
9
+ instance_variable_set(ivar, default)
10
+ end
11
+ instance_variable_get(ivar)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,60 @@
1
+ module Walt
2
+ module Support
3
+ module_function
4
+
5
+ =begin
6
+ Constant.for("UIViewAnimationOption", value)
7
+ =end
8
+
9
+ def constant(base, value)
10
+ return value if value.is_a? Numeric
11
+ value = value.to_s.camelize
12
+ Kernel.const_get("#{base}#{value}")
13
+ end
14
+
15
+ private
16
+ def hack
17
+ [
18
+ UIViewAnimationOptionLayoutSubviews,
19
+ UIViewAnimationOptionAllowUserInteraction,
20
+ UIViewAnimationOptionBeginFromCurrentState,
21
+ UIViewAnimationOptionRepeat,
22
+ UIViewAnimationOptionAutoreverse,
23
+ UIViewAnimationOptionOverrideInheritedDuration,
24
+ UIViewAnimationOptionOverrideInheritedCurve,
25
+ UIViewAnimationOptionAllowAnimatedContent,
26
+ UIViewAnimationOptionShowHideTransitionViews,
27
+ UIViewAnimationOptionCurveEaseInOut,
28
+ UIViewAnimationOptionCurveEaseIn,
29
+ UIViewAnimationOptionCurveEaseOut,
30
+ UIViewAnimationOptionCurveLinear,
31
+ UIViewAnimationOptionTransitionNone,
32
+ UIViewAnimationOptionTransitionFlipFromLeft,
33
+ UIViewAnimationOptionTransitionFlipFromRight,
34
+ UIViewAnimationOptionTransitionCurlUp,
35
+ UIViewAnimationOptionTransitionCurlDown,
36
+ UIViewAnimationOptionTransitionCrossDissolve,
37
+ UIViewAnimationOptionTransitionFlipFromTop,
38
+ UIViewAnimationOptionTransitionFlipFromBottom,
39
+
40
+ UIViewContentModeScaleToFill,
41
+ UIViewContentModeScaleAspectFit,
42
+ UIViewContentModeScaleAspectFill,
43
+ UIViewContentModeRedraw,
44
+ UIViewContentModeCenter,
45
+ UIViewContentModeTop,
46
+ UIViewContentModeBottom,
47
+ UIViewContentModeLeft,
48
+ UIViewContentModeRight,
49
+ UIViewContentModeTopLeft,
50
+ UIViewContentModeTopRight,
51
+ UIViewContentModeBottomLeft,
52
+ UIViewContentModeBottomRight,
53
+
54
+ UITextAlignmentLeft,
55
+ UITextAlignmentRight,
56
+ UITextAlignmentCenter
57
+ ]
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,87 @@
1
+ module Walt
2
+ module Font
3
+ module_function
4
+
5
+ def bold(size)
6
+ Font.make(:bold, size)
7
+ end
8
+
9
+ def system(size)
10
+ Font.make(:system, size)
11
+ end
12
+
13
+ def italic(size)
14
+ Font.make(:italic, size)
15
+ end
16
+
17
+ # Create font with params:
18
+ # String => The name of the font
19
+ # Hash => {
20
+ # size: Integer,
21
+ # name: String (see above)
22
+ # }
23
+ def make(params = {}, *args)
24
+ if params.is_a?(UIFont)
25
+ return params
26
+ end
27
+
28
+ _font = nil
29
+ if params.is_a?(NSString)
30
+ params = {name: params}
31
+ end
32
+ if args && args[0]
33
+ params.merge!({size: args[0]})
34
+ end
35
+ params[:size] ||= UIFont.systemFontSize
36
+ if [:system, :bold, :italic].member?(params[:name])
37
+ case params[:name]
38
+ when :system
39
+ _font = UIFont.systemFontOfSize(params[:size].to_f)
40
+ when :bold
41
+ _font = UIFont.boldSystemFontOfSize(params[:size].to_f)
42
+ when :italic
43
+ _font = UIFont.italicSystemFontOfSize(params[:size].to_f)
44
+ end
45
+ end
46
+
47
+ if !_font
48
+ begin
49
+ _font = UIFont.fontWithName(params[:name], size: params[:size])
50
+ rescue
51
+ end
52
+ end
53
+
54
+ if !_font
55
+ raise "Invalid font for parameters: #{params.inspect} args #{args.inspect}"
56
+ end
57
+
58
+ _font
59
+ end
60
+
61
+ # Create font attributes with keys:
62
+ # {
63
+ # font: String or Hash (see Font.make),
64
+ # color: String,
65
+ # shadow_color: String,
66
+ # shadow_offset: {
67
+ # x: Integer,
68
+ # y: Integer
69
+ # }
70
+ # }
71
+ def attributes(params = {})
72
+ _attributes = {}
73
+
74
+ _attributes[UITextAttributeFont] = Font.make(params[:font]) if params[:font]
75
+ _attributes[UITextAttributeTextColor] = params[:color].to_color if params[:color]
76
+ _attributes[UITextAttributeTextShadowColor] = params[:shadow_color].to_color if params[:shadow_color]
77
+ _attributes[UITextAttributeTextShadowOffset] = begin
78
+ x = params[:shadow_offset][:x]
79
+ y = params[:shadow_offset][:y]
80
+ offset = UIOffsetMake(x,y)
81
+ NSValue.valueWithUIOffset(offset)
82
+ end if params[:shadow_offset]
83
+
84
+ _attributes
85
+ end
86
+ end
87
+ end