sugarcube 0.14.0 → 0.15.0
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.
- 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:
|