motion-prime 0.9.5 → 0.9.6
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 +8 -8
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/doc/code/sections.rb +8 -8
- data/files/Gemfile +1 -1
- data/generators/templates/scaffold/form.rb +5 -5
- data/motion-prime/elements/base_element.rb +8 -5
- data/motion-prime/helpers/has_normalizer.rb +32 -3
- data/motion-prime/screens/extensions/_indicators_mixin.rb +1 -1
- data/motion-prime/screens/screen.rb +2 -2
- data/motion-prime/sections/base_section.rb +14 -5
- data/motion-prime/sections/form/base_field_section.rb +7 -2
- data/motion-prime/sections/form/password_field_section.rb +2 -2
- data/motion-prime/sections/form/select_field_section.rb +1 -1
- data/motion-prime/sections/form/static_field_section.rb +5 -0
- data/motion-prime/sections/form/string_field_section.rb +2 -2
- data/motion-prime/sections/form/submit_field_section.rb +1 -1
- data/motion-prime/sections/form/text_field_section.rb +2 -2
- data/motion-prime/sections/table.rb +6 -4
- data/motion-prime/sections/table/refresh_mixin.rb +1 -1
- data/motion-prime/styles/form.rb +0 -1
- data/motion-prime/version.rb +1 -1
- data/motion-prime/views/_frame_calculator_mixin.rb +4 -4
- data/motion-prime/views/layout.rb +12 -12
- data/motion-prime/views/view_styler.rb +47 -11
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MDhjOWNjZjBiYWMwMGM0YTE5YzRkZTBmZWQyNDZmMzdiM2VjOTE5OQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZTllMmM5YWMyZjg4MDNhYzVhOWY5YzEzM2ExNzZiNWY1NTcwN2E5OA==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YWQ4YTdhYjhkOWFjMDhmZjc0ZjZkMWY3MmMxYjA4ZWQwMzE1MWMxYjhkZjFl
|
10
|
+
OTQ3NjNjMWRjODI1NGQ4Y2RlOGU2N2ZhOGU5OGM1Nzc4MzZjMTU2NGRmMWM1
|
11
|
+
N2YxYmEwM2Q1MjFmZGIwOTNhZjcwZmQyZGQwNmIzYzNmMzQyYjA=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
M2M2MjUzNjk0OWI0ZWRkY2I3MzA4YTIxNzcxMTRjNDhiNTg5NjM3ZDNiOWIz
|
14
|
+
ZTJjNzg5NTAyODgzODU2MjM2M2Y4MTFiYjc3ZDk4YjE4NzI4ZGRjY2MwYzQ0
|
15
|
+
ZjA0YjY0N2IwZDY4OTMwNTU0YTFkMTlmMDBhMjYzMzVkNmM0NzA=
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
=== 0.9.6
|
2
|
+
* BREAKING CHANGE: proc for form field option will be executed in context of form, not field.
|
3
|
+
* BREAKING CHANGE: screen#setup renamed to screen#set_options.
|
4
|
+
|
1
5
|
=== 0.9.5
|
2
6
|
* Ability to set wrapper for sections in screen.
|
3
7
|
* Screen refresh reloads all sections in screen.
|
data/Gemfile.lock
CHANGED
data/doc/code/sections.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# ** What is a Section? **
|
2
2
|
#
|
3
|
-
# "Section" is something like "partial" which you may know from RubyOnRails.
|
3
|
+
# "Section" is something like "partial" which you may know from RubyOnRails.
|
4
4
|
# In the first look it's just a list of elements which will be added to the "Screen".
|
5
|
-
# But the magic is inside.
|
6
|
-
# When you add "Element" to a "Section", e.g. image or label,
|
5
|
+
# But the magic is inside.
|
6
|
+
# When you add "Element" to a "Section", e.g. image or label,
|
7
7
|
# it will try to draw it using CALayer/CGContext/etc, instead of adding new UIView.
|
8
8
|
# That way increases application speed (especially on Table elements) by 5-10 times.
|
9
9
|
#
|
@@ -18,7 +18,7 @@ end
|
|
18
18
|
|
19
19
|
# ** Add some elements to the section. **
|
20
20
|
#
|
21
|
-
# Each element should have name and type: "image", "label", "button", etc.
|
21
|
+
# Each element should have name and type: "image", "label", "button", etc.
|
22
22
|
#
|
23
23
|
# When you send `:text` option, type will be "label" by default.
|
24
24
|
#
|
@@ -31,7 +31,7 @@ class FooSection < Prime::Section
|
|
31
31
|
end
|
32
32
|
|
33
33
|
# ** Render Section to Screen **
|
34
|
-
#
|
34
|
+
#
|
35
35
|
# NOTE: it's recommended to use instance variables for sections, e.g. `@main_section` instead of `main_section`.
|
36
36
|
|
37
37
|
class FooScreen < Prime::Screen
|
@@ -42,12 +42,12 @@ class FooScreen < Prime::Screen
|
|
42
42
|
end
|
43
43
|
|
44
44
|
# ** Add some styles for section **
|
45
|
-
#
|
45
|
+
#
|
46
46
|
# Generally styles are just attributes of UIView elements.
|
47
47
|
#
|
48
48
|
# Let's style the UILabel element (:welcome label element we added above.)
|
49
49
|
#
|
50
|
-
# We send :foo parameter to `define`, because we have section named `foo` (FooSection)
|
50
|
+
# We send :foo parameter to `define`, because we have section named `foo` (FooSection)
|
51
51
|
# and :welcome parameter to `style`, because the name of element is `welcome`.
|
52
52
|
#
|
53
53
|
Prime::Styles.define :foo do
|
@@ -56,7 +56,7 @@ Prime::Styles.define :foo do
|
|
56
56
|
top: 100,
|
57
57
|
width: 320,
|
58
58
|
left: 20,
|
59
|
-
font:
|
59
|
+
font: :system.uifont(20),
|
60
60
|
size_to_fit: true,
|
61
61
|
end
|
62
62
|
|
data/files/Gemfile
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
class <%= @p_class_name %>FormSection < Prime::FormSection
|
2
2
|
field :title,
|
3
3
|
label: { text: 'Title' },
|
4
|
-
input: {
|
5
|
-
text: proc {
|
4
|
+
input: {
|
5
|
+
text: proc { model.title },
|
6
6
|
placeholder: "Enter title here"
|
7
7
|
}
|
8
8
|
|
9
9
|
field :delete, type: :submit,
|
10
|
-
button: {
|
11
|
-
title: "Delete",
|
12
|
-
background_color: :red
|
10
|
+
button: {
|
11
|
+
title: "Delete",
|
12
|
+
background_color: :red
|
13
13
|
},
|
14
14
|
action: :on_delete,
|
15
15
|
if: proc { model.persisted? }
|
@@ -84,7 +84,11 @@ module MotionPrime
|
|
84
84
|
compute_style_options(raw_options)
|
85
85
|
raw_options = Styles.for(styles).merge(raw_options)
|
86
86
|
@computed_options = raw_options
|
87
|
-
normalize_options(@computed_options, section, %w[
|
87
|
+
normalize_options(@computed_options, section.try(:elements_eval_object), %w[
|
88
|
+
text placeholder font title_label
|
89
|
+
padding padding_left padding_right padding_top padding_bottom
|
90
|
+
left right min_width min_outer_width max_width max_outer_width width
|
91
|
+
top bottom min_height min_outer_height max_height max_outer_height height])
|
88
92
|
end
|
89
93
|
|
90
94
|
def reload!
|
@@ -120,7 +124,7 @@ module MotionPrime
|
|
120
124
|
# {name: model.name}
|
121
125
|
# end
|
122
126
|
def compute_block_options
|
123
|
-
|
127
|
+
normalize_value(@block, section) if @block
|
124
128
|
end
|
125
129
|
|
126
130
|
def compute_style_options(*style_sources)
|
@@ -136,10 +140,10 @@ module MotionPrime
|
|
136
140
|
custom_styles = []
|
137
141
|
style_sources.each do |source|
|
138
142
|
if source_mixins = source.delete(:mixins)
|
139
|
-
mixins += Array.wrap(normalize_object(source_mixins, section))
|
143
|
+
mixins += Array.wrap(normalize_object(source_mixins, section.try(:elements_eval_object)))
|
140
144
|
end
|
141
145
|
if source_styles = source.delete(:styles)
|
142
|
-
custom_styles += Array.wrap(normalize_object(source_styles, section))
|
146
|
+
custom_styles += Array.wrap(normalize_object(source_styles, section.try(:elements_eval_object)))
|
143
147
|
end
|
144
148
|
end
|
145
149
|
# styles got from mixins option
|
@@ -192,7 +196,6 @@ module MotionPrime
|
|
192
196
|
base_styles[:common]
|
193
197
|
end
|
194
198
|
all_styles += Array.wrap(common_styles)
|
195
|
-
|
196
199
|
# form cell: user_form_field, user_form_string_field, user_form_field_email
|
197
200
|
# form element: user_form_field_text_field, user_form_string_field_text_field, user_form_field_email_text_field
|
198
201
|
# table cell: categories_table_cell, categories_table_title
|
@@ -1,13 +1,15 @@
|
|
1
1
|
module MotionPrime
|
2
2
|
module HasNormalizer
|
3
|
-
def normalize_options(unordered_options, receiver = nil, order = nil)
|
3
|
+
def normalize_options(unordered_options, receiver = nil, order = nil, keys = nil)
|
4
4
|
options = if order
|
5
5
|
Hash[unordered_options.sort_by { |k,v| order.index(k.to_s).to_i }]
|
6
6
|
else
|
7
7
|
unordered_options
|
8
8
|
end
|
9
9
|
|
10
|
-
|
10
|
+
filtered_options = keys.nil? ? options : options.slice(*keys)
|
11
|
+
filtered_options.each do |key, option|
|
12
|
+
@_key_chain = [key]
|
11
13
|
unordered_options[key] = normalize_object(option, receiver)
|
12
14
|
end
|
13
15
|
end
|
@@ -15,14 +17,41 @@ module MotionPrime
|
|
15
17
|
def normalize_object(object, receiver = nil)
|
16
18
|
receiver ||= self
|
17
19
|
if object.is_a?(Proc)
|
18
|
-
|
20
|
+
normalize_value(object, receiver)
|
19
21
|
elsif object.is_a?(Hash)
|
20
22
|
object.inject({}) do |result, (key, nested_object)|
|
23
|
+
@_key_chain ||= []
|
24
|
+
@_key_chain << key
|
21
25
|
result.merge(key => normalize_object(nested_object, receiver))
|
22
26
|
end
|
23
27
|
else
|
24
28
|
object
|
25
29
|
end
|
26
30
|
end
|
31
|
+
|
32
|
+
def normalize_value(object, receiver)
|
33
|
+
if element?
|
34
|
+
receiver.send(:instance_exec, section || screen, self, &object)
|
35
|
+
else
|
36
|
+
receiver.send(:instance_exec, self, &object)
|
37
|
+
end
|
38
|
+
rescue => e
|
39
|
+
Prime.logger.error "Can't normalize: ", *debug_info, @_key_chain
|
40
|
+
raise e
|
41
|
+
end
|
42
|
+
|
43
|
+
def element?
|
44
|
+
self.is_a?(BaseElement)
|
45
|
+
end
|
46
|
+
|
47
|
+
def debug_info
|
48
|
+
if element?
|
49
|
+
[self.class.name, self.name, section.try(:name)]
|
50
|
+
elsif self.is_a?(Section)
|
51
|
+
[self.class.name, self.name, @table.try(:class).try(:name)]
|
52
|
+
else
|
53
|
+
[self.class.name]
|
54
|
+
end
|
55
|
+
end
|
27
56
|
end
|
28
57
|
end
|
@@ -24,7 +24,7 @@ module MotionPrime
|
|
24
24
|
options[:add_to_view] ||= self.view
|
25
25
|
@progress_indicator_view = self.progress_hud(options).view
|
26
26
|
else
|
27
|
-
self.
|
27
|
+
self.set_options(@progress_indicator_view, options.except(:add_to_view))
|
28
28
|
@progress_indicator_view.show options.has_key?(:animated) ? options[:animatetd] : true
|
29
29
|
end
|
30
30
|
end
|
@@ -35,8 +35,8 @@ module MotionPrime
|
|
35
35
|
@visible = true
|
36
36
|
@on_appear_happened ||= {}
|
37
37
|
unless @on_appear_happened[view.object_id]
|
38
|
-
|
39
|
-
run_callbacks :render do
|
38
|
+
set_options view, styles: default_styles do
|
39
|
+
run_callbacks :render do
|
40
40
|
send((action).to_sym)
|
41
41
|
end
|
42
42
|
end
|
@@ -131,7 +131,7 @@ module MotionPrime
|
|
131
131
|
elements_options.each do |key, opts|
|
132
132
|
add_element(key, opts)
|
133
133
|
end
|
134
|
-
|
134
|
+
elements_eval(&@options_block) if @options_block.is_a?(Proc)
|
135
135
|
|
136
136
|
@section_loading = false
|
137
137
|
return @section_loaded = true
|
@@ -309,6 +309,14 @@ module MotionPrime
|
|
309
309
|
end
|
310
310
|
|
311
311
|
protected
|
312
|
+
def elements_eval_object
|
313
|
+
self
|
314
|
+
end
|
315
|
+
|
316
|
+
def elements_eval(&block)
|
317
|
+
elements_eval_object.instance_exec(self, &block)
|
318
|
+
end
|
319
|
+
|
312
320
|
def bind_keyboard_close
|
313
321
|
bindings = self.class.keyboard_close_bindings
|
314
322
|
return unless bindings.present?
|
@@ -323,7 +331,7 @@ module MotionPrime
|
|
323
331
|
|
324
332
|
def keyboard_close_bindings_options
|
325
333
|
return {} unless self.class.keyboard_close_bindings.present?
|
326
|
-
@keyboard_close_bindings_options ||= normalize_options(self.class.keyboard_close_bindings.clone,
|
334
|
+
@keyboard_close_bindings_options ||= normalize_options(self.class.keyboard_close_bindings.clone, elements_eval_object)
|
327
335
|
end
|
328
336
|
|
329
337
|
def build_options_for_element(opts)
|
@@ -366,14 +374,15 @@ module MotionPrime
|
|
366
374
|
raw_options.merge!(self.class.container_options.try(:clone) || {})
|
367
375
|
raw_options.merge!(options.delete(:container) || {})
|
368
376
|
|
369
|
-
|
377
|
+
# allow to pass styles as proc
|
378
|
+
normalize_options(raw_options, elements_eval_object, nil, [:styles])
|
379
|
+
@container_options = raw_options # must be here because section_styles may use container_options for custom styles
|
370
380
|
|
371
|
-
# must be here because section_styles may use container_options for custom styles
|
372
381
|
container_options_from_styles = Styles.for(section_styles.values.flatten)[:container] if section_styles
|
373
382
|
if container_options_from_styles.present?
|
374
383
|
@container_options = container_options_from_styles.merge(@container_options)
|
375
384
|
end
|
376
|
-
normalize_options(@container_options)
|
385
|
+
normalize_options(@container_options, elements_eval_object)
|
377
386
|
end
|
378
387
|
|
379
388
|
class << self
|
@@ -6,14 +6,13 @@ module MotionPrime
|
|
6
6
|
attr_reader :form
|
7
7
|
after_render :on_section_render
|
8
8
|
|
9
|
-
before_initialize :prepare_table_data
|
10
9
|
after_initialize :observe_model_errors
|
11
10
|
|
12
11
|
def prepare_table_data
|
13
12
|
@form = @options[:table]
|
14
13
|
if options[:observe_errors]
|
15
14
|
# Do not remove clone() after delete()
|
16
|
-
@errors_observer_options = normalize_options(options.delete(:observe_errors).clone,
|
15
|
+
@errors_observer_options = normalize_options(options.delete(:observe_errors).clone, elements_eval_object)
|
17
16
|
end
|
18
17
|
end
|
19
18
|
|
@@ -50,6 +49,7 @@ module MotionPrime
|
|
50
49
|
end
|
51
50
|
|
52
51
|
def observe_model_errors
|
52
|
+
prepare_table_data
|
53
53
|
return unless observing_errors?
|
54
54
|
on_error_change = proc { |old_value, new_value|
|
55
55
|
changes = observing_errors_for.errors.changes
|
@@ -187,5 +187,10 @@ module MotionPrime
|
|
187
187
|
error_height = element ? element.cached_content_height + 5 : 0
|
188
188
|
super + error_height
|
189
189
|
end
|
190
|
+
|
191
|
+
protected
|
192
|
+
def elements_eval_object
|
193
|
+
form
|
194
|
+
end
|
190
195
|
end
|
191
196
|
end
|
@@ -3,10 +3,10 @@ module MotionPrime
|
|
3
3
|
element :label, type: :label do
|
4
4
|
default_label_options
|
5
5
|
end
|
6
|
-
element :input, type: :text_field, delegate: proc {
|
6
|
+
element :input, type: :text_field, delegate: proc { table_delegate } do
|
7
7
|
{secure_text_entry: true}.merge(options[:input] || {})
|
8
8
|
end
|
9
|
-
element :error_message, type: :error_message, text: proc { all_errors.join("\n") if observing_errors? }
|
9
|
+
element :error_message, type: :error_message, text: proc { |field| field.all_errors.join("\n") if field.observing_errors? }
|
10
10
|
after_render :bind_text_input
|
11
11
|
|
12
12
|
def value
|
@@ -9,7 +9,7 @@ module MotionPrime
|
|
9
9
|
element :arrow, type: :image do
|
10
10
|
options[:arrow] || {}
|
11
11
|
end
|
12
|
-
element :error_message, type: :error_message, text: proc { observing_errors? and all_errors.join("\n") }
|
12
|
+
element :error_message, type: :error_message, text: proc { |field| field.observing_errors? and field.all_errors.join("\n") }
|
13
13
|
|
14
14
|
after_render :bind_select_button
|
15
15
|
|
@@ -4,11 +4,11 @@ module MotionPrime
|
|
4
4
|
default_label_options
|
5
5
|
end
|
6
6
|
|
7
|
-
element :input, type: :text_field, delegate: proc {
|
7
|
+
element :input, type: :text_field, delegate: proc { table_delegate } do
|
8
8
|
options[:input] || {}
|
9
9
|
end
|
10
10
|
|
11
|
-
element :error_message, type: :error_message, text: proc { all_errors.join("\n") if observing_errors? }
|
11
|
+
element :error_message, type: :error_message, text: proc { |field| field.all_errors.join("\n") if field.observing_errors? }
|
12
12
|
after_render :bind_text_input
|
13
13
|
|
14
14
|
def value
|
@@ -3,7 +3,7 @@ module MotionPrime
|
|
3
3
|
element :button, type: :button do
|
4
4
|
{title: options[:name].to_s.titleize}.merge(options[:button] || {})
|
5
5
|
end
|
6
|
-
element :error_message, type: :error_message, text: proc { all_errors.join("\n") if observing_errors? }
|
6
|
+
element :error_message, type: :error_message, text: proc { |field| field.all_errors.join("\n") if field.observing_errors? }
|
7
7
|
|
8
8
|
after_render :bind_button
|
9
9
|
|
@@ -3,11 +3,11 @@ module MotionPrime
|
|
3
3
|
element :label, type: :label do
|
4
4
|
default_label_options
|
5
5
|
end
|
6
|
-
element :input, type: :text_view, delegate: proc {
|
6
|
+
element :input, type: :text_view, delegate: proc { table_delegate } do
|
7
7
|
{editable: true}.merge(options[:input] || {})
|
8
8
|
end
|
9
9
|
|
10
|
-
element :error_message, type: :error_message, text: proc { observing_errors? and all_errors.join("\n") }
|
10
|
+
element :error_message, type: :error_message, text: proc { |field| field.observing_errors? and field.all_errors.join("\n") }
|
11
11
|
after_render :bind_text_input
|
12
12
|
|
13
13
|
def value
|
@@ -165,7 +165,7 @@ module MotionPrime
|
|
165
165
|
base_styles = [type]
|
166
166
|
base_styles << :"#{type}_with_sections" unless flat_data?
|
167
167
|
item_styles = [name.to_sym]
|
168
|
-
item_styles
|
168
|
+
item_styles += Array.wrap(@styles) if @styles.present?
|
169
169
|
{common: base_styles, specific: item_styles}
|
170
170
|
end
|
171
171
|
|
@@ -216,13 +216,13 @@ module MotionPrime
|
|
216
216
|
end
|
217
217
|
|
218
218
|
def table_element_options
|
219
|
-
{
|
219
|
+
container_options.slice(:render_target).merge({
|
220
220
|
section: self.weak_ref,
|
221
221
|
styles: table_styles.values.flatten,
|
222
222
|
delegate: table_delegate,
|
223
223
|
data_source: table_delegate,
|
224
224
|
style: (UITableViewStyleGrouped unless flat_data?)
|
225
|
-
}
|
225
|
+
})
|
226
226
|
end
|
227
227
|
|
228
228
|
def render_table
|
@@ -388,9 +388,11 @@ module MotionPrime
|
|
388
388
|
end
|
389
389
|
|
390
390
|
def container_element_options_for(index)
|
391
|
+
cell_section = cell_section_by_index(index)
|
391
392
|
{
|
392
393
|
reuse_identifier: cell_name(table_view, index),
|
393
|
-
parent_view: table_view
|
394
|
+
parent_view: table_view,
|
395
|
+
bounds: {height: cell_section.container_height}
|
394
396
|
}
|
395
397
|
end
|
396
398
|
|
@@ -4,7 +4,7 @@ module MotionPrime
|
|
4
4
|
screen.automaticallyAdjustsScrollViewInsets = false
|
5
5
|
|
6
6
|
table_view.addPullToRefreshWithActionHandler(block) # block must be a variable
|
7
|
-
screen.
|
7
|
+
screen.set_options table_view.pullToRefreshView, styles: [:base_pull_to_refresh]
|
8
8
|
end
|
9
9
|
|
10
10
|
def finish_pull_to_refresh
|
data/motion-prime/styles/form.rb
CHANGED
data/motion-prime/version.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module MotionPrime
|
2
2
|
module FrameCalculatorMixin
|
3
|
-
def calculate_frame_for(
|
3
|
+
def calculate_frame_for(parent_bounds, options)
|
4
4
|
width = options[:width]
|
5
5
|
height = options[:height]
|
6
6
|
top = options[:top]
|
@@ -14,11 +14,11 @@ module MotionPrime
|
|
14
14
|
height = options[:height_to_fit]
|
15
15
|
end
|
16
16
|
|
17
|
-
return
|
17
|
+
return parent_bounds if width.nil? && height.nil? && right.nil? && bottom.nil?
|
18
18
|
frame = CGRectMake(0,0,0,0)
|
19
19
|
|
20
|
-
max_width =
|
21
|
-
max_height =
|
20
|
+
max_width = parent_bounds.size.width
|
21
|
+
max_height = parent_bounds.size.height
|
22
22
|
width = 0.0 if width.nil?
|
23
23
|
height = 0.0 if height.nil?
|
24
24
|
|
@@ -8,36 +8,36 @@ module MotionPrime
|
|
8
8
|
render_target = options.delete(:render_target)
|
9
9
|
parent_view = options.delete(:parent_view) || render_target
|
10
10
|
|
11
|
-
|
11
|
+
parent_bounds = if view_stack.empty?
|
12
12
|
parent_view.try(:bounds) || CGRectZero
|
13
13
|
else
|
14
14
|
view_stack.last.bounds
|
15
15
|
end
|
16
16
|
builder = ViewBuilder.new(klass, options)
|
17
|
-
options = builder.options.merge(calculate_frame: true,
|
17
|
+
options = builder.options.merge(calculate_frame: true, parent_bounds: parent_bounds)
|
18
18
|
view = builder.view
|
19
19
|
insert_index = options.delete(:at_index)
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
insert_index ?
|
24
|
-
elsif view_stack.any?
|
25
|
-
insert_index ? view_stack.last.insertSubview(view, atIndex: insert_index) : view_stack.last.addSubview(view)
|
21
|
+
set_options(view, options, &block)
|
22
|
+
if superview = render_target || view_stack.last
|
23
|
+
insert_index ? superview.insertSubview(view, atIndex: insert_index) : superview.addSubview(view)
|
26
24
|
end
|
27
|
-
|
28
|
-
setup(view, options, &block)
|
29
25
|
view.on_added if view.respond_to?(:on_added)
|
30
|
-
|
31
26
|
view
|
32
27
|
end
|
33
28
|
|
34
|
-
def
|
35
|
-
ViewStyler.new(view, options.delete(:
|
29
|
+
def set_options(view, options = {}, &block)
|
30
|
+
ViewStyler.new(view, options.delete(:parent_bounds), options).apply
|
36
31
|
view_stack.push(view)
|
37
32
|
block.call(view) if block_given?
|
38
33
|
view_stack.pop
|
39
34
|
end
|
40
35
|
|
36
|
+
def setup(view, options = {}, &block)
|
37
|
+
puts "DEPRECATION: screen#setup is deprecated, please use screen#set_options instead"
|
38
|
+
set_options(view, options, &block)
|
39
|
+
end
|
40
|
+
|
41
41
|
def view_stack
|
42
42
|
@view_stack ||= []
|
43
43
|
end
|
@@ -7,10 +7,10 @@ module MotionPrime
|
|
7
7
|
|
8
8
|
attr_reader :view, :options
|
9
9
|
|
10
|
-
def initialize(view,
|
10
|
+
def initialize(view, parent_bounds = CGRectZero, options = {})
|
11
11
|
@options = Styles.extend_and_normalize_options options
|
12
12
|
@view = view
|
13
|
-
prepare_frame_for(
|
13
|
+
prepare_frame_for(parent_bounds) if @options.delete(:calculate_frame)
|
14
14
|
prepare_options!
|
15
15
|
end
|
16
16
|
|
@@ -29,8 +29,8 @@ module MotionPrime
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def prepare_frame_for(
|
33
|
-
options[:frame] = calculate_frame_for(
|
32
|
+
def prepare_frame_for(parent_bounds)
|
33
|
+
options[:frame] = calculate_frame_for(parent_bounds, options)
|
34
34
|
if options.slice(:width, :height, :right, :bottom, :height_to_fit).values.any?
|
35
35
|
mask = UIViewAutoresizingNone
|
36
36
|
mask |= UIViewAutoresizingFlexibleTopMargin if options[:top].nil?
|
@@ -77,6 +77,9 @@ module MotionPrime
|
|
77
77
|
:text_alignment, :font, :line_break_mode, :number_of_lines
|
78
78
|
]
|
79
79
|
attributed_text_options = options.slice(*text_attributes)
|
80
|
+
if view.is_a?(UIButton)
|
81
|
+
attributed_text_options[:text] ||= options[:title]
|
82
|
+
end
|
80
83
|
options.except!(*text_attributes)
|
81
84
|
attributed_text_options
|
82
85
|
end
|
@@ -141,7 +144,10 @@ module MotionPrime
|
|
141
144
|
end
|
142
145
|
|
143
146
|
def set_text_options(key, value)
|
144
|
-
if key
|
147
|
+
if key == 'content_horizontal_alignment' && value.is_a?(Symbol) && %[left right center fill].include?(value.to_s)
|
148
|
+
view.setValue "UIControlContentHorizontalAlignment#{value.camelize}".constantize, forKey: camelize_factory(key)
|
149
|
+
true
|
150
|
+
elsif key.end_with?('alignment') && value.is_a?(Symbol)
|
145
151
|
view.setValue value.uitextalignment, forKey: camelize_factory(key)
|
146
152
|
true
|
147
153
|
elsif key.end_with?('line_break_mode') && value.is_a?(Symbol)
|
@@ -166,7 +172,7 @@ module MotionPrime
|
|
166
172
|
current_inset.send("#{key.partition('_').first}=", value)
|
167
173
|
view.contentInset = current_inset
|
168
174
|
true
|
169
|
-
elsif key.end_with?('inset')
|
175
|
+
elsif key.end_with?('inset') || key.end_with?('indicator_insets')
|
170
176
|
inset = if value.to_s == 'none'
|
171
177
|
UIEdgeInsetsMake(0, 320, 0, 0)
|
172
178
|
elsif value.is_a?(Array) && value.count == 2
|
@@ -181,16 +187,38 @@ module MotionPrime
|
|
181
187
|
|
182
188
|
def set_layer_options(key, value)
|
183
189
|
if key == 'rounded_corners'
|
190
|
+
layer_bounds = bounds
|
191
|
+
if value[:overlap]
|
192
|
+
size = layer_bounds.size
|
193
|
+
size.height += value.fetch(:border_width, 0) # overlap to the next cell
|
194
|
+
layer_bounds.size = size
|
195
|
+
end
|
196
|
+
|
184
197
|
radius = value[:radius].to_f
|
185
198
|
corner_consts = {top_left: UIRectCornerTopLeft, bottom_left: UIRectCornerBottomLeft, bottom_right: UIRectCornerBottomRight, top_right: UIRectCornerTopRight}
|
186
199
|
corners = value[:corners].inject(0) { |result, corner| result|corner_consts[corner] }
|
187
|
-
|
188
|
-
bounds = CGRectMake(0, 0, size.width, size.height)
|
189
|
-
mask_path = UIBezierPath.bezierPathWithRoundedRect(bounds, byRoundingCorners: corners, cornerRadii: CGSizeMake(radius, radius))
|
200
|
+
mask_path = UIBezierPath.bezierPathWithRoundedRect(layer_bounds, byRoundingCorners: corners, cornerRadii: CGSizeMake(radius, radius))
|
190
201
|
mask_layer = CAShapeLayer.layer
|
191
|
-
|
202
|
+
|
203
|
+
|
204
|
+
mask_layer.frame = layer_bounds
|
192
205
|
mask_layer.path = mask_path.CGPath
|
193
206
|
view.mask = mask_layer
|
207
|
+
|
208
|
+
if value[:border_color] && value[:border_width]
|
209
|
+
stroke_layer = CAShapeLayer.layer
|
210
|
+
stroke_layer.path = mask_path.CGPath
|
211
|
+
stroke_layer.fillColor = :clear.uicolor.cgcolor
|
212
|
+
stroke_layer.strokeColor = value[:border_color].uicolor.cgcolor
|
213
|
+
stroke_layer.lineWidth = value[:border_width].to_f*2 # another half is hidden by the mask
|
214
|
+
|
215
|
+
container_view = view.delegate
|
216
|
+
stroke_view = UIView.alloc.initWithFrame(layer_bounds)
|
217
|
+
stroke_view.userInteractionEnabled = false
|
218
|
+
stroke_view.layer.addSublayer(stroke_layer)
|
219
|
+
container_view.addSubview(stroke_view)
|
220
|
+
view.addSublayer(stroke_layer)
|
221
|
+
end
|
194
222
|
true
|
195
223
|
end
|
196
224
|
end
|
@@ -199,7 +227,7 @@ module MotionPrime
|
|
199
227
|
if value.is_a?(Hash)
|
200
228
|
self.class.new(
|
201
229
|
view.send(low_camelize_factory(key).to_sym), nil,
|
202
|
-
value.merge(parent_frame: options[:frame] || options[:parent_frame])
|
230
|
+
value.merge(parent_frame: options[:frame] || options[:parent_frame], bounds: options[:bounds])
|
203
231
|
).apply
|
204
232
|
true
|
205
233
|
end
|
@@ -227,9 +255,17 @@ module MotionPrime
|
|
227
255
|
width height top right bottom left
|
228
256
|
max_width max_outer_width min_width min_outer_width
|
229
257
|
max_height max_outer_height min_height min_outer_width
|
258
|
+
bounds
|
230
259
|
].include?(key.to_s)
|
231
260
|
end
|
232
261
|
|
262
|
+
def bounds
|
263
|
+
# TODO: raise error if parent_frame is nill
|
264
|
+
frame_size = options[:parent_frame].size
|
265
|
+
bounds_options = options[:bounds] || {}
|
266
|
+
CGRectMake(0, 0, bounds_options.fetch(:width, frame_size.width), bounds_options.fetch(:height, frame_size.height))
|
267
|
+
end
|
268
|
+
|
233
269
|
STRUCTS_MAP = {
|
234
270
|
CGAffineTransform => Proc.new {|v| NSValue.valueWithCGAffineTransform(v) },
|
235
271
|
CGPoint => Proc.new {|v| NSValue.valueWithCGPoint(v) },
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: motion-prime
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Iskander Haziev
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-03-
|
12
|
+
date: 2014-03-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|