sugarcube 0.14.0 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +33 -3
- data/Rakefile +5 -0
- data/lib/sugarcube/nsarray.rb +1 -1
- data/lib/sugarcube/nsdate.rb +7 -2
- data/lib/sugarcube/uiimage.rb +264 -32
- data/lib/sugarcube/uiview.rb +14 -1
- data/lib/sugarcube/version.rb +1 -1
- data/lib/sugarcube-568/uiimage.rb +32 -0
- data/lib/sugarcube-568.rb +23 -0
- data/resources/Default-568h@2x.png +0 -0
- data/resources/Default.png +0 -0
- data/resources/Default@2x.png +0 -0
- data/resources/little_square.png +0 -0
- data/resources/little_square@2x.png +0 -0
- data/resources/tall-568h@2x.png +0 -0
- data/resources/tall.png +0 -0
- data/resources/tall@2x.png +0 -0
- data/spec/568_spec.rb +6 -0
- data/spec/calayer_spec.rb +10 -0
- data/spec/core_location_spec.rb +15 -0
- data/spec/symbol_uicolor_spec.rb +14 -0
- data/spec/uicolor_components_spec.rb +33 -0
- data/spec/uiimage_color_at_spec.rb +59 -0
- data/spec/uiimage_scale_spec.rb +90 -0
- data/spec/uiview_animation_spec.rb +16 -0
- metadata +26 -2
data/README.md
CHANGED
@@ -467,8 +467,20 @@ image.rotate(:right)
|
|
467
467
|
image.rotate(:flip) # 180° - if you have a better name, let me know!
|
468
468
|
image.rotate(45.degrees)
|
469
469
|
|
470
|
-
image.
|
471
|
-
image.
|
470
|
+
image.in_rect(frame) # returns the part of the image contained in frame
|
471
|
+
image.scale_to(new_size) # won't stretch, but the image might have transparent padding
|
472
|
+
image.scale_to(new_size, background: :white) # adds a white background before padding
|
473
|
+
image.scale_within(new_size) # same as scale_to in that it doesn't stretch the
|
474
|
+
# image, but the size is not guaranteed to be new_size. It is guaranteed not to
|
475
|
+
# be *bigger* than new_size
|
476
|
+
image.scale_to_fill(new_size) # again, like scale_to, but the image is guaranteed
|
477
|
+
# to completely fill new_size, even if some of the image has to be cropped to fit.
|
478
|
+
# You can control which side or corner you prefer to remain visible. because the
|
479
|
+
# aspect ratio is maintained, only ONE dimension will need to be cropped.
|
480
|
+
image.scale_to_fill(new_size, position: :top_left)
|
481
|
+
|
482
|
+
# returns a UIColor (and supports retina images)
|
483
|
+
image.color_at([5, 5])
|
472
484
|
|
473
485
|
# default insets are UIEdgeInsetsZero
|
474
486
|
image.tileable
|
@@ -481,6 +493,21 @@ image.stretchable(insets)
|
|
481
493
|
image.masked(mask_image)
|
482
494
|
```
|
483
495
|
|
496
|
+
#### 568
|
497
|
+
|
498
|
+
If you `require 'sugarcube-568'` in your Rakefile, you can use
|
499
|
+
`UIImage.imageNamed()` to load images that are specific to the 4" iphone.
|
500
|
+
|
501
|
+
```ruby
|
502
|
+
'tall'.uiimage
|
503
|
+
# => tall.png on iphone 3g
|
504
|
+
# => tall@2x.png on iphone 4
|
505
|
+
# => tall-568h@2x.png on iphone 5
|
506
|
+
```
|
507
|
+
|
508
|
+
This code is ported from <https://github.com/gaj/imageNamed568>, which I had
|
509
|
+
some problems with on RubyMotion (it worked, but not *always*. Very strange).
|
510
|
+
|
484
511
|
UIAlertView
|
485
512
|
--------
|
486
513
|
|
@@ -575,9 +602,12 @@ view.fade_out(0.5, delay: 0,
|
|
575
602
|
view.removeFromSuperview
|
576
603
|
}
|
577
604
|
|
578
|
-
view.move_to([0, 100])
|
605
|
+
view.move_to([0, 100]) # move to position 0, 100
|
579
606
|
view.delta_to([0, 100]) # move over 0, down 100, from current position
|
580
607
|
|
608
|
+
view.rotate_to Math::PI # rotate view upside down
|
609
|
+
view.rotate_to(duration: 0.5, angle: 45.degrees) # using options
|
610
|
+
|
581
611
|
view.slide :left # slides the entire view one "page" to the left, right, up, or down
|
582
612
|
|
583
613
|
view.shake # shakes the view.
|
data/Rakefile
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
$:.unshift('/Library/RubyMotion/lib')
|
2
2
|
require 'motion/project'
|
3
3
|
require './lib/sugarcube'
|
4
|
+
require './lib/sugarcube-gestures'
|
5
|
+
require './lib/sugarcube-568'
|
6
|
+
|
4
7
|
|
5
8
|
Motion::Project::App.setup do |app|
|
6
9
|
# Use `rake config' to see complete project settings.
|
7
10
|
app.name = 'SugarCube'
|
11
|
+
|
12
|
+
app.frameworks << 'CoreLocation'
|
8
13
|
end
|
data/lib/sugarcube/nsarray.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class NSArray
|
2
2
|
|
3
|
-
# @param [Symbol] type A pointer type from the list at {http://www.rubymotion.com/developer-center/guides/runtime/ RubyMotion Pointers Reference#_pointers}
|
3
|
+
# @param type [Symbol] type A pointer type from the list at {http://www.rubymotion.com/developer-center/guides/runtime/ RubyMotion Pointers Reference#_pointers}
|
4
4
|
# @return [Pointer] A pointer to the array, of the specified type
|
5
5
|
def to_pointer(type)
|
6
6
|
ret = Pointer.new(type, self.length)
|
data/lib/sugarcube/nsdate.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
class NSDate
|
2
2
|
|
3
|
-
def self.
|
4
|
-
|
3
|
+
def self.from_components(components)
|
4
|
+
components = NSDateComponents.new
|
5
|
+
components.each do |property,value|
|
6
|
+
components.send("#{property}=", value)
|
7
|
+
end
|
8
|
+
calendar = NSCalendar.alloc.initWithCalendarIdentifier(NSGregorianCalendar)
|
9
|
+
return calendar.dateFromComponents(components)
|
5
10
|
end
|
6
11
|
|
7
12
|
def string_with_style(style)
|
data/lib/sugarcube/uiimage.rb
CHANGED
@@ -27,22 +27,193 @@ class UIImage
|
|
27
27
|
##| <http://www.catamount.com/blog/uiimage-extensions-for-cutting-scaling-and-rotating-uiimages/>
|
28
28
|
##| <http://www.catamount.com/forums/viewtopic.php?f=21&t=967>
|
29
29
|
##|
|
30
|
+
|
31
|
+
# Merges the two images. The target is drawn first, `image` is drawn on top.
|
32
|
+
def <<(image)
|
33
|
+
size = self.size
|
34
|
+
if image.size.width > size.width
|
35
|
+
size.width = image.size.width
|
36
|
+
end
|
37
|
+
if image.size.height > size.height
|
38
|
+
size.height = image.size.height
|
39
|
+
end
|
40
|
+
|
41
|
+
UIGraphicsBeginImageContextWithOptions(size, false, self.scale)
|
42
|
+
self.drawAtPoint([0, 0])
|
43
|
+
# draw the border and drop shadow
|
44
|
+
image.drawAtPoint([0, 0])
|
45
|
+
new_image = UIGraphicsGetImageFromCurrentImageContext()
|
46
|
+
UIGraphicsEndImageContext()
|
47
|
+
return new_image
|
48
|
+
end
|
49
|
+
|
50
|
+
##|
|
51
|
+
##| image scaling
|
52
|
+
##|
|
53
|
+
|
54
|
+
# This method is used to crop an image. Scale (retina or non-retina) is preserved.
|
55
|
+
#
|
56
|
+
# @param rect [CGRect] the portion of the image to return
|
57
|
+
# @return [UIImage]
|
30
58
|
def in_rect(rect)
|
31
|
-
# not necessary, since we don't modify/examine the rect
|
32
|
-
# rect = SugarCube::CoreGraphics::Rect(rect)
|
33
59
|
imageRef = CGImageCreateWithImageInRect(self.CGImage, rect)
|
34
|
-
sub_image = UIImage.imageWithCGImage(imageRef)
|
60
|
+
sub_image = UIImage.imageWithCGImage(imageRef, scale:self.scale, orientation:self.imageOrientation)
|
35
61
|
|
36
62
|
return sub_image
|
37
63
|
end
|
38
64
|
|
65
|
+
# Delegates to scale_to_fill(position: :center)
|
66
|
+
def scale_to_fill(new_size)
|
67
|
+
scale_to_fill(new_size, position: :center)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Scales an image to fit within the given size, stretching one or both
|
71
|
+
# dimensions so that it completely fills the area. The current aspect ratio
|
72
|
+
# is maintained. If you want to place an image inside a container image, this
|
73
|
+
# is the method to use.
|
74
|
+
#
|
75
|
+
# You can specify a `position` property, which can be a symbol or a point. It
|
76
|
+
# specifies where you want the image located if it has to be cropped.
|
77
|
+
# Specifying the top-left corner will display the top-left corner of the
|
78
|
+
# image, likewise specifing the bottom-right corner will display *that*
|
79
|
+
# corner. If you want the image centered, you can use the 'position-less'
|
80
|
+
# version of this method (`scale_to_fit()`) or specify the point at the center
|
81
|
+
# of the image (`scale_to_fit(size, position:[w/2, h/2])`), or use a symbol
|
82
|
+
# (`scale_to_fit(size, position: :center)`).
|
83
|
+
#
|
84
|
+
# @param new_size [CGSize] Minimum dimensions of desired image. The returned image is
|
85
|
+
# guaranteed to fit within these dimensions.
|
86
|
+
# @param position [Symbol, CGPoint] Where to position the resized image. Valid symbols
|
87
|
+
# are: `[:topleft, :top, :topright, :left, :center, :right, :bottomleft,
|
88
|
+
# :bottom, :bottomright]` (if you forget and use an underscore, like
|
89
|
+
# `top_left`, that'll work, too)
|
90
|
+
# @return [UIImage]
|
91
|
+
def scale_to_fill(new_size, position:position)
|
92
|
+
new_size = SugarCube::CoreGraphics::Size(new_size)
|
93
|
+
my_size = self.size
|
94
|
+
|
95
|
+
if my_size.width < new_size.width
|
96
|
+
my_size.height *= new_size.width / my_size.width
|
97
|
+
my_size.width = new_size.width
|
98
|
+
end
|
99
|
+
|
100
|
+
if my_size.height < new_size.height
|
101
|
+
my_size.width *= new_size.height / my_size.height
|
102
|
+
my_size.height = new_size.height
|
103
|
+
end
|
104
|
+
|
105
|
+
if self.size.width == my_size.width && self.size.height == my_size.height
|
106
|
+
return self
|
107
|
+
end
|
108
|
+
|
109
|
+
if position.is_a?(Symbol)
|
110
|
+
min_x = 0
|
111
|
+
min_y = 0
|
112
|
+
max_x = my_size.width;
|
113
|
+
max_y = my_size.height;
|
114
|
+
mid_x = max_x / 2
|
115
|
+
mid_y = max_y / 2
|
116
|
+
case position
|
117
|
+
when :top_left, :topleft
|
118
|
+
position = SugarCube::CoreGraphics::Point(min_x, min_y)
|
119
|
+
when :top
|
120
|
+
position = SugarCube::CoreGraphics::Point(mid_x, min_y)
|
121
|
+
when :top_right, :topright
|
122
|
+
position = SugarCube::CoreGraphics::Point(max_x, min_y)
|
123
|
+
when :left
|
124
|
+
position = SugarCube::CoreGraphics::Point(min_x, mid_x)
|
125
|
+
when :center
|
126
|
+
position = SugarCube::CoreGraphics::Point(mid_x, mid_x)
|
127
|
+
when :right
|
128
|
+
position = SugarCube::CoreGraphics::Point(max_x, mid_x)
|
129
|
+
when :bottom_left, :bottomleft
|
130
|
+
position = SugarCube::CoreGraphics::Point(min_x, max_y)
|
131
|
+
when :bottom
|
132
|
+
position = SugarCube::CoreGraphics::Point(mid_x, max_y)
|
133
|
+
when :bottom_right, :bottomright
|
134
|
+
position = SugarCube::CoreGraphics::Point(max_x, max_y)
|
135
|
+
else
|
136
|
+
raise "Unknown position #{position.inspect}"
|
137
|
+
end
|
138
|
+
else
|
139
|
+
position = SugarCube::CoreGraphics::Point(position)
|
140
|
+
end
|
141
|
+
thumbnail_x = position.x * (new_size.width - my_size.width) / my_size.width
|
142
|
+
thumbnail_y = position.y * (new_size.height - my_size.height) / my_size.height
|
143
|
+
|
144
|
+
UIGraphicsBeginImageContextWithOptions(new_size, false, self.scale)
|
145
|
+
thumbnail_rect = CGRectZero
|
146
|
+
thumbnail_rect.origin = [thumbnail_x, thumbnail_y]
|
147
|
+
thumbnail_rect.size = my_size
|
148
|
+
|
149
|
+
self.drawInRect(thumbnail_rect)
|
150
|
+
|
151
|
+
new_image = UIGraphicsGetImageFromCurrentImageContext()
|
152
|
+
UIGraphicsEndImageContext()
|
153
|
+
|
154
|
+
raise "could not scale image" unless new_image
|
155
|
+
|
156
|
+
return new_image
|
157
|
+
end
|
158
|
+
|
159
|
+
# This method is similar to `scale_to`, except it doesn't pad the image, it
|
160
|
+
# just scales the image so that it will fit inside the new bounds.
|
161
|
+
def scale_within(new_size)
|
162
|
+
target_size = SugarCube::CoreGraphics::Size(new_size)
|
163
|
+
image_size = self.size
|
164
|
+
|
165
|
+
if CGSizeEqualToSize(target_size, self.size)
|
166
|
+
return self
|
167
|
+
end
|
168
|
+
|
169
|
+
width = image_size.width
|
170
|
+
height = image_size.height
|
171
|
+
|
172
|
+
target_width = target_size.width
|
173
|
+
target_height = target_size.height
|
174
|
+
|
175
|
+
width_factor = target_width / width
|
176
|
+
height_factor = target_height / height
|
177
|
+
|
178
|
+
if width_factor < height_factor
|
179
|
+
scale_factor = width_factor
|
180
|
+
else
|
181
|
+
scale_factor = height_factor
|
182
|
+
end
|
183
|
+
|
184
|
+
if scale_factor == 1
|
185
|
+
return self
|
186
|
+
end
|
187
|
+
|
188
|
+
scaled_size = CGSize.new(width * scale_factor, height * scale_factor)
|
189
|
+
return scale_to(scaled_size)
|
190
|
+
end
|
191
|
+
|
192
|
+
# Delegates to scale_to(background:), specifying background color of `nil`
|
39
193
|
def scale_to(new_size)
|
194
|
+
scale_to(new_size, background:nil)
|
195
|
+
end
|
196
|
+
|
197
|
+
# Scales an image to fit within the given size. Its current aspect ratio is
|
198
|
+
# maintained, but the image is padded so that it fills the entire area. If the
|
199
|
+
# image is too small, it will be scaled up to fit. If you specify a
|
200
|
+
# background that color will be used, otherwise the background will be
|
201
|
+
# transparent.
|
202
|
+
#
|
203
|
+
# @param new_size [CGSize] Maximum dimensions of desired image. The returned image is
|
204
|
+
# guaranteed to fit within these dimensions.
|
205
|
+
# @param background [UIColor] Color to fill padded areas. Default is transparent.
|
206
|
+
# @return [UIImage]
|
207
|
+
def scale_to(new_size, background:background)
|
40
208
|
new_size = SugarCube::CoreGraphics::Size(new_size)
|
41
209
|
|
42
|
-
|
43
|
-
|
210
|
+
image_size = self.size
|
211
|
+
|
212
|
+
if CGSizeEqualToSize(image_size, new_size)
|
213
|
+
return self
|
214
|
+
end
|
44
215
|
|
45
|
-
|
216
|
+
new_image = nil
|
46
217
|
width = image_size.width
|
47
218
|
height = image_size.height
|
48
219
|
|
@@ -54,39 +225,44 @@ class UIImage
|
|
54
225
|
scaled_height = target_height
|
55
226
|
|
56
227
|
thumbnail_point = CGPoint.new(0.0, 0.0)
|
228
|
+
width_factor = target_width / width
|
229
|
+
height_factor = target_height / height
|
57
230
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
scale_factor = width_factor
|
64
|
-
else
|
65
|
-
scale_factor = heightFactor
|
66
|
-
end
|
231
|
+
if width_factor < height_factor
|
232
|
+
scale_factor = width_factor
|
233
|
+
else
|
234
|
+
scale_factor = height_factor
|
235
|
+
end
|
67
236
|
|
68
|
-
|
69
|
-
|
237
|
+
scaled_width = width * scale_factor
|
238
|
+
scaled_height = height * scale_factor
|
70
239
|
|
71
|
-
|
240
|
+
# center the image
|
72
241
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
242
|
+
if width_factor < height_factor
|
243
|
+
thumbnail_point.y = (target_height - scaled_height) * 0.5
|
244
|
+
elsif width_factor > height_factor
|
245
|
+
thumbnail_point.x = (target_width - scaled_width) * 0.5
|
78
246
|
end
|
79
247
|
|
80
248
|
# this is actually the interesting part:
|
81
249
|
|
82
|
-
|
250
|
+
UIGraphicsBeginImageContextWithOptions(new_size, false, self.scale)
|
251
|
+
|
252
|
+
if background
|
253
|
+
background = background.uicolor
|
254
|
+
context = UIGraphicsGetCurrentContext()
|
255
|
+
background.setFill
|
256
|
+
CGContextAddRect(context, [[0, 0], new_size])
|
257
|
+
CGContextDrawPath(context, KCGPathFill)
|
258
|
+
end
|
83
259
|
|
84
260
|
thumbnail_rect = CGRectZero
|
85
261
|
thumbnail_rect.origin = thumbnail_point
|
86
262
|
thumbnail_rect.size.width = scaled_width
|
87
263
|
thumbnail_rect.size.height = scaled_height
|
88
264
|
|
89
|
-
|
265
|
+
self.drawInRect(thumbnail_rect)
|
90
266
|
|
91
267
|
new_image = UIGraphicsGetImageFromCurrentImageContext()
|
92
268
|
UIGraphicsEndImageContext()
|
@@ -96,8 +272,11 @@ class UIImage
|
|
96
272
|
return new_image
|
97
273
|
end
|
98
274
|
|
275
|
+
##|
|
276
|
+
##| image modifications
|
277
|
+
##|
|
99
278
|
def rounded(corner_radius=5)
|
100
|
-
|
279
|
+
UIGraphicsBeginImageContextWithOptions(size, false, self.scale)
|
101
280
|
path = UIBezierPath.bezierPathWithRoundedRect([[0, 0], size], cornerRadius:corner_radius)
|
102
281
|
path.addClip
|
103
282
|
self.drawInRect([[0, 0], size])
|
@@ -128,7 +307,7 @@ class UIImage
|
|
128
307
|
|
129
308
|
context = CIContext.contextWithOptions(nil)
|
130
309
|
cg_output_image = context.createCGImage(output, fromRect:output.extent)
|
131
|
-
output_image = UIImage.imageWithCGImage(cg_output_image)
|
310
|
+
output_image = UIImage.imageWithCGImage(cg_output_image, scale:self.scale, orientation:self.imageOrientation)
|
132
311
|
|
133
312
|
return output_image
|
134
313
|
end
|
@@ -156,7 +335,7 @@ class UIImage
|
|
156
335
|
new_size = self.size
|
157
336
|
|
158
337
|
# Create the bitmap context
|
159
|
-
|
338
|
+
UIGraphicsBeginImageContextWithOptions(new_size, false, self.scale)
|
160
339
|
bitmap = UIGraphicsGetCurrentContext()
|
161
340
|
|
162
341
|
# Move the origin to the middle of the image so we will rotate and scale around the center.
|
@@ -200,9 +379,11 @@ class UIImage
|
|
200
379
|
##|
|
201
380
|
##| CGImageCreateWithMask
|
202
381
|
##|
|
203
|
-
|
204
|
-
|
205
|
-
|
382
|
+
# The mask image cannot have ANY transparency. Instead, transparent areas must
|
383
|
+
# be white or some value between black and white. The more white a pixel is
|
384
|
+
# the more transparent it becomes.
|
385
|
+
# black .. white
|
386
|
+
# opaque .. transparent
|
206
387
|
def masked(mask_image)
|
207
388
|
mask_image = mask_image.CGImage
|
208
389
|
|
@@ -217,7 +398,58 @@ class UIImage
|
|
217
398
|
pixel_bits, row_bytes, data_provider,nil, false)
|
218
399
|
|
219
400
|
masked = CGImageCreateWithMask(self.CGImage, mask)
|
220
|
-
UIImage.imageWithCGImage(masked)
|
401
|
+
UIImage.imageWithCGImage(masked, scale:self.scale, orientation:self.imageOrientation)
|
402
|
+
end
|
403
|
+
|
404
|
+
# Oddly enough, this method doesn't seem to have retina support
|
405
|
+
def color_at(point)
|
406
|
+
point = SugarCube::CoreGraphics::Point(point)
|
407
|
+
point.x *= self.scale
|
408
|
+
point.y *= self.scale
|
409
|
+
|
410
|
+
# First get the image into your data buffer
|
411
|
+
cgimage = self.CGImage
|
412
|
+
width = CGImageGetWidth(cgimage)
|
413
|
+
height = CGImageGetHeight(cgimage)
|
414
|
+
bytes_per_pixel = 4
|
415
|
+
bits_per_component = 8
|
416
|
+
bytes_per_row = bytes_per_pixel * width
|
417
|
+
@raw_data || begin
|
418
|
+
color_space = CGColorSpaceCreateDeviceRGB()
|
419
|
+
@raw_data = Pointer.new(:uchar, height * width * 4)
|
420
|
+
context = CGBitmapContextCreate(@raw_data, width, height, bits_per_component, bytes_per_row, color_space, KCGImageAlphaPremultipliedLast | KCGBitmapByteOrder32Big)
|
421
|
+
|
422
|
+
CGContextDrawImage(context, CGRectMake(0, 0, width, height), cgimage)
|
423
|
+
end
|
424
|
+
|
425
|
+
# Now @raw_data contains the image data in the RGBA8888 pixel format.
|
426
|
+
xx = point.x.round
|
427
|
+
yy = point.y.round
|
428
|
+
byte_index = (bytes_per_row * yy) + xx * bytes_per_pixel
|
429
|
+
red = @raw_data[byte_index]
|
430
|
+
green = @raw_data[byte_index + 1]
|
431
|
+
blue = @raw_data[byte_index + 2]
|
432
|
+
alpha = @raw_data[byte_index + 3]
|
433
|
+
return [red, green, blue].uicolor(alpha / 255.0)
|
434
|
+
end
|
435
|
+
|
436
|
+
def at_scale(scale)
|
437
|
+
if scale == self.scale
|
438
|
+
return self
|
439
|
+
end
|
440
|
+
|
441
|
+
new_size = self.size
|
442
|
+
new_size.width = new_size.width * self.scale / scale
|
443
|
+
new_size.height = new_size.height * self.scale / scale
|
444
|
+
|
445
|
+
UIGraphicsBeginImageContextWithOptions(new_size, false, scale)
|
446
|
+
thumbnail_rect = CGRect.new([0, 0], new_size)
|
447
|
+
|
448
|
+
self.drawInRect(thumbnail_rect)
|
449
|
+
|
450
|
+
new_image = UIGraphicsGetImageFromCurrentImageContext()
|
451
|
+
UIGraphicsEndImageContext()
|
452
|
+
return new_image
|
221
453
|
end
|
222
454
|
|
223
455
|
end
|
data/lib/sugarcube/uiview.rb
CHANGED
@@ -182,10 +182,23 @@ class UIView
|
|
182
182
|
f = self.frame
|
183
183
|
delta = SugarCube::CoreGraphics::Point(delta)
|
184
184
|
position = SugarCube::CoreGraphics::Point(f.origin)
|
185
|
-
|
185
|
+
to_position = CGPoint.new(position.x + delta.x, position.y + delta.y)
|
186
|
+
move_to(to_position, options, &after)
|
186
187
|
self
|
187
188
|
end
|
188
189
|
|
190
|
+
def rotate_to(options={}, &after)
|
191
|
+
if options.is_a? Numeric
|
192
|
+
options = { angle: options }
|
193
|
+
end
|
194
|
+
|
195
|
+
options[:after] ||= after
|
196
|
+
|
197
|
+
animate(options) {
|
198
|
+
self.transform = CGAffineTransformMakeRotation(options[:angle])
|
199
|
+
}
|
200
|
+
end
|
201
|
+
|
189
202
|
def slide(direction, options={}, &after)
|
190
203
|
if options.is_a? Numeric
|
191
204
|
options = {size: options}
|
data/lib/sugarcube/version.rb
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
class UIImage
|
2
|
+
class << self
|
3
|
+
SugarCube568_TallSuffix = '-568h@2x'
|
4
|
+
|
5
|
+
def imageNamed568(name)
|
6
|
+
@may_use_taller_images ||= CGSizeEqualToSize(CGSizeMake(320, 568), UIScreen.mainScreen.bounds.size)
|
7
|
+
if ( @may_use_taller_images && name.length > 0 && name.rangeOfString(SugarCube568_TallSuffix).location == NSNotFound )
|
8
|
+
# Check if is there a path extension or not
|
9
|
+
test_name = name;
|
10
|
+
if test_name.pathExtension.length > 0
|
11
|
+
test_name = test_name.stringByDeletingPathExtension.stringByAppendingString(SugarCube568_TallSuffix).stringByAppendingPathExtension(name.pathExtension)
|
12
|
+
else
|
13
|
+
test_name = test_name.stringByAppendingString(SugarCube568_TallSuffix + ".png")
|
14
|
+
end
|
15
|
+
|
16
|
+
image = imageNamed_old(test_name)
|
17
|
+
if image
|
18
|
+
return self.imageWithCGImage(image.CGImage, scale:2.0, orientation:image.imageOrientation)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
return nil
|
23
|
+
end
|
24
|
+
|
25
|
+
alias :imageNamed_old :imageNamed
|
26
|
+
# now we've got imageNamed568 and imageNamed_old to load the respective versions
|
27
|
+
|
28
|
+
def imageNamed(name)
|
29
|
+
imageNamed568(name) || imageNamed_old(name)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
unless defined?(Motion::Project::Config)
|
2
|
+
raise "The sugarcube gem must be required within a RubyMotion project Rakefile."
|
3
|
+
end
|
4
|
+
|
5
|
+
|
6
|
+
Motion::Project::App.setup do |app|
|
7
|
+
# scans app.files until it finds app/ (the default)
|
8
|
+
# if found, it inserts just before those files, otherwise it will insert to
|
9
|
+
# the end of the list
|
10
|
+
insert_point = 0
|
11
|
+
app.files.each_index do |index|
|
12
|
+
file = app.files[index]
|
13
|
+
if file =~ /^(?:\.\/)?app\//
|
14
|
+
# found app/, so stop looking
|
15
|
+
break
|
16
|
+
end
|
17
|
+
insert_point = index + 1
|
18
|
+
end
|
19
|
+
|
20
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'sugarcube-568/**/*.rb')).reverse.each do |file|
|
21
|
+
app.files.insert(insert_point, file)
|
22
|
+
end
|
23
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/resources/tall.png
ADDED
Binary file
|
Binary file
|
data/spec/568_spec.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
describe "CoreLocation" do
|
2
|
+
before do
|
3
|
+
@denver = CLLocationCoordinate2D.new(39.764032, -104.963112)
|
4
|
+
@cincinnati = CLLocationCoordinate2D.new(39.267024, -84.251736)
|
5
|
+
end
|
6
|
+
|
7
|
+
it "should calculate distance in miles" do
|
8
|
+
@denver.distance_to(@cincinnati).miles.round.should == 1101
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should calculate distance in kilometers" do
|
12
|
+
@denver.distance_to(@cincinnati).kilometers.round.should == 1772
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/spec/symbol_uicolor_spec.rb
CHANGED
@@ -1,10 +1,24 @@
|
|
1
1
|
describe 'Symbol#uicolor' do
|
2
2
|
|
3
3
|
it "should return css color names" do
|
4
|
+
except_for = [:aqua, :fuchsia, :lime]
|
4
5
|
Symbol.css_colors.each do |name, val|
|
6
|
+
next if except_for.include? name
|
7
|
+
|
5
8
|
color = val.uicolor
|
6
9
|
color.to_s.should == "UIColor.color(#{name.inspect})"
|
7
10
|
end
|
8
11
|
end
|
9
12
|
|
13
|
+
it "should return UIColor objects" do
|
14
|
+
Symbol.uicolors.each do |name, method|
|
15
|
+
name.uicolor.should == UIColor.send(method)
|
16
|
+
end
|
17
|
+
Symbol.css_colors.each do |name, val|
|
18
|
+
name.uicolor.is_a?(UIColor).should == true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
|
10
24
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
describe "UIColor component methods" do
|
2
|
+
before do
|
3
|
+
@black = UIColor.blackColor
|
4
|
+
@gray = UIColor.grayColor
|
5
|
+
@white = UIColor.whiteColor
|
6
|
+
@some_color = UIColor.colorWithRed(0.6, green: 0.4, blue: 0.5, alpha:1.0)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should return 1,1,1 for white" do
|
10
|
+
@white.red.should == 1
|
11
|
+
@white.green.should == 1
|
12
|
+
@white.blue.should == 1
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return 0,0,0 for black" do
|
16
|
+
@black.red.should == 0
|
17
|
+
@black.green.should == 0
|
18
|
+
@black.blue.should == 0
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return 0.5,0.5,0.5 for gray" do
|
22
|
+
@gray.red.should == 0.5
|
23
|
+
@gray.green.should == 0.5
|
24
|
+
@gray.blue.should == 0.5
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return correct rgb for some_color" do
|
28
|
+
@some_color.red.should == 0.6
|
29
|
+
@some_color.green.should == 0.4
|
30
|
+
@some_color.blue.should == 0.5
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
describe "UIImage#color_at" do
|
2
|
+
before do
|
3
|
+
@image = 'little_square'.uiimage
|
4
|
+
end
|
5
|
+
|
6
|
+
describe "should return white at the corners" do
|
7
|
+
it "top_left" do
|
8
|
+
color = @image.color_at([0, 0])
|
9
|
+
color.red.should == 1
|
10
|
+
color.green.should == 1
|
11
|
+
color.blue.should == 1
|
12
|
+
end
|
13
|
+
it "top_right" do
|
14
|
+
color = @image.color_at([9, 0])
|
15
|
+
color.red.should == 1
|
16
|
+
color.green.should == 1
|
17
|
+
color.blue.should == 1
|
18
|
+
end
|
19
|
+
it "bottom_left" do
|
20
|
+
color = @image.color_at([0, 9])
|
21
|
+
color.red.should == 1
|
22
|
+
color.green.should == 1
|
23
|
+
color.blue.should == 1
|
24
|
+
end
|
25
|
+
it "bottom_right" do
|
26
|
+
color = @image.color_at([9, 9])
|
27
|
+
color.red.should == 1
|
28
|
+
color.green.should == 1
|
29
|
+
color.blue.should == 1
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "should return blue at the center" do
|
34
|
+
it "3,3" do
|
35
|
+
color = @image.color_at([3, 3])
|
36
|
+
color.red.should == 0
|
37
|
+
color.green.should == 0
|
38
|
+
color.blue.should == 1
|
39
|
+
end
|
40
|
+
it "4,4" do
|
41
|
+
color = @image.color_at([4, 4])
|
42
|
+
color.red.should == 0
|
43
|
+
color.green.should == 0
|
44
|
+
color.blue.should == 1
|
45
|
+
end
|
46
|
+
it "5,5" do
|
47
|
+
color = @image.color_at([5, 5])
|
48
|
+
color.red.should == 0
|
49
|
+
color.green.should == 0
|
50
|
+
color.blue.should == 1
|
51
|
+
end
|
52
|
+
it "6,6" do
|
53
|
+
color = @image.color_at([6, 6])
|
54
|
+
color.red.should == 0
|
55
|
+
color.green.should == 0
|
56
|
+
color.blue.should == 1
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
describe "UIImage scale methods" do
|
2
|
+
before do
|
3
|
+
@image = 'little_square'.uiimage
|
4
|
+
end
|
5
|
+
|
6
|
+
it 'should scale_to a wider size' do
|
7
|
+
scaled = @image.scale_to([20, 10])
|
8
|
+
scaled.nsdata.writeToFile('scale_to.png'.document, atomically: true)
|
9
|
+
scaled.size.width.should == 20
|
10
|
+
scaled.size.height.should == 10
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should scale_to a taller size' do
|
14
|
+
scaled = @image.scale_to([10, 20])
|
15
|
+
scaled.nsdata.writeToFile('scale_to.png'.document, atomically: true)
|
16
|
+
scaled.size.width.should == 10
|
17
|
+
scaled.size.height.should == 20
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'scale_to should support background' do
|
21
|
+
scaled = @image.scale_to([20, 10], background: :blue.uicolor)
|
22
|
+
scaled.nsdata.writeToFile('scale_to_background.png'.document, atomically: true)
|
23
|
+
scaled.size.width.should == 20
|
24
|
+
scaled.size.height.should == 10
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should scale_within a smaller size' do
|
28
|
+
scaled = @image.scale_within([5, 10])
|
29
|
+
scaled.nsdata.writeToFile('scale_within_smaller.png'.document, atomically: true)
|
30
|
+
scaled.size.width.should == 5
|
31
|
+
scaled.size.height.should == 5
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should scale_within a bigger size' do
|
35
|
+
scaled = @image.scale_within([15, 20])
|
36
|
+
scaled.nsdata.writeToFile('scale_within_bigger.png'.document, atomically: true)
|
37
|
+
scaled.size.width.should == 15
|
38
|
+
scaled.size.height.should == 15
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should scale_to_fill a wider size' do
|
42
|
+
scaled = @image.scale_to_fill([20, 10])
|
43
|
+
scaled.nsdata.writeToFile('scale_to_fill.png'.document, atomically: true)
|
44
|
+
scaled.size.width.should == 20
|
45
|
+
scaled.size.height.should == 10
|
46
|
+
scaled.scale.should == @image.scale
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'scale_to_fill should support position' do
|
50
|
+
scaled = @image.scale_to_fill([10, 20], position: :top_left)
|
51
|
+
scaled.nsdata.writeToFile('scale_to_fill_position_top_left.png'.document, atomically: true)
|
52
|
+
scaled = @image.scale_to_fill([20, 10], position: :top)
|
53
|
+
scaled.nsdata.writeToFile('scale_to_fill_position_top.png'.document, atomically: true)
|
54
|
+
scaled = @image.scale_to_fill([10, 20], position: :top_right)
|
55
|
+
scaled.nsdata.writeToFile('scale_to_fill_position_top_right.png'.document, atomically: true)
|
56
|
+
scaled = @image.scale_to_fill([10, 20], position: :left)
|
57
|
+
scaled.nsdata.writeToFile('scale_to_fill_position_left.png'.document, atomically: true)
|
58
|
+
scaled = @image.scale_to_fill([20, 10], position: :center)
|
59
|
+
scaled.nsdata.writeToFile('scale_to_fill_position_center.png'.document, atomically: true)
|
60
|
+
scaled = @image.scale_to_fill([10, 20], position: :right)
|
61
|
+
scaled.nsdata.writeToFile('scale_to_fill_position_right.png'.document, atomically: true)
|
62
|
+
scaled = @image.scale_to_fill([10, 20], position: :bottom_left)
|
63
|
+
scaled.nsdata.writeToFile('scale_to_fill_position_bottom_left.png'.document, atomically: true)
|
64
|
+
scaled = @image.scale_to_fill([20, 10], position: :bottom)
|
65
|
+
scaled.nsdata.writeToFile('scale_to_fill_position_bottom.png'.document, atomically: true)
|
66
|
+
scaled = @image.scale_to_fill([10, 20], position: :bottom_right)
|
67
|
+
scaled.nsdata.writeToFile('scale_to_fill_position_bottom_right.png'.document, atomically: true)
|
68
|
+
scaled.size.width.should == 10
|
69
|
+
scaled.size.height.should == 20
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should be able to change scale' do
|
73
|
+
if UIScreen.mainScreen.scale == 2
|
74
|
+
scaled = @image.at_scale(1.0)
|
75
|
+
scaled.nsdata.writeToFile('at_scale.png'.document, atomically: true)
|
76
|
+
|
77
|
+
scaled.size.width.should == 20
|
78
|
+
scaled.size.height.should == 20
|
79
|
+
scaled.scale.should == 1
|
80
|
+
else
|
81
|
+
scaled = @image.at_scale(2.0)
|
82
|
+
scaled.nsdata.writeToFile('at_scale.png'.document, atomically: true)
|
83
|
+
|
84
|
+
scaled.size.width.should == 5
|
85
|
+
scaled.size.height.should == 5
|
86
|
+
scaled.scale.should == 2
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
describe "UIView animation methods" do
|
2
|
+
before do
|
3
|
+
@view = UIView.alloc.initWithFrame([[1,2],[3,4]])
|
4
|
+
end
|
5
|
+
|
6
|
+
it 'should delta_to x:1 y:2' do
|
7
|
+
@view.delta_to([1,2]).frame.should == CGRectMake(2,4,3,4)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should rotate 45 degrees' do
|
11
|
+
angle = 45*Math::PI/180
|
12
|
+
@view.rotate_to(angle)
|
13
|
+
current_angle = Math.atan2(@view.transform.b, @view.transform.a)
|
14
|
+
current_angle.should == angle
|
15
|
+
end
|
16
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sugarcube
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2013-01-
|
16
|
+
date: 2013-01-29 00:00:00.000000000 Z
|
17
17
|
dependencies: []
|
18
18
|
description: ! '== Description
|
19
19
|
|
@@ -48,6 +48,8 @@ files:
|
|
48
48
|
- README.md
|
49
49
|
- Rakefile
|
50
50
|
- app/app_delegate.rb
|
51
|
+
- lib/sugarcube-568.rb
|
52
|
+
- lib/sugarcube-568/uiimage.rb
|
51
53
|
- lib/sugarcube-gestures.rb
|
52
54
|
- lib/sugarcube-gestures/gestures.rb
|
53
55
|
- lib/sugarcube.rb
|
@@ -103,9 +105,24 @@ files:
|
|
103
105
|
- lib/sugarcube/uiviewcontroller.rb
|
104
106
|
- lib/sugarcube/uuid.rb
|
105
107
|
- lib/sugarcube/version.rb
|
108
|
+
- resources/Default-568h@2x.png
|
109
|
+
- resources/Default.png
|
110
|
+
- resources/Default@2x.png
|
111
|
+
- resources/little_square.png
|
112
|
+
- resources/little_square@2x.png
|
113
|
+
- resources/tall-568h@2x.png
|
114
|
+
- resources/tall.png
|
115
|
+
- resources/tall@2x.png
|
116
|
+
- spec/568_spec.rb
|
117
|
+
- spec/calayer_spec.rb
|
106
118
|
- spec/core_graphics_spec.rb
|
119
|
+
- spec/core_location_spec.rb
|
107
120
|
- spec/nsstring_files_spec.rb
|
108
121
|
- spec/symbol_uicolor_spec.rb
|
122
|
+
- spec/uicolor_components_spec.rb
|
123
|
+
- spec/uiimage_color_at_spec.rb
|
124
|
+
- spec/uiimage_scale_spec.rb
|
125
|
+
- spec/uiview_animation_spec.rb
|
109
126
|
- sugarcube.gemspec
|
110
127
|
homepage: https://github.com/rubymotion/sugarcube
|
111
128
|
licenses: []
|
@@ -133,7 +150,14 @@ specification_version: 3
|
|
133
150
|
summary: Extensions for Ruby to make Rubymotion development more enjoyable, and hopefully
|
134
151
|
more rubyesque!
|
135
152
|
test_files:
|
153
|
+
- spec/568_spec.rb
|
154
|
+
- spec/calayer_spec.rb
|
136
155
|
- spec/core_graphics_spec.rb
|
156
|
+
- spec/core_location_spec.rb
|
137
157
|
- spec/nsstring_files_spec.rb
|
138
158
|
- spec/symbol_uicolor_spec.rb
|
159
|
+
- spec/uicolor_components_spec.rb
|
160
|
+
- spec/uiimage_color_at_spec.rb
|
161
|
+
- spec/uiimage_scale_spec.rb
|
162
|
+
- spec/uiview_animation_spec.rb
|
139
163
|
has_rdoc:
|