motion-kit 0.10.11 → 0.11.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 +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