motion-prime 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG.md +4 -0
  3. data/Gemfile.lock +1 -1
  4. data/ROADMAP.md +3 -3
  5. data/doc/code/getting_started.rb +6 -5
  6. data/files/app/screens/sidebar_screen.rb +2 -2
  7. data/files/app/sections/sidebar/action.rb +1 -1
  8. data/motion-prime/api_client.rb +1 -1
  9. data/motion-prime/core_ext/kernel.rb +4 -0
  10. data/motion-prime/elements/_content_padding_mixin.rb +12 -4
  11. data/motion-prime/elements/_content_text_mixin.rb +10 -2
  12. data/motion-prime/elements/{base.rb → base_element.rb} +16 -7
  13. data/motion-prime/elements/button.rb +1 -1
  14. data/motion-prime/elements/draw/_draw_background_mixin.rb +20 -9
  15. data/motion-prime/elements/draw/image.rb +2 -2
  16. data/motion-prime/elements/draw/label.rb +7 -6
  17. data/motion-prime/elements/draw.rb +8 -3
  18. data/motion-prime/elements/label.rb +2 -2
  19. data/motion-prime/elements/table_view_cell.rb +7 -0
  20. data/motion-prime/helpers/has_search_bar.rb +1 -1
  21. data/motion-prime/helpers/has_styles.rb +7 -7
  22. data/motion-prime/models/model.rb +1 -1
  23. data/motion-prime/models/sync.rb +10 -10
  24. data/motion-prime/screens/_navigation_mixin.rb +1 -1
  25. data/motion-prime/sections/_draw_mixin.rb +74 -0
  26. data/motion-prime/sections/{base.rb → base_section.rb} +104 -55
  27. data/motion-prime/sections/form/base_field_section.rb +6 -6
  28. data/motion-prime/sections/form/base_header_section.rb +2 -3
  29. data/motion-prime/sections/form.rb +38 -17
  30. data/motion-prime/sections/tabbed.rb +3 -3
  31. data/motion-prime/sections/table.rb +172 -80
  32. data/motion-prime/services/table_data_indexes.rb +51 -0
  33. data/motion-prime/styles/_mixins.rb +8 -0
  34. data/motion-prime/support/dm_cell_with_section.rb +1 -1
  35. data/motion-prime/support/dm_text_field.rb +17 -12
  36. data/motion-prime/support/dm_text_view.rb +10 -23
  37. data/motion-prime/version.rb +1 -1
  38. data/motion-prime/views/layout.rb +4 -2
  39. data/motion-prime/views/styles.rb +2 -0
  40. data/motion-prime/views/view_builder.rb +8 -2
  41. data/motion-prime/views/view_styler.rb +6 -2
  42. metadata +8 -9
  43. data/motion-prime/helpers/cell_section.rb +0 -9
  44. data/motion-prime/sections/draw.rb +0 -93
  45. data/motion-prime/sections/form/text_with_button_field_section.rb +0 -23
  46. data/motion-prime/sections/table/base_cell_section.rb +0 -5
  47. data/motion-prime/sections/table/draw_cell_section.rb +0 -5
@@ -5,6 +5,7 @@ module MotionPrime
5
5
  include HasStyleChainBuilder
6
6
  include HasSearchBar
7
7
 
8
+ class_attribute :async_data_options
8
9
  attr_accessor :table_element, :did_appear
9
10
  before_render :render_table
10
11
 
@@ -12,42 +13,30 @@ module MotionPrime
12
13
  []
13
14
  end
14
15
 
15
- def data
16
- @data ||= table_data.tap { |cells| set_cells_table(cells) }
17
- end
18
-
19
- def set_cells_table(cells)
20
- cells.each { |cell| cell.table = self if cell.respond_to?(:table=) }
16
+ def async_data?
17
+ self.class.async_data_options
21
18
  end
22
19
 
23
- def data_stamp_for(id)
24
- @data_stamp[id]
20
+ def data
21
+ @data || set_table_data
25
22
  end
26
23
 
27
- def set_data_stamp(cell_ids)
28
- @data_stamp ||= {}
29
- [*cell_ids].each { |id| @data_stamp[id] = Time.now.to_f }
24
+ def reload_data
25
+ reset_data
26
+ @async_loaded_data = table_data if async_data?
27
+ table_view.reloadData
30
28
  end
31
29
 
32
- def reset_data_stamps
33
- keys = data.each_with_index.map do |row, id|
34
- if row.is_a?(Array)
35
- section = id
36
- rows = (0...row.count)
37
- else
38
- section = 0
39
- rows = [id]
40
- end
41
- rows.map { |row| "#{section}_#{row}" }
42
- end.flatten
43
- set_data_stamp(keys)
30
+ def refresh_if_needed
31
+ table_view.reloadData if @data.nil?
44
32
  end
45
33
 
46
- def reload_data
34
+ def reset_data
47
35
  @did_appear = false
48
36
  @data = nil
49
- reset_data_stamps
50
- table_view.reloadData
37
+ @async_loaded_data = nil
38
+ @next_portion_starts_from = nil
39
+ @data_stamp = nil
51
40
  end
52
41
 
53
42
  def table_styles
@@ -88,7 +77,7 @@ module MotionPrime
88
77
  if cell.is_a?(BaseFieldSection)
89
78
  # form cell: _<type>_<field_name> = `_field_email`
90
79
  suffixes << :"#{type}_#{cell.name}" if cell.name
91
- elsif cell.respond_to?(:cell_name) # BaseCellSection
80
+ elsif cell.respond_to?(:cell_name) # cell section came from table
92
81
  # table cell: _<table_cell_name> = `_title`
93
82
  suffixes << cell.cell_name
94
83
  end
@@ -104,13 +93,15 @@ module MotionPrime
104
93
  end
105
94
 
106
95
  def render_table
107
- reset_data_stamps
108
96
  options = {
109
97
  styles: table_styles.values.flatten,
110
98
  delegate: self,
111
99
  data_source: self,
112
100
  style: (UITableViewStyleGrouped unless flat_data?)
113
101
  }
102
+ if async_data? && self.class.async_data_options.has_key?(:estimated_row_height)
103
+ options[:estimated_row_height] = self.class.async_data_options[:estimated_row_height]
104
+ end
114
105
  self.table_element = screen.table_view(options)
115
106
  end
116
107
 
@@ -126,60 +117,22 @@ module MotionPrime
126
117
  table_view.try(:show)
127
118
  end
128
119
 
129
- def numberOfSectionsInTableView(tableView)
130
- number_of_sections
131
- end
132
-
133
- def number_of_sections
134
- has_many_sections? ? data.count : 1
135
- end
136
-
137
- def has_many_sections?
138
- data.any? && data.first.is_a?(Array)
139
- end
140
-
141
- def row_by_index(index)
142
- rows_for_section(index.section)[index.row]
143
- end
144
-
145
-
146
120
  def render_cell(index, table)
147
121
  item = row_by_index(index)
148
-
149
- # DrawSection allows as to draw inside the cell view, so we can setup
150
- # to use cell view as container
151
- if item.is_a?(MotionPrime::DrawSection)
152
- item.render(to: screen, as: :cell,
153
- styles: cell_styles(item).values.flatten,
154
- reuse_identifier: cell_name(table, index)
155
- )
156
- else
157
- screen.table_view_cell section: item, reuse_identifier: cell_name(table, index), parent_view: table_view do
158
- item.render(to: screen)
159
- end
122
+ screen.table_view_cell section: item, reuse_identifier: cell_name(table, index), parent_view: table_view, has_drawn_content: true do |container_view, container_element|
123
+ # DrawSection allows as to draw inside the cell view, so we can setup
124
+ # to use cell view as container
125
+ item.container_element = container_element
126
+ item.render
160
127
  end
161
128
  end
162
129
 
163
- def on_click(table, index)
164
- end
165
-
166
- def on_appear; end
167
130
  def on_row_render(cell, index); end
131
+ def on_appear; end
132
+ def on_click(table, index); end
168
133
 
169
- def cell_name(table, index)
170
- record = row_by_index(index)
171
- if record && record.model &&
172
- record.model.respond_to?(:id) && record.model.id.present?
173
- "cell_#{record.model.id}_#{data_stamp_for("#{index.section}_#{index.row}")}"
174
- else
175
- "cell_#{index.section}_#{index.row}_#{data_stamp_for("#{index.section}_#{index.row}")}"
176
- end
177
- end
178
-
179
- def cached_cell(index, table = nil)
180
- table ||= self.table_view
181
- table.dequeueReusableCellWithIdentifier(cell_name(table, index))
182
- end
134
+ # ALIASES
135
+ # ---------------------
183
136
 
184
137
  # def tableView(table, viewForFooterInSection: section) # cause bug in ios7.0.0-7.0.2
185
138
  # UIView.new
@@ -188,8 +141,9 @@ module MotionPrime
188
141
  # 0.1
189
142
  # end
190
143
 
191
- # ALIASES
192
- # ---------------------
144
+ def numberOfSectionsInTableView(tableView)
145
+ number_of_sections
146
+ end
193
147
 
194
148
  def tableView(table, cellForRowAtIndexPath:index)
195
149
  @rendered_cells ||= []
@@ -198,6 +152,8 @@ module MotionPrime
198
152
  cell = cached_cell(index, table) || render_cell(index, table).tap do |cell|
199
153
  @rendered_cells[index.section][index.row] = cell
200
154
  on_row_render(cell, index)
155
+
156
+ preload_sections_for(index)
201
157
  end
202
158
 
203
159
  # run table view is appeared callback if needed
@@ -215,16 +171,152 @@ module MotionPrime
215
171
  on_click(table, index)
216
172
  end
217
173
 
218
- def tableView(table, heightForRowAtIndexPath:index)
219
- rows_for_section(index.section)[index.row].container_height
174
+ def tableView(table, heightForRowAtIndexPath: index)
175
+ load_cell_by_index(index)
176
+ cell = rows_for_section(index.section)[index.row]
177
+ cell.container_height
178
+ end
179
+
180
+ def number_of_sections
181
+ has_many_sections? ? data.count : 1
182
+ end
183
+
184
+ def has_many_sections?
185
+ data.any? && data.first.is_a?(Array)
220
186
  end
221
187
 
222
188
  def flat_data?
223
- number_of_sections == 1
189
+ !has_many_sections?
190
+ end
191
+
192
+ def row_by_index(index)
193
+ rows_for_section(index.section)[index.row]
224
194
  end
225
195
 
226
196
  def rows_for_section(section)
227
197
  flat_data? ? data : data[section]
228
198
  end
199
+
200
+ def self.async_table_data(options = {})
201
+ self.async_data_options = options
202
+ end
203
+
204
+ def on_async_data_loaded; end
205
+ def on_async_data_preloaded(loaded_index); end
206
+
207
+ private
208
+ def set_table_data
209
+ cells = async_data? ? load_sections_async : table_data
210
+ prepare_table_cells(cells)
211
+ @data = cells
212
+ reset_data_stamps
213
+ load_sections unless async_data?
214
+ @data
215
+ end
216
+
217
+ def load_sections_async
218
+ @async_loaded_data || begin
219
+ BW::Reactor.schedule_on_main do
220
+ @async_loaded_data = table_data
221
+ @data = nil
222
+ table_view.reloadData
223
+ on_async_data_loaded
224
+ end
225
+ []
226
+ end
227
+ end
228
+
229
+ def cell_name(table, index)
230
+ record = row_by_index(index)
231
+ if record && record.model &&
232
+ record.model.respond_to?(:id) && record.model.id.present?
233
+ "cell_#{record.model.id}_#{data_stamp_for("#{index.section}_#{index.row}")}"
234
+ else
235
+ "cell_#{index.section}_#{index.row}_#{data_stamp_for("#{index.section}_#{index.row}")}"
236
+ end
237
+ end
238
+
239
+ def cached_cell(index, table = nil)
240
+ table ||= self.table_view
241
+ table.dequeueReusableCellWithIdentifier(cell_name(table, index))
242
+ end
243
+
244
+ def prepare_table_cells(cells)
245
+ cells.each do |cell|
246
+ cell.send(:extend, CellSectionMixin)
247
+ cell.screen = screen
248
+ cell.table = self if cell.respond_to?(:table=)
249
+ end
250
+ end
251
+
252
+ def load_cell_by_index(index)
253
+ cell = rows_for_section(index.section)[index.row]
254
+ return unless cell.load_section # return if already loaded
255
+ cell.load_elements
256
+ end
257
+
258
+ def data_stamp_for(id)
259
+ @data_stamp[id]
260
+ end
261
+
262
+ def set_data_stamp(cell_ids)
263
+ @data_stamp ||= {}
264
+ [*cell_ids].each { |id| @data_stamp[id] = Time.now.to_f }
265
+ end
266
+
267
+ def reset_data_stamps
268
+ keys = @data.each_with_index.map do |row, id|
269
+ if row.is_a?(Array)
270
+ section = id
271
+ rows = (0...row.count)
272
+ else
273
+ section = 0
274
+ rows = [id]
275
+ end
276
+ rows.map { |row| "#{section}_#{row}" }
277
+ end.flatten
278
+ set_data_stamp(keys)
279
+ end
280
+
281
+ def load_sections
282
+ return if async_data?
283
+ if flat_data?
284
+ data.each(&:load_section)
285
+ else
286
+ data.count.times { |section_data| section_data.each(&:load_section) }
287
+ end
288
+ end
289
+
290
+ def preload_sections_for(index)
291
+ return if !async_data? || @next_portion_starts_from == false
292
+ service = index_service
293
+
294
+ load_limit = self.class.async_data_options.try(:[], :preload_rows_count)
295
+ @next_portion_starts_from ||= index
296
+ start_preload_when_index_loaded = service.sum_index(@next_portion_starts_from, load_limit ? -load_limit/2 : 0)
297
+
298
+ if service.compare_indexes(index, start_preload_when_index_loaded) >= 0
299
+ section = @next_portion_starts_from.section
300
+ next_row = @next_portion_starts_from.row
301
+ left_to_load = rows_for_section(section).count - next_row
302
+
303
+ load_count = [left_to_load, load_limit].compact.min
304
+
305
+ next_index = @next_portion_starts_from
306
+ BW::Reactor.schedule do
307
+ load_count.times do |offset|
308
+ load_cell_by_index(next_index)
309
+ next_index = service.sum_index(next_index, 1) unless offset == load_count - 1
310
+ end
311
+ on_async_data_preloaded(next_index)
312
+ end
313
+
314
+ @next_portion_starts_from = service.sum_index(@next_portion_starts_from, load_count, false)
315
+ end
316
+ end
317
+
318
+ def index_service
319
+ TableDataIndexes.new(@data)
320
+ end
229
321
  end
230
322
  end
@@ -0,0 +1,51 @@
1
+ class TableDataIndexes
2
+ attr_reader :data
3
+
4
+ def initialize(data)
5
+ @data = data
6
+ end
7
+
8
+ def max_index(*indexes)
9
+ [*indexes].compact.max &method(:compare_indexes)
10
+ end
11
+
12
+ def compare_indexes(a, b)
13
+ return 0 if a == b
14
+ a.section > b.section || a.row > b.row ? 1 : -1
15
+ end
16
+
17
+ def sum_index(a, rows, crop_to_edges = true)
18
+ row = a.row + rows
19
+ section = a.section
20
+
21
+ max_row = count_in_section(a.section) - 1
22
+ if row < 0 || row > max_row
23
+ direction = row < 0 ? -1 : 1
24
+
25
+ section = a.section + direction
26
+ edge_row = [[0, row].max, max_row].min
27
+
28
+ if section < 0 || section >= sections_count
29
+ return crop_to_edges ? NSIndexPath.indexPathForRow(edge_row, inSection: a.section) : false
30
+ end
31
+
32
+ start_row = edge_row.zero? ? count_in_section(section) - 1 : 0
33
+ rows_left = rows - (edge_row - a.row) - direction
34
+ sum_index(NSIndexPath.indexPathForRow(start_row, inSection: section), rows_left)
35
+ else
36
+ NSIndexPath.indexPathForRow(row, inSection: section)
37
+ end
38
+ end
39
+
40
+ def count_in_section(id)
41
+ flat_data? ? data.count : data[id].count
42
+ end
43
+
44
+ def sections_count
45
+ flat_data? ? 1 : data.count
46
+ end
47
+
48
+ def flat_data?
49
+ !data.first.is_a?(Array)
50
+ end
51
+ end
@@ -0,0 +1,8 @@
1
+ motion_require '../views/styles.rb'
2
+ MotionPrime::Styles.define :_mixin do
3
+ style :multiline,
4
+ size_to_fit: true,
5
+ number_of_lines: 0,
6
+ line_break_mode: :wordwrap,
7
+ line_spacing: 2
8
+ end
@@ -7,6 +7,6 @@ class DMCellWithSection < UITableViewCell
7
7
 
8
8
  def drawRect(rect)
9
9
  super
10
- section.draw_in(rect)
10
+ section.draw_in(rect) if section.respond_to?(:draw_in)
11
11
  end
12
12
  end
@@ -4,7 +4,16 @@
4
4
  class DMTextField < UITextField
5
5
  include MotionPrime::SupportKeyValueStore
6
6
  include MotionPrime::SupportPaddingAttribute
7
- attr_accessor :placeholderColor, :placeholderFont, :readonly
7
+ attr_accessor :placeholderColor, :placeholderFont, :readonly, :placeholderAlignment
8
+
9
+
10
+ def self.default_padding_left
11
+ 5
12
+ end
13
+
14
+ def self.default_padding_right
15
+ 5
16
+ end
8
17
 
9
18
  # placeholder position
10
19
  def textRectForBounds(bounds)
@@ -20,7 +29,11 @@ class DMTextField < UITextField
20
29
  color = self.placeholderColor || :gray.uicolor
21
30
  color.setFill
22
31
  font = self.placeholderFont || self.font || :system.uifont(16)
23
- self.placeholder.drawInRect(rect, withFont: font)
32
+
33
+ truncation = :tailtruncation.uilinebreakmode
34
+ alignment = (placeholderAlignment || :left)
35
+ alignment = alignment.uitextalignment if alignment.is_a?(Symbol)
36
+ self.placeholder.drawInRect(rect, withFont: font, lineBreakMode: truncation, alignment: alignment)
24
37
  end
25
38
 
26
39
  def padding_top # to center title label
@@ -30,20 +43,12 @@ class DMTextField < UITextField
30
43
  end
31
44
  end
32
45
 
33
- def self.default_padding_left
34
- 5
35
- end
36
-
37
- def self.default_padding_right
38
- 5
39
- end
40
-
41
46
  private
42
47
  def calculate_rect_for(bounds)
43
- height_diff = self.bounds.size.height - (self.font.pointSize + padding_top*2)
48
+ height_diff = self.bounds.size.height - (self.font.pointSize + padding_top + padding_bottom)
44
49
  bounds = CGRectMake(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height - height_diff)
45
50
  CGRectMake(
46
51
  bounds.origin.x + padding_left, bounds.origin.y + padding_top,
47
- bounds.size.width - (padding_left + padding_right), bounds.size.height - padding_top*2)
52
+ bounds.size.width - (padding_left + padding_right), bounds.size.height - (padding_top + padding_bottom))
48
53
  end
49
54
  end
@@ -3,40 +3,27 @@
3
3
  # * support placeholder, placeholder_color, placeholder_font options
4
4
  class DMTextView < UITextView
5
5
  include MotionPrime::SupportKeyValueStore
6
- DEFAULT_PADDING_LEFT = 7
6
+ include MotionPrime::SupportPaddingAttribute
7
+ attr_accessor :placeholderColor, :placeholderFont, :placeholder
7
8
 
8
- attr_accessor :paddingLeft, :paddingTop, :padding,
9
- :placeholderColor, :placeholderFont, :placeholder
9
+ def self.default_padding_left
10
+ 5
11
+ end
10
12
 
11
- def padding_top
12
- paddingTop || padding || paddingLeft || 5
13
+ def self.default_padding_right
14
+ 5
13
15
  end
14
16
 
15
17
  def drawPadding(rect)
16
18
  # add padding to UITextView
17
- padding_left = (self.paddingLeft || self.padding || 5) - 5
18
- padding_top = self.padding_top - 8
19
- padding = UIEdgeInsetsMake(
20
- padding_top, padding_left,
21
- padding_top, padding_left
22
- )
23
- self.contentInset = padding
24
-
25
- # must change frame before bounds because the text wrap is reformatted based on frame,
26
- # don't include the top and bottom insets
27
- insetFrame = UIEdgeInsetsInsetRect(frame, UIEdgeInsetsMake(0, padding.left, 0, padding.right))
28
- # offset frame back to original x
29
- offsetX = frame.origin.x - (insetFrame.origin.x - ( padding.left + padding.right ) / 2)
30
- insetFrame = CGRectApplyAffineTransform(insetFrame, CGAffineTransformMakeTranslation(offsetX, 0))
31
- self.frame = insetFrame
32
- self.bounds = UIEdgeInsetsInsetRect(self.bounds, UIEdgeInsetsMake(0, -padding.left, 0, -padding.right))
19
+ self.textContainer.lineFragmentPadding = 0 # left/right
20
+ self.textContainerInset = self.padding_insets
33
21
  end
34
22
 
35
23
  def drawPlaceholder(rect)
36
- padding_left = self.paddingLeft || self.padding || 5
37
24
  padding = UIEdgeInsetsMake(
38
25
  padding_top, padding_left,
39
- padding_top, padding_left
26
+ padding_bottom, padding_right
40
27
  )
41
28
  if self.placeholder && self.text.blank?
42
29
  color = self.placeholderColor || :gray.uicolor
@@ -1,3 +1,3 @@
1
1
  module MotionPrime
2
- VERSION = "0.3.3"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -1,4 +1,5 @@
1
1
  # TODO: make it part of Sections
2
+ motion_require '../support/dm_cell_with_section'
2
3
  module MotionPrime
3
4
  module Layout
4
5
  def add_view(klass, options = {}, &block)
@@ -38,13 +39,14 @@ module MotionPrime
38
39
  [::UIActionSheet, ::UIActivityIndicatorView, ::UIButton, ::UIDatePicker, ::UIImageView, ::UILabel,
39
40
  ::UIPageControl, ::UIPickerView, ::UIProgressView, ::UIScrollView, ::UISearchBar, ::UISegmentedControl,
40
41
  ::UISlider, ::UIStepper, ::UISwitch, ::UITabBar, ::UITableView, ::UITableViewCell, ::UITextField, ::UITextView,
41
- ::UIToolbar, ::UIWebView, ::UINavigationBar].each do |klass|
42
+ ::UIToolbar, ::UIWebView, ::UINavigationBar, ::DMCellWithSection].each do |klass|
42
43
 
43
44
  shorthand = "#{klass}"[2..-1].underscore.to_sym
44
45
 
45
46
  define_method(shorthand) do |options, &block|
47
+ options[:screen] = self
46
48
  element = MotionPrime::BaseElement.factory(shorthand, options)
47
- element.render(to: self, &block)
49
+ element.render({}, &block)
48
50
  element
49
51
  end
50
52
  end
@@ -22,11 +22,13 @@ module MotionPrime
22
22
  parent = options.delete(:parent)
23
23
  namespace = options.delete(:parent_namspace) || @namespace
24
24
  parent ="#{namespace}_#{parent}".to_sym if namespace
25
+ mixins = Array.wrap(options.delete(:mixins)).map { |mixin_name| :"_mixin_#{mixin_name}" }
25
26
 
26
27
  names.each do |name|
27
28
  name = "#{@namespace}_#{name}".to_sym if @namespace
28
29
  @@repo[name] ||= {}
29
30
  @@repo[name].deep_merge!(self.class.for(parent)) if parent
31
+ @@repo[name].deep_merge!(self.class.for(mixins)) if mixins.present?
30
32
  @@repo[name].deep_merge! options
31
33
  end
32
34
  end
@@ -32,10 +32,12 @@ module MotionPrime
32
32
  {
33
33
  'UIView' => Proc.new {|klass, options| klass.alloc.initWithFrame CGRectZero },
34
34
  'UILabel' => Proc.new {|klass, options|
35
- if options[:line_spacing]
35
+ if options.slice(:line_spacing, :underline, :fragment_color).any?
36
36
  options[:attributed_text_options] = {
37
37
  text: options.delete(:text),
38
- line_spacing: options.delete(:line_spacing)
38
+ line_spacing: options.delete(:line_spacing),
39
+ fragment_color: options.delete(:fragment_color),
40
+ underline: options.delete(:underline)
39
41
  }
40
42
  [:text_alignment].each do |key|# add keys which must follow after attributed text here
41
43
  value = options.delete(key)
@@ -101,6 +103,10 @@ module MotionPrime
101
103
  },
102
104
  'UITableViewCell' => Proc.new{|klass, options|
103
105
  style = options.delete(:style) || UITableViewCellStyleDefault
106
+ if options[:has_drawn_content]
107
+ options[:background_color] = :clear
108
+ options.delete(:gradient)
109
+ end
104
110
  klass.alloc.initWithStyle style, reuseIdentifier: options.delete(:reuse_identifier)
105
111
  },
106
112
  'UISearchBar' => Proc.new{|klass, options|
@@ -42,11 +42,11 @@ module MotionPrime
42
42
  def setValue(value, forUndefinedKey: key)
43
43
  # return if value.nil?
44
44
  # ignore options
45
- return if options[:section].is_a?(DrawSection) && %w[gradient].include?(key.to_s)
45
+ return if key == 'section' && !view.respond_to?(:section=)
46
46
  return if key == 'size_to_fit' && view.is_a?(UILabel)
47
47
  return if (key == 'url' || key == 'default') && view.is_a?(UIImageView)
48
48
  return if %w[
49
- styles
49
+ styles has_drawn_content
50
50
  width height top right bottom left value_type
51
51
  max_width max_outer_width min_width min_outer_width
52
52
  max_height max_outer_height min_height min_outer_width
@@ -123,6 +123,10 @@ module MotionPrime
123
123
  attributedString = NSMutableAttributedString.alloc.initWithAttributedString(attributedString)
124
124
  attributedString.addAttributes({NSUnderlineStyleAttributeName => NSUnderlineStyleSingle}, range: underline_range)
125
125
  end
126
+ if fragment_color = value[:fragment_color]
127
+ attributedString = NSMutableAttributedString.alloc.initWithAttributedString(attributedString)
128
+ attributedString.addAttributes({NSForegroundColorAttributeName => fragment_color[:color].uicolor}, range: fragment_color[:range])
129
+ end
126
130
  if view.is_a?(UIButton)
127
131
  view.setAttributedTitle attributedString, forState: UIControlStateNormal
128
132
  else
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motion-prime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Iskander Haziev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-08 00:00:00.000000000 Z
11
+ date: 2013-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -225,7 +225,7 @@ files:
225
225
  - motion-prime/core_ext/kernel.rb
226
226
  - motion-prime/elements/_content_padding_mixin.rb
227
227
  - motion-prime/elements/_content_text_mixin.rb
228
- - motion-prime/elements/base.rb
228
+ - motion-prime/elements/base_element.rb
229
229
  - motion-prime/elements/button.rb
230
230
  - motion-prime/elements/draw.rb
231
231
  - motion-prime/elements/draw/_draw_background_mixin.rb
@@ -237,9 +237,9 @@ files:
237
237
  - motion-prime/elements/image.rb
238
238
  - motion-prime/elements/label.rb
239
239
  - motion-prime/elements/map.rb
240
+ - motion-prime/elements/table_view_cell.rb
240
241
  - motion-prime/elements/text_field.rb
241
242
  - motion-prime/elements/text_view.rb
242
- - motion-prime/helpers/cell_section.rb
243
243
  - motion-prime/helpers/has_authorization.rb
244
244
  - motion-prime/helpers/has_normalizer.rb
245
245
  - motion-prime/helpers/has_search_bar.rb
@@ -267,8 +267,8 @@ files:
267
267
  - motion-prime/screens/extensions/_navigation_bar_mixin.rb
268
268
  - motion-prime/screens/sidebar_container_screen.rb
269
269
  - motion-prime/sections/_cell_section_mixin.rb
270
- - motion-prime/sections/base.rb
271
- - motion-prime/sections/draw.rb
270
+ - motion-prime/sections/_draw_mixin.rb
271
+ - motion-prime/sections/base_section.rb
272
272
  - motion-prime/sections/form.rb
273
273
  - motion-prime/sections/form/base_field_section.rb
274
274
  - motion-prime/sections/form/base_header_section.rb
@@ -279,12 +279,11 @@ files:
279
279
  - motion-prime/sections/form/submit_field_section.rb
280
280
  - motion-prime/sections/form/switch_field_section.rb
281
281
  - motion-prime/sections/form/text_field_section.rb
282
- - motion-prime/sections/form/text_with_button_field_section.rb
283
282
  - motion-prime/sections/tabbed.rb
284
283
  - motion-prime/sections/table.rb
285
- - motion-prime/sections/table/base_cell_section.rb
286
- - motion-prime/sections/table/draw_cell_section.rb
287
284
  - motion-prime/sections/table/refresh_mixin.rb
285
+ - motion-prime/services/table_data_indexes.rb
286
+ - motion-prime/styles/_mixins.rb
288
287
  - motion-prime/styles/base.rb
289
288
  - motion-prime/styles/form.rb
290
289
  - motion-prime/support/_key_value_store.rb
@@ -1,9 +0,0 @@
1
- module MotionPrime
2
- module CellSection
3
- attr_accessor :cell_view
4
-
5
- def cell
6
- cell_view
7
- end
8
- end
9
- end