easy-button 0.0.4

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.
@@ -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: []