motion-kit 0.0.1 → 0.9.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 +7 -0
- data/README.md +839 -0
- data/lib/motion-kit-cocoa/cocoa_util.rb +59 -0
- data/lib/motion-kit-cocoa/constraints/constraint.rb +765 -0
- data/lib/motion-kit-cocoa/constraints/constraint_placeholder.rb +22 -0
- data/lib/motion-kit-cocoa/constraints/constraints_layout.rb +536 -0
- data/lib/motion-kit-cocoa/constraints/constraints_target.rb +52 -0
- data/lib/motion-kit-cocoa/layouts/cagradientlayer_layout.rb +13 -0
- data/lib/motion-kit-cocoa/layouts/calayer_layout.rb +27 -0
- data/lib/motion-kit-cocoa/layouts/sugarcube_compat.rb +38 -0
- data/lib/motion-kit-ios/dummy.rb +93 -0
- data/lib/motion-kit-ios/ios_util.rb +20 -0
- data/lib/motion-kit-ios/layouts/constraints_layout.rb +22 -0
- data/lib/motion-kit-ios/layouts/layout_device.rb +32 -0
- data/lib/motion-kit-ios/layouts/layout_orientation.rb +47 -0
- data/lib/motion-kit-ios/layouts/uibutton_layout.rb +52 -0
- data/lib/motion-kit-ios/layouts/uiview_layout.rb +45 -0
- data/lib/motion-kit-ios/layouts/uiview_layout_autoresizing.rb +75 -0
- data/lib/motion-kit-ios/layouts/uiview_layout_constraints.rb +36 -0
- data/lib/motion-kit-ios/layouts/uiview_layout_frame.rb +307 -0
- data/lib/motion-kit-ios/layouts/uiview_layout_gradient.rb +20 -0
- data/lib/motion-kit-osx/dummy.rb +89 -0
- data/lib/motion-kit-osx/layouts/constraints_layout.rb +42 -0
- data/lib/motion-kit-osx/layouts/nsmenu_extensions.rb +186 -0
- data/lib/motion-kit-osx/layouts/nsmenu_layout.rb +109 -0
- data/lib/motion-kit-osx/layouts/nsmenuitem_extensions.rb +45 -0
- data/lib/motion-kit-osx/layouts/nstablecolumn_layout.rb +12 -0
- data/lib/motion-kit-osx/layouts/nstableview_layout.rb +20 -0
- data/lib/motion-kit-osx/layouts/nsview_layout.rb +47 -0
- data/lib/motion-kit-osx/layouts/nsview_layout_autoresizing.rb +75 -0
- data/lib/motion-kit-osx/layouts/nsview_layout_constraints.rb +34 -0
- data/lib/motion-kit-osx/layouts/nsview_layout_frame.rb +375 -0
- data/lib/motion-kit-osx/layouts/nswindow_frame.rb +14 -0
- data/lib/motion-kit-osx/layouts/nswindow_layout.rb +77 -0
- data/lib/motion-kit-osx/osx_util.rb +16 -0
- data/lib/motion-kit.rb +33 -0
- data/lib/motion-kit/calculate.rb +263 -0
- data/lib/motion-kit/layouts/base_layout.rb +299 -0
- data/lib/motion-kit/layouts/base_layout_class_methods.rb +43 -0
- data/lib/motion-kit/layouts/parent.rb +68 -0
- data/lib/motion-kit/layouts/view_layout.rb +327 -0
- data/lib/motion-kit/motion-kit.rb +18 -0
- data/lib/motion-kit/object.rb +16 -0
- data/lib/motion-kit/util.rb +20 -0
- data/lib/motion-kit/version.rb +1 -1
- data/spec/ios/apply_styles_spec.rb +21 -0
- data/spec/ios/autoresizing_helper_spec.rb +224 -0
- data/spec/ios/calculate_spec.rb +322 -0
- data/spec/ios/calculator_spec.rb +31 -0
- data/spec/ios/constraints_helpers/attribute_lookup_spec.rb +27 -0
- data/spec/ios/constraints_helpers/axis_lookup_spec.rb +13 -0
- data/spec/ios/constraints_helpers/center_constraints_spec.rb +419 -0
- data/spec/ios/constraints_helpers/constraint_placeholder_spec.rb +72 -0
- data/spec/ios/constraints_helpers/priority_lookup_spec.rb +19 -0
- data/spec/ios/constraints_helpers/relationship_lookup_spec.rb +27 -0
- data/spec/ios/constraints_helpers/relative_corners_spec.rb +274 -0
- data/spec/ios/constraints_helpers/relative_location_spec.rb +111 -0
- data/spec/ios/constraints_helpers/simple_constraints_spec.rb +2763 -0
- data/spec/ios/constraints_helpers/size_constraints_spec.rb +422 -0
- data/spec/ios/constraints_helpers/view_lookup_constraints_spec.rb +93 -0
- data/spec/ios/create_layout_spec.rb +40 -0
- data/spec/ios/custom_layout_spec.rb +13 -0
- data/spec/ios/deferred_spec.rb +89 -0
- data/spec/ios/device_helpers_spec.rb +51 -0
- data/spec/ios/frame_helper_spec.rb +1150 -0
- data/spec/ios/layer_layout_spec.rb +36 -0
- data/spec/ios/layout_extensions_spec.rb +70 -0
- data/spec/ios/layout_spec.rb +74 -0
- data/spec/ios/layout_state_spec.rb +27 -0
- data/spec/ios/motionkit_util_spec.rb +102 -0
- data/spec/ios/objc_selectors_spec.rb +10 -0
- data/spec/ios/orientation_helper_specs.rb +67 -0
- data/spec/ios/parent_layout_spec.rb +19 -0
- data/spec/ios/parent_spec.rb +45 -0
- data/spec/ios/remove_layout_spec.rb +25 -0
- data/spec/ios/root_layout_spec.rb +53 -0
- data/spec/ios/setters_spec.rb +63 -0
- data/spec/ios/uibutton_layout_spec.rb +24 -0
- data/spec/ios/uitextfield_spec.rb +14 -0
- data/spec/ios/view_attr_spec.rb +25 -0
- data/spec/osx/autoresizing_helper_spec.rb +224 -0
- data/spec/osx/constraints_helper_spec.rb +0 -0
- data/spec/osx/constraints_helpers/orientation_lookup_spec.rb +13 -0
- data/spec/osx/constraints_helpers/simple_constraints_spec.rb +2095 -0
- data/spec/osx/constraints_helpers/size_constraints_spec.rb +362 -0
- data/spec/osx/create_menu_spec.rb +14 -0
- data/spec/osx/create_via_extensions_spec.rb +63 -0
- data/spec/osx/deferred_spec.rb +85 -0
- data/spec/osx/frame_helper_spec.rb +1881 -0
- data/spec/osx/menu_extensions_spec.rb +376 -0
- data/spec/osx/menu_layout_spec.rb +157 -0
- data/spec/osx/menu_spec.rb +70 -0
- data/spec/osx/root_menu_spec.rb +15 -0
- metadata +166 -14
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# @provides MotionKit::BaseLayoutClassMethods
|
|
2
|
+
module MotionKit
|
|
3
|
+
module BaseLayoutClassMethods
|
|
4
|
+
def target_klasses
|
|
5
|
+
# We don't want subclasses, just BaseLayout
|
|
6
|
+
return BaseLayout.target_klasses unless self == BaseLayout
|
|
7
|
+
@target_klasses ||= {}
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def targets(klass=nil)
|
|
11
|
+
return nil if klass.nil? && self == BaseLayout
|
|
12
|
+
return @targets || superclass.targets if klass.nil?
|
|
13
|
+
@targets = klass
|
|
14
|
+
BaseLayout.target_klasses[klass] = self
|
|
15
|
+
nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Instantiates a new Layout instance using `layout` as the root-level layout
|
|
19
|
+
def layout_for(layout, klass)
|
|
20
|
+
memoized_klass = memoize(klass)
|
|
21
|
+
memoized_klass.new_child(layout) if memoized_klass
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Cache registered classes
|
|
25
|
+
def memoize(klass)
|
|
26
|
+
@memoize ||= {}
|
|
27
|
+
@memoize[klass] ||= begin
|
|
28
|
+
while klass
|
|
29
|
+
break if registered_class = target_klasses[klass]
|
|
30
|
+
klass = klass.superclass
|
|
31
|
+
end
|
|
32
|
+
@memoize[klass] = registered_class if registered_class
|
|
33
|
+
end
|
|
34
|
+
@memoize[klass]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def new_child(layout=nil)
|
|
38
|
+
child = self.new
|
|
39
|
+
child.set_layout(layout)
|
|
40
|
+
child
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# @provides MotionKit::Parent
|
|
2
|
+
module MotionKit
|
|
3
|
+
# Simple class that returns data about the parent element
|
|
4
|
+
# for use while setting the styles of a child element.
|
|
5
|
+
class Parent
|
|
6
|
+
|
|
7
|
+
attr_reader :element
|
|
8
|
+
|
|
9
|
+
def initialize(element)
|
|
10
|
+
@element = element
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def origin
|
|
14
|
+
try(:frame, :origin)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def size
|
|
18
|
+
try(:frame, :size)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def x
|
|
22
|
+
try(:frame, :origin, :x)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def y
|
|
26
|
+
try(:frame, :origin, :y)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def width
|
|
30
|
+
try(:frame, :size, :width)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def height
|
|
34
|
+
try(:frame, :size, :height)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def center_x
|
|
38
|
+
width / 2.0 if width
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def center_y
|
|
42
|
+
height / 2.0 if height
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def center
|
|
46
|
+
CGPointMake(center_x, center_y) if width && height
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
protected
|
|
50
|
+
|
|
51
|
+
# Convenience method that takes a list of method calls and tries
|
|
52
|
+
# them end-to-end, returning nil if any fail to respond to that
|
|
53
|
+
# method name.
|
|
54
|
+
# Very similar to ActiveSupport's `.try` method.
|
|
55
|
+
def try(*method_chain)
|
|
56
|
+
obj = self.element
|
|
57
|
+
method_chain.each do |m|
|
|
58
|
+
# We'll break out and return nil if any part of the chain
|
|
59
|
+
# doesn't respond properly.
|
|
60
|
+
(obj = nil) && break unless obj.respond_to?(m)
|
|
61
|
+
obj = obj.send(m)
|
|
62
|
+
end
|
|
63
|
+
obj
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
# @provides MotionKit::ViewLayout
|
|
2
|
+
# @requires MotionKit::BaseLayout
|
|
3
|
+
module MotionKit
|
|
4
|
+
# A sensible parent class for any View-like layout class. Platform agnostic.
|
|
5
|
+
# Any platform-specific tasks are offloaded to child views (add_child,
|
|
6
|
+
# remove_child).
|
|
7
|
+
# Actually, "view like" is misleading, since technically it only assumes "tree
|
|
8
|
+
# like". You could use a ViewLayout subclass to construct a hierarchy
|
|
9
|
+
# representing a family tree, for instance. But that would be a silly use of
|
|
10
|
+
# MotionKit.
|
|
11
|
+
class ViewLayout < BaseLayout
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
|
|
15
|
+
# This is an `attr_reader`-like method that also calls `build_view` if the
|
|
16
|
+
# @view doesn't exist, and so you can use it to refer to views that are
|
|
17
|
+
# assigned to ivars in your `layout` method.
|
|
18
|
+
#
|
|
19
|
+
# @example
|
|
20
|
+
# class MyLayout < MK::Layout
|
|
21
|
+
# view :label
|
|
22
|
+
# view :login_button
|
|
23
|
+
#
|
|
24
|
+
# def layout
|
|
25
|
+
# # if element id and attr name match, no need to assign to ivar
|
|
26
|
+
# add UILabel, :label
|
|
27
|
+
# # if they don't match you must assign. If you are using
|
|
28
|
+
# # Key-Value observation you should use the setter:
|
|
29
|
+
# self.login_button = add UIButton, :button
|
|
30
|
+
# end
|
|
31
|
+
#
|
|
32
|
+
# end
|
|
33
|
+
def view(name)
|
|
34
|
+
ivar_name = "@#{name}"
|
|
35
|
+
define_method(name) do
|
|
36
|
+
unless instance_variable_get(ivar_name)
|
|
37
|
+
view = self.get(name)
|
|
38
|
+
unless view
|
|
39
|
+
build_view unless @view
|
|
40
|
+
view = instance_variable_get(ivar_name) || self.get(name)
|
|
41
|
+
end
|
|
42
|
+
self.send("#{name}=", view)
|
|
43
|
+
return view
|
|
44
|
+
end
|
|
45
|
+
return instance_variable_get(ivar_name)
|
|
46
|
+
end
|
|
47
|
+
# KVO compliance
|
|
48
|
+
attr_writer name
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# The parent view. This method builds the layout and returns the root view.
|
|
54
|
+
def view
|
|
55
|
+
if @layout != self
|
|
56
|
+
return @layout.view
|
|
57
|
+
end
|
|
58
|
+
@view ||= build_view
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Assign a view to act as the 'root' view for this layout. This method can
|
|
62
|
+
# only be called once, and must be called before `add` is called for the
|
|
63
|
+
# first time (otherwise `add` will create a default root view). This method
|
|
64
|
+
# must be called from inside `layout`, otherwise you should just use
|
|
65
|
+
# `create`.
|
|
66
|
+
#
|
|
67
|
+
# You can also call this method with just an element_id, and the default
|
|
68
|
+
# root view will be created.
|
|
69
|
+
def root(element, element_id=nil, &block)
|
|
70
|
+
if @view
|
|
71
|
+
raise ContextConflictError.new("Already created the root view")
|
|
72
|
+
end
|
|
73
|
+
unless @assign_root
|
|
74
|
+
raise InvalidRootError.new("You should only create a 'root' view from inside the 'layout' method (use 'create' elsewhere)")
|
|
75
|
+
end
|
|
76
|
+
@assign_root = false
|
|
77
|
+
|
|
78
|
+
# this method can be called with just a symbol, to assign the root element_id
|
|
79
|
+
if element.is_a?(Symbol)
|
|
80
|
+
element_id = element
|
|
81
|
+
# See note below about why we don't need to `apply(:default_root)`
|
|
82
|
+
element = default_root
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
@view = initialize_view(element)
|
|
86
|
+
if block
|
|
87
|
+
if @context
|
|
88
|
+
raise ContextConflictError.new("Already in a context")
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context(@view) do
|
|
92
|
+
# We're just using the `create` method for its side effects: calling the
|
|
93
|
+
# style method and calling the block.
|
|
94
|
+
create(@view, element_id, &block)
|
|
95
|
+
end
|
|
96
|
+
elsif element_id
|
|
97
|
+
create(@view, element_id)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
return @view
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# instantiates a view, possibly running a 'layout block' to add child views.
|
|
104
|
+
def create(element, element_id=nil, &block)
|
|
105
|
+
element = initialize_view(element)
|
|
106
|
+
|
|
107
|
+
if element_id
|
|
108
|
+
# We set the optional id and call the '_style' method, if it's been
|
|
109
|
+
# defined.
|
|
110
|
+
element.motion_kit_id = element_id
|
|
111
|
+
self.call_style_method(element, element_id)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
if block
|
|
115
|
+
context(element, &block)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
element
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def call_style_method(element, element_id)
|
|
122
|
+
style_method = "#{element_id}_style"
|
|
123
|
+
if @layout.respond_to?(style_method)
|
|
124
|
+
@layout.context(element) do
|
|
125
|
+
@layout.send(style_method)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
return element
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Calls the style method of all objects in the view hierarchy
|
|
132
|
+
def reapply!(root=nil)
|
|
133
|
+
root ||= self.view
|
|
134
|
+
@layout_state = :reapply
|
|
135
|
+
MotionKit.find_all_views(root) do |view|
|
|
136
|
+
call_style_method(view, view.motion_kit_id) if view.motion_kit_id
|
|
137
|
+
end
|
|
138
|
+
@layout_state = :initial
|
|
139
|
+
|
|
140
|
+
return self
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Calls the style method of all objects in the view hierarchy
|
|
144
|
+
def reapply(&block)
|
|
145
|
+
raise ArgumentError.new('Block required') unless block
|
|
146
|
+
|
|
147
|
+
if @layout_state == :reapply
|
|
148
|
+
yield
|
|
149
|
+
end
|
|
150
|
+
return self
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def initial(&block)
|
|
154
|
+
raise ArgumentError.new('Block required') unless block
|
|
155
|
+
|
|
156
|
+
if @layout_state == :initial
|
|
157
|
+
yield
|
|
158
|
+
end
|
|
159
|
+
return self
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Delegates to `create` to instantiate a view and run a layout block, and
|
|
163
|
+
# adds the view to the current view on the view stack. If no view exists on
|
|
164
|
+
# the stack, a default root view can be created if that has been enabled.
|
|
165
|
+
def add(element, element_id=nil, &block)
|
|
166
|
+
# make sure we have a target - raises NoContextError if none exists
|
|
167
|
+
self.target
|
|
168
|
+
|
|
169
|
+
element = initialize_view(element)
|
|
170
|
+
unless @context
|
|
171
|
+
create_default_root_context
|
|
172
|
+
end
|
|
173
|
+
self.apply(:add_child, element)
|
|
174
|
+
create(element, element_id, &block)
|
|
175
|
+
|
|
176
|
+
element
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Retrieves a view by its element id. This will return the *first* view
|
|
180
|
+
# with this element_id in the tree, where *first* means the view closest to
|
|
181
|
+
# the root view. Aliased to `first` to distinguish it from `last`.
|
|
182
|
+
def get(element_id)
|
|
183
|
+
if @layout != self
|
|
184
|
+
return @layout.get(element_id)
|
|
185
|
+
end
|
|
186
|
+
self.get(element_id, in: self.view)
|
|
187
|
+
end
|
|
188
|
+
def first(element_id) ; get(element_id) ; end
|
|
189
|
+
|
|
190
|
+
# Same as `get`, but with the root view specified.
|
|
191
|
+
def get(element_id, in: root)
|
|
192
|
+
MotionKit.find_first_view(root) { |view| view.motion_kit_id == element_id }
|
|
193
|
+
end
|
|
194
|
+
def first(element_id, in: root) ; get(element_id, in: root) ; end
|
|
195
|
+
|
|
196
|
+
# Retrieves a view by its element id. This will return the *last* view
|
|
197
|
+
# with this element_id, where last means the view deepest and furthest from
|
|
198
|
+
# the root view.
|
|
199
|
+
def last(element_id)
|
|
200
|
+
if @layout != self
|
|
201
|
+
return @layout.last(element_id)
|
|
202
|
+
end
|
|
203
|
+
self.last(element_id, in: self.view)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Same as `last`, but with the root view specified.
|
|
207
|
+
def last(element_id, in: root)
|
|
208
|
+
MotionKit.find_last_view(root) { |view| view.motion_kit_id == element_id }
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Returns all the elements with a given element_id in the view tree.
|
|
212
|
+
def all(element_id)
|
|
213
|
+
if @layout != self
|
|
214
|
+
return @layout.all(element_id)
|
|
215
|
+
end
|
|
216
|
+
self.all(element_id, in: self.view)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Same as `all`, but with the root view specified.
|
|
220
|
+
def all(element_id, in: root)
|
|
221
|
+
MotionKit.find_all_views(root) { |view| view.motion_kit_id == element_id }
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# Returns all the elements with a given element_id
|
|
225
|
+
def nth(element_id, index)
|
|
226
|
+
if @layout != self
|
|
227
|
+
return @layout.nth(element_id, index)
|
|
228
|
+
end
|
|
229
|
+
self.all(element_id, in: self.view)[index]
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# Same as `nth`, but with the root view specified.
|
|
233
|
+
def nth(element_id, at: index, in: root)
|
|
234
|
+
self.all(element_id, in: root)[index]
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Removes a view (or several with the same name) from the hierarchy
|
|
238
|
+
# and forgets it entirely. Returns the views that were removed.
|
|
239
|
+
def remove(element_id)
|
|
240
|
+
if @layout != self
|
|
241
|
+
return @layout.remove(element_id)
|
|
242
|
+
end
|
|
243
|
+
self.remove(element_id, from: self.view)
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# Same as `remove`, but with the root view specified.
|
|
247
|
+
def remove(element_id, from: root)
|
|
248
|
+
context(root) do
|
|
249
|
+
all(element_id).each do |subview|
|
|
250
|
+
self.apply(:remove_child, subview)
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def create_default_root_context
|
|
256
|
+
if @assign_root
|
|
257
|
+
# Originally I thought default_root should be `apply`ied like other
|
|
258
|
+
# view-related methods, but actually this method *only* gets called
|
|
259
|
+
# from within the `layout` method, and so should already be inside the
|
|
260
|
+
# correct Layout subclass.
|
|
261
|
+
@context = root(default_root)
|
|
262
|
+
else
|
|
263
|
+
raise NoContextError.new("No top level view specified (missing outer 'create' method?)")
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
protected
|
|
268
|
+
|
|
269
|
+
# This method builds the layout and returns the root view.
|
|
270
|
+
def build_view
|
|
271
|
+
# Only in the 'layout' method will we allow default container to be
|
|
272
|
+
# created automatically (when 'add' is called)
|
|
273
|
+
@assign_root = true
|
|
274
|
+
was_top_level = @is_top_level
|
|
275
|
+
@is_top_level = true
|
|
276
|
+
layout
|
|
277
|
+
unless @view
|
|
278
|
+
if @assign_root
|
|
279
|
+
create_default_root_context
|
|
280
|
+
else
|
|
281
|
+
NSLog('Warning! No root view was set in ViewLayout#layout. Did you mean to call `root`?')
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
run_deferred(@view)
|
|
285
|
+
@is_top_level = was_top_level
|
|
286
|
+
@assign_root = false
|
|
287
|
+
# context can be set via the 'create_default_root_context' method, which
|
|
288
|
+
# may be outside a 'context' block, so make sure to restore context to
|
|
289
|
+
# it's previous value
|
|
290
|
+
@context = nil
|
|
291
|
+
|
|
292
|
+
@view
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
overrides :run_deferred
|
|
296
|
+
def run_deferred(top_level_context)
|
|
297
|
+
view_was = @view
|
|
298
|
+
@view = top_level_context
|
|
299
|
+
retval = super
|
|
300
|
+
@view = view_was
|
|
301
|
+
|
|
302
|
+
return retval
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
def layout
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
# Initializes an instance of a view. This will need to be smarter going
|
|
309
|
+
# forward as `new` isn't always the designated initializer.
|
|
310
|
+
#
|
|
311
|
+
# Accepts a view instance, a class (which is instantiated with 'new') or a
|
|
312
|
+
# `ViewLayout`, which returns the root view.
|
|
313
|
+
def initialize_view(elem)
|
|
314
|
+
if elem.is_a?(Class) && elem < ViewLayout
|
|
315
|
+
elem = elem.new_child(@layout, nil, self).view
|
|
316
|
+
elsif elem.is_a?(Class)
|
|
317
|
+
elem = elem.new
|
|
318
|
+
elsif elem.is_a?(ViewLayout)
|
|
319
|
+
elem = elem.view
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
return elem
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# @provides MotionKit::Error
|
|
2
|
+
module MotionKit
|
|
3
|
+
class NoContextError < Exception
|
|
4
|
+
end
|
|
5
|
+
class ContextConflictError < Exception
|
|
6
|
+
end
|
|
7
|
+
class InvalidRootError < Exception
|
|
8
|
+
end
|
|
9
|
+
class InvalidDeferredError < Exception
|
|
10
|
+
end
|
|
11
|
+
class ApplyError < Exception
|
|
12
|
+
end
|
|
13
|
+
class NoSuperviewError < Exception
|
|
14
|
+
end
|
|
15
|
+
class NoCommonAncestorError < Exception
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
::MK = MotionKit unless defined?(::MK)
|