sugarcube 0.20.9 → 0.20.10
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.
- data/Gemfile.lock +1 -1
- data/README.md +192 -121
- data/lib/sugarcube/adjust.rb +5 -5
- data/lib/sugarcube/nsdata.rb +1 -1
- data/lib/sugarcube/nsstring.rb +1 -1
- data/lib/sugarcube/timer.rb +11 -0
- data/lib/sugarcube/version.rb +1 -1
- data/spec/timer_spec.rb +42 -15
- metadata +2 -2
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1293,8 +1293,7 @@ This file does *one* thing very **DANGEROUS**... to "help" with defaults.
|
|
1293
1293
|
When storing `nil` into `NSUserDefaults`, it is converted into `false`, because
|
1294
1294
|
Cocoa complains if you give it `nil`, and the RubyMotion runtime refuses to
|
1295
1295
|
allow the `NSNull.null` object. Without relying on an external project (like
|
1296
|
-
[nsnulldammit]
|
1297
|
-
sensible workaround...
|
1296
|
+
[nsnulldammit][] I don't know of a sensible workaround...
|
1298
1297
|
|
1299
1298
|
If you want to "tap into" the defaults system that SugarCube uses, add a
|
1300
1299
|
`to_nsuserdefaults` method and that will get called if you hand your object to
|
@@ -1302,37 +1301,31 @@ If you want to "tap into" the defaults system that SugarCube uses, add a
|
|
1302
1301
|
usefulness of this is very limited.
|
1303
1302
|
|
1304
1303
|
```ruby
|
1305
|
-
'key'
|
1306
|
-
'key'
|
1304
|
+
NSUserDefaults['key'] = ['any', 'objects'] # => NSUserDefaults.standardUserDefaults.setObject(['any', 'objects'], forKey: :key)
|
1305
|
+
NSUserDefaults['key'] # => NSUserDefaults.standardUserDefaults.objectForKey(:key)
|
1307
1306
|
|
1308
1307
|
# symbols are converted to strings, so these are equivalent
|
1309
|
-
:key
|
1310
|
-
:key
|
1308
|
+
NSUserDefaults[:key] = ['any', 'objects'] # => NSUserDefaults.standardUserDefaults.setObject(['any', 'objects'], forKey: :key)
|
1309
|
+
NSUserDefaults[:key] # => NSUserDefaults.standardUserDefaults.objectForKey(:key)
|
1311
1310
|
```
|
1312
1311
|
|
1313
|
-
|
1314
|
-
|
1312
|
+
Keep in mind that NSUserDefaults serializes the object you pass to it, it
|
1313
|
+
doesn't maintain a reference. That means that if you modify an object *in
|
1314
|
+
place*, it will not get persisted. An example will explain this better:
|
1315
1315
|
|
1316
1316
|
```ruby
|
1317
|
-
|
1318
|
-
|
1319
|
-
#
|
1320
|
-
|
1321
|
-
# k, BubbleWrap looks better
|
1317
|
+
NSUserDefaults['test'] = { my: 'test' }
|
1318
|
+
NSUserDefaults['test']['my'] == 'test'
|
1319
|
+
# NSUserDefaults['test'] returns the hash, and the 'my' key returns 'test', so
|
1320
|
+
# this comparison returns `true`
|
1322
1321
|
|
1323
|
-
|
1324
|
-
|
1322
|
+
# but there is a temptation, perhaps, to modify that hash:
|
1323
|
+
NSUserDefaults['test']['my'] = 'new' # BUG
|
1325
1324
|
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
test =
|
1330
|
-
test[:my] = 'new'
|
1331
|
-
App::Persistance[:test] = test # saved
|
1332
|
-
|
1333
|
-
test = :test.get_default
|
1334
|
-
test[:my] = 'new'
|
1335
|
-
:test.set_default test
|
1325
|
+
# the corrected code
|
1326
|
+
test = NSUserDefaults['test']
|
1327
|
+
test['my'] = 'new'
|
1328
|
+
NSUserDefaults['test'] = test # saved
|
1336
1329
|
```
|
1337
1330
|
|
1338
1331
|
CoreGraphics
|
@@ -1344,17 +1337,14 @@ Instead, just use the coercion methods `Rect()`, `Size()` and `Point()`. They
|
|
1344
1337
|
will happily convert most sensible (and some non-sensible) arguments into a
|
1345
1338
|
`CGRect/CGSize/CGPoint` struct.
|
1346
1339
|
|
1340
|
+
These are namespaced in the `SugarCube::CoreGraphics` module, but I recommend
|
1341
|
+
you `include SugarCube::CoreGraphics` in app_delegate.rb.
|
1342
|
+
|
1347
1343
|
For more CoreGraphics additions, you should use [geomotion][] by [Clay
|
1348
1344
|
Allsopp][]. It adds methods to `CGRect`, `CGPoint`, and `CGSize` to make these
|
1349
1345
|
structures more rubyesque (these methods used to be part of SugarCube, but were
|
1350
1346
|
removed in an attempt to decrease the amount of duplicated code).
|
1351
1347
|
|
1352
|
-
[geomotion]: https://github.com/clayallsopp
|
1353
|
-
[Clay Allsopp]: https://github.com/clayallsopp/geomotion
|
1354
|
-
|
1355
|
-
These are namespaced in the `SugarCube::CoreGraphics` module, but I recommend
|
1356
|
-
you `include SugarCube::CoreGraphics` in app_delegate.rb.
|
1357
|
-
|
1358
1348
|
```ruby
|
1359
1349
|
f = Rect(view.frame) # the identity function - returns a copy of the CGRect
|
1360
1350
|
o = Point(view.frame.origin) # returns a copy of CGPoint
|
@@ -1369,12 +1359,11 @@ f = Rect(x, y, w, h)
|
|
1369
1359
|
f = Rect([x, y], [w, h])
|
1370
1360
|
# one array
|
1371
1361
|
f = Rect([[x, y], [w, h]])
|
1372
|
-
f = Rect([x, y, w, h])
|
1373
1362
|
# a CGPoint and CGSize
|
1374
1363
|
p = Point(x, y) # or just [x, y] works, too
|
1375
1364
|
s = Size(w, h) # again, [w, h] is fine
|
1376
1365
|
f = Rect(p, s)
|
1377
|
-
# any combination of
|
1366
|
+
# any combination of point/array and size/array
|
1378
1367
|
f = Rect(p, [w, h])
|
1379
1368
|
f = Rect([x, y], s)
|
1380
1369
|
```
|
@@ -1405,77 +1394,122 @@ Open up `CLLocationCoordinate2D` to provide handy-dandies
|
|
1405
1394
|
-----------------------
|
1406
1395
|
|
1407
1396
|
Pixel pushing is an unfortunate but necessary evil. Well, at least we can make
|
1408
|
-
it a little less painful.
|
1397
|
+
it a little less painful. SugarCube provides a library that adds some methods
|
1398
|
+
that are meant to be used in the REPL.
|
1399
|
+
|
1400
|
+
`require "sugarcube-repl"`
|
1401
|
+
|
1402
|
+
The actual code is, for historical reasons, in the `SugarCube::Adjust` module,
|
1403
|
+
which is included by default. But to really be handy you'll want to require the
|
1404
|
+
`sugarcube-repl` package.
|
1405
|
+
|
1406
|
+
#### Finding the view you want.
|
1407
|
+
|
1408
|
+
This is often touted as the *most useful feature* of SugarCube!
|
1409
|
+
|
1410
|
+
```
|
1411
|
+
(main)> tree
|
1412
|
+
0: . UIWindow(#6e1f950: [[0.0, 0.0], [320.0, 480.0]])
|
1413
|
+
1: `-- UIView(#8b203b0: [[0.0, 20.0], [320.0, 460.0]])
|
1414
|
+
2: +-- UIButton(#d028de0: [[10.0, 10.0], [320.0, 463.400512695312]])
|
1415
|
+
3: | `-- UIImageView(#d02aaa0: [[0.0, 0.0], [320.0, 463.400512695312]])
|
1416
|
+
4: +-- UIRoundedRectButton(#d02adb0: [[55.0, 110.0], [210.0, 20.0]])
|
1417
|
+
5: | `-- UIButtonLabel(#d02af00: [[73.0, 0.0], [63.0, 19.0]], text: "Button 1")
|
1418
|
+
6: +-- UIRoundedRectButton(#d028550: [[60.0, 30.0], [200.0, 20.0]])
|
1419
|
+
7: | `-- UIButtonLabel(#d02afb0: [[68.0, 0.0], [63.0, 19.0]], text: "Button 2")
|
1420
|
+
8: `-- UIRoundedRectButton(#d02b220: [[70.0, 30.0], [300.0, 20.0]])
|
1421
|
+
9: `-- UIButtonLabel(#d02b300: [[118.0, 0.0], [63.0, 19.0]], text: "Button 3")
|
1422
|
+
```
|
1423
|
+
|
1424
|
+
SugarCube provides lot of `to_s` methods on UIKit objects - that is so that this
|
1425
|
+
tree view is really easy to find the view you want. Once you do find the one
|
1426
|
+
you want, you can fetch it out of that list using the `adjust` method, which is
|
1427
|
+
aliased to `a` to make it easy on the fingers.
|
1409
1428
|
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1429
|
+
```
|
1430
|
+
(main)> a 6
|
1431
|
+
=> UIRoundedRectButton(#d028550: [[60.0, 30.0], [200.0, 20.0]]), child of UIView(#8b203b0)
|
1432
|
+
```
|
1413
1433
|
|
1414
|
-
|
1434
|
+
Now that we've chose the button, it is available in the `a` method, *and* there
|
1435
|
+
are a bunch of methods in the SugarCube::Adjust module that act on that object.
|
1436
|
+
Most of these methods help you adjust the frame of a view.
|
1415
1437
|
|
1416
1438
|
```ruby
|
1417
|
-
# if you are in the REPL, you might not be able to click on the view you want...
|
1418
|
-
> adjust superview.subviews[4].subviews[1]
|
1419
1439
|
> up 1
|
1420
|
-
> down 1 # same as up -1
|
1440
|
+
> down 1 # same as `up -1`
|
1421
1441
|
> down # defaults to 1 anyway
|
1422
|
-
> left
|
1423
|
-
> right
|
1442
|
+
> left 10
|
1443
|
+
> right 10
|
1424
1444
|
> left # => left 1
|
1425
1445
|
> origin 10, 12 # move to x:10, y:12
|
1426
|
-
> wider
|
1427
|
-
> thinner
|
1446
|
+
> wider 15
|
1447
|
+
> thinner 10
|
1428
1448
|
> taller # => taller 1
|
1429
1449
|
> shorter # => shorter 1
|
1430
1450
|
> size 100, 10 # set size to width:100, height: 10
|
1431
|
-
> shadow(opacity: 0.5, offset: [0, 0], color: :black, radius: 1)
|
1451
|
+
> shadow(opacity: 0.5, offset: [0, 0], color: :black, radius: 1) # and path, which is a CGPath object.
|
1432
1452
|
> center # See `Centering` section below
|
1433
|
-
> restore # original frame and shadow is saved when you call `adjust`
|
1453
|
+
> restore # original frame and shadow is saved when you first call `adjust`
|
1434
1454
|
```
|
1435
1455
|
|
1456
|
+
Here are the short versions of those methods.
|
1457
|
+
|
1436
1458
|
```ruby
|
1437
|
-
> # short versions!
|
1438
|
-
> a superview.subviews[4].subviews[1] # this is not uncommon in the REPL
|
1439
1459
|
> u # up, default value=1
|
1440
1460
|
> d # down
|
1441
1461
|
> l # left
|
1442
1462
|
> r # right
|
1443
|
-
> o 10, 12 # origin, also accepts an array (or Point() object)
|
1444
1463
|
> w # wider
|
1445
|
-
> n #
|
1464
|
+
> n # thiNNer
|
1446
1465
|
> t # taller
|
1447
1466
|
> s # shorter
|
1448
|
-
>
|
1449
|
-
>
|
1450
|
-
>
|
1451
|
-
>
|
1452
|
-
|
1453
|
-
|
1467
|
+
> o 10, 12 # origin
|
1468
|
+
> o [10, 12]
|
1469
|
+
> o CGPoint.new(10, 12)
|
1470
|
+
> o Point(10, 12)
|
1471
|
+
> z 100, 10 # siZe, also accepts an array, CGSize, or Size()
|
1472
|
+
# and frame
|
1473
|
+
> f [[0,0], [0,0]]
|
1474
|
+
# sHadow
|
1475
|
+
> h opacity: 0.5, offset: [0, 0], color: :black, radius: 1
|
1476
|
+
|
1477
|
+
# frame, size, origin, and shadow can also be used as getters
|
1478
|
+
> f
|
1479
|
+
[[0, 0], [320, 568]]
|
1480
|
+
> o # origin
|
1454
1481
|
[0, 0]
|
1455
|
-
> z
|
1456
|
-
[320,
|
1457
|
-
> h
|
1482
|
+
> z # size
|
1483
|
+
[320, 568]
|
1484
|
+
> h # this returns an object identical to what you can pass to `shadow`
|
1485
|
+
{opacity: 0.5, offset: [0, 0], color: :black, radius: 1}
|
1458
1486
|
|
1459
|
-
#
|
1487
|
+
# and of course the `a` method returns the current object
|
1460
1488
|
> a
|
1461
|
-
=> UITextField(#9ce6470,
|
1489
|
+
=> UITextField(#9ce6470, [[46, 214], [280, 33]], text: "hi!"), child of UIView(#10a6da20)
|
1462
1490
|
```
|
1463
1491
|
|
1464
1492
|
The most useful feature of the REPL adjustment is the ability to quickly
|
1465
1493
|
position and size your UI elements __visually__ and then paste the final values
|
1466
1494
|
into your code. In order to better accomodate that, `adjust` has an option to
|
1467
|
-
modify the output format.
|
1468
|
-
|
1495
|
+
modify the output format. Many thanks to [Thom Parkin][] for developing these
|
1496
|
+
output formatters.
|
1497
|
+
|
1498
|
+
```
|
1499
|
+
(main)> repl_format :ruby
|
1500
|
+
```
|
1501
|
+
|
1502
|
+
Currently supported is:
|
1469
1503
|
|
1470
|
-
|
1471
|
-
* Default (RubyMotion) (`nil`, `:default`)
|
1504
|
+
* RubyMotion (Default) (`:ruby`)
|
1472
1505
|
* Objective-C (`:objc`)
|
1473
1506
|
* JSON (`:json`)
|
1474
1507
|
|
1475
1508
|
#### Objective-C style
|
1476
1509
|
|
1477
1510
|
```
|
1478
|
-
(
|
1511
|
+
(main)> repl_format :objc
|
1512
|
+
(main)> tree
|
1479
1513
|
0: . UIWindow(#6e27180: {{0, 0}, {320, 480}})
|
1480
1514
|
1: `-- UIView(#8d631b0: {{0, 20}, {320, 460}})
|
1481
1515
|
2: +-- UIButton(#6d6c090: {{10, 10}, {320, 463.401}})
|
@@ -1485,47 +1519,44 @@ This better facilitates copy/paste of the values. Currently supported is:
|
|
1485
1519
|
=> UIWindow(#6e27180, {{0, 0}, {320, 480}},
|
1486
1520
|
|
1487
1521
|
# you can pass the format into the adjust method:
|
1488
|
-
(
|
1489
|
-
=> "UIRoundedRectButton(#8d68170:
|
1490
|
-
|
1491
|
-
# or you can assign repl_format explicitly (adjust does this for you when you hand it a format)
|
1492
|
-
(UIImageView(#8d67e00, {{0, 0},...)> repl_format :objc
|
1493
|
-
=> :objc
|
1522
|
+
(main)> a 4, :objc
|
1523
|
+
=> "UIRoundedRectButton(#8d68170: {{10.0, 30.0}, {200.0, 30.0}})"
|
1494
1524
|
|
1495
|
-
#
|
1496
|
-
(
|
1497
|
-
|
1498
|
-
=> "UIRoundedRectButton(#8d68170:
|
1525
|
+
# it will continue to be used in subsequent calls
|
1526
|
+
(main)> wider 15
|
1527
|
+
{{10.0, 30.0}, {200.0, 45.0}}
|
1528
|
+
=> "UIRoundedRectButton(#8d68170: {{10.0, 30.0}, {200.0, 45.0}}) child of UIView(#8d631b0)"
|
1499
1529
|
```
|
1500
1530
|
|
1501
1531
|
#### JSON (or GeoMotion)
|
1502
1532
|
|
1503
1533
|
```
|
1504
|
-
(
|
1505
|
-
=> "UIView(#8d631b0:
|
1506
|
-
(
|
1507
|
-
=> "CGRect(#6e9c9f0:
|
1508
|
-
(
|
1509
|
-
=> "CGRect(#8dc6a40:
|
1510
|
-
(
|
1511
|
-
0: . UIWindow(#6e27180:
|
1512
|
-
1: `-- UIView(#8d631b0:
|
1513
|
-
2: +-- UIButton(#6d6c090:
|
1514
|
-
3: | `-- UIImageView(#8d67e00:
|
1515
|
-
4: `-- UIRoundedRectButton(#8d68170:
|
1516
|
-
5: `-- UIButtonLabel(#8d69c30:
|
1517
|
-
=> UIWindow(#6e27180
|
1534
|
+
(main)> a 1, :json
|
1535
|
+
=> "UIView(#8d631b0: {x: 0.0, y: 20.0, height: 460.0, width: 320.0})"
|
1536
|
+
(main)> wider 30
|
1537
|
+
=> "CGRect(#6e9c9f0: {x: 0.0, y: 20.0, height: 460.0, width: 350.0})"
|
1538
|
+
(main)> right 130
|
1539
|
+
=> "CGRect(#8dc6a40: {x: 130.0, y: 20.0, height: 460.0, width: 350.0})"
|
1540
|
+
(main)> tree
|
1541
|
+
0: . UIWindow(#6e27180: {x: 0.0, y: 0.0, height: 480.0, width: 320.0})
|
1542
|
+
1: `-- UIView(#8d631b0: {x: 130.0, y: 20.0, height: 460.0, width: 350.0})
|
1543
|
+
2: +-- UIButton(#6d6c090: {x: 10.0, y: 10.0, height: 463.400512695312, width: 320.0})
|
1544
|
+
3: | `-- UIImageView(#8d67e00: {x: 0.0, y: 0.0, height: 463.400512695312, width: 320.0})
|
1545
|
+
4: `-- UIRoundedRectButton(#8d68170: {x: 10.0, y: 30.0, height: 200.0, width: 45.0})
|
1546
|
+
5: `-- UIButtonLabel(#8d69c30: {x: 4.0, y: 90.0, height: 19.0, width: 37.0})
|
1547
|
+
=> UIWindow(#6e27180: {x: 0.0, y: 0.0, height: 480.0, width: 320.0})
|
1518
1548
|
```
|
1519
1549
|
|
1520
|
-
Note: The `format` parameter can be passed as either a symbol or a string
|
1521
|
-
|
1522
1550
|
### CENTER (in parent frame)
|
1523
|
-
It is called as `center(which_element, of_total_number, horizontal_or_vertical, verbose_output)`
|
1524
|
-
#### you can set 'direction' with any number of forms: 'horiz', 'vert', 'x', 'x and y'
|
1525
1551
|
|
1526
|
-
|
1552
|
+
It is called as `center(which_index, of_total_number, direction)`. The order can
|
1553
|
+
be changed, and all the arguments are optional. Default values are
|
1554
|
+
`center(1, 1, 'h')` (center the item horizontally).
|
1527
1555
|
|
1528
|
-
|
1556
|
+
You can set 'direction' using a string or symbol: 'horiz', 'vert', 'x', even 'x
|
1557
|
+
and y'. The method searches for the letters `[xyhv]`.
|
1558
|
+
|
1559
|
+
Here are a few examples:
|
1529
1560
|
|
1530
1561
|
```
|
1531
1562
|
(main)> center
|
@@ -1534,48 +1565,53 @@ UIRoundedRectButton.origin = [145.0, 30.0]
|
|
1534
1565
|
=> "[[145.0, 30.0], [30.0, 200.0]]"
|
1535
1566
|
```
|
1536
1567
|
|
1537
|
-
In order to place that same button in the
|
1538
|
-
|
1568
|
+
In order to place that same button in the center of the screen - horizontally
|
1569
|
+
and vertically - you can use this shorthand syntax:
|
1570
|
+
|
1571
|
+
`center :xy`
|
1539
1572
|
|
1540
|
-
|
1573
|
+
If you have three buttons and want them spaced evenly (vertically) across their
|
1574
|
+
parent frame, you can accomplish that this way:
|
1541
1575
|
|
1542
|
-
If you have three buttons and want them spaced evenly (vertically) across their parent frame, you can call it this way:
|
1543
1576
|
```
|
1544
1577
|
(main)> tree
|
1545
1578
|
0: . UIWindow(#6e1f950: [[0.0, 0.0], [320.0, 480.0]])
|
1546
1579
|
1: `-- UIView(#8b203b0: [[0.0, 20.0], [320.0, 460.0]])
|
1547
|
-
2: +-- UIButton(#d028de0: [[10.0, 10.0], [320.0,
|
1548
|
-
3: | `-- UIImageView(#d02aaa0: [[0.0, 0.0], [320.0,
|
1549
|
-
4: +-- UIRoundedRectButton(#d02adb0: [[55.0, 110.0], [210.0, 20.0]])
|
1580
|
+
2: +-- UIButton(#d028de0: [[10.0, 10.0], [320.0, 464]])
|
1581
|
+
3: | `-- UIImageView(#d02aaa0: [[0.0, 0.0], [320.0, 464]])
|
1582
|
+
4: +-- UIRoundedRectButton(#d02adb0: [[55.0, 110.0], [210.0, 20.0]], text: "Button 1")
|
1550
1583
|
5: | `-- UIButtonLabel(#d02af00: [[73.0, 0.0], [63.0, 19.0]])
|
1551
|
-
6: +-- UIRoundedRectButton(#d028550: [[60.0, 30.0], [200.0, 20.0]])
|
1584
|
+
6: +-- UIRoundedRectButton(#d028550: [[60.0, 30.0], [200.0, 20.0]], text: "Button 2")
|
1552
1585
|
7: | `-- UIButtonLabel(#d02afb0: [[68.0, 0.0], [63.0, 19.0]])
|
1553
|
-
8: `-- UIRoundedRectButton(#d02b220: [[70.0, 30.0], [300.0, 20.0]])
|
1586
|
+
8: `-- UIRoundedRectButton(#d02b220: [[70.0, 30.0], [300.0, 20.0]], text: "Button 3")
|
1554
1587
|
9: `-- UIButtonLabel(#d02b300: [[118.0, 0.0], [63.0, 19.0]])
|
1555
1588
|
=> UIWindow(#6e1f950, [[0.0, 0.0], [320.0, 480.0]])
|
1556
|
-
|
1557
|
-
|
1589
|
+
# grab the first button, and center it vertically. It is the first of three buttons
|
1590
|
+
(main)> a 4; center 1, 3, :vert; center
|
1558
1591
|
[[55.0, 110.0], [210.0, 20.0]]
|
1559
1592
|
UIRoundedRectButton.origin = [55.0, 110.0]
|
1560
1593
|
=> "[[55.0, 110.0], [210.0, 20.0]]"
|
1561
|
-
|
1562
|
-
|
1594
|
+
# grab the second button. The first parameter changes to `2`, because this
|
1595
|
+
# button is in the second position.
|
1596
|
+
(main)> a 6; center 2, 3, :vert; center
|
1563
1597
|
[[60.0, 220.0], [200.0, 20.0]]
|
1564
1598
|
UIRoundedRectButton.origin = [60.0, 220.0]
|
1565
1599
|
=> "[[60.0, 220.0], [200.0, 20.0]]"
|
1566
|
-
|
1567
|
-
|
1600
|
+
# grab the third button and place it in the third position
|
1601
|
+
(main)> a 8; center 3, 3, :vert; center
|
1568
1602
|
[[10.0, 330.0], [300.0, 20.0]]
|
1569
1603
|
UIRoundedRectButton.origin = [10.0, 330.0]
|
1570
1604
|
=> "[[10.0, 330.0], [300.0, 20.0]]"
|
1571
1605
|
```
|
1606
|
+
|
1572
1607
|
The calculated positions (x,y) are in the REPL output
|
1573
1608
|
|
1609
|
+
#### Finding the *[controller,layer,...]* you want.
|
1574
1610
|
|
1575
1611
|
**Don't stop there!**
|
1576
1612
|
|
1577
|
-
You can analyze `UIViewController` hierarchies, too. There's even
|
1578
|
-
`root` method to grab the `rootViewController`:
|
1613
|
+
You can analyze `UIViewController` and `CALayer` hierarchies, too. There's even
|
1614
|
+
a handy `root` method to grab the `rootViewController`:
|
1579
1615
|
|
1580
1616
|
```ruby
|
1581
1617
|
(main)> tree root
|
@@ -1591,7 +1627,36 @@ You can analyze `UIViewController` hierarchies, too. There's even a handy
|
|
1591
1627
|
=> #<MainScreenController:0xac23b80>
|
1592
1628
|
```
|
1593
1629
|
|
1594
|
-
|
1630
|
+
If you have a tree structure and you want to output it using `tree`, you can do
|
1631
|
+
so by passing either a method name (that should return an array) or a block. The
|
1632
|
+
block will be passed your object, and should return the children.
|
1633
|
+
|
1634
|
+
```ruby
|
1635
|
+
class Foo
|
1636
|
+
attr_accessor :children
|
1637
|
+
end
|
1638
|
+
```
|
1639
|
+
```
|
1640
|
+
(main)> foo = Foo.new
|
1641
|
+
(main)> foo.children = [Foo.new,Foo.new,Foo.new]
|
1642
|
+
(main)> tree foo, :children
|
1643
|
+
(main)> tree foo, :children
|
1644
|
+
0: . #<Foo:0x12d6e0d0>
|
1645
|
+
1: +-- #<Foo:0x114146c0>
|
1646
|
+
2: +-- #<Foo:0x114149d0>
|
1647
|
+
3: `-- #<Foo:0x114149e0>
|
1648
|
+
|
1649
|
+
=> #<Foo:0x12d6e0d0 @children=[#<Foo:0x114146c0>, #<Foo:0x114149d0>, #<Foo:0x114149e0>]>
|
1650
|
+
(main)> tree(foo) { |f| f.children }
|
1651
|
+
0: . #<Foo:0x12d6e0d0>
|
1652
|
+
1: +-- #<Foo:0x114146c0>
|
1653
|
+
2: +-- #<Foo:0x114149d0>
|
1654
|
+
3: `-- #<Foo:0x114149e0>
|
1655
|
+
|
1656
|
+
=> #<Foo:0x12d6e0d0 @children=[#<Foo:0x114146c0>, #<Foo:0x114149d0>, #<Foo:0x114149e0>]>
|
1657
|
+
```
|
1658
|
+
|
1659
|
+
##### Global objects
|
1595
1660
|
|
1596
1661
|
The adjust and tree methods act on global objects. Once either of these methods
|
1597
1662
|
is used, you can access that global if you want:
|
@@ -1611,6 +1676,7 @@ convention.
|
|
1611
1676
|
```ruby
|
1612
1677
|
[0.0, 1.1, 2.2].to_pointer(:float)
|
1613
1678
|
|
1679
|
+
# is equivalent to
|
1614
1680
|
floats = Pointer.new(:float, 3)
|
1615
1681
|
floats[0] = 0.0
|
1616
1682
|
floats[1] = 1.1
|
@@ -1633,12 +1699,6 @@ Quick wrapper for `CFUUIDCreate()` and `CFUUIDCreateString()`. Identical to the
|
|
1633
1699
|
# => "0A3A76C6-9738-4458-969E-3B9DF174A3D9"
|
1634
1700
|
```
|
1635
1701
|
|
1636
|
-
[BubbleWrap]: https://github.com/rubymotion/BubbleWrap
|
1637
|
-
[sweettea]: https://github.com/colinta/sweettea
|
1638
|
-
[teacup]: https://github.com/rubymotion/teacup
|
1639
|
-
[Fusionbox]: http://www.fusionbox.com/
|
1640
|
-
[fusionbox announcement]: http://fusionbox.org/projects/rubymotion-sugarcube/
|
1641
|
-
|
1642
1702
|
Ruby on Rails Ripoffs (RoR-R?)
|
1643
1703
|
---------------
|
1644
1704
|
|
@@ -1735,3 +1795,14 @@ foo.instance_variable_set(var_name.ivar, value) # => foo.instance_variable_set(
|
|
1735
1795
|
# (:symbol || 'string').cvar
|
1736
1796
|
Baz.class_variable_set(var_name.cvar, value) # => Baz.class_variable_set("@@#{var_name}", value)
|
1737
1797
|
```
|
1798
|
+
|
1799
|
+
[BubbleWrap]: https://github.com/rubymotion/BubbleWrap
|
1800
|
+
[sweettea]: https://github.com/colinta/sweettea
|
1801
|
+
[teacup]: https://github.com/rubymotion/teacup
|
1802
|
+
[nsnulldammit]: https://github.com/colinta/nsnulldammit
|
1803
|
+
[geomotion]: https://github.com/clayallsopp/geomotion
|
1804
|
+
|
1805
|
+
[Fusionbox]: http://www.fusionbox.com/
|
1806
|
+
[fusionbox announcement]: http://fusionbox.org/projects/rubymotion-sugarcube/
|
1807
|
+
[Clay Allsopp]: https://github.com/clayallsopp
|
1808
|
+
[Thom Parkin]: https://github.com/ParkinT
|
data/lib/sugarcube/adjust.rb
CHANGED
@@ -196,13 +196,13 @@ module SugarCube
|
|
196
196
|
top = view.origin.y
|
197
197
|
|
198
198
|
if /h|x/.match(direction.downcase)
|
199
|
-
swidth = view.frame.width
|
200
|
-
pwidth = view.superview.frame.width / total
|
199
|
+
swidth = view.frame.size.width
|
200
|
+
pwidth = view.superview.frame.size.width / total
|
201
201
|
left = (pwidth - swidth) / 2 + pwidth * (element - 1)
|
202
202
|
end
|
203
203
|
if /v|y/.match(direction.downcase)
|
204
|
-
sheight = view.frame.height
|
205
|
-
pheight = view.superview.frame.height / total
|
204
|
+
sheight = view.frame.size.height
|
205
|
+
pheight = view.superview.frame.size.height / total
|
206
206
|
top = (pheight - sheight) / 2 + pheight * (element - 1)
|
207
207
|
end
|
208
208
|
|
@@ -393,7 +393,7 @@ module SugarCube
|
|
393
393
|
when :ruby then
|
394
394
|
"[[#{frame.origin.x}, #{frame.origin.y}], [#{frame.size.width}, #{frame.size.height}]]"
|
395
395
|
when :objc
|
396
|
-
frame.
|
396
|
+
"{{#{frame.origin.x}, #{frame.origin.y}}, {#{frame.size.width}, #{frame.size.height}}}"
|
397
397
|
else
|
398
398
|
raise "Unknown repl_format #{SugarCube::Adjust::repl_format.inspect}"
|
399
399
|
end
|
data/lib/sugarcube/nsdata.rb
CHANGED
data/lib/sugarcube/nsstring.rb
CHANGED
data/lib/sugarcube/timer.rb
CHANGED
@@ -100,3 +100,14 @@ module SugarCube
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
end
|
103
|
+
|
104
|
+
|
105
|
+
class NSTimer
|
106
|
+
def self.every(time, user_info=nil, &fire)
|
107
|
+
time.every user_info, &fire
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.after(time, user_info=nil, &fire)
|
111
|
+
time.later user_info, &fire
|
112
|
+
end
|
113
|
+
end
|
data/lib/sugarcube/version.rb
CHANGED
data/spec/timer_spec.rb
CHANGED
@@ -97,25 +97,52 @@ describe "Numeric Timer methods" do
|
|
97
97
|
2.years.in_years.should == 2
|
98
98
|
end
|
99
99
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
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
|
+
}
|
104
120
|
end
|
105
|
-
wait 1 {
|
106
|
-
@later.should == true
|
107
|
-
}
|
108
121
|
end
|
109
122
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
@
|
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
|
+
}
|
114
133
|
end
|
115
|
-
|
116
|
-
|
117
|
-
@
|
118
|
-
|
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
|
+
|
119
146
|
end
|
120
147
|
|
121
148
|
end
|
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: 0.20.
|
4
|
+
version: 0.20.10
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2013-04-
|
16
|
+
date: 2013-04-20 00:00:00.000000000 Z
|
17
17
|
dependencies: []
|
18
18
|
description: ! '== Description
|
19
19
|
|