motion-prime 0.3.2 → 0.3.3
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 +3 -0
- data/Gemfile.lock +1 -1
- data/README.md +10 -0
- data/doc/code/getting_started.rb +61 -0
- data/doc/docs/docco.css +500 -0
- data/doc/docs/getting_started.html +177 -0
- data/doc/docs/public/fonts/aller-bold.eot +0 -0
- data/doc/docs/public/fonts/aller-bold.ttf +0 -0
- data/doc/docs/public/fonts/aller-bold.woff +0 -0
- data/doc/docs/public/fonts/aller-light.eot +0 -0
- data/doc/docs/public/fonts/aller-light.ttf +0 -0
- data/doc/docs/public/fonts/aller-light.woff +0 -0
- data/doc/docs/public/fonts/novecento-bold.eot +0 -0
- data/doc/docs/public/fonts/novecento-bold.ttf +0 -0
- data/doc/docs/public/fonts/novecento-bold.woff +0 -0
- data/doc/docs/public/stylesheets/normalize.css +375 -0
- data/files/app/sections/sidebar/action.rb +1 -1
- data/motion-prime/app_delegate.rb +8 -2
- data/motion-prime/elements/_content_padding_mixin.rb +12 -12
- data/motion-prime/elements/_content_text_mixin.rb +65 -0
- data/motion-prime/elements/base.rb +51 -19
- data/motion-prime/elements/button.rb +1 -1
- data/motion-prime/elements/draw.rb +26 -113
- data/motion-prime/elements/draw/_draw_background_mixin.rb +26 -0
- data/motion-prime/elements/draw/image.rb +10 -1
- data/motion-prime/elements/draw/label.rb +61 -42
- data/motion-prime/elements/draw/view.rb +14 -0
- data/motion-prime/elements/error_message.rb +1 -1
- data/motion-prime/elements/label.rb +1 -1
- data/motion-prime/elements/text_field.rb +2 -2
- data/motion-prime/elements/text_view.rb +3 -0
- data/motion-prime/helpers/has_style_chain_builder.rb +1 -1
- data/motion-prime/helpers/has_styles.rb +28 -0
- data/motion-prime/models/bag.rb +1 -1
- data/motion-prime/models/sync.rb +4 -4
- data/motion-prime/screens/_base_mixin.rb +1 -1
- data/motion-prime/screens/extensions/_navigation_bar_mixin.rb +7 -0
- data/motion-prime/screens/sidebar_container_screen.rb +8 -2
- data/motion-prime/sections/_cell_section_mixin.rb +25 -0
- data/motion-prime/sections/base.rb +17 -16
- data/motion-prime/sections/draw.rb +32 -10
- data/motion-prime/sections/form.rb +27 -17
- data/motion-prime/sections/form/base_field_section.rb +0 -1
- data/motion-prime/sections/form/base_header_section.rb +3 -2
- data/motion-prime/sections/form/password_field_section.rb +1 -1
- data/motion-prime/sections/table.rb +31 -10
- data/motion-prime/sections/table/base_cell_section.rb +1 -22
- data/motion-prime/sections/table/draw_cell_section.rb +5 -0
- data/motion-prime/styles/form.rb +12 -4
- data/motion-prime/support/_key_value_store.rb +0 -2
- data/motion-prime/support/dm_text_field.rb +2 -2
- data/motion-prime/support/tab_bar_controller.rb +28 -0
- data/motion-prime/version.rb +1 -1
- data/motion-prime/views/_frame_calculator_mixin.rb +75 -0
- data/motion-prime/views/view_styler.rb +36 -94
- metadata +23 -4
- data/motion-prime/elements/_field_dimensions_mixin.rb +0 -59
- data/motion-prime/elements/_text_dimensions_mixin.rb +0 -35
@@ -20,22 +20,23 @@ module MotionPrime
|
|
20
20
|
|
21
21
|
class_attribute :text_field_limits, :text_view_limits
|
22
22
|
class_attribute :fields_options, :section_header_options
|
23
|
-
attr_accessor :fields, :field_indexes, :keyboard_visible, :rendered_views, :section_headers
|
23
|
+
attr_accessor :fields, :field_indexes, :keyboard_visible, :rendered_views, :section_headers, :section_header_options
|
24
24
|
|
25
25
|
def table_data
|
26
26
|
if @groups_count == 1
|
27
27
|
fields.values
|
28
28
|
else
|
29
29
|
section_indexes = []
|
30
|
-
fields.inject([]) do |result, (key, field)|
|
30
|
+
data = fields.inject([]) do |result, (key, field)|
|
31
31
|
section = self.class.fields_options[key][:group].to_i
|
32
|
-
|
33
32
|
section_indexes[section] ||= 0
|
34
33
|
result[section] ||= []
|
35
34
|
result[section][section_indexes[section]] = field
|
36
35
|
section_indexes[section] += 1
|
37
36
|
result
|
38
37
|
end
|
38
|
+
self.section_header_options.delete_if.each_with_index { |opts, id| data[id].nil? }
|
39
|
+
data.compact
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
@@ -56,7 +57,7 @@ module MotionPrime
|
|
56
57
|
|
57
58
|
def render_cell(index, table)
|
58
59
|
field = rows_for_section(index.section)[index.row]
|
59
|
-
screen.table_view_cell section: field,
|
60
|
+
screen.table_view_cell section: field, reuse_identifier: cell_name(table, index), parent_view: table_view do |cell_view|
|
60
61
|
field.cell_view = cell_view if field.respond_to?(:cell_view)
|
61
62
|
field.render(to: screen)
|
62
63
|
end
|
@@ -168,6 +169,9 @@ module MotionPrime
|
|
168
169
|
def textFieldShouldReturn(text_field)
|
169
170
|
on_input_return(text_field)
|
170
171
|
end
|
172
|
+
def textFieldShouldBeginEditing(text_field)
|
173
|
+
text_field.respond_to?(:readonly) ? !text_field.readonly : true
|
174
|
+
end
|
171
175
|
def textFieldDidBeginEditing(text_field)
|
172
176
|
on_input_edit(text_field)
|
173
177
|
end
|
@@ -176,16 +180,12 @@ module MotionPrime
|
|
176
180
|
end
|
177
181
|
|
178
182
|
def textView(text_view, shouldChangeTextInRange:range, replacementText:string)
|
179
|
-
|
180
|
-
view("#{field_name}:input")
|
181
|
-
end.try(:last)
|
182
|
-
return true unless limit
|
183
|
-
allow_string_replacement?(text_view, limit, range, string)
|
183
|
+
textField(text_view, shouldChangeCharactersInRange:range, replacementString:string)
|
184
184
|
end
|
185
185
|
|
186
186
|
def textField(text_field, shouldChangeCharactersInRange:range, replacementString:string)
|
187
187
|
limit = (self.class.text_field_limits || {}).find do |field_name, limit|
|
188
|
-
view("#{field_name}:input")
|
188
|
+
view("#{field_name}:input") == text_field
|
189
189
|
end.try(:last)
|
190
190
|
return true unless limit
|
191
191
|
allow_string_replacement?(text_field, limit, range, string)
|
@@ -205,18 +205,16 @@ module MotionPrime
|
|
205
205
|
end
|
206
206
|
|
207
207
|
def render_field?(name, options)
|
208
|
-
condition = options
|
209
|
-
if condition.
|
210
|
-
true
|
211
|
-
elsif condition.is_a?(Proc)
|
208
|
+
return true unless condition = options[:if]
|
209
|
+
if condition.is_a?(Proc)
|
212
210
|
self.instance_eval(&condition)
|
213
211
|
else
|
214
|
-
condition
|
212
|
+
condition.to_proc.call(self)
|
215
213
|
end
|
216
214
|
end
|
217
215
|
|
218
216
|
def render_header(section)
|
219
|
-
return unless options = self.
|
217
|
+
return unless options = self.section_header_options.try(:[], section)
|
220
218
|
self.section_headers[section] ||= BaseHeaderSection.new(options.merge(table: self))
|
221
219
|
end
|
222
220
|
|
@@ -265,6 +263,12 @@ module MotionPrime
|
|
265
263
|
end
|
266
264
|
end
|
267
265
|
|
266
|
+
def reload_data
|
267
|
+
@groups_count = nil
|
268
|
+
init_form_fields
|
269
|
+
super
|
270
|
+
end
|
271
|
+
|
268
272
|
private
|
269
273
|
def init_form_fields
|
270
274
|
self.fields = {}
|
@@ -273,12 +277,18 @@ module MotionPrime
|
|
273
277
|
(self.class.fields_options || []).each do |key, field|
|
274
278
|
next unless render_field?(key, field)
|
275
279
|
section_id = field[:group].to_i
|
276
|
-
section_indexes[section_id] ||= 0
|
277
280
|
@groups_count = [@groups_count || 1, section_id + 1].max
|
278
281
|
self.fields[key] = load_field(field)
|
282
|
+
|
283
|
+
section_indexes[section_id] ||= 0
|
279
284
|
self.field_indexes[key] = "#{section_id}_#{section_indexes[section_id]}"
|
280
285
|
section_indexes[section_id] += 1
|
281
286
|
end
|
287
|
+
init_form_headers
|
288
|
+
end
|
289
|
+
|
290
|
+
def init_form_headers
|
291
|
+
self.section_header_options = Array.wrap(self.class.section_header_options).clone
|
282
292
|
end
|
283
293
|
end
|
284
294
|
end
|
@@ -5,14 +5,15 @@ module MotionPrime
|
|
5
5
|
DEFAULT_HEADER_HEIGHT = 20
|
6
6
|
|
7
7
|
element :title, text: proc { @options[:title] }
|
8
|
+
element :hint, text: proc { @options[:hint] }
|
8
9
|
|
9
10
|
def initialize(options = {})
|
10
11
|
@cell_type = :header
|
11
12
|
super
|
12
13
|
end
|
13
14
|
|
14
|
-
def
|
15
|
-
|
15
|
+
def render_element?(name)
|
16
|
+
@options[name].present?
|
16
17
|
end
|
17
18
|
|
18
19
|
def container_height
|
@@ -4,7 +4,7 @@ module MotionPrime
|
|
4
4
|
options[:label] || {}
|
5
5
|
end
|
6
6
|
element :input, type: :text_field do
|
7
|
-
options[:input] || {}
|
7
|
+
{secure_text_entry: true}.merge(options[:input] || {})
|
8
8
|
end
|
9
9
|
element :error_message, type: :error_message, text: proc { all_errors.join("\n") if observing_errors? }
|
10
10
|
after_render :bind_text_input
|
@@ -61,24 +61,45 @@ module MotionPrime
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def cell_styles(cell)
|
64
|
-
# type
|
64
|
+
# type = [`cell`, `header`, `field`]
|
65
|
+
|
66
|
+
# UserFormSection example: field :email, type: :string
|
67
|
+
# form_name = `user`
|
68
|
+
# type = `field`
|
69
|
+
# field_name = `email`
|
70
|
+
# field_type = `string_field`
|
71
|
+
|
72
|
+
# CategoriesTableSection example: table is a `CategoryTableSection`, cell is a `CategoryTitleSection`, element :icon, type: :image
|
73
|
+
# table_name = `categories`
|
74
|
+
# type = `cell` (always true)
|
75
|
+
# table_cell_name = `title`
|
65
76
|
type = cell.respond_to?(:cell_type) ? cell.cell_type : 'cell'
|
66
77
|
|
67
78
|
suffixes = [type]
|
68
79
|
if cell.is_a?(BaseFieldSection)
|
69
80
|
suffixes << cell.default_name
|
70
|
-
elsif cell.respond_to?(:cell_name)
|
71
|
-
suffixes << cell.cell_name
|
72
81
|
end
|
73
82
|
|
74
|
-
styles = {
|
75
|
-
|
76
|
-
|
77
|
-
|
83
|
+
styles = {}
|
84
|
+
# table: base_table_<type>
|
85
|
+
# form: base_form_<type>, base_form_<field_type>
|
86
|
+
styles[:common] = build_styles_chain(table_styles[:common], suffixes)
|
78
87
|
|
79
|
-
if cell.
|
80
|
-
|
88
|
+
if cell.is_a?(BaseFieldSection)
|
89
|
+
# form cell: _<type>_<field_name> = `_field_email`
|
90
|
+
suffixes << :"#{type}_#{cell.name}" if cell.name
|
91
|
+
elsif cell.respond_to?(:cell_name) # BaseCellSection
|
92
|
+
# table cell: _<table_cell_name> = `_title`
|
93
|
+
suffixes << cell.cell_name
|
81
94
|
end
|
95
|
+
# table: <table_name>_table_<type>, <table_name>_table_<table_cell_name> = `categories_table_cell`, `categories_table_title`
|
96
|
+
# form: <form_name>_form_<type>, <form_name>_form_<field_type>, user_form_<type>_email = `user_form_field`, `user_form_string_field`, `user_form_field_email`
|
97
|
+
styles[:specific] = build_styles_chain(table_styles[:specific], suffixes)
|
98
|
+
|
99
|
+
if respond_to?(:container_styles) && container_styles.present?
|
100
|
+
@section_styles[:specific] += Array.wrap(container_styles)
|
101
|
+
end
|
102
|
+
|
82
103
|
styles
|
83
104
|
end
|
84
105
|
|
@@ -133,7 +154,7 @@ module MotionPrime
|
|
133
154
|
reuse_identifier: cell_name(table, index)
|
134
155
|
)
|
135
156
|
else
|
136
|
-
screen.table_view_cell section: item,
|
157
|
+
screen.table_view_cell section: item, reuse_identifier: cell_name(table, index), parent_view: table_view do
|
137
158
|
item.render(to: screen)
|
138
159
|
end
|
139
160
|
end
|
@@ -1,26 +1,5 @@
|
|
1
1
|
module MotionPrime
|
2
2
|
class BaseCellSection < BaseSection
|
3
|
-
|
4
|
-
|
5
|
-
def initialize(options = {})
|
6
|
-
@table ||= options[:table]
|
7
|
-
super
|
8
|
-
end
|
9
|
-
|
10
|
-
def section_styles
|
11
|
-
@table.try(:cell_styles, self) || {}
|
12
|
-
end
|
13
|
-
|
14
|
-
def cell_type
|
15
|
-
@cell_type ||= begin
|
16
|
-
self.is_a?(BaseFieldSection) ? :field : :cell
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def cell_name
|
21
|
-
return name unless table
|
22
|
-
table_name = table.name.gsub('_table', '')
|
23
|
-
name.gsub("#{table_name}_", '')
|
24
|
-
end
|
3
|
+
include CellSectionMixin
|
25
4
|
end
|
26
5
|
end
|
data/motion-prime/styles/form.rb
CHANGED
@@ -2,8 +2,16 @@ motion_require '../views/styles.rb'
|
|
2
2
|
MotionPrime::Styles.define :base_form do
|
3
3
|
style :header, container: {height: 25}
|
4
4
|
style :header_label,
|
5
|
-
left: 0,
|
6
|
-
bottom:
|
5
|
+
left: 0,
|
6
|
+
bottom: 5,
|
7
|
+
top: nil,
|
8
|
+
width: 320,
|
9
|
+
size_to_fit: true
|
10
|
+
style :header_hint,
|
11
|
+
left: 0,
|
12
|
+
bottom: 5,
|
13
|
+
top: nil,
|
14
|
+
width: 320
|
7
15
|
|
8
16
|
style :field,
|
9
17
|
selection_style: UITableViewCellSelectionStyleNone,
|
@@ -71,7 +79,7 @@ MotionPrime::Styles.define :base_form do
|
|
71
79
|
title_label: {
|
72
80
|
font: proc { MotionPrime::Config.font.name.uifont(16) }
|
73
81
|
}
|
74
|
-
style :
|
82
|
+
style :select_field_image,
|
75
83
|
image: "images/forms/select_arrow.png",
|
76
84
|
top: 40,
|
77
85
|
right: 5,
|
@@ -85,7 +93,7 @@ MotionPrime::Styles.define :base_form do
|
|
85
93
|
left: 20,
|
86
94
|
right: 20
|
87
95
|
|
88
|
-
style :
|
96
|
+
style :with_sections_select_field_image,
|
89
97
|
right: 25
|
90
98
|
|
91
99
|
style :with_sections_switch_field_input,
|
@@ -4,7 +4,7 @@
|
|
4
4
|
class DMTextField < UITextField
|
5
5
|
include MotionPrime::SupportKeyValueStore
|
6
6
|
include MotionPrime::SupportPaddingAttribute
|
7
|
-
attr_accessor :placeholderColor, :placeholderFont
|
7
|
+
attr_accessor :placeholderColor, :placeholderFont, :readonly
|
8
8
|
|
9
9
|
# placeholder position
|
10
10
|
def textRectForBounds(bounds)
|
@@ -26,7 +26,7 @@ class DMTextField < UITextField
|
|
26
26
|
def padding_top # to center title label
|
27
27
|
self.paddingTop || self.padding || begin
|
28
28
|
single_line_height = self.font.pointSize
|
29
|
-
(self.bounds.size.height - single_line_height)/2 +
|
29
|
+
(self.bounds.size.height - single_line_height)/2 + 1
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module MotionPrime
|
2
|
+
class TabBarController < UITabBarController
|
3
|
+
|
4
|
+
def self.new(screens)
|
5
|
+
controller = alloc.init
|
6
|
+
|
7
|
+
view_controllers = []
|
8
|
+
|
9
|
+
screens.each_with_index do |screen, index|
|
10
|
+
screen.tabBarItem.tag = index
|
11
|
+
screen.send(:on_screen_load) if screen.respond_to?(:on_screen_load)
|
12
|
+
screen.wrap_in_navigation if screen.respond_to?(:wrap_in_navigation)
|
13
|
+
screen.tab_bar = controller if screen.respond_to?(:tab_bar=)
|
14
|
+
view_controllers << screen.main_controller
|
15
|
+
end
|
16
|
+
|
17
|
+
controller.viewControllers = view_controllers
|
18
|
+
controller
|
19
|
+
end
|
20
|
+
|
21
|
+
def open_tab(tab)
|
22
|
+
controller = viewControllers[tab]
|
23
|
+
if controller
|
24
|
+
self.selectedViewController = controller
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/motion-prime/version.rb
CHANGED
@@ -0,0 +1,75 @@
|
|
1
|
+
module MotionPrime
|
2
|
+
module FrameCalculatorMixin
|
3
|
+
def calculate_frome_for(bounds, options)
|
4
|
+
width = options[:width]
|
5
|
+
height = options[:height]
|
6
|
+
top = options[:top]
|
7
|
+
right = options[:right]
|
8
|
+
bottom = options[:bottom]
|
9
|
+
left = options[:left]
|
10
|
+
value_type = options[:value_type].to_s # absolute/relative
|
11
|
+
|
12
|
+
if options[:height_to_fit].present? && height.nil? && (top.nil? || bottom.nil?)
|
13
|
+
height = options[:height_to_fit]
|
14
|
+
end
|
15
|
+
|
16
|
+
return bounds if width.nil? && height.nil? && right.nil? && bottom.nil?
|
17
|
+
frame = CGRectMake(0,0,0,0)
|
18
|
+
|
19
|
+
max_width = bounds.size.width
|
20
|
+
max_height = bounds.size.height
|
21
|
+
width = 0.0 if width.nil?
|
22
|
+
height = 0.0 if height.nil?
|
23
|
+
|
24
|
+
# calculate left and right if width is relative, e.g 0.7
|
25
|
+
if width && width > 0 && width <= 1 && value_type != 'absolute'
|
26
|
+
if right.nil?
|
27
|
+
left ||= 0
|
28
|
+
right = max_width - max_width * width
|
29
|
+
else
|
30
|
+
left = max_width - max_width * width
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# calculate top and bottom if height is relative, e.g 0.7
|
35
|
+
if height && height > 0 && height <= 1 && value_type != 'absolute'
|
36
|
+
if bottom.nil?
|
37
|
+
top ||= 0
|
38
|
+
bottom = max_height - max_height * height
|
39
|
+
else
|
40
|
+
top = max_height - max_height * height
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
if !left.nil? && !right.nil?
|
45
|
+
frame.origin.x = left
|
46
|
+
frame.size.width = max_width - left - right
|
47
|
+
elsif !right.nil?
|
48
|
+
frame.origin.x = max_width - width - right
|
49
|
+
frame.size.width = width
|
50
|
+
elsif !left.nil?
|
51
|
+
frame.origin.x = left
|
52
|
+
frame.size.width = width
|
53
|
+
else
|
54
|
+
frame.origin.x = max_width / 2 - width / 2
|
55
|
+
frame.size.width = width
|
56
|
+
end
|
57
|
+
|
58
|
+
if !top.nil? && !bottom.nil?
|
59
|
+
frame.origin.y = top
|
60
|
+
frame.size.height = max_height - top - bottom
|
61
|
+
elsif !bottom.nil?
|
62
|
+
frame.origin.y = max_height - height - bottom
|
63
|
+
frame.size.height = height
|
64
|
+
elsif !top.nil?
|
65
|
+
frame.origin.y = top
|
66
|
+
frame.size.height = height
|
67
|
+
else
|
68
|
+
frame.origin.y = max_height / 2 - height / 2
|
69
|
+
frame.size.height = height
|
70
|
+
end
|
71
|
+
|
72
|
+
frame
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -1,104 +1,40 @@
|
|
1
1
|
module MotionPrime
|
2
2
|
class ViewStyler
|
3
|
+
include FrameCalculatorMixin
|
4
|
+
include HasStyles
|
5
|
+
|
3
6
|
attr_reader :view, :options
|
4
7
|
|
5
8
|
def initialize(view, bounds = CGRectZero, options = {})
|
6
9
|
@options = Styles.extend_and_normalize_options options
|
7
10
|
@view = view
|
8
|
-
|
11
|
+
prepare_frame_for(bounds) if @options.delete(:calculate_frame)
|
9
12
|
end
|
10
13
|
|
11
14
|
def apply
|
12
|
-
convert_primitives_to_objects(options)
|
13
|
-
setValuesForKeysWithDictionary(
|
15
|
+
converted_options = convert_primitives_to_objects(options)
|
16
|
+
setValuesForKeysWithDictionary(converted_options)
|
14
17
|
end
|
15
18
|
|
16
19
|
def convert_primitives_to_objects(options)
|
17
|
-
options.
|
18
|
-
|
20
|
+
options.inject({}) do |result, (k, v)|
|
21
|
+
v = STRUCTS_MAP[v.class].call(v) if STRUCTS_MAP.has_key?(v.class)
|
22
|
+
result[k] = v
|
23
|
+
result
|
19
24
|
end
|
20
25
|
end
|
21
26
|
|
22
|
-
def
|
23
|
-
|
24
|
-
height = options.delete(:height)
|
25
|
-
top = options.delete(:top)
|
26
|
-
right = options.delete(:right)
|
27
|
-
bottom = options.delete(:bottom)
|
28
|
-
left = options.delete(:left)
|
29
|
-
value_type = options.delete(:value_type).to_s # absolute/relative
|
30
|
-
|
31
|
-
if options[:height_to_fit].present? && height.nil? && (top.nil? || bottom.nil?)
|
32
|
-
height = options[:height_to_fit]
|
33
|
-
end
|
34
|
-
|
35
|
-
if width.nil? && height.nil? && right.nil? && bottom.nil?
|
36
|
-
options[:frame] = bounds
|
37
|
-
else
|
38
|
-
frame = CGRectZero
|
39
|
-
|
40
|
-
max_width = bounds.size.width
|
41
|
-
max_height = bounds.size.height
|
42
|
-
width = 0.0 if width.nil?
|
43
|
-
height = 0.0 if height.nil?
|
44
|
-
|
45
|
-
# calculate left and right if width is relative, e.g 0.7
|
46
|
-
if width && width > 0 && width <= 1 && value_type != 'absolute'
|
47
|
-
if right.nil?
|
48
|
-
left ||= 0
|
49
|
-
right = max_width - max_width * width
|
50
|
-
else
|
51
|
-
left = max_width - max_width * width
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# calculate top and bottom if height is relative, e.g 0.7
|
56
|
-
if height && height > 0 && height <= 1 && value_type != 'absolute'
|
57
|
-
if bottom.nil?
|
58
|
-
top ||= 0
|
59
|
-
bottom = max_height - max_height * height
|
60
|
-
else
|
61
|
-
top = max_height - max_height * height
|
62
|
-
end
|
63
|
-
end
|
27
|
+
def prepare_frame_for(bounds)
|
28
|
+
options[:frame] = calculate_frome_for(bounds, options)
|
64
29
|
|
30
|
+
if options.slice(:width, :height, :right, :bottom, :height_to_fit).values.any?
|
65
31
|
mask = UIViewAutoresizingNone
|
66
|
-
mask |= UIViewAutoresizingFlexibleTopMargin if top.nil?
|
67
|
-
mask |= UIViewAutoresizingFlexibleLeftMargin if left.nil?
|
68
|
-
mask |= UIViewAutoresizingFlexibleBottomMargin if bottom.nil?
|
69
|
-
mask |= UIViewAutoresizingFlexibleRightMargin if right.nil?
|
70
|
-
mask |= UIViewAutoresizingFlexibleWidth if !left.nil? && !right.nil?
|
71
|
-
mask |= UIViewAutoresizingFlexibleHeight if !top.nil? && !bottom.nil?
|
72
|
-
|
73
|
-
if !left.nil? && !right.nil?
|
74
|
-
frame.origin.x = left
|
75
|
-
frame.size.width = max_width - left - right
|
76
|
-
elsif !right.nil?
|
77
|
-
frame.origin.x = max_width - width - right
|
78
|
-
frame.size.width = width
|
79
|
-
elsif !left.nil?
|
80
|
-
frame.origin.x = left
|
81
|
-
frame.size.width = width
|
82
|
-
else
|
83
|
-
frame.origin.x = max_width / 2 - width / 2
|
84
|
-
frame.size.width = width
|
85
|
-
end
|
86
|
-
|
87
|
-
if !top.nil? && !bottom.nil?
|
88
|
-
frame.origin.y = top
|
89
|
-
frame.size.height = max_height - top - bottom
|
90
|
-
elsif !bottom.nil?
|
91
|
-
frame.origin.y = max_height - height - bottom
|
92
|
-
frame.size.height = height
|
93
|
-
elsif !top.nil?
|
94
|
-
frame.origin.y = top
|
95
|
-
frame.size.height = height
|
96
|
-
else
|
97
|
-
frame.origin.y = max_height / 2 - height / 2
|
98
|
-
frame.size.height = height
|
99
|
-
end
|
100
|
-
|
101
|
-
options[:frame] = frame
|
32
|
+
mask |= UIViewAutoresizingFlexibleTopMargin if options[:top].nil?
|
33
|
+
mask |= UIViewAutoresizingFlexibleLeftMargin if options[:left].nil?
|
34
|
+
mask |= UIViewAutoresizingFlexibleBottomMargin if options[:bottom].nil?
|
35
|
+
mask |= UIViewAutoresizingFlexibleRightMargin if options[:right].nil?
|
36
|
+
mask |= UIViewAutoresizingFlexibleWidth if !options[:left].nil? && !options[:right].nil?
|
37
|
+
mask |= UIViewAutoresizingFlexibleHeight if !options[:top].nil? && !options[:bottom].nil?
|
102
38
|
options[:autoresizingMask] = mask
|
103
39
|
end
|
104
40
|
end
|
@@ -106,12 +42,15 @@ module MotionPrime
|
|
106
42
|
def setValue(value, forUndefinedKey: key)
|
107
43
|
# return if value.nil?
|
108
44
|
# ignore options
|
45
|
+
return if options[:section].is_a?(DrawSection) && %w[gradient].include?(key.to_s)
|
109
46
|
return if key == 'size_to_fit' && view.is_a?(UILabel)
|
110
47
|
return if (key == 'url' || key == 'default') && view.is_a?(UIImageView)
|
111
48
|
return if %w[
|
49
|
+
styles
|
50
|
+
width height top right bottom left value_type
|
112
51
|
max_width max_outer_width min_width min_outer_width
|
113
52
|
max_height max_outer_height min_height min_outer_width
|
114
|
-
height_to_fit container].include? key.to_s
|
53
|
+
height_to_fit container parent_frame].include? key.to_s
|
115
54
|
|
116
55
|
# apply options
|
117
56
|
if key.end_with?('title_color')
|
@@ -152,6 +91,17 @@ module MotionPrime
|
|
152
91
|
view.autocapitalizationType = UITextAutocapitalizationTypeNone if value === false
|
153
92
|
elsif key == 'keyboard_type'
|
154
93
|
view.setKeyboardType value.uikeyboardtype
|
94
|
+
elsif key == 'rounded_corners'
|
95
|
+
radius = value[:radius].to_f
|
96
|
+
corner_consts = {top_left: UIRectCornerTopLeft, bottom_left: UIRectCornerBottomLeft, bottom_right: UIRectCornerBottomRight, top_right: UIRectCornerTopRight}
|
97
|
+
corners = value[:corners].inject(0) { |result, corner| result|corner_consts[corner] }
|
98
|
+
size = options[:parent_frame].size
|
99
|
+
bounds = CGRectMake(0, 0, size.width, size.height)
|
100
|
+
mask_path = UIBezierPath.bezierPathWithRoundedRect(bounds, byRoundingCorners: corners, cornerRadii: CGSizeMake(radius, radius))
|
101
|
+
mask_layer = CAShapeLayer.layer
|
102
|
+
mask_layer.frame = bounds
|
103
|
+
mask_layer.path = mask_path.CGPath
|
104
|
+
view.mask = mask_layer
|
155
105
|
elsif key == 'mask'
|
156
106
|
radius = value[:radius]
|
157
107
|
bounds = CGRectMake(0, 0, value[:width], value[:height])
|
@@ -160,11 +110,6 @@ module MotionPrime
|
|
160
110
|
mask_layer.frame = bounds
|
161
111
|
mask_layer.path = mask_path.CGPath
|
162
112
|
view.layer.mask = mask_layer
|
163
|
-
# TODO: apply for corner_radius_top/bottom
|
164
|
-
# CAShapeLayer *shape = [[CAShapeLayer alloc] init];
|
165
|
-
# shape.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height) byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight cornerRadii:CGSizeMake(10, 10)].CGPath;
|
166
|
-
# self.layer.mask = shape;
|
167
|
-
# self.layer.masksToBounds = YES;
|
168
113
|
elsif key == 'attributed_text_options'
|
169
114
|
attributes = {}
|
170
115
|
if line_spacing = value[:line_spacing]
|
@@ -184,13 +129,10 @@ module MotionPrime
|
|
184
129
|
view.attributedText = attributedString
|
185
130
|
end
|
186
131
|
elsif key == 'gradient'
|
187
|
-
gradient =
|
188
|
-
gradient.frame = CGRectMake(value[:frame_x].to_f, value[:frame_y].to_f, value[:frame_width].to_f, value[:frame_height].to_f)
|
189
|
-
gradient.colors = value[:colors].map(&:uicolor).map(&:cgcolor)
|
190
|
-
gradient.locations = value[:locations] if value[:locations]
|
132
|
+
gradient = prepare_gradient(value)
|
191
133
|
view.layer.insertSublayer(gradient, atIndex: 0)
|
192
134
|
elsif value.is_a?(Hash)
|
193
|
-
self.class.new(view.send(key.camelize(:lower).to_sym), nil, value).apply
|
135
|
+
self.class.new(view.send(key.camelize(:lower).to_sym), nil, value.merge(parent_frame: options[:frame] || options[:parent_frame])).apply
|
194
136
|
else
|
195
137
|
view.setValue value, forKey: key.camelize(:lower)
|
196
138
|
end
|