sugarcube 2.8.2 → 2.9.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 64d971eb3d120c7952f35581299baa11b8f05040
4
- data.tar.gz: 1cd8be72a4aefac254d0b29d0250a942a7318297
3
+ metadata.gz: 3a0e6febb6aacdab99ba33a9b6c0cd0b454b12da
4
+ data.tar.gz: 0c9dbcb46e81cb7ba3f85e695c0940b7bd19cc9b
5
5
  SHA512:
6
- metadata.gz: a7fde608a38bfe81d70cdc61298af9feca8bf9f369f2d950746dbf123132cd2eb6baabf24834998269c56f6fd64963f4efc5fa796a60eb2bd8a18b5a90cc63a0
7
- data.tar.gz: c1b0618b2e4be3d733b0f0436fc708383fa8ed0e4d2a632fbade2a16f31cd335c76c8a082921ba573fa555409131a251e5da5e9fc399eab300efabe978a78442
6
+ metadata.gz: a7f0cee0a51409f9e4c48fe257bb89577e5e2ee651862b7fe1e218a69fed9183524fd1191180988cf9d5ff99bf9936b82d26103aafbb3ce62344c1b66e77762e
7
+ data.tar.gz: fabd1cf378ee275c5358e4ee23e4a09e1e6c3ca749deafa9e46953e29e6f0d0fe539f2e38e5bea754879e1ad311e58c41473d85fdcfa1bae0e772da8eaff8000
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  SugarCube
2
2
  =========
3
3
 
4
- Some sugar for your [cocoa](http://rubymotion.com), or your [tea][sweettea].
5
-
6
4
  [![Build Status](https://travis-ci.org/rubymotion/sugarcube.svg?branch=master)](https://travis-ci.org/rubymotion/sugarcube)
7
5
  [![Version](https://badge.fury.io/rb/sugarcube.svg)](https://rubygems.org/gems/sugarcube)
8
6
 
@@ -38,8 +36,8 @@ Cocoa-wrappage.
38
36
  SugarCube started out as a [Fusionbox][] project (see the
39
37
  [announcement][fusionbox announcement]), but as its popularity increased, the
40
38
  decision was made to offer it to the rubymotion community, in the spirit of
41
- open-source and collaboration. It is a great complement to [teacup][],
42
- especially when paired with [sweettea][]!
39
+ open-source and collaboration. It is a great complement to [MotionKit][],
40
+ especially when paired with [SweetKit][]!
43
41
 
44
42
  Documentation
45
43
  =============
@@ -82,20 +80,34 @@ written so that it does *not* pollute any classes by default. So if all you do
82
80
  is `require "sugarcube"`, you are NOT going to get much mileage!
83
81
 
84
82
  In the installation code above, I show the example of using `:require => 'sugarcube-all'`
85
- to include *all* of SugarCube's extensions. Usually you will require the
86
- packages you need from your Rakefile:
83
+ to include *all* of SugarCube's extensions. You can, alternatively require just
84
+ the packages you need:
85
+
86
+ ###### Gemfile
87
+ ```ruby
88
+ gem 'sugarcube', :require => [
89
+ 'sugarcube-uikit',
90
+ 'sugarcube-events',
91
+ 'sugarcube-gestures',
92
+ 'sugarcube-568',
93
+ 'sugarcube-attributedstring',
94
+ ]
95
+ ```
96
+
97
+ Or, from your Rakefile:
87
98
 
88
99
  ```ruby
89
100
  $:.unshift('/Library/RubyMotion/lib')
90
101
  require 'motion/project/template/ios'
102
+
91
103
  require 'bundler'
92
104
  Bundler.require
93
- require './lib/sugarcube-uikit'
94
- require './lib/sugarcube-events'
95
- require './lib/sugarcube-gestures'
96
- require './lib/sugarcube-568'
97
- require './lib/sugarcube-attributedstring'
98
- # ...
105
+
106
+ require 'sugarcube-uikit'
107
+ require 'sugarcube-events'
108
+ require 'sugarcube-gestures'
109
+ require 'sugarcube-568'
110
+ require 'sugarcube-attributedstring'
99
111
  ```
100
112
 
101
113
  You can require the packages in piecemeal like this, or you can require a group
@@ -406,6 +418,9 @@ view.on_press(duration: 1.5, taps: 1, fingers: 1)
406
418
  # this version is only fired when the long-press begins; this is *probably* more
407
419
  # useful to you:
408
420
  view.on_press_begin do ... end
421
+
422
+ # or, when the gesture ends:
423
+ view.on_press_ended do ... end
409
424
  ```
410
425
 
411
426
  Notifications
@@ -1168,6 +1183,17 @@ distance = 2.miles # => 3218.688, that's how many meters are in 2 miles
1168
1183
  1500.in_miles # converts meters to miles => 0.932056427001953
1169
1184
  ```
1170
1185
 
1186
+ ### Time
1187
+
1188
+ By now you have probably "gotten it" and are hooked on these number helpers.
1189
+ Heads up, though, some of these conflict with MotionSupport's definition.
1190
+
1191
+ ```ruby
1192
+ 1.second * 5.per_second = 5
1193
+ 1.day * 3.per_hour = 72
1194
+ 1.year.in_minutes = 525960.0
1195
+ ```
1196
+
1171
1197
  ### Sizes
1172
1198
 
1173
1199
  Similar conversion methods for hard disk sizes. Uses the "mebi-byte" concepts,
@@ -1321,17 +1347,29 @@ Shorthands and hash-like access to the coder/decoder objects.
1321
1347
  ```ruby
1322
1348
  # hash access is the handiest
1323
1349
  coder['key'] = self.value
1324
- self.value = decoder['key']
1350
+ @value = decoder['key']
1351
+
1352
+ if decoder.key?('key')
1353
+ value = decoder['key']
1354
+ end
1325
1355
 
1326
1356
  # but if you want to store booleans and such (in their C form,
1327
1357
  # which will take up less space):
1328
1358
  coder.set('sugarcube_is_neat', toBool: self.sugarcube_is_neat?)
1329
- self.sugarcube_is_neat = decoder.bool('sugarcube_is_neat')
1359
+ @sugarcube_is_neat = decoder.bool('sugarcube_is_neat')
1330
1360
 
1331
1361
  coder.set('number_of_things', toInt:self.number_of_things)
1332
- self.number_of_things = decoder.int('number_of_things')
1362
+ @number_of_things = decoder.int('number_of_things')
1363
+
1364
+ # Archiving and unarchiving is straightforward
1365
+ # archiving uses NSKeyedArchiver
1366
+ NSCoder.archive(root_object) # returns NSData
1367
+ NSCoder.archive(root_object, to_file: 'foo'.document_path) # returns success boolean
1368
+ # unarchiving uses NSKeyedUnarchiver
1369
+ NSCoder.unarchive(data)
1370
+ NSCoder.unarchive('foo'.document_path)
1333
1371
 
1334
- # the entire list:
1372
+ # the entire list of encode/decode helpers:
1335
1373
  coder.set(key, toBool:value)
1336
1374
  coder.set(key, toDouble:value)
1337
1375
  coder.set(key, toFloat:value)
@@ -1720,8 +1758,8 @@ Contributions
1720
1758
  If you want to see new features, please fork, commit, and pull-request! :smiley:
1721
1759
 
1722
1760
  [BubbleWrap]: https://github.com/rubymotion/BubbleWrap
1723
- [sweettea]: https://github.com/colinta/sweettea
1724
- [teacup]: https://github.com/rubymotion/teacup
1761
+ [SweetKit]: https://github.com/motion-kit/sweet-kit
1762
+ [MotionKit]: https://github.com/motion-kit/motion-kit
1725
1763
  [nsnulldammit]: https://github.com/colinta/nsnulldammit
1726
1764
  [geomotion]: https://github.com/clayallsopp/geomotion
1727
1765
 
@@ -10,6 +10,7 @@ class Numeric
10
10
  def in_milliseconds
11
11
  self * 1000
12
12
  end
13
+ alias per_millisecond in_milliseconds
13
14
 
14
15
  def seconds
15
16
  self
@@ -21,6 +22,7 @@ class Numeric
21
22
  def in_seconds
22
23
  self
23
24
  end
25
+ alias per_second in_seconds
24
26
 
25
27
  def minutes
26
28
  self * 60
@@ -32,6 +34,7 @@ class Numeric
32
34
  def in_minutes
33
35
  self / 1.minute.to_f
34
36
  end
37
+ alias per_minute in_minutes
35
38
 
36
39
  def hours
37
40
  self * 3600
@@ -41,6 +44,7 @@ class Numeric
41
44
  def in_hours
42
45
  self / 1.hour.to_f
43
46
  end
47
+ alias per_hour in_hours
44
48
 
45
49
  def days
46
50
  self.hours * 24
@@ -50,6 +54,7 @@ class Numeric
50
54
  def in_days
51
55
  self / 1.day.to_f
52
56
  end
57
+ alias per_day in_days
53
58
 
54
59
  def weeks
55
60
  self.days * 7
@@ -59,23 +64,28 @@ class Numeric
59
64
  def in_weeks
60
65
  self / 1.week.to_f
61
66
  end
67
+ alias per_week in_weeks
62
68
 
69
+ # INACCURATE and COULD CHANGE in the future.
63
70
  def months
64
- self.days * 30
71
+ self.days * 30.416
65
72
  end
66
73
  alias month months
67
74
 
68
75
  def in_months
69
76
  self / 1.month.to_f
70
77
  end
78
+ alias per_month in_months
71
79
 
80
+ # INACCURATE and COULD CHANGE in the future.
72
81
  def years
73
- self.days * 365
82
+ self.days * 365.25
74
83
  end
75
84
  alias year years
76
85
 
77
86
  def in_years
78
87
  self / 1.year.to_f
79
88
  end
89
+ alias per_year in_years
80
90
 
81
91
  end
@@ -3,13 +3,28 @@ class CAAnimation
3
3
  class << self
4
4
 
5
5
  private def _sugarcube_apply_animation_options(animation, options)
6
+ if options.key?(:delay)
7
+ animation.beginTime = CACurrentMediaTime() + options[:delay]
8
+ end
6
9
  animation.duration = options[:duration] if options.key?(:duration)
7
10
  animation.delegate = options[:delegate] if options.key?(:delegate)
8
11
  animation.speed = options[:speed] if options.key?(:speed)
9
- animation.repeatCount = options[:repeat] if options.key?(:repeat)
10
- animation.repeatCount = options[:repeat_count] if options.key?(:repeat_count)
12
+ if options[:repeat] == true
13
+ animation.repeatCount = Float::MAX
14
+ elsif options.key?(:repeat)
15
+ animation.repeatCount = options[:repeat]
16
+ elsif options.key?(:repeat_count)
17
+ animation.repeatCount = options[:repeat_count]
18
+ end
11
19
  animation.repeatDuration = options[:repeat_duration] if options.key?(:repeat_duration)
12
20
  animation.removedOnCompletion = options.fetch(:remove, true)
21
+ if options.key?(:timing)
22
+ timing_function = options[:timing]
23
+ if timing_function.is_a?(NSString)
24
+ timing_function = CAMediaTimingFunction.functionWithName(timing_function)
25
+ end
26
+ animation.timingFunction = timing_function
27
+ end
13
28
  end
14
29
 
15
30
  # If you pass a block, that block will be called at the end of the
@@ -29,14 +44,10 @@ class CAAnimation
29
44
 
30
45
  def keyframe(key_path, options={}, &block)
31
46
  timing_function = options.fetch(:timing, KCAMediaTimingFunctionDefault)
32
- if timing_function.is_a?(NSString)
33
- timing_function = CAMediaTimingFunction.functionWithName(timing_function)
34
- end
35
47
  fill_mode = options.fetch(:fill_mode, KCAFillModeForwards)
36
48
 
37
49
  animation = CAKeyframeAnimation.animationWithKeyPath(key_path)
38
50
  _sugarcube_apply_animation_options(animation, options)
39
- animation.timingFunction = timing_function
40
51
  animation.fillMode = fill_mode
41
52
 
42
53
  if options.key?(:values)
@@ -54,4 +65,43 @@ class CAAnimation
54
65
 
55
66
  end
56
67
 
68
+ def completion(&completion)
69
+ if completion
70
+ unless self.delegate.is_a?(SugarCubeAnimationDelegate)
71
+ delegate = SugarCubeAnimationDelegate.new
72
+ self.delegate = delegate
73
+ end
74
+ self.delegate.completion = completion.weak!
75
+ elsif self.delegate.is_a?(SugarCubeAnimationDelegate)
76
+ return self.delegate.completion
77
+ end
78
+ end
79
+
80
+ def start(&start)
81
+ if start
82
+ unless self.delegate.is_a?(SugarCubeAnimationDelegate)
83
+ delegate = SugarCubeAnimationDelegate.new
84
+ self.delegate = delegate
85
+ end
86
+ self.delegate.start = start.weak!
87
+ elsif self.delegate.is_a?(SugarCubeAnimationDelegate)
88
+ return self.delegate.start
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+
95
+ class SugarCubeAnimationDelegate
96
+ attr_accessor :start
97
+ attr_accessor :completion
98
+
99
+ def animationDidStart
100
+ @start && @start.call
101
+ end
102
+
103
+ def animationDidStop(anim, finished: finished)
104
+ @completion && @completion.call(finished)
105
+ end
106
+
57
107
  end
@@ -1,74 +1,101 @@
1
+ # Hash-like access for NSCoder. Converts the `key` argument to a String,
2
+ # because Symbols can mess things up.
1
3
  class NSCoder
2
4
 
3
5
  def [] key
4
- return self.decodeObjectForKey key
6
+ self.decodeObjectForKey(key.to_s)
5
7
  end
6
8
 
7
9
  def []= key, value
8
- return self.encodeObject(value, forKey:key)
10
+ self.encodeObject(value, forKey: key.to_s)
11
+ end
12
+
13
+ def key?(key)
14
+ self.containsValueForKey(key.to_s)
9
15
  end
10
16
 
11
17
  def bool(key)
12
- return self.decodeBoolForKey(key)
18
+ self.decodeBoolForKey(key.to_s)
13
19
  end
14
20
 
15
21
  def double(key)
16
- return self.decodeDoubleForKey(key)
22
+ self.decodeDoubleForKey(key.to_s)
17
23
  end
18
24
 
19
25
  def float(key)
20
- return self.decodeFloatForKey(key)
26
+ self.decodeFloatForKey(key.to_s)
21
27
  end
22
28
 
23
29
  def int(key)
24
- return self.decodeIntegerForKey(key)
30
+ self.decodeIntegerForKey(key.to_s)
25
31
  end
26
32
 
27
33
  def point(key)
28
- return CGPointFromString(self.decodeObjectForKey(key))
34
+ CGPointFromString(self.decodeObjectForKey(key.to_s))
29
35
  end
30
36
 
31
37
  def rect(key)
32
- return CGRectFromString(self.decodeObjectForKey(key))
38
+ CGRectFromString(self.decodeObjectForKey(key.to_s))
33
39
  end
34
40
 
35
41
  def size(key)
36
- return CGSizeFromString(self.decodeObjectForKey(key))
42
+ CGSizeFromString(self.decodeObjectForKey(key.to_s))
43
+ end
44
+
45
+ def set(key, toBool: value)
46
+ self.encodeBool(value, forKey: key.to_s)
47
+ self
37
48
  end
38
49
 
39
- def set(key, toBool:value)
40
- self.encodeBool(value, forKey:key)
41
- return self
50
+ def set(key, toDouble: value)
51
+ self.encodeDouble(value, forKey: key.to_s)
52
+ self
42
53
  end
43
54
 
44
- def set(key, toDouble:value)
45
- self.encodeDouble(value, forKey:key)
46
- return self
55
+ def set(key, toFloat: value)
56
+ self.encodeFloat(value, forKey: key.to_s)
57
+ self
47
58
  end
48
59
 
49
- def set(key, toFloat:value)
50
- self.encodeFloat(value, forKey:key)
51
- return self
60
+ def set(key, toInt: value)
61
+ self.encodeInteger(value, forKey: key.to_s)
62
+ self
52
63
  end
53
64
 
54
- def set(key, toInt:value)
55
- self.encodeInteger(value, forKey:key)
56
- return self
65
+ def set(key, toPoint: value)
66
+ self.encodeObject(NSStringFromCGPoint(value), forKey: key.to_s)
67
+ self
57
68
  end
58
69
 
59
- def set(key, toPoint:value)
60
- self.encodeObject(NSStringFromCGPoint(value), forKey:key)
61
- return self
70
+ def set(key, toRect: value)
71
+ self.encodeObject(NSStringFromCGRect(value), forKey: key.to_s)
72
+ self
73
+ end
74
+
75
+ def set(key, toSize: value)
76
+ self.encodeObject(NSStringFromCGSize(value), forKey: key.to_s)
77
+ self
78
+ end
79
+
80
+ end
81
+
82
+
83
+ class NSCoder
84
+
85
+ def self.archive(root)
86
+ NSKeyedArchiver.archivedDataWithRootObject(root)
62
87
  end
63
88
 
64
- def set(key, toRect:value)
65
- self.encodeObject(NSStringFromCGRect(value), forKey:key)
66
- return self
89
+ def self.archive(root, to_file: file)
90
+ NSKeyedArchiver.archivedRootObject(root, toFile: file)
67
91
  end
68
92
 
69
- def set(key, toSize:value)
70
- self.encodeObject(NSStringFromCGSize(value), forKey:key)
71
- return self
93
+ def self.unarchive(data_or_file)
94
+ if data_or_file.is_a?(NSData)
95
+ NSKeyedUnarchiver.unarchiveObjectWithData(data_or_file)
96
+ else
97
+ NSKeyedUnarchiver.unarchiveObjectWithFile(data_or_file)
98
+ end
72
99
  end
73
100
 
74
101
  end
@@ -18,11 +18,11 @@ module Kernel
18
18
  end
19
19
  alias coll collapse
20
20
 
21
- def tree(*args)
21
+ def tree(*args, &sel_blk)
22
22
  if self.nil?
23
23
  super
24
24
  else
25
- SugarCube::Repl.tree(*args)
25
+ SugarCube::Repl.tree(*args, &sel_blk)
26
26
  end
27
27
  end
28
28
 
@@ -223,8 +223,18 @@ module SugarCube
223
223
  end
224
224
  alias c center
225
225
 
226
+ def set_default(item)
227
+ @sugarcube_default_item = item
228
+ end
229
+
230
+ def clear_default
231
+ @sugarcube_default_item = nil
232
+ end
233
+
226
234
  def get_tree_item(item)
227
- if item.nil? || item.is_a?(Fixnum)
235
+ if item.nil? && @sugarcube_default_item
236
+ @sugarcube_default_item
237
+ elsif item.nil? || item.is_a?(Fixnum)
228
238
  window(item)
229
239
  else
230
240
  item
@@ -255,6 +265,14 @@ module SugarCube
255
265
  selector = get_tree_selector(item)
256
266
  end
257
267
 
268
+ if !selector && @sugarcube_tree_selectors
269
+ klass = item.class
270
+ while klass && !selector
271
+ selector = @sugarcube_tree_selectors[klass]
272
+ klass = klass.superclass
273
+ end
274
+ end
275
+
258
276
  unless selector
259
277
  raise "Unable to determine a SugarCube::Repl::tree selector for #{item.class.to_s}"
260
278
  end
@@ -274,6 +292,11 @@ module SugarCube
274
292
  return item
275
293
  end
276
294
 
295
+ def register_tree_selector(klass, selector=nil, &sel_blk)
296
+ @sugarcube_tree_selectors ||= {}
297
+ @sugarcube_tree_selectors[klass] = selector || sel_blk
298
+ end
299
+
277
300
  # Draws the tree items
278
301
  def draw_tree(item, selector, tab=nil, is_last=true, items_index=0)
279
302
  space = ' '
@@ -4,8 +4,20 @@ class SKNode
4
4
  addChild(node)
5
5
  end
6
6
 
7
+ def run_action(action, &completion)
8
+ runAction(action, completion: completion)
9
+ end
10
+
11
+ def [](key)
12
+ userData[key]
13
+ end
14
+
15
+ def []=(key, value)
16
+ userData[key] = value
17
+ end
18
+
7
19
  def to_s
8
- "#<#{self.class}:0x#{self.object_id.to_s(16)} position=#{position.inspect}>"
20
+ "#<#{self.class}:0x#{self.object_id.to_s(16)} position=#{position.inspect} name=#{name.inspect}>"
9
21
  end
10
22
 
11
23
  end
@@ -0,0 +1,21 @@
1
+ class CALayer
2
+
3
+ def sugarcube_to_s(options={})
4
+ if options[:inner].is_a? Hash
5
+ inner = ''
6
+ options[:inner].each do |key, value|
7
+ inner += ', ' if inner.length > 0
8
+ inner += "#{key}: #{value.inspect}"
9
+ end
10
+ else
11
+ inner = options[:inner]
12
+ end
13
+
14
+ "#{self.class.to_s}(##{self.object_id.to_s(16)}, [[#{frame.origin.x}, #{frame.origin.y}], [#{frame.size.width}, #{frame.size.height}]])"
15
+ end
16
+
17
+ def to_s
18
+ sugarcube_to_s
19
+ end
20
+
21
+ end
@@ -53,7 +53,7 @@ module SugarCube
53
53
  AnimationChain.stop_chain(self)
54
54
  end
55
55
  end
56
- }
56
+ }.weak!
57
57
  options[:after] = @after_block
58
58
 
59
59
  UIView.animate(options) do
@@ -115,9 +115,9 @@ class UIView
115
115
  end
116
116
 
117
117
  # @yield [recognizer] Handles the gesture event, and passes the recognizer instance to the block.
118
- # @overload on_tap(taps)
119
- # @param taps [Fixnum] Number of taps
120
- # @overload on_tap(options)
118
+ # @overload on_pan(fingers)
119
+ # @param taps [Fixnum] Number of fingers
120
+ # @overload on_pan(options)
121
121
  # @option options [Fixnum] :min_fingers Minimum number of fingers for gesture to be recognized
122
122
  # @option options [Fixnum] :max_fingers Maximum number of fingers for gesture to be recognized
123
123
  # @option options [Fixnum] :fingers If min_fingers or max_fingers is not assigned, this will be the default.
@@ -149,7 +149,7 @@ class UIView
149
149
  # @yield [recognizer] Handles the gesture event, and passes the recognizer instance to the block.
150
150
  # @overload on_press(duration)
151
151
  # @param duration [Fixnum] How long in seconds before gesture is recognized
152
- # @overload on_tap(options)
152
+ # @overload on_press(options)
153
153
  # @option options [Fixnum] :duration How long in seconds before gesture is recognized
154
154
  # @option options [Fixnum] :taps Number of taps before gesture is recognized
155
155
  # @option options [Fixnum] :fingers Number of fingers before gesture is recognized
@@ -157,12 +157,14 @@ class UIView
157
157
  duration = nil
158
158
  taps = nil
159
159
  fingers = nil
160
+ distance = nil
160
161
 
161
162
  if duration_or_options
162
163
  if duration_or_options.is_a? Hash
163
164
  duration = duration_or_options[:duration] || duration
164
165
  taps = duration_or_options[:taps] || taps
165
166
  fingers = duration_or_options[:fingers] || fingers
167
+ distance = duration_or_options[:distance] || distance
166
168
  else
167
169
  duration = duration_or_options
168
170
  end
@@ -172,6 +174,7 @@ class UIView
172
174
  recognizer.minimumPressDuration = duration if duration
173
175
  recognizer.numberOfTapsRequired = taps if taps
174
176
  recognizer.numberOfTouchesRequired = fingers if fingers
177
+ recognizer.allowableMovement = distance if distance
175
178
  sugarcube_add_gesture(proc, recognizer)
176
179
  end
177
180
 
@@ -179,24 +182,51 @@ class UIView
179
182
  duration = nil
180
183
  taps = nil
181
184
  fingers = nil
185
+ distance = nil
182
186
 
183
187
  if duration_or_options
184
188
  if duration_or_options.is_a? Hash
185
189
  duration = duration_or_options[:duration] || duration
186
190
  taps = duration_or_options[:taps] || taps
187
191
  fingers = duration_or_options[:fingers] || fingers
192
+ distance = duration_or_options[:distance] || distance
188
193
  else
189
194
  duration = duration_or_options
190
195
  end
191
196
  end
192
197
 
193
- recognizer = UILongPressGestureRecognizer.alloc.initWithTarget(self, action:'sugarcube_handle_gesture_long_press_on_begin:')
198
+ recognizer = UILongPressGestureRecognizer.alloc.initWithTarget(self, action:'sugarcube_handle_gesture_on_begin:')
194
199
  recognizer.minimumPressDuration = duration if duration
195
200
  recognizer.numberOfTapsRequired = taps if taps
196
201
  recognizer.numberOfTouchesRequired = fingers if fingers
202
+ recognizer.allowableMovement = distance if distance
197
203
  sugarcube_add_gesture(proc, recognizer)
198
204
  end
199
205
 
206
+ def on_press_ended(duration_or_options=nil, &proc)
207
+ duration = nil
208
+ taps = nil
209
+ fingers = nil
210
+ distance = nil
211
+
212
+ if duration_or_options
213
+ if duration_or_options.is_a? Hash
214
+ duration = duration_or_options[:duration] || duration
215
+ taps = duration_or_options[:taps] || taps
216
+ fingers = duration_or_options[:fingers] || fingers
217
+ distance = duration_or_options[:distance] || distance
218
+ else
219
+ duration = duration_or_options
220
+ end
221
+ end
222
+
223
+ recognizer = UILongPressGestureRecognizer.alloc.initWithTarget(self, action:'sugarcube_handle_gesture_on_ended:')
224
+ recognizer.minimumPressDuration = duration if duration
225
+ recognizer.numberOfTapsRequired = taps if taps
226
+ recognizer.numberOfTouchesRequired = fingers if fingers
227
+ recognizer.allowableMovement = distance if distance
228
+ sugarcube_add_gesture(proc, recognizer)
229
+ end
200
230
 
201
231
  private
202
232
  def sugarcube_handle_gesture(recognizer)
@@ -207,8 +237,20 @@ private
207
237
  handler.call(recognizer)
208
238
  end
209
239
  end
210
- def sugarcube_handle_gesture_long_press_on_begin(recognizer)
211
- if recognizer.state==UIGestureRecognizerStateBegan
240
+
241
+ def sugarcube_handle_gesture_on_begin(recognizer)
242
+ if recognizer.state == UIGestureRecognizerStateBegan
243
+ handler = @sugarcube_recognizers[recognizer]
244
+ if handler.arity == 0
245
+ handler.call
246
+ else
247
+ handler.call(recognizer)
248
+ end
249
+ end
250
+ end
251
+
252
+ def sugarcube_handle_gesture_on_ended(recognizer)
253
+ if recognizer.state == UIGestureRecognizerStateEnded
212
254
  handler = @sugarcube_recognizers[recognizer]
213
255
  if handler.arity == 0
214
256
  handler.call
@@ -1,3 +1,3 @@
1
1
  module SugarCube
2
- Version = '2.8.2'
2
+ Version = '2.9.1'
3
3
  end
@@ -60,8 +60,8 @@ describe "NSCoder" do
60
60
  end
61
61
 
62
62
  it "is nscoding compliant" do
63
- data = NSKeyedArchiver.archivedDataWithRootObject(@subject)
64
- test = NSKeyedUnarchiver.unarchiveObjectWithData(data)
63
+ data = NSCoder.archive(@subject)
64
+ test = NSCoder.unarchive(data)
65
65
  test.object.class.should == CoderHelper
66
66
  test.bool.should == @subject.bool
67
67
  test.double.should == @subject.double
@@ -1,4 +1,4 @@
1
- describe "Numeric Timer methods" do
1
+ describe 'Numeric - Time methods' do
2
2
 
3
3
  it "should have a #millisecond(s) method" do
4
4
  0.milliseconds.should == 0
@@ -13,6 +13,12 @@ describe "Numeric Timer methods" do
13
13
  2000.milliseconds.in_milliseconds.should == 2000
14
14
  end
15
15
 
16
+ it "should have an #per_millisecond method" do
17
+ 0.milliseconds.per_millisecond.should == 0
18
+ 500.millisecond.per_millisecond.should == 500
19
+ 2000.milliseconds.per_millisecond.should == 2000
20
+ end
21
+
16
22
  it "should have a #second(s) method" do
17
23
  0.seconds.should == 0
18
24
  1.second.should == 1
@@ -25,6 +31,12 @@ describe "Numeric Timer methods" do
25
31
  2.seconds.in_seconds.should == 2
26
32
  end
27
33
 
34
+ it "should have an #per_second method" do
35
+ 0.seconds.per_second.should == 0
36
+ 1.second.per_second.should == 1
37
+ 2.seconds.per_second.should == 2
38
+ end
39
+
28
40
  it "should have a #minute(s) method" do
29
41
  0.minutes.should == 0
30
42
  1.minute.should == 60.seconds
@@ -37,6 +49,12 @@ describe "Numeric Timer methods" do
37
49
  2.minutes.in_minutes.should == 2
38
50
  end
39
51
 
52
+ it "should have an #per_minute method" do
53
+ 0.minutes.per_minute.should == 0
54
+ 1.minute.per_minute.should == 1
55
+ 2.minutes.per_minute.should == 2
56
+ end
57
+
40
58
  it "should have a #hour(s) method" do
41
59
  0.hours.should == 0
42
60
  1.hour.should == 60.minutes
@@ -49,6 +67,12 @@ describe "Numeric Timer methods" do
49
67
  2.hours.in_hours.should == 2
50
68
  end
51
69
 
70
+ it "should have an #per_hour method" do
71
+ 0.hours.per_hour.should == 0
72
+ 1.hour.per_hour.should == 1
73
+ 2.hours.per_hour.should == 2
74
+ end
75
+
52
76
  it "should have a #day(s) method" do
53
77
  0.days.should == 0
54
78
  1.day.should == 24.hours
@@ -61,6 +85,12 @@ describe "Numeric Timer methods" do
61
85
  2.days.in_days.should == 2
62
86
  end
63
87
 
88
+ it "should have an #per_day method" do
89
+ 0.days.per_day.should == 0
90
+ 1.day.per_day.should == 1
91
+ 2.days.per_day.should == 2
92
+ end
93
+
64
94
  it "should have a #week(s) method" do
65
95
  0.weeks.should == 0
66
96
  1.week.should == 7.days
@@ -73,10 +103,16 @@ describe "Numeric Timer methods" do
73
103
  2.weeks.in_weeks.should == 2
74
104
  end
75
105
 
106
+ it "should have an #per_week method" do
107
+ 0.weeks.per_week.should == 0
108
+ 1.week.per_week.should == 1
109
+ 2.weeks.per_week.should == 2
110
+ end
111
+
76
112
  it "should have a #month(s) method" do
77
113
  0.months.should == 0
78
- 1.month.should == 30.days
79
- 2.months.should == 60.days
114
+ 1.month.should == 30.416.days
115
+ 2.months.should == 60.832.days
80
116
  end
81
117
 
82
118
  it "should have an #in_months method" do
@@ -85,10 +121,16 @@ describe "Numeric Timer methods" do
85
121
  2.months.in_months.should == 2
86
122
  end
87
123
 
124
+ it "should have an #per_month method" do
125
+ 0.months.per_month.should == 0
126
+ 1.month.per_month.should == 1
127
+ 2.months.per_month.should == 2
128
+ end
129
+
88
130
  it "should have a #year(s) method" do
89
131
  0.years.should == 0
90
- 1.year.should == 365.days
91
- 2.years.should == 730.days
132
+ 1.year.should == 365.25.days
133
+ 2.years.should == 730.5.days
92
134
  end
93
135
 
94
136
  it "should have an #in_years method" do
@@ -97,52 +139,10 @@ describe "Numeric Timer methods" do
97
139
  2.years.in_years.should == 2
98
140
  end
99
141
 
100
- describe "Numeric" do
101
- it "should have a #later method" do
102
- @later = nil
103
- 0.9.seconds.later do
104
- @later = true
105
- end
106
- wait 1 {
107
- @later.should == true
108
- }
109
- end
110
-
111
- it "should have a #every method" do
112
- @every = 0
113
- @stop_me = 480.milliseconds.every do
114
- @every += 1
115
- end
116
- wait 1 {
117
- @every.should == 2
118
- @stop_me.invalidate
119
- }
120
- end
121
- end
122
-
123
- describe "NSTimer" do
124
-
125
- it "should have a #later method" do
126
- @later = nil
127
- NSTimer.after(0.9.seconds) do
128
- @later = true
129
- end
130
- wait 1 {
131
- @later.should == true
132
- }
133
- end
134
-
135
- it "should have a #every method" do
136
- @every = 0
137
- @stop_me = NSTimer.every(480.milliseconds) do
138
- @every += 1
139
- end
140
- wait 1 {
141
- @every.should == 2
142
- @stop_me.invalidate
143
- }
144
- end
145
-
142
+ it "should have an #per_year method" do
143
+ 0.years.per_year.should == 0
144
+ 1.year.per_year.should == 1
145
+ 2.years.per_year.should == 2
146
146
  end
147
147
 
148
148
  end
@@ -0,0 +1,51 @@
1
+ describe "Numeric Timer methods" do
2
+
3
+ describe "Numeric" do
4
+ it "should have a #later method" do
5
+ @later = nil
6
+ 0.9.seconds.later do
7
+ @later = true
8
+ end
9
+ wait 1 {
10
+ @later.should == true
11
+ }
12
+ end
13
+
14
+ it "should have a #every method" do
15
+ @every = 0
16
+ @stop_me = 480.milliseconds.every do
17
+ @every += 1
18
+ end
19
+ wait 1 {
20
+ @every.should == 2
21
+ @stop_me.invalidate
22
+ }
23
+ end
24
+ end
25
+
26
+ describe "NSTimer" do
27
+
28
+ it "should have a #later method" do
29
+ @later = nil
30
+ NSTimer.after(0.9.seconds) do
31
+ @later = true
32
+ end
33
+ wait 1 {
34
+ @later.should == true
35
+ }
36
+ end
37
+
38
+ it "should have a #every method" do
39
+ @every = 0
40
+ @stop_me = NSTimer.every(480.milliseconds) do
41
+ @every += 1
42
+ end
43
+ wait 1 {
44
+ @every.should == 2
45
+ @stop_me.invalidate
46
+ }
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -24,6 +24,20 @@ describe "SugarCube::AnimationChain" do
24
24
  end
25
25
  end
26
26
 
27
+ it "should not leak memory" do
28
+ chain = UIView.animation_chain(duration:0.01){
29
+ f = controller.view.frame
30
+ f.origin.x -= 20
31
+ controller.view.frame = f
32
+ }.start
33
+
34
+ wait 0.1 do
35
+ weak = WeakRef.new(chain)
36
+ chain = nil
37
+ weak.weakref_alive?.should == false
38
+ end
39
+ end
40
+
27
41
  it "should support chains" do
28
42
  SugarCube::AnimationChain.chains.length.should == 0
29
43
  @variable_a = nil
@@ -0,0 +1,142 @@
1
+ describe 'Gestures' do
2
+ before do
3
+ @view = UIView.alloc.initWithFrame([[0, 0], [10, 10]])
4
+ end
5
+
6
+ after do
7
+ @view.off_gestures
8
+ end
9
+
10
+ describe 'on_tap' do
11
+ it 'should work' do
12
+ gesture = @view.on_tap do |gesture|
13
+ end
14
+ gesture.should.be.kind_of(UITapGestureRecognizer)
15
+ @view.gestureRecognizers.should.include?(gesture)
16
+ end
17
+
18
+ it 'should work with options' do
19
+ gesture = @view.on_tap(taps: 2, fingers: 2) do |gesture|
20
+ end
21
+ gesture.should.be.kind_of(UITapGestureRecognizer)
22
+ gesture.numberOfTapsRequired.should == 2
23
+ gesture.numberOfTouchesRequired.should == 2
24
+ @view.gestureRecognizers.should.include?(gesture)
25
+ end
26
+ end
27
+
28
+ describe 'on_pinch' do
29
+ it 'should work' do
30
+ gesture = @view.on_pinch do |gesture|
31
+ end
32
+ gesture.should.be.kind_of(UIPinchGestureRecognizer)
33
+ @view.gestureRecognizers.should.include?(gesture)
34
+ end
35
+ end
36
+
37
+ describe 'on_rotate' do
38
+ it 'should work' do
39
+ gesture = @view.on_rotate do |gesture|
40
+ end
41
+ gesture.should.be.kind_of(UIRotationGestureRecognizer)
42
+ @view.gestureRecognizers.should.include?(gesture)
43
+ end
44
+ end
45
+
46
+ describe 'on_swipe' do
47
+ it 'should work' do
48
+ gesture = @view.on_swipe do |gesture|
49
+ end
50
+ gesture.should.be.kind_of(UISwipeGestureRecognizer)
51
+ @view.gestureRecognizers.should.include?(gesture)
52
+ end
53
+
54
+ it 'should work with options' do
55
+ gesture = @view.on_swipe(direction: :left, fingers: 2) do |gesture|
56
+ end
57
+ gesture.should.be.kind_of(UISwipeGestureRecognizer)
58
+ gesture.direction.should == UISwipeGestureRecognizerDirectionLeft
59
+ gesture.numberOfTouchesRequired.should == 2
60
+ @view.gestureRecognizers.should.include?(gesture)
61
+ end
62
+ end
63
+
64
+ describe 'on_pan' do
65
+ it 'should work' do
66
+ gesture = @view.on_pan do |gesture|
67
+ end
68
+ gesture.should.be.kind_of(UIPanGestureRecognizer)
69
+ @view.gestureRecognizers.should.include?(gesture)
70
+ end
71
+
72
+ it 'should work with options' do
73
+ gesture = @view.on_pan(min_fingers: 2, max_fingers: 2) do |gesture|
74
+ end
75
+ gesture.should.be.kind_of(UIPanGestureRecognizer)
76
+ gesture.maximumNumberOfTouches.should == 2
77
+ gesture.minimumNumberOfTouches.should == 2
78
+ @view.gestureRecognizers.should.include?(gesture)
79
+ end
80
+ end
81
+
82
+ describe 'on_press' do
83
+ it 'should work' do
84
+ gesture = @view.on_press do |gesture|
85
+ end
86
+ gesture.should.be.kind_of(UILongPressGestureRecognizer)
87
+ @view.gestureRecognizers.should.include?(gesture)
88
+ end
89
+
90
+ it 'should work with options' do
91
+ gesture = @view.on_press(duration: 1, taps: 2, fingers: 2, distance: 4) do |gesture|
92
+ end
93
+ gesture.should.be.kind_of(UILongPressGestureRecognizer)
94
+ gesture.minimumPressDuration.should == 1
95
+ gesture.numberOfTapsRequired.should == 2
96
+ gesture.numberOfTouchesRequired.should == 2
97
+ gesture.allowableMovement.should == 4
98
+ @view.gestureRecognizers.should.include?(gesture)
99
+ end
100
+ end
101
+
102
+ describe 'on_press_begin' do
103
+ it 'should work' do
104
+ gesture = @view.on_press_begin do |gesture|
105
+ end
106
+ gesture.should.be.kind_of(UILongPressGestureRecognizer)
107
+ @view.gestureRecognizers.should.include?(gesture)
108
+ end
109
+
110
+ it 'should work with options' do
111
+ gesture = @view.on_press_begin(duration: 1, taps: 2, fingers: 2, distance: 4) do |gesture|
112
+ end
113
+ gesture.should.be.kind_of(UILongPressGestureRecognizer)
114
+ gesture.minimumPressDuration.should == 1
115
+ gesture.numberOfTapsRequired.should == 2
116
+ gesture.numberOfTouchesRequired.should == 2
117
+ gesture.allowableMovement.should == 4
118
+ @view.gestureRecognizers.should.include?(gesture)
119
+ end
120
+ end
121
+
122
+ describe 'on_press_ended' do
123
+ it 'should work' do
124
+ gesture = @view.on_press_ended do |gesture|
125
+ end
126
+ gesture.should.be.kind_of(UILongPressGestureRecognizer)
127
+ @view.gestureRecognizers.should.include?(gesture)
128
+ end
129
+
130
+ it 'should work with options' do
131
+ gesture = @view.on_press_ended(duration: 1, taps: 2, fingers: 2, distance: 4) do |gesture|
132
+ end
133
+ gesture.should.be.kind_of(UILongPressGestureRecognizer)
134
+ gesture.minimumPressDuration.should == 1
135
+ gesture.numberOfTapsRequired.should == 2
136
+ gesture.numberOfTouchesRequired.should == 2
137
+ gesture.allowableMovement.should == 4
138
+ @view.gestureRecognizers.should.include?(gesture)
139
+ end
140
+ end
141
+
142
+ end
@@ -1,4 +1,4 @@
1
- describe "UIView animation methods" do
1
+ describe "UIView tumble animation" do
2
2
  # the 'tumble' animation requires an app window to be present
3
3
  tests UIViewController
4
4
 
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: 2.8.2
4
+ version: 2.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Colin T.A. Gray
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2014-10-08 00:00:00.000000000 Z
14
+ date: 2014-10-29 00:00:00.000000000 Z
15
15
  dependencies: []
16
16
  description: |
17
17
  == Description
@@ -82,6 +82,7 @@ files:
82
82
  - lib/cocoa/sugarcube-repl/repl.rb
83
83
  - lib/cocoa/sugarcube-spritekit/sknode.rb
84
84
  - lib/cocoa/sugarcube-timer/timer.rb
85
+ - lib/cocoa/sugarcube-to_s/calayer.rb
85
86
  - lib/cocoa/sugarcube-to_s/nserror.rb
86
87
  - lib/cocoa/sugarcube-to_s/nsindexpath.rb
87
88
  - lib/cocoa/sugarcube-to_s/nslayoutconstraint.rb
@@ -211,8 +212,11 @@ files:
211
212
  - spec/cocoa/caanimation_spec.rb
212
213
  - spec/cocoa/calayer_spec.rb
213
214
  - spec/cocoa/nsarray_files_spec.rb
215
+ - spec/cocoa/nscoder_spec.rb
214
216
  - spec/cocoa/nsdata_files_spec.rb
215
217
  - spec/cocoa/nsdictionary_files_spec.rb
218
+ - spec/cocoa/numeric_time_spec.rb
219
+ - spec/cocoa/timer_spec.rb
216
220
  - spec/ios/568_spec.rb
217
221
  - spec/ios/animation_chain_spec.rb
218
222
  - spec/ios/color_components_spec.rb
@@ -224,6 +228,7 @@ files:
224
228
  - spec/ios/factories_spec.rb
225
229
  - spec/ios/fixnum_spec.rb
226
230
  - spec/ios/frameable_spec.rb
231
+ - spec/ios/gestures_spec.rb
227
232
  - spec/ios/image_cifilters_spec.rb
228
233
  - spec/ios/image_color_at_spec.rb
229
234
  - spec/ios/image_scale_spec.rb
@@ -231,7 +236,6 @@ files:
231
236
  - spec/ios/notification_spec.rb
232
237
  - spec/ios/nsarray_spec.rb
233
238
  - spec/ios/nsattributedstring_spec.rb
234
- - spec/ios/nscoder_spec.rb
235
239
  - spec/ios/nsdata_spec.rb
236
240
  - spec/ios/nsdate_delta_spec.rb
237
241
  - spec/ios/nsdate_spec.rb
@@ -247,7 +251,6 @@ files:
247
251
  - spec/ios/symbol_constants_spec.rb
248
252
  - spec/ios/symbol_uicolor_spec.rb
249
253
  - spec/ios/symbol_uifont_spec.rb
250
- - spec/ios/timer_spec.rb
251
254
  - spec/ios/uiactionsheet_spec.rb
252
255
  - spec/ios/uialertcontroller_spec.rb
253
256
  - spec/ios/uialertview_spec.rb
@@ -302,8 +305,11 @@ test_files:
302
305
  - spec/cocoa/caanimation_spec.rb
303
306
  - spec/cocoa/calayer_spec.rb
304
307
  - spec/cocoa/nsarray_files_spec.rb
308
+ - spec/cocoa/nscoder_spec.rb
305
309
  - spec/cocoa/nsdata_files_spec.rb
306
310
  - spec/cocoa/nsdictionary_files_spec.rb
311
+ - spec/cocoa/numeric_time_spec.rb
312
+ - spec/cocoa/timer_spec.rb
307
313
  - spec/ios/568_spec.rb
308
314
  - spec/ios/animation_chain_spec.rb
309
315
  - spec/ios/color_components_spec.rb
@@ -315,6 +321,7 @@ test_files:
315
321
  - spec/ios/factories_spec.rb
316
322
  - spec/ios/fixnum_spec.rb
317
323
  - spec/ios/frameable_spec.rb
324
+ - spec/ios/gestures_spec.rb
318
325
  - spec/ios/image_cifilters_spec.rb
319
326
  - spec/ios/image_color_at_spec.rb
320
327
  - spec/ios/image_scale_spec.rb
@@ -322,7 +329,6 @@ test_files:
322
329
  - spec/ios/notification_spec.rb
323
330
  - spec/ios/nsarray_spec.rb
324
331
  - spec/ios/nsattributedstring_spec.rb
325
- - spec/ios/nscoder_spec.rb
326
332
  - spec/ios/nsdata_spec.rb
327
333
  - spec/ios/nsdate_delta_spec.rb
328
334
  - spec/ios/nsdate_spec.rb
@@ -338,7 +344,6 @@ test_files:
338
344
  - spec/ios/symbol_constants_spec.rb
339
345
  - spec/ios/symbol_uicolor_spec.rb
340
346
  - spec/ios/symbol_uifont_spec.rb
341
- - spec/ios/timer_spec.rb
342
347
  - spec/ios/uiactionsheet_spec.rb
343
348
  - spec/ios/uialertcontroller_spec.rb
344
349
  - spec/ios/uialertview_spec.rb