motion-prime 1.0.3 → 1.0.4

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/Gemfile.lock +1 -1
  4. data/ROADMAP.md +3 -0
  5. data/files/Gemfile +1 -1
  6. data/lib/motion-prime.rb +1 -1
  7. data/motion-prime/api_client.rb +7 -5
  8. data/motion-prime/elements/_content_text_mixin.rb +14 -4
  9. data/motion-prime/elements/_text_mixin.rb +6 -2
  10. data/motion-prime/elements/base_element.rb +37 -12
  11. data/motion-prime/elements/button.rb +1 -1
  12. data/motion-prime/elements/draw.rb +6 -0
  13. data/motion-prime/elements/draw/_draw_background_mixin.rb +33 -2
  14. data/motion-prime/elements/draw/image.rb +9 -5
  15. data/motion-prime/elements/draw/label.rb +1 -1
  16. data/motion-prime/elements/label.rb +1 -1
  17. data/motion-prime/helpers/has_normalizer.rb +2 -1
  18. data/motion-prime/helpers/has_style_options.rb +16 -0
  19. data/motion-prime/helpers/has_styles.rb +5 -1
  20. data/motion-prime/models/_association_mixin.rb +17 -2
  21. data/motion-prime/models/_base_mixin.rb +5 -1
  22. data/motion-prime/models/_dirty_mixin.rb +1 -1
  23. data/motion-prime/models/_nano_bag_mixin.rb +18 -5
  24. data/motion-prime/models/_sync_mixin.rb +3 -3
  25. data/motion-prime/models/_timestamps_mixin.rb +3 -3
  26. data/motion-prime/sections/_draw_section_mixin.rb +20 -3
  27. data/motion-prime/sections/_section_with_container_mixin.rb +1 -1
  28. data/motion-prime/sections/abstract_collection.rb +6 -2
  29. data/motion-prime/sections/base_section.rb +6 -6
  30. data/motion-prime/sections/collection/collection_delegate.rb +6 -4
  31. data/motion-prime/sections/form/base_field_section.rb +8 -0
  32. data/motion-prime/sections/page_view.rb +19 -5
  33. data/motion-prime/sections/page_view/page_view_delegate.rb +19 -6
  34. data/motion-prime/sections/table/refresh_mixin.rb +1 -1
  35. data/motion-prime/sections/table/table_delegate.rb +6 -4
  36. data/motion-prime/styles/base.rb +1 -1
  37. data/motion-prime/support/consts.rb +6 -1
  38. data/motion-prime/support/mp_table_view.rb +4 -4
  39. data/motion-prime/version.rb +1 -1
  40. data/motion-prime/views/styles.rb +1 -1
  41. data/motion-prime/views/view_builder.rb +9 -5
  42. data/motion-prime/views/view_styler.rb +16 -15
  43. metadata +37 -36
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6b5a8d65686ce22cebae1f6a18212692367805be
4
- data.tar.gz: 3e66ba6bf3966649c60a86210fdad3165a5822a2
3
+ metadata.gz: c05d314976c62a856091891705c135ec7efcec22
4
+ data.tar.gz: c36d99bc5fbd5c2220d0eac3677d87dbc0acf4b8
5
5
  SHA512:
6
- metadata.gz: 599c6c60f50516854af50238bcbfd1e09a6d2e248e8687c9436672bbe9b7c86192d36c642e0a647da3f04667a57411df4de03aa557efec3a32511738fffad736
7
- data.tar.gz: 04eadebb2e6967e2abb9ff613bdbc1c38632ec2b907442df57c54ddcd19f3b0477ec6592093ba100cb44c5f6e91f17f769c25fbfadc39989072686ad346e4a7f
6
+ metadata.gz: 89864fab09b0b64a7c1ad1610300141c5ae60296a4a858e7abb83ceecf1277ebd3ff027886a061e1e022e1df551e9270b24f435a12f33d34973e7d4940d72e35
7
+ data.tar.gz: 6c83f9726a57b620a1d2f93fd0e8e8b2089d3e71de9f5bea27acd279f98ad9a9f536bd247d1b4fd42822cc31341510d3ce82316eba8b49314ca8a71ee7dc5829
@@ -1,3 +1,8 @@
1
+ === 1.0.4
2
+ * Multiple bug fixes
3
+ * Model#save will be performed on main thread (now you can fetch models in thread)
4
+ * Improved support for UIPageViewController
5
+
1
6
  === 1.0.3
2
7
  * Fixed issue with overriding background color
3
8
  * Improved support for UIPageViewController
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- motion-prime (1.0.3)
4
+ motion-prime (1.0.4)
5
5
  activesupport
6
6
  afmotion (~> 2.1.0)
7
7
  bubble-wrap (~> 1.6.0)
data/ROADMAP.md CHANGED
@@ -1,4 +1,5 @@
1
1
  === 1.1.0
2
+ * Model.fetch should always return status of main model fetch response
2
3
  * grid item width should be calculated based on uicollectionview with.
3
4
  * ability to change access token param name.
4
5
  * bug: if mp label do not have text and was set as hidden, it should unhide after setting text.
@@ -7,6 +8,8 @@
7
8
  * bug: dealloc of Prime::Section will not be called for cell created in collection_data using #map.
8
9
  * bug: images does not render after reload table if using draw_with_layer (prerender not enabled).
9
10
  * bug: incorrect height (cropped) for draw label with lineSpacing in cases when there is just one line.
11
+ * use one style to set rounded corners for view/draw elements (remove :rounded_corners option)
12
+ * add :sides option to BaseElement border (like in draw)
10
13
  * add dsl for push notifications.
11
14
  * add some extensions/middleware system, at least for networking.
12
15
  * create "display_network_error" extension.
@@ -1,7 +1,7 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
3
  gem 'motion-cocoapods', '~> 1.4.1'
4
- gem 'motion-prime', '1.0.3'
4
+ gem 'motion-prime', '1.0.4'
5
5
 
6
6
  # add reside menu for sidebar support
7
7
  # gem 'prime_reside_menu', '~> 0.1.4'
@@ -18,7 +18,7 @@ Motion::Project::App.setup do |app|
18
18
  app.pods do
19
19
  pod 'NanoStore', '~> 2.7.7'
20
20
  pod 'SDWebImage'
21
- pod 'SVPullToRefresh', git: 'git@github.com:droidlabs/SVPullToRefresh.git'
21
+ pod 'SVPullToRefresh', git: 'https://github.com/droidlabs/SVPullToRefresh.git'
22
22
  pod 'MBAlertView'
23
23
  pod 'MBProgressHUD', '~> 0.8'
24
24
  end
@@ -43,13 +43,12 @@ class ApiClient
43
43
  end
44
44
 
45
45
  def page_url(path)
46
- "#{config.base}#{path}"
46
+ path_with_base(path, config.base)
47
47
  end
48
48
 
49
49
  def resource_url(path)
50
- # return if path.blank?
51
50
  base = config.resource_base? ? config.resource_base : config.base
52
- "#{base}#{path}"
51
+ path_with_base(path, base)
53
52
  end
54
53
 
55
54
  def request(method, path, params = {}, options = {}, &block)
@@ -73,7 +72,7 @@ class ApiClient
73
72
 
74
73
  def request!(method, path, data, files = nil, options = {}, &block)
75
74
  use_callback = block_given?
76
- path = "#{config.api_namespace}#{path}" unless path.starts_with?('http')
75
+ path = path_with_base(path, config.api_namespace)
77
76
  client_method = files.present? ? :"multipart_#{method}" : method
78
77
  AFMotion::Client.shared.send client_method, path, data do |response, form_data, progress|
79
78
  if form_data && files.present?
@@ -131,7 +130,6 @@ class ApiClient
131
130
 
132
131
  # TODO: temporary solution, add real caching system here
133
132
  def read_cache(key)
134
- puts "read cache #{key}"
135
133
  @cache ||= {}
136
134
  @cache[key]
137
135
  end
@@ -143,6 +141,10 @@ class ApiClient
143
141
  end
144
142
 
145
143
  protected
144
+ def path_with_base(path, base)
145
+ path.to_s.starts_with?('http') ? path : "#{base}#{path}"
146
+ end
147
+
146
148
  def allow_queue?(method, path, options)
147
149
  options[:allow_queue] && config.allow_queue?
148
150
  end
@@ -35,15 +35,22 @@ module MotionPrime
35
35
  @content_width = width_for_attributed_text(current_attributed_text)
36
36
  end
37
37
 
38
+ def multiline_content_width
39
+ unless computed_options[:width]
40
+ Prime.logger.error "Please set element width for multiline content width calculation (`#{self.name}` in section `#{section.try(:name)}`)"
41
+ end
42
+ width_for_attributed_text(current_attributed_text, computed_options[:width] - content_padding_width)
43
+ end
44
+
38
45
  def width_for_text(text)
39
46
  width_for_attributed_text(attributed_text_for_text(text))
40
47
  end
41
48
 
42
- def width_for_attributed_text(attributed_text)
49
+ def width_for_attributed_text(attributed_text, width = Float::MAX)
43
50
  min, max = computed_options[:min_width].to_f, computed_options[:max_width]
44
51
  return min if attributed_text.to_s.blank?
45
52
 
46
- rect = get_content_rect(attributed_text, Float::MAX)
53
+ rect = get_content_rect(attributed_text, width)
47
54
  [[rect.size.width.ceil, max].compact.min, min].max.ceil
48
55
  end
49
56
 
@@ -61,6 +68,9 @@ module MotionPrime
61
68
 
62
69
  def height_for_attributed_text(attributed_text)
63
70
  min, max = computed_options[:min_height].to_f, computed_options[:max_height]
71
+ unless computed_options[:width]
72
+ Prime.logger.error "Please set element width for content height calculation (`#{self.name}` in section `#{section.try(:name)}`)"
73
+ end
64
74
  return min if attributed_text.to_s.blank?
65
75
  rect = get_content_rect(attributed_text, computed_options[:width] - content_padding_width)
66
76
  [[rect.size.height.ceil, max].compact.min, min].max.ceil
@@ -92,7 +102,7 @@ module MotionPrime
92
102
  end
93
103
 
94
104
  def button_content_font
95
- computed_options[:title_label].try(:[], :font)
105
+ extract_font_from(computed_options[:title_label])
96
106
  end
97
107
 
98
108
  def input_content_text
@@ -101,7 +111,7 @@ module MotionPrime
101
111
 
102
112
  # TODO: normalize_object will not be required after refactoring computed options.
103
113
  def input_content_font
104
- font = input_value_text.blank? ? computed_options[:placeholder_font] : computed_options[:font]
114
+ font = input_value_text.blank? ? extract_font_from(computed_options, 'placeholder') : extract_font_from(computed_options)
105
115
  normalize_object(font, section || self)
106
116
  end
107
117
 
@@ -71,8 +71,12 @@ module MotionPrime
71
71
  end
72
72
  attributes[NSParagraphStyleAttributeName] = paragrah_style
73
73
  end
74
- attributes[NSForegroundColorAttributeName] = options[:text_color].uicolor if options[:text_color]
75
- attributes[NSFontAttributeName] = options[:font].uifont if options[:font]
74
+ if color = options[:text_color] || options[:title_color]
75
+ attributes[NSForegroundColorAttributeName] = color.uicolor
76
+ end
77
+ if font = extract_font_from(options)
78
+ attributes[NSFontAttributeName] = font.uifont
79
+ end
76
80
  [attributes, paragrah_style]
77
81
  end
78
82
  end
@@ -1,6 +1,7 @@
1
1
  motion_require '../helpers/has_normalizer'
2
2
  motion_require '../helpers/has_style_chain_builder'
3
3
  motion_require '../helpers/has_class_factory'
4
+ motion_require '../helpers/has_style_options'
4
5
  module MotionPrime
5
6
  class BaseElement
6
7
  # MotionPrime::BaseElement is container for UIView class elements with options.
@@ -10,6 +11,7 @@ module MotionPrime
10
11
  include HasNormalizer
11
12
  include HasStyleChainBuilder
12
13
  include HasClassFactory
14
+ include HasStyleOptions
13
15
  extend HasClassFactory
14
16
 
15
17
  attr_accessor :options, :section, :name,
@@ -54,6 +56,14 @@ module MotionPrime
54
56
  self.view.addTarget(target || section, action: action, forControlEvents: event.uicontrolevent)
55
57
  end
56
58
 
59
+ def notify_section_before_render
60
+ section.try(:before_element_render, self)
61
+ end
62
+
63
+ def notify_section_after_render
64
+ section.try(:after_element_render, self)
65
+ end
66
+
57
67
  def render(options = {}, &block)
58
68
  run_callbacks :render do
59
69
  render!(options, &block)
@@ -82,10 +92,10 @@ module MotionPrime
82
92
  block_options = compute_block_options || {}
83
93
  raw_options = self.options.except(:screen, :name, :block, :view_class).merge(block_options)
84
94
  compute_style_options(raw_options)
85
- raw_options = Styles.for(styles).merge(raw_options)
95
+ raw_options = Styles.for(styles).deep_merge(raw_options)
86
96
  @computed_options = raw_options
87
97
  normalize_options(@computed_options, section.try(:elements_eval_object), %w[
88
- font text placeholder title_label
98
+ font font_name font_size text placeholder title_label
89
99
  padding padding_left padding_right padding_top padding_bottom
90
100
  left right min_width min_outer_width max_width max_outer_width width
91
101
  top bottom min_height min_outer_height max_height max_outer_height height])
@@ -104,18 +114,27 @@ module MotionPrime
104
114
  if (changed_options & [:text, :size_to_fit]).any? && respond_to?(:size_to_fit)
105
115
  size_to_fit
106
116
  end
107
- section.try(:on_element_render, self)
108
117
  end
109
118
 
110
119
  def update_with_options(new_options = {})
111
- options.merge!(new_options)
120
+ options.deep_merge!(new_options)
112
121
  reload!
122
+ computed_options.deep_merge!(new_options)
113
123
  rerender!(new_options.keys)
114
124
  end
115
125
 
116
126
  def update_options(new_options)
117
- options.merge!(new_options)
127
+ options.deep_merge!(new_options)
118
128
  return unless view
129
+
130
+ required_options = if new_options.slice(:width, :height, :top, :left, :right, :bottom).any?
131
+ new_options[:calculate_frame] = true
132
+ [:width, :height, :top, :left, :right, :bottom]
133
+ elsif new_options.slice(:text, :title).any?
134
+ [:line_spacing, :line_height, :underline, :fragment_color, :text_alignment, :font, :font_name, :font_size, :line_break_mode, :number_of_lines]
135
+ end
136
+ new_options = computed_options.slice(*Array.wrap(required_options)).merge(new_options)
137
+
119
138
  ViewStyler.new(view, view.superview.try(:bounds), new_options).apply
120
139
  end
121
140
 
@@ -161,11 +180,10 @@ module MotionPrime
161
180
  end
162
181
 
163
182
  def compute_style_options(*style_sources)
164
- has_errors = section.respond_to?(:observing_errors?) && observing_errors? && has_errors?
165
-
166
183
  @styles = []
167
184
  if cell_section?
168
- @styles += compute_cell_style_options(style_sources, has_errors)
185
+ suffixes = section.style_suffixes if section.respond_to?(:style_suffixes)
186
+ @styles += compute_cell_style_options(style_sources, Array.wrap(suffixes))
169
187
  end
170
188
 
171
189
  mixins = []
@@ -189,11 +207,11 @@ module MotionPrime
189
207
 
190
208
  # custom style (from options or block options), using for TableViews as well
191
209
  @styles += custom_styles
192
- # pp @view_class.to_s + @styles.inspect; puts()
210
+ # pp(@view_class.to_s + @styles.inspect); puts()
193
211
  @styles
194
212
  end
195
213
 
196
- def compute_cell_style_options(style_sources, has_errors)
214
+ def compute_cell_style_options(style_sources, additional_suffixes)
197
215
  base_styles = {common: [], specific: []}
198
216
  suffixes = {common: [], specific: []}
199
217
  all_styles = []
@@ -208,13 +226,17 @@ module MotionPrime
208
226
  # form element: _input
209
227
  # table element: _image
210
228
  suffixes[:common] << @view_name.to_sym
211
- suffixes[:common] << :"#{@view_name}_with_errors" if has_errors
229
+ additional_suffixes.each do |additional_suffix|
230
+ suffixes[:common] << [@view_name, additional_suffix].join('_').to_sym
231
+ end
212
232
  end
213
233
  if name && name.to_s != @view_name
214
234
  # form element: _input
215
235
  # table element: _icon
216
236
  suffixes[:specific] << name.to_sym
217
- suffixes[:specific] << :"#{name}_with_errors" if has_errors
237
+ additional_suffixes.each do |additional_suffix|
238
+ suffixes[:specific] << [name, additional_suffix].join('_').to_sym
239
+ end
218
240
  end
219
241
  # form cell: base_form_field, base_form_string_field
220
242
  # form element: base_form_field_string_field, base_form_string_field_text_field, base_form_string_field_input
@@ -259,5 +281,8 @@ module MotionPrime
259
281
  set_callback :render, :after, method_name
260
282
  end
261
283
  end
284
+
285
+ before_render :notify_section_before_render
286
+ after_render :notify_section_after_render
262
287
  end
263
288
  end
@@ -22,7 +22,7 @@ module MotionPrime
22
22
  end
23
23
 
24
24
  def font
25
- computed_options[:title_label].try(:[], :font) || :system.uifont
25
+ extract_font_from(computed_options[:title_label]) || :system.uifont
26
26
  end
27
27
  end
28
28
  end
@@ -17,12 +17,18 @@ module MotionPrime
17
17
  corner_radius: options[:layer].try(:[], :corner_radius).to_f,
18
18
  border_width: options[:layer].try(:[], :border_width).to_f,
19
19
  border_color: options[:layer].try(:[], :border_color).try(:uicolor) || background_color,
20
+ border_sides: options[:layer].try(:[], :border_sides),
20
21
  dashes: options[:layer].try(:[], :dashes),
21
22
  }
22
23
  end
23
24
 
24
25
  def render!; end
25
26
 
27
+ def on_container_render
28
+ @view = nil
29
+ @computed_frame = nil
30
+ end
31
+
26
32
  def view
27
33
  @view ||= section.container_view
28
34
  end
@@ -3,7 +3,7 @@ module MotionPrime
3
3
  def draw_background_in_context(context = nil)
4
4
  context ||= UIGraphicsGetCurrentContext()
5
5
  options = draw_options
6
- rect, background_color, border_width, border_color, corner_radius, dashes_array = options.slice(:rect, :background_color, :border_width, :border_color, :corner_radius, :dashes).values
6
+ rect, background_color, border_width, border_color, border_sides, corner_radius, dashes_array = options.slice(:rect, :background_color, :border_width, :border_color, :border_sides, :corner_radius, :dashes).values
7
7
 
8
8
  return unless background_color || border_width > 0
9
9
 
@@ -34,7 +34,38 @@ module MotionPrime
34
34
  CGContextSetLineDash(context, dashes_array.count, dashes, 0) if dashes
35
35
  CGContextSetLineWidth(context, border_width)
36
36
  CGContextSetStrokeColorWithColor(context, border_color.uicolor.cgcolor)
37
- CGContextStrokeRect(context, rect)
37
+ if border_sides.present?
38
+ points = [
39
+ [rect.origin.x, rect.origin.y],
40
+ [rect.origin.x + rect.size.width, rect.origin.y],
41
+ [rect.origin.x + rect.size.width, rect.origin.y + rect.size.height],
42
+ [rect.origin.x, rect.origin.y + rect.size.height]
43
+ ]
44
+ CGContextMoveToPoint(context, *points[0])
45
+ if border_sides.include?(:top)
46
+ CGContextAddLineToPoint(context, *points[1])
47
+ else
48
+ CGContextMoveToPoint(context, *points[1])
49
+ end
50
+ if border_sides.include?(:right)
51
+ CGContextAddLineToPoint(context, *points[2])
52
+ else
53
+ CGContextMoveToPoint(context, *points[2])
54
+ end
55
+ if border_sides.include?(:bottom)
56
+ CGContextAddLineToPoint(context, *points[3])
57
+ else
58
+ CGContextMoveToPoint(context, *points[3])
59
+ end
60
+ if border_sides.include?(:left)
61
+ CGContextAddLineToPoint(context, *points[0])
62
+ else
63
+ CGContextMoveToPoint(context, *points[0])
64
+ end
65
+ CGContextStrokePath(context)
66
+ else
67
+ CGContextStrokeRect(context, rect)
68
+ end
38
69
  end
39
70
  CGContextSetFillColorWithColor(context, background_color.uicolor.cgcolor) if background_color
40
71
  CGContextFillRect(context, rect) if background_color
@@ -9,7 +9,10 @@ module MotionPrime
9
9
  image ||= computed_options[:default] if computed_options[:url]
10
10
 
11
11
  # already initialized image or image from resources or default image
12
- super.merge({image: image.try(:uiimage)})
12
+ super.merge({
13
+ image: image.try(:uiimage),
14
+ inner_rect: CGRectMake(frame_inner_left, frame_inner_top, frame_width, frame_height)
15
+ })
13
16
  end
14
17
 
15
18
  def draw_in(rect)
@@ -32,7 +35,7 @@ module MotionPrime
32
35
 
33
36
  border_width = options[:border_width]
34
37
  inset = border_width > 0 ? (border_width - 1 ).abs*0.5 : 0
35
- rect = CGRectInset(options[:rect], inset, inset)
38
+ rect = CGRectInset(options[:inner_rect], inset, inset)
36
39
  radius = options[:corner_radius].to_f if options[:corner_radius] && options[:masks_to_bounds]
37
40
 
38
41
  UIGraphicsPushContext(context)
@@ -52,9 +55,9 @@ module MotionPrime
52
55
 
53
56
  def draw_with_layer
54
57
  options = draw_options
55
- @layer.removeFromSuperlayer if @layer
58
+ @layer.try(:removeFromSuperlayer)
56
59
  return unless image = options[:image]
57
- rect = options[:rect]
60
+ rect = options[:inner_rect]
58
61
  radius = options[:corner_radius].to_f if options[:corner_radius] && options[:masks_to_bounds]
59
62
 
60
63
  @layer = CALayer.layer
@@ -106,8 +109,9 @@ module MotionPrime
106
109
  end
107
110
 
108
111
  def update_with_options(new_options = {})
112
+ self.image_data = nil if new_options.slice(:url, :image).any? || new_options.blank?
113
+ @layer.try(:removeFromSuperlayer)
109
114
  super
110
- self.image_data = nil if new_options.slice(:url, :image).any?
111
115
  end
112
116
  end
113
117
  end
@@ -9,7 +9,7 @@ module MotionPrime
9
9
  options = computed_options
10
10
  text = (options[:html] || options[:text]).to_s.gsub(/\A[\n\r]+/, '')
11
11
  text_color = (options[:text_color] || :black).uicolor
12
- font = (options[:font] || :system).uifont
12
+ font = (extract_font_from(options) || :system).uifont
13
13
 
14
14
  text_alignment_name = options.fetch(:text_alignment, :left)
15
15
  text_alignment = text_alignment_name.nstextalignment
@@ -31,7 +31,7 @@ module MotionPrime
31
31
  end
32
32
 
33
33
  def set_text(value)
34
- computed_options[:text] = value
34
+ options[:text] = computed_options[:text] = value
35
35
  styler = ViewStyler.new(view, CGRectZero, computed_options)
36
36
  if styler.options[:attributed_text]
37
37
  view.attributedText = styler.options[:attributed_text]