motion-kit 0.10.11 → 0.11.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 +92 -2
- data/lib/motion-kit/calculator/calculate.rb +1 -1
- data/lib/motion-kit/calculator/view_calculator.rb +5 -5
- data/lib/motion-kit/layouts/base_layout.rb +21 -15
- data/lib/motion-kit/layouts/base_layout_class_methods.rb +2 -7
- data/lib/motion-kit/layouts/tree_layout.rb +141 -106
- data/lib/motion-kit/object.rb +0 -9
- data/lib/motion-kit/version.rb +1 -1
- data/lib/motion-kit-cocoa/constraints/constraint.rb +11 -12
- data/lib/motion-kit-cocoa/constraints/constraint_placeholder.rb +3 -3
- data/lib/motion-kit-cocoa/constraints/constraints_layout.rb +103 -58
- data/lib/motion-kit-ios/layouts/constraints_layout.rb +4 -2
- data/lib/motion-kit-ios/layouts/uiview_layout.rb +0 -17
- data/lib/motion-kit-ios/layouts/uiview_layout_constraints.rb +10 -10
- data/lib/motion-kit-ios/layouts/uiview_layout_frame.rb +1 -1
- data/lib/motion-kit-osx/layouts/constraints_layout.rb +18 -16
- data/lib/motion-kit-osx/layouts/nstableview_layout.rb +13 -0
- data/lib/motion-kit-osx/layouts/nsview_layout.rb +0 -19
- data/lib/motion-kit-osx/layouts/nsview_layout_constraints.rb +10 -10
- data/lib/motion-kit-osx/layouts/nsview_layout_frame.rb +1 -1
- data/lib/motion-kit-osx/layouts/nswindow_layout.rb +0 -49
- data/spec/ios/apply_styles_spec.rb +27 -12
- data/spec/ios/calayer_spec.rb +9 -0
- data/spec/ios/child_layouts_spec.rb +53 -0
- data/spec/ios/constraints_helpers/scale_constraints_spec.rb +62 -0
- data/spec/ios/create_layout_spec.rb +1 -1
- data/spec/ios/custom_root_layout_spec.rb +1 -1
- data/spec/ios/frame_helper_spec.rb +2 -2
- data/spec/ios/layout_spec.rb +3 -20
- data/spec/ios/layout_state_spec.rb +1 -1
- data/spec/ios/motionkit_util_spec.rb +0 -87
- data/spec/ios/reapply_frame.rb +0 -2
- data/spec/ios/relative_layout.spec.rb +2 -2
- data/spec/ios/remove_layout_spec.rb +2 -3
- data/spec/ios/view_attr_spec.rb +7 -0
- data/spec/osx/constraints_helpers/table_view_spec.rb +34 -0
- data/spec/osx/custom_root_layout_spec.rb +1 -1
- data/spec/osx/frame_helper_spec.rb +2 -2
- metadata +10 -3
- data/lib/motion-kit-cocoa/cocoa_util.rb +0 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e90a4e2a89071ea4a7c57be68a26bcef7b868a84
|
4
|
+
data.tar.gz: 4ac95d41d19e21264920f090de6a5516c226d331
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 884f0edc12798df07d0f82b0396d6cbdb48f5eb4fa2da67c2554259403e7402c8de6f7076a26d473bd1f5de385b8216efd3bf944e838ec5573fe4a15ec131c5d
|
7
|
+
data.tar.gz: bec3426f2ffe80d9f47a7d6f0423816b3595a5474753893a00d6e9caf022b781347beb944a6fea3a690924f24911f18a243dd966404cd819a78de2e9fd07689a
|
data/README.md
CHANGED
@@ -20,7 +20,7 @@
|
|
20
20
|
7. Styles and layouts are "just code" (not hash-based like in Teacup)
|
21
21
|
8. Written by [the authors][authors] of [ProMotion][] and [Teacup][]
|
22
22
|
|
23
|
-
[authors]: CONTRIBUTORS.
|
23
|
+
[authors]: CONTRIBUTORS.yaml
|
24
24
|
[Colin]: https://github.com/colinta
|
25
25
|
[Jamon]: https://github.com/jamonholmgren
|
26
26
|
[ProMotion]: https://github.com/clearsightstudio/ProMotion
|
@@ -115,6 +115,8 @@ class SimpleLayout < MotionKit::Layout
|
|
115
115
|
def button_style
|
116
116
|
# this will call 'setTitle(forState:)' via a UIButton helper
|
117
117
|
title 'Press it!'
|
118
|
+
size_to_fit
|
119
|
+
|
118
120
|
# this shorthand is much better! More about frame helpers below.
|
119
121
|
center ['50%', '50% + 50']
|
120
122
|
end
|
@@ -267,6 +269,32 @@ end
|
|
267
269
|
```
|
268
270
|
|
269
271
|
|
272
|
+
### Using child-layouts
|
273
|
+
|
274
|
+
If you have a very complicated layout that you want to break up into child
|
275
|
+
layouts, that is supported as well:
|
276
|
+
|
277
|
+
```ruby
|
278
|
+
class ParentLayout < MK::Layout
|
279
|
+
|
280
|
+
def layout
|
281
|
+
add ChildLayout, :child_id
|
282
|
+
end
|
283
|
+
|
284
|
+
end
|
285
|
+
```
|
286
|
+
|
287
|
+
The id is (as always) optional, but allows you to fetch the layout using
|
288
|
+
`get(id)`.
|
289
|
+
|
290
|
+
```ruby
|
291
|
+
layout.get(:child_id) # => ChildLayout
|
292
|
+
```
|
293
|
+
|
294
|
+
Calling `get(:child_id).view` will return the *view* associated with that
|
295
|
+
layout.
|
296
|
+
|
297
|
+
|
270
298
|
### Setting a custom root view
|
271
299
|
|
272
300
|
If you need to use a custom root view, you can use the `root` method from within
|
@@ -593,6 +621,8 @@ constraints do
|
|
593
621
|
# setting the priority:
|
594
622
|
(x.is >= 10).priority(:required)
|
595
623
|
(x.is == 15).priority(:low)
|
624
|
+
# setting the identifier
|
625
|
+
x.equals(15).identifier('foo')
|
596
626
|
end
|
597
627
|
```
|
598
628
|
|
@@ -601,12 +631,20 @@ the element-id as a placeholder for a view works especially well here.
|
|
601
631
|
|
602
632
|
```ruby
|
603
633
|
constraints do
|
604
|
-
top_left.equals x: 5, y:5
|
634
|
+
top_left.equals x: 5, y: 5 # this sets the origin relative to the superview
|
635
|
+
top_left.equals(:superview).plus([5, 5]) # this will do the same thing!
|
636
|
+
|
605
637
|
width.equals(:foo).minus(10) # searches for a view named :foo
|
606
638
|
height.equals(:foo).minus(10)
|
607
639
|
# that's repetitive, so just set 'size'
|
608
640
|
size.equals(:foo).minus(10)
|
609
641
|
size.equals(:foo).minus([10, 15]) # 10pt thinner, 15pt shorter
|
642
|
+
|
643
|
+
# if you are using a view that has a sensible intrinsic size, like an image,
|
644
|
+
# you can use :scale to have the width or height adjusted according to the
|
645
|
+
# other size
|
646
|
+
width.equals(:superview)
|
647
|
+
height(:scale) # scale the height according to the width
|
610
648
|
end
|
611
649
|
```
|
612
650
|
|
@@ -700,6 +738,58 @@ class MainController < UIViewController
|
|
700
738
|
end
|
701
739
|
```
|
702
740
|
|
741
|
+
#### Animating and Changing constraints
|
742
|
+
|
743
|
+
It might feel natural to treat constraints as "frame setters", but they are
|
744
|
+
persistent objects that are attached to your views. This means if you create
|
745
|
+
new constraints, like during a screen rotation, your old constraints don't “go
|
746
|
+
away”. For example:
|
747
|
+
|
748
|
+
```ruby
|
749
|
+
def label_style
|
750
|
+
portrait do
|
751
|
+
left 10
|
752
|
+
end
|
753
|
+
|
754
|
+
landscape do
|
755
|
+
left 15 # adds *another* constraint on the left attribute - in addition to the `left 10` constraint!
|
756
|
+
end
|
757
|
+
end
|
758
|
+
```
|
759
|
+
|
760
|
+
Instead, you should retain the constraint and make changes to it directly:
|
761
|
+
|
762
|
+
```ruby
|
763
|
+
initial do
|
764
|
+
constraints do
|
765
|
+
@label_left_constraint = left 10
|
766
|
+
end
|
767
|
+
end
|
768
|
+
|
769
|
+
reapply do
|
770
|
+
portrait do
|
771
|
+
@label_left_constraint.equals 10
|
772
|
+
end
|
773
|
+
|
774
|
+
landscape do
|
775
|
+
@label_left_constraint.equals 15
|
776
|
+
end
|
777
|
+
end
|
778
|
+
```
|
779
|
+
|
780
|
+
If you want to animate a constraint change, you can use `layoutIfNeeded` from
|
781
|
+
within a UIView animation block. The sample app "Chatty" does this to move a
|
782
|
+
text field when the keyboard is displayed. `kbd_height` is the height of the
|
783
|
+
keyboard.
|
784
|
+
|
785
|
+
```ruby
|
786
|
+
@container_bottom.minus kbd_height # set @container_bottom.constant = 0 when the keyboard disappears
|
787
|
+
|
788
|
+
UIView.animateWithDuration(duration, delay: 0, options: curve, animations: -> do
|
789
|
+
self.view.layoutIfNeeded # applies the constraint change
|
790
|
+
end, completion: nil)
|
791
|
+
```
|
792
|
+
|
703
793
|
### MotionKit::Events
|
704
794
|
|
705
795
|
gem install motion-kit-events
|
@@ -5,11 +5,11 @@
|
|
5
5
|
# @provides MotionKit::ViewCalculator
|
6
6
|
module MotionKit
|
7
7
|
class ViewCalculator
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
extend MotionKit::OriginCalculator
|
9
|
+
extend MotionKit::SizeCalculator
|
10
|
+
extend MotionKit::FrameCalculator
|
11
11
|
|
12
|
-
def calculate(view, dimension, amount, full_view=nil)
|
12
|
+
def self.calculate(view, dimension, amount, full_view=nil)
|
13
13
|
if amount.is_a? Proc
|
14
14
|
return view.instance_exec(&amount)
|
15
15
|
elsif dimension == :origin || dimension == :center
|
@@ -35,7 +35,7 @@ module MotionKit
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def intrinsic_size(view)
|
38
|
+
def self.intrinsic_size(view)
|
39
39
|
size_that_fits = view.intrinsicContentSize
|
40
40
|
if size_that_fits.width == MotionKit.no_intrinsic_metric
|
41
41
|
size_that_fits.width = 0
|
@@ -30,7 +30,7 @@ module MotionKit
|
|
30
30
|
@preset_root = args[:root]
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
33
|
+
def set_parent_layout(layout)
|
34
34
|
@layout = WeakRef.new(layout)
|
35
35
|
end
|
36
36
|
|
@@ -88,14 +88,14 @@ module MotionKit
|
|
88
88
|
# corner_radius 5
|
89
89
|
# end
|
90
90
|
# end
|
91
|
-
def context(
|
92
|
-
return
|
91
|
+
def context(new_target, &block)
|
92
|
+
return new_target unless block
|
93
93
|
# this little line is incredibly important; the context is only set on
|
94
94
|
# the top-level Layout object.
|
95
|
-
return parent_layout.context(
|
95
|
+
return parent_layout.context(new_target, &block) unless is_parent_layout?
|
96
96
|
|
97
|
-
if
|
98
|
-
|
97
|
+
if new_target.is_a?(Symbol)
|
98
|
+
new_target = self.get_view(new_target)
|
99
99
|
end
|
100
100
|
|
101
101
|
context_was, parent_was, delegate_was = @context, @parent, @layout_delegate
|
@@ -107,17 +107,20 @@ module MotionKit
|
|
107
107
|
@should_run_deferred = false
|
108
108
|
end
|
109
109
|
@parent = MK::Parent.new(context_was)
|
110
|
-
@context =
|
111
|
-
@context.motion_kit_meta[:delegate] ||= Layout.layout_for(
|
110
|
+
@context = new_target
|
111
|
+
@context.motion_kit_meta[:delegate] ||= Layout.layout_for(@context.class)
|
112
112
|
@layout_delegate = @context.motion_kit_meta[:delegate]
|
113
|
+
if @layout_delegate
|
114
|
+
@layout_delegate.set_parent_layout(parent_layout)
|
115
|
+
end
|
113
116
|
yield
|
114
117
|
@layout_delegate, @context, @parent = delegate_was, context_was, parent_was
|
115
118
|
if @should_run_deferred
|
116
|
-
run_deferred(
|
119
|
+
run_deferred(new_target)
|
117
120
|
end
|
118
121
|
@should_run_deferred = prev_should_run
|
119
122
|
|
120
|
-
|
123
|
+
new_target
|
121
124
|
end
|
122
125
|
|
123
126
|
# Blocks passed to `deferred` are run at the end of a "session", usually
|
@@ -217,11 +220,14 @@ module MotionKit
|
|
217
220
|
objc_method_name, objc_method_args = objc_version(method_name, args)
|
218
221
|
ruby_method_name = ruby_version(method_name)
|
219
222
|
|
220
|
-
@layout_delegate ||= Layout.layout_for(
|
221
|
-
if
|
222
|
-
|
223
|
-
|
224
|
-
|
223
|
+
@layout_delegate ||= Layout.layout_for(target.class)
|
224
|
+
if @layout_delegate
|
225
|
+
@layout_delegate.set_parent_layout(parent_layout)
|
226
|
+
if objc_method_name && @layout_delegate.respond_to?(objc_method_name)
|
227
|
+
return @layout_delegate.send(objc_method_name, *objc_method_args, &block)
|
228
|
+
elsif @layout_delegate.respond_to?(ruby_method_name)
|
229
|
+
return @layout_delegate.send(ruby_method_name, *args, &block)
|
230
|
+
end
|
225
231
|
end
|
226
232
|
|
227
233
|
if block
|
@@ -22,9 +22,9 @@ module MotionKit
|
|
22
22
|
end
|
23
23
|
|
24
24
|
# Instantiates a new Layout instance using `layout` as the root-level layout
|
25
|
-
def layout_for(
|
25
|
+
def layout_for(klass)
|
26
26
|
memoized_klass = memoize(klass)
|
27
|
-
memoized_klass
|
27
|
+
memoized_klass && memoized_klass.new
|
28
28
|
end
|
29
29
|
|
30
30
|
# Cache registered classes
|
@@ -40,10 +40,5 @@ module MotionKit
|
|
40
40
|
@memoize[klass]
|
41
41
|
end
|
42
42
|
|
43
|
-
def new_child(layout=nil)
|
44
|
-
child = self.new
|
45
|
-
child.set_layout(layout)
|
46
|
-
child
|
47
|
-
end
|
48
43
|
end
|
49
44
|
end
|
@@ -28,26 +28,41 @@ module MotionKit
|
|
28
28
|
# end
|
29
29
|
#
|
30
30
|
# end
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
31
|
+
#
|
32
|
+
# You can also set multiple views in a single line.
|
33
|
+
#
|
34
|
+
# @example
|
35
|
+
# class MyLayout < MK::Layout
|
36
|
+
# view :label, :login_button
|
37
|
+
# end
|
38
|
+
def view(*names)
|
39
|
+
names.each do |name|
|
40
|
+
ivar_name = "@#{name}"
|
41
|
+
define_method(name) do
|
42
|
+
unless instance_variable_get(ivar_name)
|
43
|
+
view = self.get_view(name)
|
44
|
+
unless view
|
45
|
+
build_view unless @view
|
46
|
+
view = instance_variable_get(ivar_name) || self.get_view(name)
|
47
|
+
end
|
48
|
+
self.send("#{name}=", view)
|
49
|
+
return view
|
39
50
|
end
|
40
|
-
|
41
|
-
return view
|
51
|
+
return instance_variable_get(ivar_name)
|
42
52
|
end
|
43
|
-
|
53
|
+
# KVO compliance
|
54
|
+
attr_writer name
|
44
55
|
end
|
45
|
-
# KVO compliance
|
46
|
-
attr_writer name
|
47
56
|
end
|
48
57
|
|
49
58
|
end
|
50
59
|
|
60
|
+
def initialize(args={})
|
61
|
+
super
|
62
|
+
@child_layouts = []
|
63
|
+
@elements = {}
|
64
|
+
end
|
65
|
+
|
51
66
|
# The main view. This method builds the layout and returns the root view.
|
52
67
|
def view
|
53
68
|
unless is_parent_layout?
|
@@ -56,14 +71,6 @@ module MotionKit
|
|
56
71
|
@view ||= build_view
|
57
72
|
end
|
58
73
|
|
59
|
-
# For private use. The "root" is context sensitive, whereas the "view" is
|
60
|
-
# constant. In most cases they are the same object, but when you are
|
61
|
-
# building a hierarchy that is *outside* the view created from the "layout"
|
62
|
-
# method, the top-most view in that hierarchy will be "root".
|
63
|
-
def _root
|
64
|
-
@root || view
|
65
|
-
end
|
66
|
-
|
67
74
|
# Builds the layout and then returns self for chaining.
|
68
75
|
def build
|
69
76
|
view
|
@@ -104,59 +111,44 @@ module MotionKit
|
|
104
111
|
raise ContextConflictError.new("Already created the root view")
|
105
112
|
end
|
106
113
|
|
107
|
-
@view = initialize_element(element)
|
114
|
+
@view = initialize_element(element, element_id)
|
115
|
+
|
108
116
|
if block
|
109
117
|
if @context
|
110
118
|
raise ContextConflictError.new("Already in a context")
|
111
119
|
end
|
112
|
-
|
113
|
-
context(@view) do
|
114
|
-
# We're just using the `create` method for its side effects: calling the
|
115
|
-
# style method and calling the block.
|
116
|
-
create(@view, element_id, &block)
|
117
|
-
end
|
118
|
-
elsif element_id
|
119
|
-
create(@view, element_id)
|
120
120
|
end
|
121
121
|
|
122
|
+
style_and_context(@view, element_id, &block)
|
123
|
+
|
122
124
|
return @view
|
123
125
|
end
|
124
126
|
|
125
127
|
# instantiates a view, possibly running a 'layout block' to add child views.
|
126
128
|
def create(element, element_id=nil, &block)
|
127
|
-
element = initialize_element(element)
|
128
|
-
|
129
|
-
if element_id
|
130
|
-
# We set the optional id and call the '_style' method, if it's been
|
131
|
-
# defined.
|
132
|
-
element.motion_kit_id = element_id
|
133
|
-
self.call_style_method(element, element_id)
|
134
|
-
end
|
135
|
-
|
136
|
-
if block
|
137
|
-
context(element, &block)
|
138
|
-
end
|
129
|
+
element = initialize_element(element, element_id)
|
130
|
+
style_and_context(element, element_id, &block)
|
139
131
|
|
140
132
|
element
|
141
133
|
end
|
142
134
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
135
|
+
# Calls the style method of all objects in the view hierarchy that are
|
136
|
+
# part of this layout. The views in a child layout are not styled, but
|
137
|
+
# those layouts will receive a `reapply!` message if no root is specified.
|
138
|
+
def reapply!
|
139
|
+
root ||= self.view
|
140
|
+
@layout_state = :reapply
|
141
|
+
|
142
|
+
@elements.each do |element_id, elements|
|
143
|
+
elements.each do |element|
|
144
|
+
style_and_context(element, element_id)
|
148
145
|
end
|
149
146
|
end
|
150
|
-
return element
|
151
|
-
end
|
152
147
|
|
153
|
-
|
154
|
-
|
155
|
-
root ||= self.view
|
156
|
-
@layout_state = :reapply
|
157
|
-
MotionKit.find_all_views(root) do |view|
|
158
|
-
call_style_method(view, view.motion_kit_id) if view.motion_kit_id
|
148
|
+
@child_layouts.each do |child_layout|
|
149
|
+
child_layout.reapply!
|
159
150
|
end
|
151
|
+
|
160
152
|
@layout_state = :initial
|
161
153
|
|
162
154
|
return self
|
@@ -189,70 +181,93 @@ module MotionKit
|
|
189
181
|
return self
|
190
182
|
end
|
191
183
|
|
184
|
+
def name_element(element, element_id)
|
185
|
+
@elements[element_id] ||= []
|
186
|
+
@elements[element_id] << element
|
187
|
+
end
|
188
|
+
|
192
189
|
# Instantiates a view via `create` and adds the view to the current target.
|
193
|
-
# If
|
194
|
-
#
|
190
|
+
# If there is no context, a default root view can be created if that has
|
191
|
+
# been enabled (e.g. within the `layout` method). The block is run in the
|
192
|
+
# context of the new view.
|
195
193
|
def add(element, element_id=nil, &block)
|
196
194
|
# make sure we have a target - raises NoContextError if none exists
|
197
195
|
self.target
|
198
196
|
|
199
|
-
element = initialize_element(element)
|
200
197
|
unless @context
|
201
198
|
create_default_root_context
|
202
199
|
end
|
203
|
-
self.apply(:add_child, element)
|
204
|
-
create(element, element_id)
|
205
200
|
|
206
|
-
|
207
|
-
|
208
|
-
|
201
|
+
# We want to be sure that the element has a supeview or superlayer before
|
202
|
+
# the style method is called.
|
203
|
+
element = initialize_element(element, element_id)
|
204
|
+
self.apply(:add_child, element)
|
205
|
+
style_and_context(element, element_id, &block)
|
209
206
|
|
210
207
|
element
|
211
208
|
end
|
212
209
|
|
210
|
+
def child_layouts
|
211
|
+
@child_layouts
|
212
|
+
end
|
213
|
+
|
213
214
|
# Retrieves a view by its element id. This will return the *first* view
|
214
|
-
# with this element_id in the tree, where *first* means the
|
215
|
-
#
|
215
|
+
# with this element_id in the tree, where *first* means the first object
|
216
|
+
# that was added with assigned that name.
|
216
217
|
def get(element_id)
|
217
218
|
unless is_parent_layout?
|
218
219
|
return parent_layout.get(element_id)
|
219
220
|
end
|
220
|
-
|
221
|
+
@elements[element_id] && @elements[element_id].first
|
221
222
|
end
|
222
223
|
def first(element_id) ; get(element_id) ; end
|
223
224
|
|
224
|
-
#
|
225
|
-
|
226
|
-
|
225
|
+
# Just like `get`, but if `get` returns a Layout, this method returns the
|
226
|
+
# layout's view.
|
227
|
+
def get_view(element_id)
|
228
|
+
element = get(element_id)
|
229
|
+
if element.is_a?(Layout)
|
230
|
+
element = element.view
|
231
|
+
end
|
232
|
+
element
|
227
233
|
end
|
228
|
-
def first(element_id, in: root) ; get(element_id, in: root) ; end
|
229
234
|
|
230
|
-
# Retrieves a view by its element id. This will return the *last* view
|
231
|
-
#
|
232
|
-
#
|
235
|
+
# Retrieves a view by its element id. This will return the *last* view with
|
236
|
+
# this element_id in the tree, where *last* means the last object that was
|
237
|
+
# added with assigned that name.
|
233
238
|
def last(element_id)
|
234
239
|
unless is_parent_layout?
|
235
240
|
return parent_layout.last(element_id)
|
236
241
|
end
|
237
|
-
|
242
|
+
@elements[element_id] && @elements[element_id].last
|
238
243
|
end
|
239
244
|
|
240
|
-
#
|
241
|
-
|
242
|
-
|
245
|
+
# Just like `last`, but if `last` returns a Layout, this method returns the
|
246
|
+
# layout's view.
|
247
|
+
def last_view(element_id)
|
248
|
+
element = last(element_id)
|
249
|
+
if element.is_a?(Layout)
|
250
|
+
element = element.view
|
251
|
+
end
|
252
|
+
element
|
243
253
|
end
|
244
254
|
|
245
|
-
# Returns all the elements with a given element_id
|
255
|
+
# Returns all the elements with a given element_id
|
246
256
|
def all(element_id)
|
247
257
|
unless is_parent_layout?
|
248
258
|
return parent_layout.all(element_id)
|
249
259
|
end
|
250
|
-
|
260
|
+
@elements[element_id] || []
|
251
261
|
end
|
252
262
|
|
253
|
-
#
|
254
|
-
|
255
|
-
|
263
|
+
# Just like `all`, but if `all` returns a Layout, this method returns the
|
264
|
+
# layout's view.
|
265
|
+
def all_views(element_id)
|
266
|
+
element = all(element_id)
|
267
|
+
if element.is_a?(Layout)
|
268
|
+
element = element.view
|
269
|
+
end
|
270
|
+
element
|
256
271
|
end
|
257
272
|
|
258
273
|
# Returns all the elements with a given element_id
|
@@ -260,9 +275,14 @@ module MotionKit
|
|
260
275
|
self.all(element_id)[index]
|
261
276
|
end
|
262
277
|
|
263
|
-
#
|
264
|
-
|
265
|
-
|
278
|
+
# Just like `nth`, but if `nth` returns a Layout, this method returns the
|
279
|
+
# layout's view.
|
280
|
+
def nth_view(element_id, index)
|
281
|
+
element = nth(element_id)
|
282
|
+
if element.is_a?(Layout)
|
283
|
+
element = element.view
|
284
|
+
end
|
285
|
+
element
|
266
286
|
end
|
267
287
|
|
268
288
|
# Removes a view (or several with the same name) from the hierarchy
|
@@ -271,15 +291,11 @@ module MotionKit
|
|
271
291
|
unless is_parent_layout?
|
272
292
|
return parent_layout.remove(element_id)
|
273
293
|
end
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
# Same as `remove`, but with the root view specified.
|
278
|
-
def remove(element_id, from: root)
|
279
|
-
context(root) do
|
280
|
-
all(element_id).each do |subview|
|
281
|
-
self.apply(:remove_child, subview)
|
294
|
+
context(self.view) do
|
295
|
+
all(element_id).each do |element|
|
296
|
+
self.apply(:remove_child, element)
|
282
297
|
end
|
298
|
+
@elements[element_id] = nil
|
283
299
|
end
|
284
300
|
end
|
285
301
|
|
@@ -329,17 +345,6 @@ module MotionKit
|
|
329
345
|
@view
|
330
346
|
end
|
331
347
|
|
332
|
-
# This method needs to set the @root so that calls to `get(:id)` defer to
|
333
|
-
# the "current root", not the layout root view.
|
334
|
-
def run_deferred(top_level_context)
|
335
|
-
root_was = @root
|
336
|
-
@root = top_level_context
|
337
|
-
retval = super
|
338
|
-
@root = root_was
|
339
|
-
|
340
|
-
return retval
|
341
|
-
end
|
342
|
-
|
343
348
|
def layout
|
344
349
|
end
|
345
350
|
|
@@ -348,18 +353,48 @@ module MotionKit
|
|
348
353
|
#
|
349
354
|
# Accepts a view instance, a class (which is instantiated with 'new') or a
|
350
355
|
# `ViewLayout`, which returns the root view.
|
351
|
-
def initialize_element(elem)
|
356
|
+
def initialize_element(elem, element_id)
|
352
357
|
if elem.is_a?(Class) && elem < TreeLayout
|
353
|
-
|
358
|
+
layout = elem.new
|
359
|
+
elem = layout.view
|
354
360
|
elsif elem.is_a?(Class)
|
355
361
|
elem = elem.new
|
356
362
|
elsif elem.is_a?(TreeLayout)
|
363
|
+
layout = elem
|
357
364
|
elem = elem.view
|
358
365
|
end
|
359
366
|
|
367
|
+
if layout
|
368
|
+
if element_id
|
369
|
+
name_element(layout, element_id)
|
370
|
+
end
|
371
|
+
@child_layouts << layout
|
372
|
+
elsif element_id
|
373
|
+
name_element(elem, element_id)
|
374
|
+
end
|
375
|
+
|
360
376
|
return elem
|
361
377
|
end
|
362
378
|
|
379
|
+
# Calls the `_style` method with the element as the context, and runs the
|
380
|
+
# optional block in that context. This is usually done immediately after
|
381
|
+
# `initialize_element`, except in the case of `add`, which adds the item to
|
382
|
+
# the tree before styling it.
|
383
|
+
def style_and_context(element, element_id, &block)
|
384
|
+
style_method = "#{element_id}_style"
|
385
|
+
if parent_layout.respond_to?(style_method) || block_given?
|
386
|
+
parent_layout.context(element) do
|
387
|
+
if parent_layout.respond_to?(style_method)
|
388
|
+
parent_layout.send(style_method)
|
389
|
+
end
|
390
|
+
|
391
|
+
if block_given?
|
392
|
+
yield
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
363
398
|
end
|
364
399
|
|
365
400
|
end
|
data/lib/motion-kit/object.rb
CHANGED
data/lib/motion-kit/version.rb
CHANGED