motion-ui-geometry 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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