sugarcube 0.20.9 → 0.20.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|