sugarcube 2.8.2 → 2.9.1

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.
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