motion-ui-geometry 0.5.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.
@@ -0,0 +1,42 @@
1
+ class Float
2
+
3
+ EPSILON = 0.00001
4
+
5
+ def clamp(min, max)
6
+ max = 0 + max
7
+ min = 0 + min
8
+
9
+ min, max = max, min if min > max
10
+
11
+ if self > max
12
+ max
13
+ elsif self < min
14
+ min
15
+ else
16
+ self
17
+ end
18
+ end
19
+
20
+ def to_radians
21
+ self * Math::PI / 180.0
22
+ end
23
+ alias :to_rad :to_radians
24
+
25
+ def to_degrees
26
+ self * 180.0 / Math::PI
27
+ end
28
+ alias :to_deg :to_degrees
29
+
30
+ def roughly_equal?(other, epsilon = EPSILON)
31
+ (self - other).abs <= epsilon
32
+ end
33
+
34
+ def =~(other)
35
+ roughly_equal?(other)
36
+ end
37
+
38
+ def to_value
39
+ NSNumber.numberWithFloat self
40
+ end
41
+
42
+ end
@@ -0,0 +1,21 @@
1
+ class NSDictionary
2
+
3
+ def to_point
4
+ point = Pointer.new CGPoint.type
5
+ CGPointMakeWithDictionaryRepresentation self, point
6
+ point[0]
7
+ end
8
+
9
+ def to_size
10
+ size = Pointer.new CGSize.type
11
+ CGSizeMakeWithDictionaryRepresentation self, size
12
+ size[0]
13
+ end
14
+
15
+ def to_rect
16
+ rect = Pointer.new CGRect.type
17
+ CGRectMakeWithDictionaryRepresentation self, rect
18
+ rect[0]
19
+ end
20
+
21
+ end
@@ -0,0 +1,17 @@
1
+ class NSString
2
+ def to_point
3
+ CGPointFromString(self)
4
+ end
5
+
6
+ def to_size
7
+ CGSizeFromString(self)
8
+ end
9
+
10
+ def to_rect
11
+ CGRectFromString(self)
12
+ end
13
+
14
+ def to_transform
15
+ CGAffineTransformFromString(self)
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ class SpecAppDelegate
2
+ def application(application, didFinishLaunchingWithOptions:launchOptions)
3
+ @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
4
+ @window.rootViewController = UIViewController.alloc.init
5
+ true
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Motion
2
+ module UI
3
+ module Geometry
4
+ VERSION = "0.5.1"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/motion-ui-geometry/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Sebastian Burkhart"]
6
+ gem.email = ["sebastianburkhart@me.com"]
7
+ gem.description = %q{Access CoreGraphics UI geometry the Ruby way.}
8
+ gem.summary = %q{Contains Ruby-ish interfaces mixed into Float, CGPoint, CGRect, CGSize and CGPoint.}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "motion-ui-geometry"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Motion::UI::Geometry::VERSION
17
+ end
@@ -0,0 +1,272 @@
1
+ describe CGAffineTransform do
2
+
3
+ before do
4
+ @t = CGAffineTransform.new 1, 2, 3, 4, 5, 6
5
+ @double_scale = CGAffineTransform.new 2, 0, 0, 2, 0, 0
6
+ @double_t = CGAffineTransform.new 2, 4, 6, 8, 10, 12
7
+ end
8
+
9
+
10
+ describe "#initialize(a, b, c, d, tx, ty)" do
11
+ it "initializes an affine transform" do
12
+ t = CGAffineTransform.new 1, 2, 3, 4, 5, 6
13
+ t.should.is_a(CGAffineTransform)
14
+ t.a.should == 1
15
+ t.b.should == 2
16
+ t.c.should == 3
17
+ t.d.should == 4
18
+ t.tx.should == 5
19
+ t.ty.should == 6
20
+ end
21
+ end
22
+
23
+
24
+ describe "Factory methods" do
25
+
26
+ describe ".identity" do
27
+ it "returns the identity transform" do
28
+ CGAffineTransform.identity.should == CGAffineTransformIdentity
29
+ CGAffineTransform.identity.should.is_a(CGAffineTransform)
30
+ end
31
+ end
32
+
33
+ describe ".rotation(angle_in_rad)" do
34
+ it "creates a rotation transform" do
35
+ t = CGAffineTransform.rotation(Math::PI)
36
+ t.should =~ CGAffineTransform.new(-1, 0, 0, -1, 0, 0)
37
+ end
38
+ end
39
+
40
+ describe ".scale(sx, sy)" do
41
+ it "creates a scale transform" do
42
+ t = CGAffineTransform.scale(2, 3)
43
+ t.should.is_a(CGAffineTransform)
44
+ t.should == CGAffineTransform.new(2, 0, 0, 3, 0, 0)
45
+ end
46
+
47
+ it "works with only one parameter" do
48
+ t = CGAffineTransform.scale(2)
49
+ t.should.is_a(CGAffineTransform)
50
+ t.should == CGAffineTransform.new(2, 0, 0, 2, 0, 0)
51
+ end
52
+ end
53
+
54
+ describe ".translation(tx, ty)" do
55
+ it "creates a translation transform" do
56
+ t = CGAffineTransform.translation(4, 5)
57
+ t.should.is_a(CGAffineTransform)
58
+ t.should == CGAffineTransform.new(1, 0, 0, 1, 4, 5)
59
+ end
60
+ end
61
+
62
+ describe ".skew(sx, sy)" do
63
+ it "creates a skew transform" do
64
+ skew = CGAffineTransform.skew(4, 5)
65
+ skew.should.is_a(CGAffineTransform)
66
+ skew.should == CGAffineTransformMake(1, 5, 4, 1, 0, 0)
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+
73
+ describe "Comparison operators" do
74
+
75
+ describe "==" do
76
+ it "returns true when equal" do
77
+ CGAffineTransformIdentity.should == CGAffineTransformIdentity
78
+ CGAffineTransformIdentity.should == CGAffineTransform.new(1, 0, 0, 1, 0, 0)
79
+ end
80
+
81
+ it "returns false when not equal" do
82
+ CGAffineTransformIdentity.should != CGAffineTransform.new(1, 1, 1, 1, 1, 1)
83
+ end
84
+ end
85
+
86
+ describe "=~" do
87
+ before do
88
+ @t1 = CGAffineTransform.new 1, 1, 1, 1, 1, 1
89
+ @t2 = CGAffineTransform.new 0.999999, 0.999999, 0.999999, 0.999999, 0.999999, 0.999999
90
+ @t3 = CGAffineTransform.new 1.0000001, 1.0000001, 1.0000001, 1.0000001, 1.0000001, 1.0000001
91
+ @t4 = CGAffineTransform.new -1.0000001, 1.0000001, 1.0000001, 1.0000001, 1.0000001, 1.0000001
92
+ end
93
+
94
+ it "returns true if transforms are roughly equal" do
95
+ @t1.should =~ @t1
96
+ @t1.should =~ @t2
97
+ @t2.should =~ @t3
98
+ end
99
+
100
+ it "returns false if transforms are not roughly equal" do
101
+ @t1.should.not =~ @t4
102
+ @t2.should.not =~ @t4
103
+ @t3.should.not =~ @t4
104
+ end
105
+ end
106
+
107
+ end
108
+
109
+
110
+ describe "Applying transforms on other transforms" do
111
+
112
+ describe "#concat(other)" do
113
+ it "returns the result of applying the other transform on self" do
114
+ @t.concat(CGAffineTransformIdentity).should == @t
115
+ CGAffineTransformIdentity.concat(@t).should == @t
116
+ @t.concat(@double_scale).should == @double_t
117
+ end
118
+ end
119
+
120
+ describe "#apply_on(other)" do
121
+ it "behaves reverse to concat" do
122
+ CGAffineTransformIdentity.apply_on(@t).should == @t
123
+ @t.apply_on(CGAffineTransformIdentity).should == @t
124
+ @double_scale.apply_on(@t).should == @double_t
125
+ end
126
+ end
127
+
128
+ describe "via operators" do
129
+
130
+ describe "+" do
131
+ it "translates if given a CGSize" do
132
+ t = CGAffineTransformIdentity + CGSizeMake(2, 3)
133
+ t.should == CGAffineTransform.translation(2, 3)
134
+ end
135
+
136
+ it "translates if given a CGPoint" do
137
+ t = CGAffineTransformIdentity + CGPointMake(2, 3)
138
+ t.should == CGAffineTransform.translation(2, 3)
139
+ end
140
+
141
+ it "raises if given another type" do
142
+ lambda { CGAffineTransformIdentity + "abc" }.should.raise TypeError
143
+ end
144
+ end
145
+
146
+ describe "-" do
147
+ it "translates if given a CGSize" do
148
+ t = CGAffineTransformIdentity - CGSizeMake(2, 3)
149
+ t.should == CGAffineTransform.translation(-2, -3)
150
+ end
151
+
152
+ it "translates if given a CGPoint" do
153
+ t = CGAffineTransformIdentity - CGPointMake(2, 3)
154
+ t.should == CGAffineTransform.translation(-2, -3)
155
+ end
156
+ end
157
+
158
+ describe "unary -" do
159
+ it "inverts the transform" do
160
+ (-CGAffineTransform.identity).should == CGAffineTransform.identity
161
+ (-CGAffineTransform.scale(2, 4)).should == CGAffineTransform.scale(0.5, 0.25)
162
+ (-CGAffineTransform.rotation(20)).should =~ CGAffineTransform.rotation(-20)
163
+ (-CGAffineTransform.translation(2, 4)).should == CGAffineTransform.translation(-2, -4)
164
+ end
165
+ end
166
+
167
+ describe "*" do
168
+ it "behaves like #concat if given a transform" do
169
+ @t.concat(CGAffineTransformIdentity).should == @t
170
+ CGAffineTransformIdentity.concat(@t).should == @t
171
+ @t.concat(@double_scale).should == @double_t
172
+ end
173
+
174
+ it "scales the transform if given a Float" do
175
+ (CGAffineTransformIdentity * 23.0).should =~ CGAffineTransform.scale(23.0, 23.0)
176
+ end
177
+
178
+ it "scales the transform if given a Fixnum" do
179
+ (CGAffineTransformIdentity * 5).should =~ CGAffineTransform.scale(5.0, 5.0)
180
+ end
181
+
182
+ it "raises if given another type" do
183
+ lambda { CGAffineTransformIdentity * "abc" }.should.raise TypeError
184
+ end
185
+ end
186
+
187
+ end
188
+
189
+ describe "via shortcut methods" do
190
+
191
+ describe "#translate(tx, ty)" do
192
+ it "translates the transform by an offset of (tx, ty)" do
193
+ t = CGAffineTransform.identity.translate(4, 5)
194
+ t.should == CGAffineTransform.translation(4, 5)
195
+ t.should == CGAffineTransform.new(1, 0, 0, 1, 4, 5)
196
+ end
197
+ end
198
+
199
+ describe "#scale(sx, sy)" do
200
+ it "scales the transform by a factor of (sx, sy)" do
201
+ t = CGAffineTransform.identity.scale(23, 42)
202
+ t.should == CGAffineTransform.scale(23, 42)
203
+ t.should == CGAffineTransform.new(23, 0, 0, 42, 0, 0)
204
+ end
205
+
206
+ it "works with only one parameter" do
207
+ t = CGAffineTransform.identity
208
+ t.should.is_a(CGAffineTransform)
209
+ t.scale(2).should == CGAffineTransform.new(2, 0, 0, 2, 0, 0)
210
+ end
211
+ end
212
+
213
+ describe "#rotate(angle_in_rad)" do
214
+ it "rotates the transform by given angle" do
215
+ t = CGAffineTransform.identity.rotate(Math::PI)
216
+ t.should == CGAffineTransform.rotation(Math::PI)
217
+ t.a.should == -1
218
+ t.b.should =~ 0
219
+ t.c.should =~ 0
220
+ t.d.should == -1
221
+ t.tx.should == 0
222
+ t.ty.should == 0
223
+ end
224
+ end
225
+
226
+ describe "#skew(sx, sy)" do
227
+ it "skew the transform by given offsets" do
228
+ t = CGAffineTransform.identity.skew(3, 4)
229
+ t.should == CGAffineTransform.skew(3, 4)
230
+ t.should == CGAffineTransform.new(1, 4, 3, 1, 0, 0)
231
+ end
232
+ end
233
+
234
+ end
235
+
236
+ end
237
+
238
+ describe "#invert" do
239
+ it "inverts the transform" do
240
+ i = CGAffineTransform.identity
241
+ i.invert.should == i
242
+ CGAffineTransform.scale(2, 4).invert.should == CGAffineTransform.scale(0.5, 0.25)
243
+ CGAffineTransform.rotation(10).invert.should == CGAffineTransform.rotation(-10)
244
+ CGAffineTransform.translation(2, 4).invert.should == CGAffineTransform.translation(-2, -4)
245
+ end
246
+ end
247
+
248
+ describe "#identity?" do
249
+ it "returns true for the identity transform" do
250
+ CGAffineTransform.identity.should.be.identity
251
+ end
252
+
253
+ it "returns false for other transforms" do
254
+ CGAffineTransform.translation(1, 2).should.not.be.identity
255
+ end
256
+ end
257
+
258
+ describe "#to_value" do
259
+ it "returns a NSValue containing the transform" do
260
+ t = CGAffineTransform.new 1, 2, 3, 4, 5, 6
261
+ t.to_value.CGAffineTransformValue.should == t
262
+ end
263
+ end
264
+
265
+ describe "#to_s" do
266
+ it "returns a NSString encoding" do
267
+ CGAffineTransform.new(1, 2, 3, 4, 5, 6).to_s.
268
+ should == "[1, 2, 3, 4, 5, 6]"
269
+ end
270
+ end
271
+
272
+ end
@@ -0,0 +1,210 @@
1
+ describe "CGPoint" do
2
+
3
+ describe "== operator" do
4
+ it "returns true for the same point" do
5
+ CGPointMake(-12345, -12345).should == CGPointMake(-12345, -12345)
6
+ CGPointMake(1, 1).should == CGPointMake(1, 1)
7
+ end
8
+
9
+ it "returns false for other points" do
10
+ CGPointMake(1, 1).should != CGPointMake(0.999, 0.999)
11
+ CGPointMake(1, 1).should != CGPointZero
12
+ end
13
+ end
14
+
15
+ describe "=~ operator" do
16
+ it "should return true if the points are roughly equal" do
17
+ CGPointZero.should =~ CGPointZero
18
+ CGPointZero.should =~ CGPointMake( 0.00001, 0.00001)
19
+ CGPointZero.should =~ CGPointMake(-0.00001, -0.00001)
20
+ end
21
+
22
+ it "should return false if the points are not roughly equal" do
23
+ CGPointZero.should.not =~ CGPointMake(1, 1)
24
+ end
25
+
26
+ it "should return true if vectors are roughly equal" do
27
+ CGPointZero.should =~ CGSizeZero
28
+ CGPointZero.should =~ CGSizeMake( 0.00001, 0.00001)
29
+ CGPointZero.should =~ CGSizeMake(-0.00001, -0.00001)
30
+ end
31
+
32
+ it "should return false if vectors are not roughly equal" do
33
+ CGPointZero.should.not =~ CGSizeMake(1, 1)
34
+ end
35
+
36
+ it "should raise if given a wrong type" do
37
+ lambda { CGPointZero =~ "abc" }.should.raise(TypeError)
38
+ end
39
+ end
40
+
41
+ describe "unary -" do
42
+ it "returns the point with negative coordinates" do
43
+ (-CGPointMake(1, 1)).should == CGPointMake(-1, -1)
44
+ (-CGPointZero).should == CGPointZero
45
+ end
46
+ end
47
+
48
+ describe "- operator" do
49
+ it "returns the subtracted point vectors as point" do
50
+ (CGPointMake(1, 1) - CGPointMake(1, 1)).should == CGPointZero
51
+ (CGPointZero - CGPointMake(1, 1)).should == CGPointMake(-1, -1)
52
+ end
53
+
54
+ it "raises if not given a point" do
55
+ lambda { CGPointZero - "abc" }.should.raise(TypeError)
56
+ end
57
+ end
58
+
59
+ describe "+ operator" do
60
+ it "returns the added point vectors as point" do
61
+ (CGPointMake(1, 2) + CGPointMake(3, 4)).should == CGPointMake(4, 6)
62
+ (CGPointMake(-1, -2) + CGPointMake(1, 2)).should == CGPointZero
63
+ end
64
+
65
+ it "raises if not given a point" do
66
+ lambda { CGPointZero + "abc" }.should.raise(TypeError)
67
+ end
68
+ end
69
+
70
+ describe "* operator" do
71
+ it "scales the point if given a Float" do
72
+ (CGPointZero * 23.0).should == CGPointZero
73
+ (CGPointMake(1, 2) * 23.0).should == CGPointMake(23, 46)
74
+ (CGPointMake(1, 2) * -1.0).should == CGPointMake(-1, -2)
75
+ end
76
+
77
+ it "scales the point if given a Fixnum" do
78
+ (CGPointZero * 23).should == CGPointZero
79
+ (CGPointMake(1, 2) * 23).should == CGPointMake(23, 46)
80
+ (CGPointMake(1, 2) * -1).should == CGPointMake(-1, -2)
81
+ end
82
+
83
+ it "scales the point if given a CGSize" do
84
+ size = CGSizeMake(2, 4)
85
+ (CGPointZero * size).should == CGPointZero
86
+ (CGPointZero * size).should.is_a CGPoint
87
+ (CGPointMake(1, 1) * size).should =~ size
88
+ (CGPointMake(3, 5) * size).should == CGPointMake(6, 20)
89
+ end
90
+
91
+ it "scales the point if given a CGPoint" do
92
+ point = CGPointMake(2, 4)
93
+ (CGPointZero * point).should == CGPointZero
94
+ (CGPointZero * point).should.is_a CGPoint
95
+ (CGPointMake(1, 1) * point).should == point
96
+ (CGPointMake(3, 5) * point).should == CGPointMake(6, 20)
97
+ end
98
+
99
+ it "applies a transform if given" do
100
+ (CGPointZero * CGAffineTransform.scale(5)).should == CGPointZero
101
+ point = CGPointMake(1, 2)
102
+ (point * CGAffineTransform.scale(5)).should == point * 5
103
+ end
104
+
105
+ it "raises if given another type" do
106
+ lambda { CGPointZero * "abc" }.should.raise(TypeError)
107
+ end
108
+ end
109
+
110
+ describe "#distance_to(other)" do
111
+ it "returns 0.0 for the same points" do
112
+ (CGPointMake(1, 1).distance_to CGPointMake(1, 1)).should == 0.0
113
+ (CGPointMake(-1234, -1234).distance_to CGPointMake(-1234, -1234)).should == 0.0
114
+ end
115
+
116
+ it "returns the absolute distance" do
117
+ (CGPointMake(1, 0).distance_to CGPointZero).should =~ 1.0
118
+ (CGPointMake(0, 1).distance_to CGPointZero).should =~ 1.0
119
+ (CGPointZero.distance_to CGPointMake(1, 0)).should =~ 1.0
120
+ (CGPointZero.distance_to CGPointMake(0, 1)).should =~ 1.0
121
+ end
122
+
123
+ it "returns the distance to the given other point as float" do
124
+ (CGPointMake(1, 1).distance_to CGPointZero).should =~ Math.sqrt(2.0)
125
+ (CGPointMake(-1, -1).distance_to CGPointZero).should =~ Math.sqrt(2.0)
126
+ end
127
+
128
+ it "raises if given no point" do
129
+ lambda { CGPointZero.distance_to "abc" }.should.raise(TypeError)
130
+ end
131
+ end
132
+
133
+ describe '#clamp_to_rect(rect)' do
134
+ it "limits the point coordinates to the given rect" do
135
+ rect = CGRectMake(0, 0, 1, 1)
136
+ CGPointZero.clamp_to_rect(rect).should == CGPointZero
137
+ CGPointMake(1, 1).clamp_to_rect(rect).should == CGPointMake(1, 1)
138
+ CGPointMake(0.5, 0.5).clamp_to_rect(rect).should == CGPointMake(0.5, 0.5)
139
+ CGPointMake(-1, -1).clamp_to_rect(rect).should == CGPointZero
140
+ CGPointMake(2, 2).clamp_to_rect(rect).should == CGPointMake(1, 1)
141
+ end
142
+
143
+ it "raises if given no rect" do
144
+ lambda { CGPointZero.clamp_to_rect "abc" }.should.raise(TypeError)
145
+ end
146
+ end
147
+
148
+ describe '#round' do
149
+ it "returns the point rounded to next integer coordinates" do
150
+ CGPointMake(0.1, 0.1).round.should == CGPointZero
151
+ CGPointMake(-0.1, -0.1).round.should == CGPointZero
152
+ CGPointMake(12.34, 12.34).round.should == CGPointMake(12, 12)
153
+ CGPointMake(34.56, 34.56).round.should == CGPointMake(35, 35)
154
+ end
155
+ end
156
+
157
+ describe '#floor' do
158
+ it "returns the point rounded down to integer coordinates" do
159
+ CGPointMake(0.1, 0.1).floor.should == CGPointZero
160
+ CGPointMake(-0.1, -0.1).floor.should == CGPointMake(-1, -1)
161
+ CGPointMake(12.34, 12.34).floor.should == CGPointMake(12, 12)
162
+ CGPointMake(34.56, 34.56).floor.should == CGPointMake(34, 34)
163
+ end
164
+ end
165
+
166
+ # describe "#angle" do
167
+ # it "should work"
168
+ # end
169
+
170
+ describe "#apply(transform)" do
171
+ it "returns a new point with the given transform applied" do
172
+ p = CGPointMake(1, 1)
173
+ scale = CGAffineTransform.scale(2.0, 2.0)
174
+ p = p.apply(scale)
175
+ p.should == CGPointMake(2, 2)
176
+ end
177
+
178
+ it "raises if given no transform" do
179
+ lambda { CGPointZero.clamp_to_rect "abc" }.should.raise(TypeError)
180
+ end
181
+ end
182
+
183
+ describe "#to_dictionary" do
184
+ it "returns a dictionary" do
185
+ CGPointMake(1, 1).to_dictionary.should.is_a(NSDictionary)
186
+ end
187
+ end
188
+
189
+ describe "#to_value" do
190
+ it "returns a correct NSValue" do
191
+ value = CGPointMake(1, 1).to_value
192
+ value.CGPointValue.should == CGPointMake(1, 1)
193
+ end
194
+ end
195
+
196
+ describe "#to_size" do
197
+ it "returns a CGSize" do
198
+ size = CGPointMake(1, 2).to_size
199
+ size.should.is_a(CGSize)
200
+ size.should == CGSizeMake(1, 2)
201
+ end
202
+ end
203
+
204
+ describe "#to_s" do
205
+ it "should return a sensible string" do
206
+ CGPointMake(23, 42).to_s.should == "{23, 42}"
207
+ end
208
+ end
209
+
210
+ end