teacup 2.3.0 → 3.0.0
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 +4 -4
- data/README.md +59 -42
- data/lib/teacup-ios/style.rb +5 -1
- data/lib/teacup-osx/style.rb +11 -7
- data/lib/teacup/layout.rb +1 -1
- data/lib/teacup/stylesheet.rb +9 -6
- data/lib/teacup/teacup_controller.rb +42 -7
- data/lib/teacup/version.rb +1 -1
- data/spec/{limelight_spec.rb → ios/limelight_spec.rb} +0 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4821b6532d8a60017501696bb0ba85647b46974b
|
4
|
+
data.tar.gz: 00a8be407b48a624e3e07c735122871029228bc4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ed282b7d63702e9ffc0c72a2a5ea436ca989f41111d1c5e13172376da27160216c43806884f7fe0dd49e62fa6ca528c4a1cf12431c06817da41fed2458cbb4b
|
7
|
+
data.tar.gz: 7f61cfc625f369c9e53802b9aa28e3a1f016f888fc9936505942c4b093febcf02a9ea2edb120d5ec9daf92121d52c54a400326ebaead379ade403bd82b1ee125
|
data/README.md
CHANGED
@@ -63,7 +63,7 @@ require 'teacup'
|
|
63
63
|
class MyController < UIViewController
|
64
64
|
stylesheet :main_screen
|
65
65
|
|
66
|
-
|
66
|
+
def teacup_layout
|
67
67
|
subview(UIButton, :hi_button)
|
68
68
|
end
|
69
69
|
end
|
@@ -103,7 +103,7 @@ other GUI system ever*. :-|
|
|
103
103
|
class MyController < TeacupWindowController
|
104
104
|
stylesheet :main_window
|
105
105
|
|
106
|
-
|
106
|
+
def teacup_layout
|
107
107
|
subview(NSButton, :hi_button)
|
108
108
|
end
|
109
109
|
end
|
@@ -139,6 +139,36 @@ Teacup supports [Pixate][] and [NUI][], too, so you can use those systems for
|
|
139
139
|
styling and Teacup to manage your view hierarchy and apply auto-layout
|
140
140
|
constraints. Teacup can also integrate with the [motion-layout][] gem!
|
141
141
|
|
142
|
+
### Changes in 3.0
|
143
|
+
|
144
|
+
There is one significant change in version 3.0. In every version of Teacup
|
145
|
+
prior (from 0.2.0 to 2.3.0) the controller layout was usually created by calling
|
146
|
+
a class method called `layout`. It was discovered, embarrassingly late, that
|
147
|
+
this system is causing memory leaks. To fix it we had to remove this feature
|
148
|
+
altogether. So if you are looking at old Teacup examples, you will see this
|
149
|
+
block syntax that is no longer offered. It is easy to update to 3.0, though:
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
# <= 2.3.0
|
153
|
+
class MyController < UIViewController
|
154
|
+
layout(:root_stylename) do # <= this block is what caused the memory leak!
|
155
|
+
# teacup code goes here
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# 3.0
|
160
|
+
class MyController < UIViewController
|
161
|
+
def teacup_layout # in 3.0 we just changed it to be a method
|
162
|
+
# introduced in 3.0, this is how you assign a stylename to the root view
|
163
|
+
root(:root_stylename, { background: UIColor.blueColor })
|
164
|
+
# teacup code goes here - no other code changes necessary
|
165
|
+
end
|
166
|
+
# actually, this method still works as long as you don't pass a block. It's
|
167
|
+
# the same as calling `root(stylename, {})`
|
168
|
+
layout(:root_stylename, {})
|
169
|
+
end
|
170
|
+
```
|
171
|
+
|
142
172
|
### Table of Contents
|
143
173
|
|
144
174
|
* [Layouts](#layouts) — define your views
|
@@ -178,17 +208,18 @@ iOS, and `NSWindowController`, `NSViewController`, and `NSView` on OS X. These
|
|
178
208
|
classes can take advantage of the view-hierarchy DSL.
|
179
209
|
|
180
210
|
You saw an example in the primer, using the
|
181
|
-
`UIViewController`/`NSWindowController` class method `layout
|
182
|
-
|
183
|
-
|
211
|
+
`UIViewController`/`NSWindowController` class method `layout` and the
|
212
|
+
`teacup_layout` method. You could just as easily use Teacup's DSL to create
|
213
|
+
your views from a `loadView` method, for instance you might want to use a
|
214
|
+
custom view subclass as your root view. An example might look like this:
|
184
215
|
|
185
216
|
```ruby
|
186
217
|
# controller example
|
187
218
|
class MyController < UIViewController
|
188
219
|
|
189
|
-
def
|
190
|
-
# we will
|
191
|
-
|
220
|
+
def loadView
|
221
|
+
# we will create the controller's view, assigning it the stylename :root
|
222
|
+
self.view = layout(FancyView, :root) do
|
192
223
|
# these subviews will be added to `self.view`
|
193
224
|
subview(UIToolbar, :toolbar)
|
194
225
|
subview(UIButton, :hi_button)
|
@@ -243,9 +274,11 @@ The reason it is so easy to define view hierarchies in Teacup is because the
|
|
243
274
|
```ruby
|
244
275
|
subview(UIView, :container) do # create a UIView instance and give it the stylename :container
|
245
276
|
subview(UIView, :inputs) do # create another container
|
277
|
+
# these views will be added to the :inputs view
|
246
278
|
@email_input = subview(UITextField, :email_input)
|
247
279
|
@password_input = subview(UITextField, :password_input)
|
248
280
|
end
|
281
|
+
# this view will be added to :container
|
249
282
|
subview(UIButton.buttonWithType(UIButtonTypeRoundedRect), :submit_button)
|
250
283
|
end
|
251
284
|
```
|
@@ -255,7 +288,7 @@ to add your *own view helpers*! I refer to this as a "partials" system, but
|
|
255
288
|
really it's just Ruby code (and isn't that the best system?).
|
256
289
|
|
257
290
|
```ruby
|
258
|
-
# the methods you add here will be available in UIView/
|
291
|
+
# the methods you add here will be available in UIView/NSView,
|
259
292
|
# UIViewController/NSViewController/NSWindowController, and any of your own
|
260
293
|
# classes that `include Teacup::Layout`
|
261
294
|
module Teacup::Layout
|
@@ -297,7 +330,7 @@ end
|
|
297
330
|
```ruby
|
298
331
|
class MyController < UIViewController
|
299
332
|
|
300
|
-
|
333
|
+
def teacup_layout
|
301
334
|
@button1 = button()
|
302
335
|
@button2 = button(:blue_button)
|
303
336
|
@button3 = button_with_icon(UIImage.imageNamed('email_icon'), 'Email')
|
@@ -306,31 +339,14 @@ class MyController < UIViewController
|
|
306
339
|
end
|
307
340
|
```
|
308
341
|
|
309
|
-
The `Controller
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
```ruby
|
314
|
-
# defined in teacup/teacup_controller.rb as Teacup::Controller module
|
315
|
-
UIViewController.layout(stylename=nil, styles={}, &block)
|
316
|
-
NSViewController.layout(stylename=nil, styles={}, &block)
|
317
|
-
NSWindowController.layout(stylename=nil, styles={}, &block)
|
318
|
-
```
|
319
|
-
|
320
|
-
* `stylename` is the stylename you want applied to your controller's `self.view`
|
321
|
-
object.
|
322
|
-
* `styles` are *rarely* applied here, but one common use case is when you assign
|
323
|
-
a custom view in `loadView`, and you want to apply settings to it. I find it
|
324
|
-
cleaner to move this code into the body of the `layout` block, though.
|
325
|
-
* `&block` is the most important - it is the layout code that will be called
|
326
|
-
during `viewDidLoad`.
|
342
|
+
The `Controller#teacup_layout` method is going to be the first or second thing
|
343
|
+
you add to a controller when you are building an app with Teacup. Inside you
|
344
|
+
will add subviews using `subview` *or* you can create a view using the `layout`
|
345
|
+
method (`subview` delegates most of its work to `layout`)
|
327
346
|
|
328
347
|
After the views have been added and styles have been applied Teacup calls the
|
329
348
|
`layoutDidLoad` method. If you need to perform some additional initialization
|
330
|
-
on your views, you
|
331
|
-
the styles have not yet been applied. Frames will not be set, text and titles
|
332
|
-
will be empty, and images will not have images. This all happens at the *end*
|
333
|
-
of the `layout` block.
|
349
|
+
on your views, you can do it in this method.
|
334
350
|
|
335
351
|
Stylesheets
|
336
352
|
-----------
|
@@ -418,7 +434,7 @@ class MainController < UIViewController
|
|
418
434
|
|
419
435
|
stylesheet :main # <= assigns the stylesheet named :main to this controller
|
420
436
|
|
421
|
-
|
437
|
+
def teacup_layout
|
422
438
|
subview(UILabel, :h1) # <= :h1 is the stylename
|
423
439
|
end
|
424
440
|
|
@@ -442,7 +458,7 @@ We can tackle this a couple ways. You can apply "last-minute" styles in the
|
|
442
458
|
`layout` and `subview` methods:
|
443
459
|
|
444
460
|
```ruby
|
445
|
-
|
461
|
+
def teacup_layout
|
446
462
|
subview(UILabel, :h1,
|
447
463
|
# the `subview` and `layout` methods can apply styles
|
448
464
|
text: "Omg, it's full of stars"
|
@@ -473,7 +489,7 @@ not all our labels say "OMG", but we want to use our font from the `:h1` style.
|
|
473
489
|
We can tell the `:main_header` style that it `extends` the `:h1` style:
|
474
490
|
|
475
491
|
```ruby
|
476
|
-
|
492
|
+
def teacup_layout
|
477
493
|
subview(UILabel, :main_header)
|
478
494
|
end
|
479
495
|
|
@@ -936,7 +952,7 @@ springs and struts. And honestly, I recommend you try using the
|
|
936
952
|
|
937
953
|
But at the end of the day, once you really understand the auto-layout system
|
938
954
|
that Apple released in iOS 6, you can build your UIs to be responsive to
|
939
|
-
different devices, orientations, and sizes. UIs built with auto-layout
|
955
|
+
different devices, orientations, and sizes. UIs built with auto-layout not
|
940
956
|
usually need to adjust anything during a rotation. The constraints take *care*
|
941
957
|
of it all. It's impressive.
|
942
958
|
|
@@ -1007,7 +1023,7 @@ Teacup stylenames assigned to your views will be used in the dictionary that the
|
|
1007
1023
|
ASCII-based system relies on.
|
1008
1024
|
|
1009
1025
|
```ruby
|
1010
|
-
|
1026
|
+
def teacup_layout
|
1011
1027
|
subview(UIView, :view_a)
|
1012
1028
|
subview(UIView, :view_b)
|
1013
1029
|
subview(UIView, :view_c)
|
@@ -1214,7 +1230,8 @@ class SomeController < UIViewController
|
|
1214
1230
|
|
1215
1231
|
stylesheet :some_view
|
1216
1232
|
|
1217
|
-
|
1233
|
+
def teacup_layout
|
1234
|
+
root(:root)
|
1218
1235
|
subview(UITextField, :field)
|
1219
1236
|
@search = subview(UITextField, :search)
|
1220
1237
|
end
|
@@ -1298,7 +1315,7 @@ okay, because we have a chance to add these styles in the `subview` and `layout`
|
|
1298
1315
|
methods.
|
1299
1316
|
|
1300
1317
|
```ruby
|
1301
|
-
|
1318
|
+
def teacup_layout
|
1302
1319
|
subview(UITableView, delegate: self)
|
1303
1320
|
end
|
1304
1321
|
```
|
@@ -1309,7 +1326,7 @@ stylesheet is not necessarily applied immediately, these styles could be
|
|
1309
1326
|
overwritten before they take effect.
|
1310
1327
|
|
1311
1328
|
```ruby
|
1312
|
-
|
1329
|
+
def teacup_layout
|
1313
1330
|
table_view = subview(UITableView, :tableview, delegate: self,
|
1314
1331
|
font: UIFont.boldSystemFontOfSize(10) # the stylesheet could override this during rotation
|
1315
1332
|
)
|
@@ -1328,7 +1345,7 @@ More examples!
|
|
1328
1345
|
```ruby
|
1329
1346
|
class MyController < UIViewController
|
1330
1347
|
stylesheet :my_sheet
|
1331
|
-
|
1348
|
+
def teacup_layout
|
1332
1349
|
subview(UILabel, :label, text: 'overrides')
|
1333
1350
|
end
|
1334
1351
|
end
|
@@ -1387,7 +1404,7 @@ appear on many screens in an app. You should not shy away from adding teacup's
|
|
1387
1404
|
|
1388
1405
|
If you are using your controller as your table view dataSource, the `subview`
|
1389
1406
|
and `layout` methods continue to work as you expect them to. This is for the
|
1390
|
-
case when you are using a helper class.
|
1407
|
+
case when you are using a helper class as the dataSource and/or delegate.
|
1391
1408
|
|
1392
1409
|
```ruby
|
1393
1410
|
class TableHelper
|
data/lib/teacup-ios/style.rb
CHANGED
@@ -96,7 +96,11 @@ module Teacup
|
|
96
96
|
# if we know the class of the target, we can apply styles via class
|
97
97
|
# inheritance.
|
98
98
|
if target_class
|
99
|
-
target_class.
|
99
|
+
unless target_class.is_a?(Class)
|
100
|
+
target_class = target_class.class
|
101
|
+
end
|
102
|
+
|
103
|
+
target_class.ancestors.each do |ancestor|
|
100
104
|
extended_properties = stylesheet.query(ancestor, nil, rotation_orientation)
|
101
105
|
Teacup::merge_defaults!(properties, extended_properties)
|
102
106
|
end
|
data/lib/teacup-osx/style.rb
CHANGED
@@ -10,7 +10,7 @@ module Teacup
|
|
10
10
|
# orientation is completely ignored on OS X, but the Teacup code was written
|
11
11
|
# to support them, and it was easier to ignore the orientation system than
|
12
12
|
# refactor it out of the shared code base.
|
13
|
-
def build(
|
13
|
+
def build(target_class=nil, rotation_orientation=nil, seen={})
|
14
14
|
properties = Style.new
|
15
15
|
properties.stylename = self.stylename
|
16
16
|
properties.stylesheet = self.stylesheet
|
@@ -24,7 +24,7 @@ module Teacup
|
|
24
24
|
# local style
|
25
25
|
if stylesheet && stylesheet.is_a?(Teacup::Stylesheet)
|
26
26
|
stylesheet.imported_stylesheets.reverse.each do |stylesheet|
|
27
|
-
imported_properties = stylesheet.query(self.stylename,
|
27
|
+
imported_properties = stylesheet.query(self.stylename, target_class, rotation_orientation, seen)
|
28
28
|
delete_keys.each do |key|
|
29
29
|
imported_properties.delete(key)
|
30
30
|
end
|
@@ -37,7 +37,7 @@ module Teacup
|
|
37
37
|
# turn style names into Hashes by querying them on the stylesheet
|
38
38
|
# (this does not pass `seen`, because this is a new query)
|
39
39
|
also_includes.each do |also_include|
|
40
|
-
extended_properties = stylesheet.query(also_include,
|
40
|
+
extended_properties = stylesheet.query(also_include, target_class, rotation_orientation)
|
41
41
|
delete_keys.each do |key|
|
42
42
|
extended_properties.delete(key)
|
43
43
|
end
|
@@ -46,10 +46,14 @@ module Teacup
|
|
46
46
|
end
|
47
47
|
properties.delete(:extends)
|
48
48
|
|
49
|
-
# if we know the class of the
|
50
|
-
# inheritance. We do not pass `
|
51
|
-
if
|
52
|
-
|
49
|
+
# if we know the class of the target_class, we can apply styles via class
|
50
|
+
# inheritance. We do not pass `target_class` in this case.
|
51
|
+
if target_class
|
52
|
+
unless target_class.is_a?(Class)
|
53
|
+
target_class = target_class.class
|
54
|
+
end
|
55
|
+
|
56
|
+
target_class.ancestors.each do |ancestor|
|
53
57
|
extended_properties = stylesheet.query(ancestor, nil, rotation_orientation)
|
54
58
|
Teacup::merge_defaults!(properties, extended_properties)
|
55
59
|
end
|
data/lib/teacup/layout.rb
CHANGED
@@ -158,7 +158,7 @@ module Teacup
|
|
158
158
|
begin
|
159
159
|
# yield will not work if this is defined in the context of the
|
160
160
|
# UIViewController `layout` class method.
|
161
|
-
|
161
|
+
yield view
|
162
162
|
rescue NoMethodError => e
|
163
163
|
NSLog("Exception executing layout(#{view.inspect}) in #{self.inspect} (stylesheet=#{stylesheet})")
|
164
164
|
raise e
|
data/lib/teacup/stylesheet.rb
CHANGED
@@ -127,12 +127,15 @@ module Teacup
|
|
127
127
|
# @stylesheet_cache object is manipulated directly (to invalidate entries,
|
128
128
|
# or the entire cache)
|
129
129
|
def stylesheet_cache
|
130
|
-
@stylesheet_cache ||= Hash.new do |by_stylename,_stylename|
|
131
|
-
by_stylename[_stylename] = Hash.new do |by_target_class,_target_class|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
130
|
+
@stylesheet_cache ||= Hash.new(&lambda do |by_stylename,_stylename|
|
131
|
+
by_stylename[_stylename] = Hash.new(&lambda do |by_target_class,_target_class|
|
132
|
+
if _target_class && ! _target_class.is_a?(Class)
|
133
|
+
_target_class = _target_class.class
|
134
|
+
end
|
135
|
+
|
136
|
+
by_target_class[_target_class] = {}
|
137
|
+
end.weak!)
|
138
|
+
end.weak!)
|
136
139
|
end
|
137
140
|
|
138
141
|
def get_stylesheet_cache(stylename, target_class, orientation)
|
@@ -27,7 +27,8 @@ module Teacup
|
|
27
27
|
#
|
28
28
|
# @example
|
29
29
|
# class MyViewController < UIViewController
|
30
|
-
#
|
30
|
+
# def teacup_layout
|
31
|
+
# root :my_view
|
31
32
|
# subview UILabel, title: "Test"
|
32
33
|
# subview UITextField, {
|
33
34
|
# frame: [[200, 200], [100, 100]]
|
@@ -39,8 +40,25 @@ module Teacup
|
|
39
40
|
# end
|
40
41
|
# end
|
41
42
|
#
|
42
|
-
def layout(stylename=nil, properties={}
|
43
|
-
|
43
|
+
def layout(stylename=nil, properties={})
|
44
|
+
if block_given?
|
45
|
+
msg = <<-MSG
|
46
|
+
Time to update your syntax!
|
47
|
+
|
48
|
+
It was discovered that passing a block to the Controller##layout was causing
|
49
|
+
irreparable memory leaks. The only recourse is to use a new syntax and remove
|
50
|
+
the old functionality.
|
51
|
+
|
52
|
+
If you need to assign a stylename to the root view, you can still do this using
|
53
|
+
`layout :stylename`, but you cannot pass a block to this class method any
|
54
|
+
longer.
|
55
|
+
|
56
|
+
Instead, define a method called `teacup_layout` and create your views there. No
|
57
|
+
other changes are required.
|
58
|
+
MSG
|
59
|
+
raise msg
|
60
|
+
end
|
61
|
+
@layout_definition = [stylename, properties]
|
44
62
|
end
|
45
63
|
|
46
64
|
end
|
@@ -61,8 +79,8 @@ module Teacup
|
|
61
79
|
#
|
62
80
|
# @example
|
63
81
|
#
|
64
|
-
# stylesheet = Teacup::Stylesheet[:
|
65
|
-
# stylesheet = :
|
82
|
+
# stylesheet = Teacup::Stylesheet[:main]
|
83
|
+
# stylesheet = :main
|
66
84
|
def stylesheet=(new_stylesheet)
|
67
85
|
super
|
68
86
|
if self.viewLoaded?
|
@@ -70,6 +88,19 @@ module Teacup
|
|
70
88
|
end
|
71
89
|
end
|
72
90
|
|
91
|
+
def root(stylename=nil, properties={})
|
92
|
+
if stylename.is_a?(NSDictionary)
|
93
|
+
properties = stylename
|
94
|
+
stylename = nil
|
95
|
+
end
|
96
|
+
|
97
|
+
if stylename || properties
|
98
|
+
layout(top_level_view, stylename, properties)
|
99
|
+
else
|
100
|
+
top_level_view
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
73
104
|
# Instantiate the layout from the class, and then call layoutDidLoad.
|
74
105
|
#
|
75
106
|
# If you want to use Teacup in your controller, please hook into layoutDidLoad,
|
@@ -97,8 +128,12 @@ module Teacup
|
|
97
128
|
end
|
98
129
|
|
99
130
|
if layout_definition
|
100
|
-
stylename, properties
|
101
|
-
layout(top_level_view, stylename, properties
|
131
|
+
stylename, properties = layout_definition
|
132
|
+
layout(top_level_view, stylename, properties)
|
133
|
+
end
|
134
|
+
|
135
|
+
if respond_to?(:teacup_layout)
|
136
|
+
teacup_layout
|
102
137
|
end
|
103
138
|
|
104
139
|
layoutDidLoad
|
data/lib/teacup/version.rb
CHANGED
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: teacup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- the rubymotion community
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-07-22 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
Teacup is a community-driven DSL for RubyMotion. It has CSS-like styling, and
|
@@ -67,6 +67,7 @@ files:
|
|
67
67
|
- spec/ios/gradient_spec.rb
|
68
68
|
- spec/ios/layout_module_spec.rb
|
69
69
|
- spec/ios/layout_spec.rb
|
70
|
+
- spec/ios/limelight_spec.rb
|
70
71
|
- spec/ios/main_spec.rb
|
71
72
|
- spec/ios/memory_leak_spec.rb
|
72
73
|
- spec/ios/motion_layout_spec.rb
|
@@ -79,7 +80,6 @@ files:
|
|
79
80
|
- spec/ios/ui_view_getters_spec.rb
|
80
81
|
- spec/ios/uiswitch_spec.rb
|
81
82
|
- spec/ios/view_spec.rb
|
82
|
-
- spec/limelight_spec.rb
|
83
83
|
homepage: https://github.com/rubymotion/teacup
|
84
84
|
licenses:
|
85
85
|
- BSD
|
@@ -114,6 +114,7 @@ test_files:
|
|
114
114
|
- spec/ios/gradient_spec.rb
|
115
115
|
- spec/ios/layout_module_spec.rb
|
116
116
|
- spec/ios/layout_spec.rb
|
117
|
+
- spec/ios/limelight_spec.rb
|
117
118
|
- spec/ios/main_spec.rb
|
118
119
|
- spec/ios/memory_leak_spec.rb
|
119
120
|
- spec/ios/motion_layout_spec.rb
|
@@ -126,4 +127,3 @@ test_files:
|
|
126
127
|
- spec/ios/ui_view_getters_spec.rb
|
127
128
|
- spec/ios/uiswitch_spec.rb
|
128
129
|
- spec/ios/view_spec.rb
|
129
|
-
- spec/limelight_spec.rb
|