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