purplish-red 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +6 -0
- data/lib/purplish-red.rb +9 -0
- data/lib/purplish-red/non-ui/ns_data.rb +5 -0
- data/lib/purplish-red/non-ui/ns_date.rb +66 -0
- data/lib/purplish-red/non-ui/ns_string.rb +39 -0
- data/lib/purplish-red/non-ui/ui_color.rb +57 -0
- data/lib/purplish-red/non-ui/ui_device.rb +5 -0
- data/lib/purplish-red/non-ui/ui_image.rb +236 -0
- data/lib/purplish-red/symbol.rb +5 -0
- data/lib/purplish-red/ui/mf_mail_compose_view_controller.rb +27 -0
- data/lib/purplish-red/ui/ui_view.rb +182 -0
- data/lib/purplish-red/version.rb +3 -0
- data/purplish-red.gemspec +19 -0
- metadata +56 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
Y2M5ODc1ZWEzODkyMGQwOThkNDM3M2IxZTNmOTIzZjgzY2JjMjIzYw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YWZkODM2NDI0NjMyZjU4MmY3NTg0MDgzNjdmYzg2YmFhZjRhZmJjMA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
Y2IwZjg0YjJkYTk4MDQ5OTUyZDkzOWVkYWQ0NTgwZDMyY2EwYjI2NmNlYzNj
|
10
|
+
ZTZiMTlhYzYxODE0NmYxMzJlMjIyMzIxMzBmN2YyZTdkMjk0ZjgwZGJkNzA4
|
11
|
+
ODY4ODM3MmU2NTA4Nzg0M2Q3MTA3MTdiYzVjMzhmYzY0ZjlkMGU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NjFhOTQyNGFhN2I3ZjIyYzg2YmY3NzI4Njg5MGQ0NmQ0M2MwZDczYTNmMDg5
|
14
|
+
N2ExZjI1MjdhMDVhMGZkNDZiOGFkMjQ2ZDg0MGRmODljZTY4MDlhOTAzZGNh
|
15
|
+
MDE0MzU0NmU5ZmUxN2U1NmNiZGMxNTVjOTI1ZjdkOTI1ZjUyZDY=
|
data/.gitignore
ADDED
data/lib/purplish-red.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
unless defined?(Motion::Project::Config)
|
2
|
+
raise "This file must be required within a RubyMotion project Rakefile."
|
3
|
+
end
|
4
|
+
|
5
|
+
Motion::Project::App.setup do |app|
|
6
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'purplish-red/**/*.rb')).each do |file|
|
7
|
+
app.files.unshift(file)
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#Mostly copied from MOCommon
|
2
|
+
|
3
|
+
class NSDate
|
4
|
+
def self.from_day_month_year(d, m, y)
|
5
|
+
dc = NSDateComponents.new
|
6
|
+
dc.day = d
|
7
|
+
dc.month = m
|
8
|
+
dc.year = y
|
9
|
+
NSCalendar.currentCalendar.dateFromComponents(dc)
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
def self.is_leap_year?(year)
|
14
|
+
return false if year % 4 != 0
|
15
|
+
return true if year % 100 != 0
|
16
|
+
return year % 400 == 0
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
#month is 1-12 representing Jan-Dec
|
21
|
+
def self.days_in_month(month, year:year)
|
22
|
+
case month
|
23
|
+
when 1, 3, 5, 7, 8, 10, 12
|
24
|
+
return 31
|
25
|
+
when 4, 6, 9, 11
|
26
|
+
return 30
|
27
|
+
when 2
|
28
|
+
return is_leap_year(year)? 29: 28
|
29
|
+
else
|
30
|
+
#NSAssert(NO, @" Invalid month %d", month)
|
31
|
+
return 0
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def yesterday_exactly
|
37
|
+
self.dateByAddingTimeInterval(-60*60*24)
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
#0h, 0m, 0s
|
42
|
+
def yesterday
|
43
|
+
d_m_y = yesterday_exactly.day_month_year
|
44
|
+
NSDate.from_day_month_year(d_m_y[0], d_m_y[1], d_m_y[2])
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def day_month_year
|
49
|
+
components = NSCalendar.currentCalendar.components(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit, fromDate:self)
|
50
|
+
[components.day, components.month, components.year]
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def hour_minute_second
|
55
|
+
components = NSCalendar.currentCalendar.components(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit, fromDate:self)
|
56
|
+
[components.hour, components.minute, components.second]
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def year_month_day_s
|
61
|
+
s = self.day_month_year
|
62
|
+
'%.4d%.2d%.2d' % [s[2], s[1], s[0]]
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class NSString
|
2
|
+
def to_img
|
3
|
+
UIImage.imageNamed(self)
|
4
|
+
end
|
5
|
+
|
6
|
+
|
7
|
+
def to_imgt
|
8
|
+
UIImage.imageNamed(self).imageWithRenderingMode(UIImageRenderingModeAlwaysTemplate)
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
def to_btn_template_rendering_mode(template_or_not)
|
13
|
+
if template_or_not
|
14
|
+
img = self.to_imgt
|
15
|
+
else
|
16
|
+
img = self.to_img
|
17
|
+
end
|
18
|
+
b = UIButton.buttonWithType(UIButtonTypeCustom)
|
19
|
+
b.frame = [[0,0], [img.size.width, img.size.height]]
|
20
|
+
b.setImage(img, forState:UIControlStateNormal)
|
21
|
+
|
22
|
+
b
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def to_btn
|
27
|
+
self.to_btn_template_rendering_mode(false)
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def to_btnt
|
32
|
+
self.to_btn_template_rendering_mode(true)
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def is_digits_only?
|
37
|
+
self.split('').detect {|e| e < '0' || e > '9'}.nil?
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class UIColor
|
2
|
+
def grayscale_colorspace?
|
3
|
+
CGColorGetNumberOfComponents(self.CGColor) == 2
|
4
|
+
end
|
5
|
+
|
6
|
+
|
7
|
+
def components
|
8
|
+
if grayscale_colorspace?
|
9
|
+
white = Pointer.new(:float)
|
10
|
+
alpha = Pointer.new(:float)
|
11
|
+
self.getWhite(white, alpha:alpha)
|
12
|
+
[white[0], alpha[0]]
|
13
|
+
else
|
14
|
+
red = Pointer.new(:float)
|
15
|
+
green = Pointer.new(:float)
|
16
|
+
blue = Pointer.new(:float)
|
17
|
+
alpha = Pointer.new(:float)
|
18
|
+
self.getRed(red, green:green, blue:blue, alpha:alpha)
|
19
|
+
[red[0], green[0], blue[0], alpha[0]]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def red
|
25
|
+
(components[0]*255).round
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def green
|
30
|
+
(components[1]*255).round
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def blue
|
35
|
+
(components[2]*255).round
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def alpha
|
40
|
+
if grayscale_colorspace?
|
41
|
+
components[1]
|
42
|
+
else
|
43
|
+
components[3]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def white
|
49
|
+
components[0]
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
def color_with_alpha(a)
|
54
|
+
comps = components
|
55
|
+
UIColor.alloc.initWithRed(comps[0], green:comps[1], blue:comps[2], alpha:a)
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,236 @@
|
|
1
|
+
#Stuff I copied from MOCommon, some new
|
2
|
+
class UIImage
|
3
|
+
M_PI = 3.14159265358979323846264338327950288
|
4
|
+
|
5
|
+
def self.size_at_path(s)
|
6
|
+
imageFileURL = NSURL.fileURLWithPath(s)
|
7
|
+
imageSource = CGImageSourceCreateWithURL(imageFileURL, nil)
|
8
|
+
if imageSource.nil?
|
9
|
+
#p "Error loading image"
|
10
|
+
else
|
11
|
+
imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, {KCGImageSourceShouldCache => false})
|
12
|
+
if imageProperties.nil?
|
13
|
+
#p "Failed to get properties for image"
|
14
|
+
else
|
15
|
+
return CGSizeMake(imageProperties[KCGImagePropertyPixelWidth], imageProperties[KCGImagePropertyPixelHeight])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
return CGSizeZero
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def to_btn
|
24
|
+
b = UIButton.buttonWithType(UIButtonTypeCustom)
|
25
|
+
b.setImage(self, forState:UIControlStateNormal)
|
26
|
+
b.frame = [[0, 0], [size.width, size.height]]
|
27
|
+
b
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_imgv
|
31
|
+
UIImageView.alloc.initWithImage(self)
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def width
|
36
|
+
size.width
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def height
|
41
|
+
size.height
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def scale_aspect_to_size(size)
|
46
|
+
scale_aspect_to_maximum_size(size)
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
def scale_to_size(size)
|
51
|
+
colorSpace = CGColorSpaceCreateDeviceRGB()
|
52
|
+
|
53
|
+
context = CGBitmapContextCreate(nil, size.width*scale, size.height*scale, 8, size.width*4*scale, colorSpace, KCGImageAlphaPremultipliedLast)
|
54
|
+
imageReference = self.CGImage
|
55
|
+
CGContextDrawImage(context, CGRectMake(0, 0, size.width*scale, size.height*scale), imageReference)
|
56
|
+
copy = CGBitmapContextCreateImage(context)
|
57
|
+
UIImage.imageWithCGImage(copy, scale:scale, orientation:imageOrientation)
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
#Preserve aspect ratio while scaling. E.g if aSize = (612,612), the longer side will be 612 and the shorter side will be at most 612
|
62
|
+
def scale_aspect_to_maximum_size(aSize)
|
63
|
+
if aSize.width/aSize.height > self.size.width/self.size.height
|
64
|
+
s = CGSize.new((aSize.height/size.height * size.width).to_i, aSize.height)
|
65
|
+
else
|
66
|
+
s = CGSize.new(aSize.width, (aSize.width/size.width * size.height).to_i)
|
67
|
+
end
|
68
|
+
|
69
|
+
scale_to_size(s)
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
#Preserve aspect ratio while scaling. E.g if aSize = (612,612), the shorter side will be 612 and the shorter side will be at least 612
|
74
|
+
def scale_aspect_to_minimum_size(aSize)
|
75
|
+
if aSize.width/aSize.height > self.size.width/self.size.height
|
76
|
+
s = CGSize.new(aSize.width, (aSize.width/size.width * size.height).to_i)
|
77
|
+
else
|
78
|
+
s = CGSize.new((aSize.height/size.height * size.width).to_i, aSize.height)
|
79
|
+
end
|
80
|
+
|
81
|
+
scale_to_size(s)
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
#Preserve aspect ratio while scaling to fill. Part of the content may be clipped
|
86
|
+
def scale_aspect_to_fill_size(aSize)
|
87
|
+
if aSize.width/aSize.height > size.width/size.height
|
88
|
+
croppedImg = image_by_cropping_to_center_size(CGSize.new(size.width, (size.width/aSize.width * aSize.height).to_i))
|
89
|
+
else
|
90
|
+
croppedImg = image_by_cropping_to_center_size(CGSize.new((size.height/aSize.height * aSize.width).to_i, size.height))
|
91
|
+
end
|
92
|
+
|
93
|
+
croppedImg.scale_to_size(aSize)
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
#aRect is assumed to be in the "same scale" as self
|
98
|
+
def image_by_cropping_to_rect(aRect)
|
99
|
+
if aRect.is_a? CGRect
|
100
|
+
cropped = CGImageCreateWithImageInRect(self.CGImage, [[aRect.origin.x*self.scale, aRect.origin.y*self.scale], [aRect.size.width*self.scale, aRect.size.height*self.scale]])
|
101
|
+
else
|
102
|
+
cropped = CGImageCreateWithImageInRect(self.CGImage, [[aRect[0][0]*self.scale, aRect[0][1]*self.scale], [aRect[1][0]*self.scale, aRect[1][1]*self.scale]])
|
103
|
+
end
|
104
|
+
UIImage.imageWithCGImage(cropped, scale:self.scale, orientation:self.imageOrientation)
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
def image_by_cropping_to_center_size(aSize)
|
109
|
+
if aSize.width/aSize.height > size.width/size.height
|
110
|
+
return image_by_cropping_to_rect(CGRect.new([0, (size.height-aSize.height)/2], [aSize.width, aSize.height]))
|
111
|
+
else
|
112
|
+
return image_by_cropping_to_rect(CGRect.new([(size.width-aSize.width)/2, 0], [aSize.width, aSize.height]))
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
def rotate_with_orientation(anOrientation)
|
118
|
+
#Front camera? We try to make fix it
|
119
|
+
if (size.width == 640 && size.height == 480) || (size.width == 480 && size.height == 640)
|
120
|
+
p 'Front camera photo'
|
121
|
+
if anOrientation == UIImageOrientationUp
|
122
|
+
#EXIF = 1
|
123
|
+
elsif anOrientation == UIImageOrientationDown
|
124
|
+
#EXIF = 3
|
125
|
+
anOrientation = UIImageOrientationLeftMirrored
|
126
|
+
elsif anOrientation == UIImageOrientationLeft
|
127
|
+
#EXIF = 6
|
128
|
+
elsif anOrientation == UIImageOrientationRight
|
129
|
+
#EXIF = 8
|
130
|
+
anOrientation = UIImageOrientationLeftMirrored
|
131
|
+
elsif anOrientation == UIImageOrientationUpMirrored
|
132
|
+
#EXIF = 2
|
133
|
+
elsif anOrientation == UIImageOrientationDownMirrored
|
134
|
+
#EXIF = 4
|
135
|
+
elsif anOrientation == UIImageOrientationLeftMirrored
|
136
|
+
#EXIF = 5
|
137
|
+
elsif UIImageOrientationRightMirrored
|
138
|
+
#EXIF = 7
|
139
|
+
anOrientation = UIImageOrientationRightMirrored
|
140
|
+
end
|
141
|
+
elsif
|
142
|
+
p 'Not front camera photo'
|
143
|
+
end
|
144
|
+
|
145
|
+
imgRef = self.CGImage
|
146
|
+
width = CGImageGetWidth(imgRef)
|
147
|
+
height = CGImageGetHeight(imgRef)
|
148
|
+
transform = CGAffineTransformIdentity
|
149
|
+
bounds = CGRect.new([0, 0], [width, height])
|
150
|
+
imageSize = CGSize.new(width, height)
|
151
|
+
|
152
|
+
if anOrientation == UIImageOrientationUp
|
153
|
+
#EXIF = 1
|
154
|
+
transform = CGAffineTransformIdentity
|
155
|
+
elsif anOrientation == UIImageOrientationUpMirrored
|
156
|
+
#EXIF = 2
|
157
|
+
transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0)
|
158
|
+
transform = CGAffineTransformScale(transform, -1.0, 1.0)
|
159
|
+
elsif anOrientation == UIImageOrientationDown
|
160
|
+
#EXIF = 3
|
161
|
+
transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height)
|
162
|
+
transform = CGAffineTransformRotate(transform, M_PI)
|
163
|
+
elsif anOrientation == UIImageOrientationDownMirrored
|
164
|
+
#EXIF = 4
|
165
|
+
transform = CGAffineTransformMakeTranslation(0.0, imageSize.height)
|
166
|
+
transform = CGAffineTransformScale(transform, 1.0, -1.0)
|
167
|
+
elsif anOrientation == UIImageOrientationLeftMirrored
|
168
|
+
#EXIF = 5
|
169
|
+
boundHeight = bounds.size.height
|
170
|
+
bounds.size.height = bounds.size.width
|
171
|
+
bounds.size.width = boundHeight
|
172
|
+
transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width)
|
173
|
+
transform = CGAffineTransformScale(transform, -1.0, 1.0)
|
174
|
+
transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0)
|
175
|
+
elsif anOrientation == UIImageOrientationLeft
|
176
|
+
#EXIF = 6
|
177
|
+
boundHeight = bounds.size.height
|
178
|
+
bounds.size.height = bounds.size.width
|
179
|
+
bounds.size.width = boundHeight
|
180
|
+
transform = CGAffineTransformMakeTranslation(0.0, imageSize.width)
|
181
|
+
transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0)
|
182
|
+
elsif anOrientation == UIImageOrientationRightMirrored
|
183
|
+
#EXIF = 7
|
184
|
+
boundHeight = bounds.size.height
|
185
|
+
bounds.size.height = bounds.size.width
|
186
|
+
bounds.size.width = boundHeight
|
187
|
+
transform = CGAffineTransformMakeScale(-1.0, 1.0)
|
188
|
+
transform = CGAffineTransformRotate(transform, M_PI / 2.0)
|
189
|
+
elsif anOrientation == UIImageOrientationRight
|
190
|
+
#EXIF = 8
|
191
|
+
boundHeight = bounds.size.height
|
192
|
+
bounds.size.height = bounds.size.width
|
193
|
+
bounds.size.width = boundHeight
|
194
|
+
transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0)
|
195
|
+
transform = CGAffineTransformRotate(transform, M_PI / 2.0)
|
196
|
+
end
|
197
|
+
|
198
|
+
UIGraphicsBeginImageContext(bounds.size)
|
199
|
+
context = UIGraphicsGetCurrentContext()
|
200
|
+
|
201
|
+
if anOrientation == UIImageOrientationRight || anOrientation == UIImageOrientationLeft
|
202
|
+
CGContextScaleCTM(context, -1, 1)
|
203
|
+
CGContextTranslateCTM(context, -height, 0)
|
204
|
+
elsif anOrientation == UIImageOrientationLeft || anOrientation == UIImageOrientationLeftMirrored || anOrientation == UIImageOrientationRightMirrored
|
205
|
+
CGContextScaleCTM(context, 1, -1)
|
206
|
+
CGContextTranslateCTM(context, 0, -width)
|
207
|
+
else
|
208
|
+
CGContextScaleCTM(context, 1, -1)
|
209
|
+
CGContextTranslateCTM(context, 0, -height)
|
210
|
+
end
|
211
|
+
|
212
|
+
CGContextConcatCTM(context, transform)
|
213
|
+
|
214
|
+
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRect.new([0, 0], [width, height]), imgRef)
|
215
|
+
imageCopy = UIGraphicsGetImageFromCurrentImageContext()
|
216
|
+
UIGraphicsEndImageContext()
|
217
|
+
|
218
|
+
imageCopy
|
219
|
+
end
|
220
|
+
|
221
|
+
|
222
|
+
def rotate_to_correct_orientation
|
223
|
+
rotate_with_orientation(imageOrientation)
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
def show_globally
|
228
|
+
btn = self.to_btn
|
229
|
+
btn.addTarget(btn, action:'removeFromSuperview', forControlEvents:UIControlEventTouchUpInside)
|
230
|
+
parent = App.delegate.window
|
231
|
+
btn.backgroundColor = UIColor.redColor
|
232
|
+
btn.center_x = parent.width/2
|
233
|
+
btn.center_y = parent.height/2
|
234
|
+
parent.addSubview(btn)
|
235
|
+
end
|
236
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class MFMailComposeViewController
|
2
|
+
def self.compose(subject, options={})
|
3
|
+
delegate = MOCommon::MailComposerDelegate.new
|
4
|
+
delegate.on_finish = options[:finish]
|
5
|
+
delegate.send(:retain)
|
6
|
+
|
7
|
+
vc = MFMailComposeViewController.new
|
8
|
+
vc.setSubject(subject)
|
9
|
+
vc.setToRecipients(options[:recipients]) if options[:recipients]
|
10
|
+
vc.setMessageBody(options[:body], isHTML:options[:is_html]) if options[:body]
|
11
|
+
vc.mailComposeDelegate = delegate
|
12
|
+
|
13
|
+
vc
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
module MOCommon
|
19
|
+
class MailComposerDelegate
|
20
|
+
attr_accessor :on_finish
|
21
|
+
|
22
|
+
def mailComposeController(vc, didFinishWithResult:result, error:error)
|
23
|
+
on_finish.call(result, error)
|
24
|
+
send(:autorelease)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
#Stuff I copied from MOCommon
|
2
|
+
class UIView
|
3
|
+
def left
|
4
|
+
frame.origin.x
|
5
|
+
end
|
6
|
+
|
7
|
+
|
8
|
+
def left=(x)
|
9
|
+
f = self.frame
|
10
|
+
f.origin.x = x
|
11
|
+
self.frame = f
|
12
|
+
end
|
13
|
+
|
14
|
+
def top
|
15
|
+
frame.origin.y
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def top=(y)
|
20
|
+
f = self.frame
|
21
|
+
f.origin.y = y
|
22
|
+
self.frame = f
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def right
|
27
|
+
frame.origin.x + frame.size.width
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def right=(right)
|
32
|
+
f = self.frame
|
33
|
+
f.origin.x = right - f.size.width
|
34
|
+
self.frame = f
|
35
|
+
end
|
36
|
+
|
37
|
+
def bottom
|
38
|
+
frame.origin.y + frame.size.height
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
def bottom=(bottom)
|
43
|
+
f = self.frame
|
44
|
+
f.origin.y = bottom - f.size.height
|
45
|
+
self.frame = f
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def center_x
|
50
|
+
center.x
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def center_x=(center_x)
|
55
|
+
self.center = [center_x, self.center.y]
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
def center_y
|
60
|
+
center.y
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
def center_y=(center_y)
|
65
|
+
self.center = [self.center.x, center_y]
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def width
|
70
|
+
frame.size.width
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def width=(width)
|
75
|
+
f = self.frame
|
76
|
+
f.size.width = width
|
77
|
+
self.frame = f
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
def height
|
82
|
+
frame.size.height
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
def height=(height)
|
87
|
+
f = self.frame
|
88
|
+
f.size.height = height
|
89
|
+
self.frame = f
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
def size_width_to_fit
|
94
|
+
h = self.height
|
95
|
+
sizeToFit
|
96
|
+
self.height = h
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
def size_height_to_fit
|
101
|
+
w = self.width
|
102
|
+
#Otherwise it doesn't expand short UILabel when it's too short to fit longer text
|
103
|
+
self.height = 1000
|
104
|
+
sizeToFit
|
105
|
+
self.width = w
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
def size_width_to_fit_align_right
|
110
|
+
x = self.right
|
111
|
+
size_width_to_fit
|
112
|
+
self.right = x
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
def size_height_to_fit_align_bottom
|
117
|
+
y = self.bottom
|
118
|
+
size_height_to_fit
|
119
|
+
self.bottom = y
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
def size_width_to_fit_max(f)
|
124
|
+
size_width_to_fit
|
125
|
+
|
126
|
+
if self.width > f
|
127
|
+
self.width = f
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
def size_width_to_fit_min(f)
|
133
|
+
size_width_to_fit
|
134
|
+
|
135
|
+
if self.width < f
|
136
|
+
self.width = f
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
def size_height_to_fit_max(f)
|
142
|
+
size_height_to_fit
|
143
|
+
|
144
|
+
if self.height > f
|
145
|
+
self.height = f
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
def size_height_to_fit_min(f)
|
152
|
+
size_height_to_fit
|
153
|
+
|
154
|
+
if self.height < f
|
155
|
+
self.height = f
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
def origin_relative_to_superview(v)
|
161
|
+
sup = self.superview
|
162
|
+
offset = CGPointZero
|
163
|
+
|
164
|
+
#if ([sup isKindOfClass:[UIScrollView class]]) {
|
165
|
+
#offset = ((UIScrollView*)sup).contentOffset
|
166
|
+
#}
|
167
|
+
|
168
|
+
if !sup || v == sup
|
169
|
+
return CGPoint.new(left-offset.x, top-offset.y)
|
170
|
+
else
|
171
|
+
d = sup.origin_relative_to_superview(v)
|
172
|
+
return CGPoint.new(left+d.x-offset.x, top+d.y-offset.y)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
def move_origin_relative_to_superview(v)
|
178
|
+
pt = self.origin_relative_to_superview(v)
|
179
|
+
self.left = pt.x
|
180
|
+
self.top = pt.y
|
181
|
+
end
|
182
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/purplish-red/version.rb', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = 'purplish-red'
|
6
|
+
gem.version = PurplishRed::VERSION
|
7
|
+
gem.licenses = ['BSD']
|
8
|
+
|
9
|
+
gem.authors = ['Hwee-Boon Yar']
|
10
|
+
|
11
|
+
gem.description = 'A set of wrappers and helpers for working with iOS using RubyMotion'
|
12
|
+
gem.summary = 'A set of wrappers and helpers for working with iOS using RubyMotion'
|
13
|
+
gem.homepage = 'https://github.com/hboon/purplish-red'
|
14
|
+
gem.email = 'hboon@motionobj.com'
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($\)
|
17
|
+
gem.require_paths = ['lib']
|
18
|
+
#gem.test_files = gem.files.grep(%r{^spec/})
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: purplish-red
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Hwee-Boon Yar
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-31 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A set of wrappers and helpers for working with iOS using RubyMotion
|
14
|
+
email: hboon@motionobj.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- .gitignore
|
20
|
+
- lib/purplish-red.rb
|
21
|
+
- lib/purplish-red/non-ui/ns_data.rb
|
22
|
+
- lib/purplish-red/non-ui/ns_date.rb
|
23
|
+
- lib/purplish-red/non-ui/ns_string.rb
|
24
|
+
- lib/purplish-red/non-ui/ui_color.rb
|
25
|
+
- lib/purplish-red/non-ui/ui_device.rb
|
26
|
+
- lib/purplish-red/non-ui/ui_image.rb
|
27
|
+
- lib/purplish-red/symbol.rb
|
28
|
+
- lib/purplish-red/ui/mf_mail_compose_view_controller.rb
|
29
|
+
- lib/purplish-red/ui/ui_view.rb
|
30
|
+
- lib/purplish-red/version.rb
|
31
|
+
- purplish-red.gemspec
|
32
|
+
homepage: https://github.com/hboon/purplish-red
|
33
|
+
licenses:
|
34
|
+
- BSD
|
35
|
+
metadata: {}
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
requirements: []
|
51
|
+
rubyforge_project:
|
52
|
+
rubygems_version: 2.0.7
|
53
|
+
signing_key:
|
54
|
+
specification_version: 4
|
55
|
+
summary: A set of wrappers and helpers for working with iOS using RubyMotion
|
56
|
+
test_files: []
|