motion-prime 0.9.9 → 0.9.9.1
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 +8 -2
- data/Gemfile.lock +2 -2
- data/ROADMAP.md +1 -3
- data/files/Gemfile +1 -1
- data/generators/templates/scaffold/table.rb +1 -1
- data/generators/templates/table.rb +1 -1
- data/motion-prime/config/base.rb +2 -2
- data/motion-prime/elements/_content_text_mixin.rb +1 -1
- data/motion-prime/elements/base_element.rb +14 -7
- data/motion-prime/elements/collection_view_cell.rb +7 -0
- data/motion-prime/elements/draw/image.rb +7 -2
- data/motion-prime/elements/table_view_cell.rb +1 -1
- data/motion-prime/helpers/has_normalizer.rb +1 -1
- data/motion-prime/helpers/has_search_bar.rb +1 -1
- data/motion-prime/models/_nano_bag_mixin.rb +1 -1
- data/motion-prime/models/model.rb +8 -8
- data/motion-prime/models/store.rb +1 -1
- data/motion-prime/screens/screen.rb +3 -3
- data/motion-prime/sections/_async_form_mixin.rb +2 -2
- data/motion-prime/sections/_async_table_mixin.rb +7 -7
- data/motion-prime/sections/_cell_section_mixin.rb +16 -11
- data/motion-prime/sections/_draw_section_mixin.rb +1 -0
- data/motion-prime/sections/{__section_with_container_mixin.rb → _section_with_container_mixin.rb} +2 -2
- data/motion-prime/sections/abstract_collection.rb +291 -0
- data/motion-prime/sections/base_section.rb +2 -2
- data/motion-prime/sections/collection/collection_delegate.rb +62 -0
- data/motion-prime/sections/form.rb +22 -18
- data/motion-prime/sections/form/base_field_section.rb +7 -7
- data/motion-prime/sections/form/form_delegate.rb +1 -1
- data/motion-prime/sections/form/form_header_section.rb +1 -1
- data/motion-prime/sections/form/password_field_section.rb +1 -1
- data/motion-prime/sections/form/static_field_section.rb +1 -1
- data/motion-prime/sections/form/string_field_section.rb +1 -1
- data/motion-prime/sections/form/text_field_section.rb +1 -1
- data/motion-prime/sections/grid.rb +92 -0
- data/motion-prime/sections/table.rb +26 -260
- data/motion-prime/sections/table/refresh_mixin.rb +3 -3
- data/motion-prime/sections/table/table_delegate.rb +1 -0
- data/motion-prime/styles/_mixins.rb +1 -1
- data/motion-prime/styles/base.rb +20 -6
- data/motion-prime/styles/form.rb +1 -1
- data/motion-prime/support/_control_content_alignment.rb +39 -0
- data/motion-prime/support/mp_button.rb +5 -13
- data/motion-prime/support/mp_collection_cell_with_section.rb +12 -0
- data/motion-prime/support/{mp_cell_content_view.rb → mp_table_cell_content_view.rb} +0 -0
- data/motion-prime/support/{mp_cell_with_section.rb → mp_table_cell_with_section.rb} +1 -1
- data/motion-prime/support/mp_text_field.rb +24 -18
- data/motion-prime/support/mp_text_view.rb +1 -0
- data/motion-prime/version.rb +1 -1
- data/motion-prime/views/_frame_calculator_mixin.rb +15 -11
- data/motion-prime/views/layout.rb +6 -4
- data/motion-prime/views/view_builder.rb +10 -0
- data/motion-prime/views/view_styler.rb +5 -1
- data/spec/factories/scaffold/sections/tasks/index_table.rb +1 -1
- data/spec/unit/support/filter_mixin_spec.rb +7 -3
- data/spec/unit/support/frame_calculator_mixin_spec.rb +43 -0
- metadata +13 -5
@@ -3,13 +3,13 @@ module MotionPrime
|
|
3
3
|
def add_pull_to_refresh(options = {}, &block)
|
4
4
|
screen.automaticallyAdjustsScrollViewInsets = false
|
5
5
|
|
6
|
-
|
7
|
-
screen.set_options_for
|
6
|
+
collection_view.addPullToRefreshWithActionHandler(block) # block must be a variable
|
7
|
+
screen.set_options_for collection_view.pullToRefreshView, styles: [:base_pull_to_refresh]
|
8
8
|
end
|
9
9
|
|
10
10
|
def finish_pull_to_refresh
|
11
11
|
reload_data
|
12
|
-
|
12
|
+
collection_view.pullToRefreshView.stopAnimating
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
data/motion-prime/styles/base.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
motion_require '../views/styles
|
1
|
+
motion_require '../views/styles'
|
2
2
|
MotionPrime::Styles.define :base do
|
3
3
|
# basic screen styles
|
4
4
|
style :screen,
|
@@ -9,17 +9,23 @@ MotionPrime::Styles.define :base do
|
|
9
9
|
style :table,
|
10
10
|
top: 0,
|
11
11
|
left: 0,
|
12
|
-
|
12
|
+
right: 0,
|
13
13
|
bottom: 0,
|
14
14
|
separator_inset: 0
|
15
15
|
|
16
|
+
style :collection,
|
17
|
+
top: 0,
|
18
|
+
left: 0,
|
19
|
+
right: 0,
|
20
|
+
bottom: 0
|
21
|
+
|
16
22
|
style :table_cell,
|
17
23
|
background_color: :clear
|
18
24
|
|
19
25
|
# basic form styles
|
20
26
|
# ----------
|
21
27
|
style :form,
|
22
|
-
|
28
|
+
right: 0,
|
23
29
|
left: 0,
|
24
30
|
top: 0,
|
25
31
|
right: 0,
|
@@ -41,14 +47,22 @@ MotionPrime::Styles.define :base do
|
|
41
47
|
height: 44
|
42
48
|
|
43
49
|
style :segmented_control,
|
44
|
-
height: 40,
|
50
|
+
height: 40,
|
51
|
+
left: 0,
|
52
|
+
right: 0,
|
53
|
+
top: 0
|
45
54
|
|
46
55
|
style :google_map,
|
47
|
-
top: 0,
|
56
|
+
top: 0,
|
57
|
+
left: 0,
|
58
|
+
right: 0,
|
59
|
+
bottom: 0
|
48
60
|
|
49
61
|
style :spinner,
|
50
62
|
annular: true,
|
51
|
-
center: proc { screen.view.center },
|
63
|
+
center: proc { screen.view.center },
|
64
|
+
width: 37,
|
65
|
+
height: 37,
|
52
66
|
progress_tint_color: :app_base.uicolor,
|
53
67
|
background_tint_color: :black.uicolor(0.05),
|
54
68
|
progress: 0.25
|
data/motion-prime/styles/form.rb
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
module MotionPrime
|
2
|
+
module SupportControlContentAlignment
|
3
|
+
VERTICAL_ALIGNMENT_CONSTS = {
|
4
|
+
UIControlContentVerticalAlignmentCenter => :center,
|
5
|
+
UIControlContentVerticalAlignmentTop => :top,
|
6
|
+
UIControlContentVerticalAlignmentBottom => :bottom,
|
7
|
+
UIControlContentVerticalAlignmentFill => :fill # TODO: handle this value
|
8
|
+
}
|
9
|
+
def setContentVerticalAlignment(value)
|
10
|
+
return unless @_content_vertical_alignment = VERTICAL_ALIGNMENT_CONSTS[value]
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def padding_top
|
15
|
+
padding_top = self.paddingTop || self.padding
|
16
|
+
if @_content_vertical_alignment == :bottom
|
17
|
+
padding_bottom = self.paddingBottom || self.padding
|
18
|
+
bounds_height - padding_bottom.to_i - line_height
|
19
|
+
elsif @_content_vertical_alignment == :top
|
20
|
+
padding_top.to_i
|
21
|
+
else # center label
|
22
|
+
padding_top_offset = padding_top.to_i - (self.paddingBottom || self.padding).to_i
|
23
|
+
(bounds_height - line_height)/2 + 1 + padding_top_offset
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def padding_bottom
|
28
|
+
(bounds_height - (line_height + padding_top))
|
29
|
+
end
|
30
|
+
|
31
|
+
def line_height
|
32
|
+
@_line_height || self.font.pointSize
|
33
|
+
end
|
34
|
+
|
35
|
+
def bounds_height
|
36
|
+
self.bounds.size.height
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,8 +1,11 @@
|
|
1
|
-
motion_require '
|
2
|
-
motion_require '
|
1
|
+
motion_require '_key_value_store'
|
2
|
+
motion_require '_padding_attribute'
|
3
|
+
motion_require '_control_content_alignment'
|
3
4
|
class MPButton < UIButton
|
4
5
|
include MotionPrime::SupportKeyValueStore
|
5
6
|
include MotionPrime::SupportPaddingAttribute
|
7
|
+
include MotionPrime::SupportControlContentAlignment
|
8
|
+
|
6
9
|
attr_accessor :sizeToFit
|
7
10
|
|
8
11
|
def setTitle(value)
|
@@ -26,17 +29,6 @@ class MPButton < UIButton
|
|
26
29
|
5
|
27
30
|
end
|
28
31
|
|
29
|
-
def padding_top # to center title label
|
30
|
-
self.paddingTop || self.padding || begin
|
31
|
-
single_line_height = self.font.pointSize
|
32
|
-
(self.bounds.size.height - single_line_height)/2 + 1
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def padding_bottom
|
37
|
-
self.bounds.size.height - (self.font.pointSize + padding_top)
|
38
|
-
end
|
39
|
-
|
40
32
|
def apply_padding!(rect)
|
41
33
|
self.setTitleEdgeInsets(padding_insets)
|
42
34
|
end
|
File without changes
|
@@ -1,13 +1,15 @@
|
|
1
1
|
# This class have some modifications for UITextField:
|
2
2
|
# * support padding, padding_left, padding_right options
|
3
3
|
# * support placeholder_color, placeholder_font options
|
4
|
-
motion_require '
|
5
|
-
motion_require '
|
4
|
+
motion_require '_key_value_store'
|
5
|
+
motion_require '_padding_attribute'
|
6
|
+
motion_require '_control_content_alignment'
|
6
7
|
class MPTextField < UITextField
|
7
8
|
include MotionPrime::SupportKeyValueStore
|
8
9
|
include MotionPrime::SupportPaddingAttribute
|
9
|
-
|
10
|
+
include MotionPrime::SupportControlContentAlignment
|
10
11
|
|
12
|
+
attr_accessor :placeholderColor, :placeholderFont, :readonly, :placeholderAlignment
|
11
13
|
|
12
14
|
def self.default_padding_left
|
13
15
|
5
|
@@ -19,38 +21,42 @@ class MPTextField < UITextField
|
|
19
21
|
|
20
22
|
# placeholder position
|
21
23
|
def textRectForBounds(bounds)
|
22
|
-
|
24
|
+
@_line_height = placeholder_font.pointSize
|
25
|
+
rect = calculate_rect_for(bounds)
|
26
|
+
@_line_height = nil
|
27
|
+
rect
|
23
28
|
end
|
24
29
|
|
25
30
|
# text position
|
26
31
|
def editingRectForBounds(bounds)
|
27
|
-
|
32
|
+
@_line_height = self.font.pointSize
|
33
|
+
rect = calculate_rect_for(bounds)
|
34
|
+
@_line_height = nil
|
35
|
+
rect
|
28
36
|
end
|
29
37
|
|
30
38
|
def drawPlaceholderInRect(rect)
|
31
39
|
color = self.placeholderColor || :gray.uicolor
|
32
40
|
color.setFill
|
33
|
-
font = self.placeholderFont || self.font || :system.uifont(16)
|
34
41
|
|
35
42
|
truncation = :tail_truncation.uilinebreakmode
|
36
|
-
alignment = (placeholderAlignment || :left)
|
37
|
-
|
38
|
-
self.placeholder.drawInRect(rect, withFont: font, lineBreakMode: truncation, alignment: alignment)
|
43
|
+
alignment = (placeholderAlignment || :left.nstextalignment)
|
44
|
+
self.placeholder.drawInRect(rect, withFont: placeholder_font, lineBreakMode: truncation, alignment: alignment)
|
39
45
|
end
|
40
46
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
(self.bounds.size.height - single_line_height)/2 + 1
|
47
|
+
private
|
48
|
+
def placeholder_font
|
49
|
+
self.placeholderFont || self.font || :system.uifont(16)
|
45
50
|
end
|
46
|
-
end
|
47
51
|
|
48
|
-
private
|
49
52
|
def calculate_rect_for(bounds)
|
50
|
-
height_diff = self.bounds.size.height - (
|
53
|
+
height_diff = self.bounds.size.height - (line_height + padding_top + padding_bottom)
|
51
54
|
bounds = CGRectMake(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height - height_diff)
|
52
55
|
CGRectMake(
|
53
|
-
bounds.origin.x + padding_left,
|
54
|
-
bounds.
|
56
|
+
bounds.origin.x + padding_left,
|
57
|
+
bounds.origin.y + padding_top,
|
58
|
+
bounds.size.width - (padding_left + padding_right),
|
59
|
+
bounds.size.height - (padding_top + padding_bottom)
|
60
|
+
)
|
55
61
|
end
|
56
62
|
end
|
@@ -6,6 +6,7 @@ motion_require '../support/_padding_attribute'
|
|
6
6
|
class MPTextView < UITextView
|
7
7
|
include MotionPrime::SupportKeyValueStore
|
8
8
|
include MotionPrime::SupportPaddingAttribute
|
9
|
+
|
9
10
|
attr_accessor :placeholderColor, :placeholderFont, :placeholder
|
10
11
|
|
11
12
|
def self.default_padding_left
|
data/motion-prime/version.rb
CHANGED
@@ -19,8 +19,8 @@ module MotionPrime
|
|
19
19
|
|
20
20
|
max_width = parent_bounds.size.width
|
21
21
|
max_height = parent_bounds.size.height
|
22
|
-
|
23
|
-
|
22
|
+
temp_width = width || 0.0
|
23
|
+
temp_height = height || 0.0
|
24
24
|
|
25
25
|
if left && left > 0 && left <= 1 && value_type != 'absolute' && left.is_a?(Float)
|
26
26
|
left = max_width * left
|
@@ -41,7 +41,7 @@ module MotionPrime
|
|
41
41
|
end
|
42
42
|
|
43
43
|
# calculate top and bottom if height is relative, e.g 0.7
|
44
|
-
if height && height > 0 && height <= 1 && value_type != 'absolute' &&
|
44
|
+
if height && height > 0 && height <= 1 && value_type != 'absolute' && height.is_a?(Float)
|
45
45
|
if bottom.nil?
|
46
46
|
top ||= 0
|
47
47
|
bottom = max_height - max_height * height
|
@@ -52,27 +52,31 @@ module MotionPrime
|
|
52
52
|
|
53
53
|
if !left.nil? && !right.nil?
|
54
54
|
frame.origin.x = left
|
55
|
-
|
55
|
+
if options[:height_to_fit].nil? && width.nil?
|
56
|
+
width = max_width - left - right
|
57
|
+
end
|
56
58
|
elsif !right.nil?
|
57
|
-
frame.origin.x = max_width -
|
59
|
+
frame.origin.x = max_width - temp_width - right
|
58
60
|
elsif !left.nil?
|
59
61
|
frame.origin.x = left
|
60
62
|
else
|
61
|
-
frame.origin.x = max_width / 2 -
|
63
|
+
frame.origin.x = max_width / 2 - temp_width / 2
|
62
64
|
end
|
63
|
-
frame.size.width = width
|
65
|
+
frame.size.width = width || 0.0
|
64
66
|
|
65
67
|
if !top.nil? && !bottom.nil?
|
66
68
|
frame.origin.y = top
|
67
|
-
|
69
|
+
if options[:height_to_fit].nil? && height.nil?
|
70
|
+
height = max_height - top - bottom
|
71
|
+
end
|
68
72
|
elsif !bottom.nil?
|
69
|
-
frame.origin.y = max_height -
|
73
|
+
frame.origin.y = max_height - temp_height - bottom
|
70
74
|
elsif !top.nil?
|
71
75
|
frame.origin.y = top
|
72
76
|
else
|
73
|
-
frame.origin.y = max_height / 2 -
|
77
|
+
frame.origin.y = max_height / 2 - temp_height / 2
|
74
78
|
end
|
75
|
-
frame.size.height = height
|
79
|
+
frame.size.height = height || 0.0
|
76
80
|
|
77
81
|
frame
|
78
82
|
rescue => e
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# TODO: make it part of Sections
|
2
|
-
motion_require '../support/
|
2
|
+
motion_require '../support/mp_table_cell_with_section'
|
3
|
+
motion_require '../support/mp_collection_cell_with_section'
|
3
4
|
motion_require '../support/mp_spinner'
|
4
5
|
motion_require '../support/mp_button'
|
5
6
|
motion_require '../support/mp_label'
|
@@ -17,7 +18,7 @@ module MotionPrime
|
|
17
18
|
else
|
18
19
|
view_stack.last.bounds
|
19
20
|
end
|
20
|
-
builder = ViewBuilder.new(klass, options)
|
21
|
+
builder = ViewBuilder.new(klass, options.merge(parent_bounds: parent_bounds))
|
21
22
|
options = builder.options.merge(calculate_frame: true, parent_bounds: parent_bounds)
|
22
23
|
view = builder.view
|
23
24
|
insert_index = options.delete(:at_index)
|
@@ -51,8 +52,9 @@ module MotionPrime
|
|
51
52
|
base.class_eval do
|
52
53
|
[::UIActionSheet, ::UIActivityIndicatorView, ::MPButton, ::UIDatePicker, ::UIImageView, ::MPLabel,
|
53
54
|
::UIPageControl, ::UIPickerView, ::UIProgressView, ::UIScrollView, ::UISearchBar, ::UISegmentedControl,
|
54
|
-
::UISlider, ::UIStepper, ::UISwitch, ::UITabBar, ::
|
55
|
-
::
|
55
|
+
::UISlider, ::UIStepper, ::UISwitch, ::UITabBar, ::UICollectionView, ::UITableView, ::UITableViewCell,
|
56
|
+
::MPTextField, ::MPTextView, ::UIToolbar, ::UIWebView, ::UINavigationBar,
|
57
|
+
::MPTableCellWithSection, ::MPCollectionCellWithSection, ::MBProgressHUD, ::MPSpinner].each do |klass|
|
56
58
|
|
57
59
|
shorthand = "#{klass}"[2..-1].underscore.to_sym
|
58
60
|
|
@@ -86,6 +86,16 @@ module MotionPrime
|
|
86
86
|
view.tableFooterView = UIView.new
|
87
87
|
view
|
88
88
|
},
|
89
|
+
'UICollectionView' => Proc.new{|klass, options|
|
90
|
+
unless layout = options.delete(:layout)
|
91
|
+
layout = UICollectionViewFlowLayout.alloc.init
|
92
|
+
total_width = options[:parent_bounds].size.width / (options.delete(:grid_size) || 4)
|
93
|
+
width = total_width - layout.minimumInteritemSpacing
|
94
|
+
layout.setItemSize CGSizeMake(width, options.delete(:item_height) || 100)
|
95
|
+
end
|
96
|
+
view = klass.alloc.initWithFrame CGRectZero, collectionViewLayout: layout
|
97
|
+
view
|
98
|
+
},
|
89
99
|
'UITableViewCell' => Proc.new{|klass, options|
|
90
100
|
style = options.delete(:style) || UITableViewCellStyleDefault
|
91
101
|
if options[:has_drawn_content]
|
@@ -5,6 +5,8 @@ module MotionPrime
|
|
5
5
|
include HasClassFactory
|
6
6
|
include ElementTextMixin
|
7
7
|
|
8
|
+
ORDER = %w[font placeholder_font text]
|
9
|
+
|
8
10
|
attr_reader :view, :options
|
9
11
|
|
10
12
|
def initialize(view, parent_bounds = CGRectZero, options = {})
|
@@ -46,7 +48,7 @@ module MotionPrime
|
|
46
48
|
def prepare_options!
|
47
49
|
if options[:size_to_fit]
|
48
50
|
options[:line_break_mode] ||= :word_wrap
|
49
|
-
options[:number_of_lines] ||= 0
|
51
|
+
options[:number_of_lines] ||= 0 if view.is_a?(UILabel)
|
50
52
|
end
|
51
53
|
|
52
54
|
if options.slice(:html, :line_spacing, :line_height, :underline, :fragment_color).any?
|
@@ -63,6 +65,8 @@ module MotionPrime
|
|
63
65
|
end
|
64
66
|
extract_font_options(options)
|
65
67
|
extract_font_options(options, 'placeholder')
|
68
|
+
|
69
|
+
@options = Hash[options.sort_by { |k,v| ORDER.index(k.to_s).to_i }]
|
66
70
|
end
|
67
71
|
|
68
72
|
def extract_font_options(options, prefix = nil)
|
@@ -1,4 +1,8 @@
|
|
1
1
|
describe MotionPrime::FilterMixin do
|
2
|
+
before do
|
3
|
+
@subject = MotionPrime::FilterMixin.new
|
4
|
+
end
|
5
|
+
|
2
6
|
def data
|
3
7
|
model_stub = Struct.new(:info, :id) # :id is used for sorting
|
4
8
|
data_array.map do |item|
|
@@ -11,15 +15,15 @@ describe MotionPrime::FilterMixin do
|
|
11
15
|
end
|
12
16
|
|
13
17
|
it "should filter array by inclusion" do
|
14
|
-
|
18
|
+
@subject.filter_array(data, {id: %w[4 5]}).count.should.equal 2
|
15
19
|
end
|
16
20
|
|
17
21
|
it "should find a single record (case sensitive)" do
|
18
|
-
|
22
|
+
@subject.filter_array(data, {id: 4, name: 'iPhone'}).count.should.equal 1
|
19
23
|
end
|
20
24
|
|
21
25
|
it "order filtered records" do
|
22
|
-
result =
|
26
|
+
result = @subject.filter_array(data, {id: %w[4 5]}, sort: {id: :desc})
|
23
27
|
result.first[:id].should.equal 5
|
24
28
|
end
|
25
29
|
end
|