easy-button 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,54 @@
1
+ # Easy Button for RubyMotion
2
+
3
+ A nice looking button in RubyMotion that extends the UIButton class and adds a couple properties for easy styling.
4
+
5
+ Just pass a single hex value to `backgroundColor` and get a nice gradient button with a shadow.
6
+
7
+ You can also more easily set the `borderRadius`, `font`, `textColor`, and `title` for the button's label. Everything else works just like a UIButton!
8
+
9
+ # Install
10
+
11
+ I find it very easy to use Bundler to manage gems in RubyMotion.
12
+
13
+ Rakefile
14
+
15
+ ```ruby
16
+ $:.unshift("/Library/RubyMotion/lib")
17
+ require 'motion/project'
18
+ require 'bundler'
19
+ Bundler.require
20
+
21
+ Motion::Project::App.setup do |app|
22
+ # Use `rake config' to see complete project settings.
23
+ app.name = 'Testing'
24
+ end
25
+ ```
26
+
27
+ Gemfile
28
+
29
+ ```ruby
30
+ source :rubygems
31
+
32
+ gem 'easy-button', :git => 'git://github.com/brianpattison/easy-button.git'
33
+ ```
34
+
35
+ Run `bundle install`.
36
+
37
+ # Usage
38
+
39
+ ```ruby
40
+ @button = EasyButton.alloc.initWithFrame([[10, 160], [300, 80]])
41
+ @button.backgroundColor = '#ff0000'
42
+ @button.borderRadius = 14
43
+ @button.font = UIFont.boldSystemFontOfSize(26)
44
+ @button.textColor = '#fff'
45
+ @button.title = "That Was Easy!"
46
+ ```
47
+
48
+ # Screenshot
49
+
50
+ ![Easy Button Screenshot](http://www.brianpattison.com/images/easy-button.png)
51
+
52
+ # Thanks
53
+
54
+ Thanks to [@seanlilmateus](https://github.com/seanlilmateus) for the inspiration and a bunch of code from [CoolButton](https://github.com/seanlilmateus/CoolButton)!
@@ -0,0 +1,12 @@
1
+ Gem::Specification.new do |gem|
2
+ gem.authors = ["Brian Pattison"]
3
+ gem.email = ["brian@brianpattison.com"]
4
+ gem.description = "A nice looking button in RubyMotion"
5
+ gem.summary = "Extends to UIButton class and adds properties for easy styling."
6
+ gem.homepage = "https://github.com/brianpattison/easy-button"
7
+
8
+ gem.files = `git ls-files`.split($\)
9
+ gem.name = "easy-button"
10
+ gem.require_paths = ["lib"]
11
+ gem.version = '0.0.4'
12
+ end
@@ -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__), 'easy-button/*.rb')).each do |file|
7
+ app.files.unshift(file)
8
+ end
9
+ end
@@ -0,0 +1,205 @@
1
+ class EasyButton < UIButton
2
+ attr_accessor :borderRadius, :font, :textColor, :title
3
+
4
+ def initWithFrame(frame)
5
+ if super
6
+ buttonSetup
7
+ end
8
+ self
9
+ end
10
+
11
+ def initWithCoder(a_decoder)
12
+ if super
13
+ buttonSetup
14
+ end
15
+ self
16
+ end
17
+
18
+ def buttonSetup
19
+ self.opaque = false
20
+ self.backgroundColor = UIColor.clearColor
21
+ self.backgroundColor = "#ff0000"
22
+ self.borderRadius = 10
23
+ self.font = UIFont.boldSystemFontOfSize(18)
24
+ self.textColor = '#fff'
25
+ titleLabel.shadowColor = UIColor.colorWithWhite(0, alpha:0.5);
26
+ titleLabel.shadowOffset = [0, -1]
27
+ end
28
+
29
+ def backgroundColor=(value)
30
+ if value.is_a? String
31
+ rgb = rgbFromHex(value)
32
+ @backGroundColorRed = rgb[0]
33
+ @backGroundColorGreen = rgb[1]
34
+ @backGroundColorBlue = rgb[2]
35
+ @backgroundColorTop = UIColor.colorWithRed(@backGroundColorRed * 1.2, green:@backGroundColorGreen * 1.2, blue:@backGroundColorBlue * 1.2, alpha:1)
36
+ @backgroundColorBottom = UIColor.colorWithRed(@backGroundColorRed * 0.7, green:@backGroundColorGreen * 0.7, blue:@backGroundColorBlue * 0.7, alpha:1)
37
+ elsif value = UIColor.clearColor
38
+ super
39
+ else
40
+ @backgroundColorStart = value
41
+ @backgroundColorBottom = value
42
+ end
43
+ self.setNeedsDisplay
44
+ end
45
+
46
+ def borderRadius=(value)
47
+ @borderRadius = value
48
+ self.setNeedsDisplay
49
+ end
50
+
51
+ def textColor=(value)
52
+ @textColor = value
53
+ if value.is_a? String
54
+ red, green, blue = rgbFromHex(value)
55
+ titleLabel.textColor = UIColor.colorWithRed(red, green:green, blue:blue, alpha:1)
56
+ else
57
+ titleLabel.textColor = value
58
+ end
59
+ end
60
+
61
+ def font=(value)
62
+ @font = value
63
+ titleLabel.setFont(@font)
64
+ end
65
+
66
+ def title=(value)
67
+ @title = value
68
+ self.setTitle(@title, forState:UIControlStateNormal)
69
+ end
70
+
71
+ def drawRect(rect)
72
+ super
73
+ context = UIGraphicsGetCurrentContext()
74
+
75
+ if self.state == UIControlStateHighlighted && @backGroundColorRed && @backGroundColorGreen && @backGroundColorBlue
76
+ backgroundColorTop = UIColor.colorWithRed(@backGroundColorRed * 0.8, green:@backGroundColorGreen * 0.8, blue:@backGroundColorBlue * 0.8, alpha:1).CGColor
77
+ else
78
+ backgroundColorTop = @backgroundColorTop.CGColor
79
+ end
80
+ backgroundColorBottom = @backgroundColorBottom.CGColor
81
+
82
+ outerMargin = 5
83
+ outerRect = CGRectInset(self.bounds, outerMargin, outerMargin)
84
+ outerPath = createRoundedRectForRect(outerRect, @borderRadius)
85
+
86
+ highlightRect = CGRectInset(outerRect, 2, 3)
87
+ highlightPath = createRoundedRectForRect(highlightRect, @borderRadius - 1)
88
+
89
+ # Draw Shadow When Not Pressed
90
+ unless self.state == UIControlStateHighlighted
91
+ CGContextSaveGState(context)
92
+ CGContextSetFillColorWithColor(context, backgroundColorTop)
93
+ CGContextSetShadowWithColor(context, CGSizeMake(0, 2), 3, UIColor.colorWithWhite(0, alpha:0.5).CGColor)
94
+ CGContextAddPath(context, outerPath)
95
+ CGContextFillPath(context)
96
+ CGContextRestoreGState(context)
97
+ end
98
+
99
+ # Draw Button Gradient
100
+ CGContextSaveGState(context)
101
+ CGContextAddPath(context, outerPath)
102
+ CGContextClip(context)
103
+ drawLinearGradient(context, outerRect, backgroundColorTop, backgroundColorBottom)
104
+ CGContextRestoreGState(context)
105
+
106
+ # Draw Highlight or Inner Shadow
107
+ CGContextSaveGState(context)
108
+ if self.state == UIControlStateHighlighted
109
+ CGContextSetLineWidth(context, 4)
110
+ CGContextAddPath(context, outerPath)
111
+ CGContextAddPath(context, highlightPath)
112
+ CGContextEOClip(context)
113
+ drawLinearGradient(context, outerRect, UIColor.colorWithWhite(0, alpha:0.12).CGColor, UIColor.colorWithWhite(0, alpha:0.03).CGColor)
114
+ else
115
+ CGContextSetLineWidth(context, 4)
116
+ CGContextAddPath(context, outerPath)
117
+ CGContextAddPath(context, highlightPath)
118
+ CGContextEOClip(context)
119
+ drawLinearGradient(context, outerRect, UIColor.colorWithWhite(1, alpha:0.2).CGColor, UIColor.colorWithWhite(1, alpha:0.02).CGColor)
120
+ end
121
+ CGContextRestoreGState(context)
122
+
123
+ # Draw Button Border
124
+ CGContextSaveGState(context)
125
+ CGContextSetLineWidth(context, 1)
126
+ CGContextSetStrokeColorWithColor(context, UIColor.colorWithWhite(0, alpha:0.3).CGColor)
127
+ CGContextAddPath(context, outerPath)
128
+ CGContextStrokePath(context)
129
+ CGContextRestoreGState(context)
130
+
131
+ # Move Title Label Down When Pressed
132
+ if self.state == UIControlStateHighlighted
133
+ titleLabel.transform = CGAffineTransformIdentity
134
+ titleLabel.transform = CGAffineTransformMakeTranslation(0, 1)
135
+ end
136
+ end
137
+
138
+ def drawLinearGradient(context, rect, start_color, end_color)
139
+ color_space = CGColorSpaceCreateDeviceRGB()
140
+ locations = Pointer.new(:float, 2)
141
+ locations[1] = 1.0
142
+
143
+ colors = [start_color, end_color]
144
+
145
+ gradient = CGGradientCreateWithColors(color_space, colors, locations)
146
+
147
+ start_point = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect))
148
+ end_point = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect))
149
+
150
+ CGContextSaveGState(context)
151
+ CGContextAddRect(context, rect)
152
+ CGContextClip(context)
153
+ CGContextDrawLinearGradient(context, gradient, start_point, end_point, 0)
154
+ CGContextRestoreGState(context)
155
+ end
156
+
157
+ def createRoundedRectForRect(rect, radius)
158
+ path = CGPathCreateMutable()
159
+ CGPathMoveToPoint(path, nil, CGRectGetMidX(rect), CGRectGetMinY(rect))
160
+ CGPathAddArcToPoint(path, nil, CGRectGetMaxX(rect), CGRectGetMinY(rect), CGRectGetMaxX(rect), CGRectGetMaxY(rect), radius)
161
+ CGPathAddArcToPoint(path, nil, CGRectGetMaxX(rect), CGRectGetMaxY(rect), CGRectGetMinX(rect), CGRectGetMaxY(rect), radius)
162
+ CGPathAddArcToPoint(path, nil, CGRectGetMinX(rect), CGRectGetMaxY(rect), CGRectGetMinX(rect), CGRectGetMinY(rect), radius)
163
+ CGPathAddArcToPoint(path, nil, CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetMaxX(rect), CGRectGetMinY(rect), radius)
164
+ CGPathCloseSubpath(path)
165
+ path
166
+ end
167
+
168
+ def rgbFromHex(hex)
169
+ hex = hex.gsub(%r{[#;]}, '')
170
+ case hex.size
171
+ when 3
172
+ hex.scan(%r{[0-9A-Fa-f]}).map { |el| (1.0 * (el * 2).to_i(16)) / 255 }
173
+ when 6
174
+ hex.scan(%r<[0-9A-Fa-f]{2}>).map { |el| (1.0 * el.to_i(16)) / 255 }
175
+ else
176
+ raise ArgumentError, 'Argument is not a valid hex code.'
177
+ end
178
+ end
179
+
180
+ def hesitateUpdate
181
+ self.setNeedsDisplay
182
+ end
183
+
184
+ def touchesBegan(touches, withEvent:the_event)
185
+ super
186
+ self.setNeedsDisplay
187
+ end
188
+
189
+ def touchesMoved(touches, withEvent:the_event)
190
+ super
191
+ self.setNeedsDisplay
192
+ end
193
+
194
+ def touchesCancelled(touches, withEvent:the_event)
195
+ super
196
+ self.setNeedsDisplay
197
+ self.performSelector(:hesitateUpdate, withObject:nil, afterDelay:0.1)
198
+ end
199
+
200
+ def touchesEnded(touches, withEvent:the_event)
201
+ super
202
+ self.setNeedsDisplay
203
+ self.performSelector(:hesitateUpdate, withObject:nil, afterDelay:0.1)
204
+ end
205
+ end
@@ -0,0 +1,47 @@
1
+ describe EasyButton do
2
+ before do
3
+ @easyButton = EasyButton.alloc.initWithFrame([[0.0, 0.0], [10.0, 50.0]])
4
+ end
5
+
6
+ it "backgroundColor should be transparent" do
7
+ @easyButton.backgroundColor.should.equal UIColor.clearColor
8
+ end
9
+
10
+ it "borderRadius should have a default value" do
11
+ @easyButton.borderRadius.should.equal 10
12
+ end
13
+
14
+ it "font should have a default value" do
15
+ @easyButton.font.should.equal UIFont.boldSystemFontOfSize(18)
16
+ end
17
+
18
+ it "titleLabel should have a default shadowColor" do
19
+ @easyButton.titleLabel.shadowColor.should.equal UIColor.colorWithWhite(0, alpha:0.5);
20
+ end
21
+
22
+ it "titleLabel should have a default shadowOffset" do
23
+ @easyButton.titleLabel.shadowOffset.should.equal CGSizeMake(0, -1)
24
+ end
25
+
26
+ it "titleLabel should have a default textColor" do
27
+ @easyButton.titleLabel.textColor.should.equal UIColor.colorWithRed(1, green:1, blue:1, alpha:1)
28
+ end
29
+
30
+ it "titleLabel text should change with title" do
31
+ title = 'That Was Easy!'
32
+ @easyButton.title = title
33
+ @easyButton.titleLabel.text.should.equal title
34
+ end
35
+
36
+ it "titleLabel font should change with font" do
37
+ font = UIFont.boldSystemFontOfSize(10)
38
+ @easyButton.font = font
39
+ @easyButton.titleLabel.font.should.equal font
40
+ end
41
+
42
+ it "titleLabel textColor should change with textColor" do
43
+ textColor = '#000'
44
+ @easyButton.textColor = textColor
45
+ @easyButton.titleLabel.textColor.should.equal UIColor.colorWithRed(0, green:0, blue:0, alpha:1)
46
+ end
47
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: easy-button
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Brian Pattison
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-07 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: A nice looking button in RubyMotion
15
+ email:
16
+ - brian@brianpattison.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - README.md
22
+ - easy-button.gemspec
23
+ - lib/easy-button.rb
24
+ - lib/easy-button/easy-button.rb
25
+ - spec/easy_button_spec.rb
26
+ homepage: https://github.com/brianpattison/easy-button
27
+ licenses: []
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ required_rubygems_version: !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ requirements: []
45
+ rubyforge_project:
46
+ rubygems_version: 1.8.6
47
+ signing_key:
48
+ specification_version: 3
49
+ summary: Extends to UIButton class and adds properties for easy styling.
50
+ test_files: []