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.
- checksums.yaml +8 -8
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/ROADMAP.md +3 -3
- data/doc/code/getting_started.rb +6 -5
- data/files/app/screens/sidebar_screen.rb +2 -2
- data/files/app/sections/sidebar/action.rb +1 -1
- data/motion-prime/api_client.rb +1 -1
- data/motion-prime/core_ext/kernel.rb +4 -0
- data/motion-prime/elements/_content_padding_mixin.rb +12 -4
- data/motion-prime/elements/_content_text_mixin.rb +10 -2
- data/motion-prime/elements/{base.rb → base_element.rb} +16 -7
- data/motion-prime/elements/button.rb +1 -1
- data/motion-prime/elements/draw/_draw_background_mixin.rb +20 -9
- data/motion-prime/elements/draw/image.rb +2 -2
- data/motion-prime/elements/draw/label.rb +7 -6
- data/motion-prime/elements/draw.rb +8 -3
- data/motion-prime/elements/label.rb +2 -2
- data/motion-prime/elements/table_view_cell.rb +7 -0
- data/motion-prime/helpers/has_search_bar.rb +1 -1
- data/motion-prime/helpers/has_styles.rb +7 -7
- data/motion-prime/models/model.rb +1 -1
- data/motion-prime/models/sync.rb +10 -10
- data/motion-prime/screens/_navigation_mixin.rb +1 -1
- data/motion-prime/sections/_draw_mixin.rb +74 -0
- data/motion-prime/sections/{base.rb → base_section.rb} +104 -55
- data/motion-prime/sections/form/base_field_section.rb +6 -6
- data/motion-prime/sections/form/base_header_section.rb +2 -3
- data/motion-prime/sections/form.rb +38 -17
- data/motion-prime/sections/tabbed.rb +3 -3
- data/motion-prime/sections/table.rb +172 -80
- data/motion-prime/services/table_data_indexes.rb +51 -0
- data/motion-prime/styles/_mixins.rb +8 -0
- data/motion-prime/support/dm_cell_with_section.rb +1 -1
- data/motion-prime/support/dm_text_field.rb +17 -12
- data/motion-prime/support/dm_text_view.rb +10 -23
- data/motion-prime/version.rb +1 -1
- data/motion-prime/views/layout.rb +4 -2
- data/motion-prime/views/styles.rb +2 -0
- data/motion-prime/views/view_builder.rb +8 -2
- data/motion-prime/views/view_styler.rb +6 -2
- metadata +8 -9
- data/motion-prime/helpers/cell_section.rb +0 -9
- data/motion-prime/sections/draw.rb +0 -93
- data/motion-prime/sections/form/text_with_button_field_section.rb +0 -23
- data/motion-prime/sections/table/base_cell_section.rb +0 -5
- 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
|
16
|
-
|
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
|
24
|
-
@
|
20
|
+
def data
|
21
|
+
@data || set_table_data
|
25
22
|
end
|
26
23
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
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
|
33
|
-
|
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
|
34
|
+
def reset_data
|
47
35
|
@did_appear = false
|
48
36
|
@data = nil
|
49
|
-
|
50
|
-
|
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) #
|
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
|
-
|
150
|
-
|
151
|
-
|
152
|
-
item.render
|
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
|
-
|
170
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
@@ -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
|
-
|
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
|
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
|
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
|
-
|
6
|
+
include MotionPrime::SupportPaddingAttribute
|
7
|
+
attr_accessor :placeholderColor, :placeholderFont, :placeholder
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
def self.default_padding_left
|
10
|
+
5
|
11
|
+
end
|
10
12
|
|
11
|
-
def
|
12
|
-
|
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
|
-
|
18
|
-
|
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
|
-
|
26
|
+
padding_bottom, padding_right
|
40
27
|
)
|
41
28
|
if self.placeholder && self.text.blank?
|
42
29
|
color = self.placeholderColor || :gray.uicolor
|
data/motion-prime/version.rb
CHANGED
@@ -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(
|
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
|
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
|
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.
|
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-
|
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/
|
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/
|
271
|
-
- motion-prime/sections/
|
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
|