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.
Files changed (59) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG.md +3 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.md +10 -0
  5. data/doc/code/getting_started.rb +61 -0
  6. data/doc/docs/docco.css +500 -0
  7. data/doc/docs/getting_started.html +177 -0
  8. data/doc/docs/public/fonts/aller-bold.eot +0 -0
  9. data/doc/docs/public/fonts/aller-bold.ttf +0 -0
  10. data/doc/docs/public/fonts/aller-bold.woff +0 -0
  11. data/doc/docs/public/fonts/aller-light.eot +0 -0
  12. data/doc/docs/public/fonts/aller-light.ttf +0 -0
  13. data/doc/docs/public/fonts/aller-light.woff +0 -0
  14. data/doc/docs/public/fonts/novecento-bold.eot +0 -0
  15. data/doc/docs/public/fonts/novecento-bold.ttf +0 -0
  16. data/doc/docs/public/fonts/novecento-bold.woff +0 -0
  17. data/doc/docs/public/stylesheets/normalize.css +375 -0
  18. data/files/app/sections/sidebar/action.rb +1 -1
  19. data/motion-prime/app_delegate.rb +8 -2
  20. data/motion-prime/elements/_content_padding_mixin.rb +12 -12
  21. data/motion-prime/elements/_content_text_mixin.rb +65 -0
  22. data/motion-prime/elements/base.rb +51 -19
  23. data/motion-prime/elements/button.rb +1 -1
  24. data/motion-prime/elements/draw.rb +26 -113
  25. data/motion-prime/elements/draw/_draw_background_mixin.rb +26 -0
  26. data/motion-prime/elements/draw/image.rb +10 -1
  27. data/motion-prime/elements/draw/label.rb +61 -42
  28. data/motion-prime/elements/draw/view.rb +14 -0
  29. data/motion-prime/elements/error_message.rb +1 -1
  30. data/motion-prime/elements/label.rb +1 -1
  31. data/motion-prime/elements/text_field.rb +2 -2
  32. data/motion-prime/elements/text_view.rb +3 -0
  33. data/motion-prime/helpers/has_style_chain_builder.rb +1 -1
  34. data/motion-prime/helpers/has_styles.rb +28 -0
  35. data/motion-prime/models/bag.rb +1 -1
  36. data/motion-prime/models/sync.rb +4 -4
  37. data/motion-prime/screens/_base_mixin.rb +1 -1
  38. data/motion-prime/screens/extensions/_navigation_bar_mixin.rb +7 -0
  39. data/motion-prime/screens/sidebar_container_screen.rb +8 -2
  40. data/motion-prime/sections/_cell_section_mixin.rb +25 -0
  41. data/motion-prime/sections/base.rb +17 -16
  42. data/motion-prime/sections/draw.rb +32 -10
  43. data/motion-prime/sections/form.rb +27 -17
  44. data/motion-prime/sections/form/base_field_section.rb +0 -1
  45. data/motion-prime/sections/form/base_header_section.rb +3 -2
  46. data/motion-prime/sections/form/password_field_section.rb +1 -1
  47. data/motion-prime/sections/table.rb +31 -10
  48. data/motion-prime/sections/table/base_cell_section.rb +1 -22
  49. data/motion-prime/sections/table/draw_cell_section.rb +5 -0
  50. data/motion-prime/styles/form.rb +12 -4
  51. data/motion-prime/support/_key_value_store.rb +0 -2
  52. data/motion-prime/support/dm_text_field.rb +2 -2
  53. data/motion-prime/support/tab_bar_controller.rb +28 -0
  54. data/motion-prime/version.rb +1 -1
  55. data/motion-prime/views/_frame_calculator_mixin.rb +75 -0
  56. data/motion-prime/views/view_styler.rb +36 -94
  57. metadata +23 -4
  58. data/motion-prime/elements/_field_dimensions_mixin.rb +0 -59
  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, styles: cell_styles(field).values.flatten, reuse_identifier: cell_name(table, index), parent_view: table_view do |cell_view|
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
- limit = (self.class.text_view_limits || {}).find do |field_name, limit|
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.delete(:if)
209
- if condition.nil?
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.class.section_header_options.try(:[], section)
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
@@ -1,7 +1,6 @@
1
1
  motion_require '../table/base_cell_section'
2
2
  module MotionPrime
3
3
  class BaseFieldSection < BaseCellSection
4
- include CellSection
5
4
  include BW::KVO
6
5
 
7
6
  attr_reader :form
@@ -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 section_styles
15
- table.cell_styles(self)
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: cell/field/header
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
- common: build_styles_chain(table_styles[:common], suffixes),
76
- specific: build_styles_chain(table_styles[:specific], suffixes)
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.respond_to?(:container_styles) && cell.container_styles.present?
80
- styles[:specific] += Array.wrap(cell.container_styles)
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, styles: cell_styles(item).values.flatten, reuse_identifier: cell_name(table, index), parent_view: table_view do
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
- attr_accessor :table, :cell_type
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
@@ -0,0 +1,5 @@
1
+ module MotionPrime
2
+ class DrawCellSection < DrawSection
3
+ include CellSectionMixin
4
+ end
5
+ end
@@ -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, right: 0, size_to_fit: true,
6
- bottom: 20, top: nil
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 :select_field_arrow,
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 :with_sections_select_field_arrow,
96
+ style :with_sections_select_field_image,
89
97
  right: 25
90
98
 
91
99
  style :with_sections_switch_field_input,
@@ -1,7 +1,5 @@
1
1
  module MotionPrime
2
2
  module SupportKeyValueStore
3
- extend ::MotionSupport::Concern
4
-
5
3
  # Key-Value accessors
6
4
  def setValue(value, forUndefinedKey: key)
7
5
  self.send(:"#{key}=", key)
@@ -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 + 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
@@ -1,3 +1,3 @@
1
1
  module MotionPrime
2
- VERSION = "0.3.2"
2
+ VERSION = "0.3.3"
3
3
  end
@@ -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
- calculate_frame_for(bounds) if @options.delete(:calculate_frame)
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(options)
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.each do |k,v|
18
- options[k] = STRUCTS_MAP[v.class].call(v) if STRUCTS_MAP.has_key?(v.class)
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 calculate_frame_for(bounds)
23
- width = options.delete(:width)
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 = CAGradientLayer.layer
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