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.
- checksums.yaml +8 -8
- data/CHANGELOG.md +3 -0
- data/Gemfile.lock +1 -1
- data/README.md +10 -0
- data/doc/code/getting_started.rb +61 -0
- data/doc/docs/docco.css +500 -0
- data/doc/docs/getting_started.html +177 -0
- data/doc/docs/public/fonts/aller-bold.eot +0 -0
- data/doc/docs/public/fonts/aller-bold.ttf +0 -0
- data/doc/docs/public/fonts/aller-bold.woff +0 -0
- data/doc/docs/public/fonts/aller-light.eot +0 -0
- data/doc/docs/public/fonts/aller-light.ttf +0 -0
- data/doc/docs/public/fonts/aller-light.woff +0 -0
- data/doc/docs/public/fonts/novecento-bold.eot +0 -0
- data/doc/docs/public/fonts/novecento-bold.ttf +0 -0
- data/doc/docs/public/fonts/novecento-bold.woff +0 -0
- data/doc/docs/public/stylesheets/normalize.css +375 -0
- data/files/app/sections/sidebar/action.rb +1 -1
- data/motion-prime/app_delegate.rb +8 -2
- data/motion-prime/elements/_content_padding_mixin.rb +12 -12
- data/motion-prime/elements/_content_text_mixin.rb +65 -0
- data/motion-prime/elements/base.rb +51 -19
- data/motion-prime/elements/button.rb +1 -1
- data/motion-prime/elements/draw.rb +26 -113
- data/motion-prime/elements/draw/_draw_background_mixin.rb +26 -0
- data/motion-prime/elements/draw/image.rb +10 -1
- data/motion-prime/elements/draw/label.rb +61 -42
- data/motion-prime/elements/draw/view.rb +14 -0
- data/motion-prime/elements/error_message.rb +1 -1
- data/motion-prime/elements/label.rb +1 -1
- data/motion-prime/elements/text_field.rb +2 -2
- data/motion-prime/elements/text_view.rb +3 -0
- data/motion-prime/helpers/has_style_chain_builder.rb +1 -1
- data/motion-prime/helpers/has_styles.rb +28 -0
- data/motion-prime/models/bag.rb +1 -1
- data/motion-prime/models/sync.rb +4 -4
- data/motion-prime/screens/_base_mixin.rb +1 -1
- data/motion-prime/screens/extensions/_navigation_bar_mixin.rb +7 -0
- data/motion-prime/screens/sidebar_container_screen.rb +8 -2
- data/motion-prime/sections/_cell_section_mixin.rb +25 -0
- data/motion-prime/sections/base.rb +17 -16
- data/motion-prime/sections/draw.rb +32 -10
- data/motion-prime/sections/form.rb +27 -17
- data/motion-prime/sections/form/base_field_section.rb +0 -1
- data/motion-prime/sections/form/base_header_section.rb +3 -2
- data/motion-prime/sections/form/password_field_section.rb +1 -1
- data/motion-prime/sections/table.rb +31 -10
- data/motion-prime/sections/table/base_cell_section.rb +1 -22
- data/motion-prime/sections/table/draw_cell_section.rb +5 -0
- data/motion-prime/styles/form.rb +12 -4
- data/motion-prime/support/_key_value_store.rb +0 -2
- data/motion-prime/support/dm_text_field.rb +2 -2
- data/motion-prime/support/tab_bar_controller.rb +28 -0
- data/motion-prime/version.rb +1 -1
- data/motion-prime/views/_frame_calculator_mixin.rb +75 -0
- data/motion-prime/views/view_styler.rb +36 -94
- metadata +23 -4
- data/motion-prime/elements/_field_dimensions_mixin.rb +0 -59
- data/motion-prime/elements/_text_dimensions_mixin.rb +0 -35
@@ -20,9 +20,10 @@ module MotionPrime
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def open_screen(screen, options = {})
|
23
|
+
screen = create_tab_bar(screen) if screen.is_a?(Array)
|
23
24
|
if options[:sidebar]
|
24
25
|
open_with_sidebar(screen, options.delete(:sidebar), options)
|
25
|
-
elsif options[:root]
|
26
|
+
elsif options[:root] || !self.window
|
26
27
|
open_root_screen(screen)
|
27
28
|
else
|
28
29
|
open_content_screen(screen)
|
@@ -59,7 +60,7 @@ module MotionPrime
|
|
59
60
|
end
|
60
61
|
|
61
62
|
def sidebar?
|
62
|
-
self.window.rootViewController.is_a?(SidebarContainerScreen)
|
63
|
+
self.window && self.window.rootViewController.is_a?(SidebarContainerScreen)
|
63
64
|
end
|
64
65
|
|
65
66
|
def show_sidebar
|
@@ -81,5 +82,10 @@ module MotionPrime
|
|
81
82
|
@current_user = nil
|
82
83
|
NSNotificationCenter.defaultCenter.postNotificationName(:on_current_user_reset, object: user_was)
|
83
84
|
end
|
85
|
+
|
86
|
+
private
|
87
|
+
def create_tab_bar(screens)
|
88
|
+
MotionPrime::TabBarController.new(screens)
|
89
|
+
end
|
84
90
|
end
|
85
91
|
end
|
@@ -1,31 +1,27 @@
|
|
1
1
|
module MotionPrime
|
2
2
|
module ElementContentPaddingMixin
|
3
3
|
def content_padding_left
|
4
|
-
|
5
|
-
computed_options[:padding_left] ||
|
4
|
+
computed_options[:padding_left] ||
|
6
5
|
computed_options[:padding] ||
|
7
|
-
|
6
|
+
default_padding_for(:left) || 0
|
8
7
|
end
|
9
8
|
|
10
9
|
def content_padding_right
|
11
|
-
|
12
|
-
computed_options[:padding_right] ||
|
10
|
+
computed_options[:padding_right] ||
|
13
11
|
computed_options[:padding] ||
|
14
|
-
|
12
|
+
default_padding_for(:right) || 0
|
15
13
|
end
|
16
14
|
|
17
15
|
def content_padding_top
|
18
|
-
|
19
|
-
computed_options[:padding_top] ||
|
16
|
+
computed_options[:padding_top] ||
|
20
17
|
computed_options[:padding] ||
|
21
|
-
|
18
|
+
default_padding_for(:top) || 0
|
22
19
|
end
|
23
20
|
|
24
21
|
def content_padding_bottom
|
25
|
-
|
26
|
-
computed_options[:padding_bottom] ||
|
22
|
+
computed_options[:padding_bottom] ||
|
27
23
|
computed_options[:padding] ||
|
28
|
-
|
24
|
+
default_padding_for(:bottom) || 0
|
29
25
|
end
|
30
26
|
|
31
27
|
def content_padding_height
|
@@ -45,5 +41,9 @@ module MotionPrime
|
|
45
41
|
width = content_padding_width + content_width
|
46
42
|
[[width, computed_options[:min_outer_width]].compact.max, computed_options[:max_outer_width]].compact.min
|
47
43
|
end
|
44
|
+
|
45
|
+
def default_padding_for(side)
|
46
|
+
view_class.constantize.send(:"default_padding_#{side}")
|
47
|
+
end
|
48
48
|
end
|
49
49
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module MotionPrime
|
2
|
+
module ElementContentTextMixin
|
3
|
+
def content_text
|
4
|
+
(is_a?(ButtonElement) ? button_content_text : input_content_text).to_s
|
5
|
+
end
|
6
|
+
|
7
|
+
def content_font
|
8
|
+
(is_a?(ButtonElement) ? button_content_font : input_content_font) || :system.uifont
|
9
|
+
end
|
10
|
+
|
11
|
+
def content_width
|
12
|
+
min, max = computed_options[:min_width].to_f, computed_options[:max_width]
|
13
|
+
return min if content_text.blank?
|
14
|
+
|
15
|
+
rect = get_content_rect(Float::MAX)
|
16
|
+
[[rect.size.width.ceil, max].compact.min, min].max.ceil
|
17
|
+
end
|
18
|
+
|
19
|
+
def content_height
|
20
|
+
min, max = computed_options[:min_height].to_f, computed_options[:max_height]
|
21
|
+
return min if content_text.blank?
|
22
|
+
rect = get_content_rect(computed_options[:width])
|
23
|
+
[[rect.size.height.ceil, max].compact.min, min].max.ceil
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def get_content_rect(width)
|
28
|
+
raise "Please set element width for content size calculation" unless width
|
29
|
+
attributes = {NSFontAttributeName => content_font }
|
30
|
+
if computed_options[:line_spacing]
|
31
|
+
paragrahStyle = NSMutableParagraphStyle.alloc.init
|
32
|
+
paragrahStyle.setLineSpacing(computed_options[:line_spacing])
|
33
|
+
attributes[NSParagraphStyleAttributeName] = paragrahStyle
|
34
|
+
end
|
35
|
+
attributed_text = NSAttributedString.alloc.initWithString(content_text, attributes: attributes)
|
36
|
+
attributed_text.boundingRectWithSize(
|
37
|
+
[width, Float::MAX], options:NSStringDrawingUsesLineFragmentOrigin, context:nil
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def button_content_text
|
42
|
+
view ? view.titleLabel.text : computed_options[:title]
|
43
|
+
end
|
44
|
+
|
45
|
+
def button_content_font
|
46
|
+
computed_options[:title_label][:font]
|
47
|
+
end
|
48
|
+
|
49
|
+
def input_content_text
|
50
|
+
input_value_text.blank? ? input_placeholder_text : input_value_text
|
51
|
+
end
|
52
|
+
|
53
|
+
def input_content_font
|
54
|
+
input_value_text.blank? ? computed_options[:placeholder_font] : computed_options[:font]
|
55
|
+
end
|
56
|
+
|
57
|
+
def input_value_text
|
58
|
+
view && !is_a?(DrawElement) ? view.text : computed_options[:text]
|
59
|
+
end
|
60
|
+
|
61
|
+
def input_placeholder_text
|
62
|
+
computed_options[:placeholder]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -59,30 +59,62 @@ module MotionPrime
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def compute_style_options(*style_sources)
|
62
|
-
|
63
|
-
|
64
|
-
suffixes = {common: [@view_name.to_sym, name.try(:to_sym)].compact, specific: []}
|
62
|
+
has_errors = section.respond_to?(:observing_errors?) && observing_errors? && has_errors?
|
63
|
+
is_cell_section = section.is_a?(BaseCellSection) || section.is_a?(DrawCellSection)
|
65
64
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
65
|
+
@styles = []
|
66
|
+
if is_cell_section
|
67
|
+
base_styles = {common: [], specific: []}
|
68
|
+
suffixes = {common: [], specific: []}
|
69
|
+
|
70
|
+
# following example in Prime::TableSection#cell_styles
|
71
|
+
# form element/cell: <base|user>_form_field, <base|user>_form_string_field, user_form_field_email
|
72
|
+
# table element/cell: <base|categories>_table_cell, categories_table_title
|
73
|
+
section.section_styles.each { |type, values| base_styles[type] += values }
|
74
|
+
if %w[base table_view_cell].exclude?(@view_name.to_s)
|
75
|
+
# form element: _input
|
76
|
+
# table element: _image
|
77
|
+
suffixes[:common] << @view_name.to_sym
|
78
|
+
suffixes[:common] << :"#{@view_name}_with_errors" if has_errors
|
79
|
+
end
|
80
|
+
if name && name.to_s != @view_name.to_s
|
81
|
+
# form element: _input
|
82
|
+
# table element: _icon
|
83
|
+
suffixes[:specific] << name.to_sym
|
84
|
+
suffixes[:specific] << :"#{name}_with_errors" if has_errors
|
70
85
|
end
|
71
|
-
|
72
|
-
|
86
|
+
# form cell: base_form_field, base_form_string_field
|
87
|
+
# form element: base_form_field_string_field, base_form_string_field_text_field
|
88
|
+
# table cell: base_table_cell
|
89
|
+
# table element: base_table_cell_image
|
90
|
+
common_styles = if suffixes[:common].any?
|
91
|
+
build_styles_chain(base_styles[:common], suffixes[:common])
|
92
|
+
elsif suffixes[:specific].any?
|
93
|
+
build_styles_chain(base_styles[:common], suffixes[:specific])
|
94
|
+
elsif @view_name.to_s == 'table_view_cell'
|
95
|
+
base_styles[:common]
|
73
96
|
end
|
97
|
+
@styles += Array.wrap(common_styles)
|
98
|
+
|
99
|
+
# form cell: user_form_field, user_form_string_field, user_form_field_email
|
100
|
+
# form element: user_form_field_text_field, user_form_string_field_text_field, user_form_field_email_text_field
|
101
|
+
# table cell: categories_table_cell, categories_table_title
|
102
|
+
# table element: categories_table_cell_image, categories_table_title_image
|
103
|
+
specific_base_common_suffix_styles = if suffixes[:common].any?
|
104
|
+
build_styles_chain(base_styles[:specific], suffixes[:common])
|
105
|
+
elsif suffixes[:specific].empty? && @view_name.to_s == 'table_view_cell'
|
106
|
+
base_styles[:specific]
|
107
|
+
end
|
108
|
+
@styles += Array.wrap(specific_base_common_suffix_styles)
|
109
|
+
# form element: user_form_field_input, user_form_string_field_input, user_form_field_email_input
|
110
|
+
# table element: categories_table_cell_icon, categories_table_title_icon
|
111
|
+
@styles += build_styles_chain(base_styles[:specific], suffixes[:specific])
|
74
112
|
end
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
@styles << [section.name, name].compact.join('_').to_sym if section
|
79
|
-
@styles += build_styles_chain(base_styles[:specific], suffixes[:common])
|
80
|
-
# specific base - specific suffixes
|
81
|
-
@styles += build_styles_chain(base_styles[:specific], suffixes[:specific])
|
82
|
-
if cell_section && section.table.present?
|
83
|
-
@styles << [section.table.name, section.cell_type, section.name, name].compact.join('_').to_sym
|
113
|
+
if section
|
114
|
+
# using for base sections
|
115
|
+
@styles << [section.name, name].compact.join('_').to_sym
|
84
116
|
end
|
85
|
-
# custom style (from options or block options)
|
117
|
+
# custom style (from options or block options), using for TableViews as well
|
86
118
|
custom_styles = style_sources.map do |source|
|
87
119
|
normalize_object(source.delete(:styles), section)
|
88
120
|
end.compact.flatten
|
@@ -1,142 +1,55 @@
|
|
1
|
+
motion_require '../views/_frame_calculator_mixin'
|
1
2
|
module MotionPrime
|
2
3
|
class DrawElement < BaseElement
|
3
4
|
# MotionPrime::DrawElement is container for drawRect method options.
|
4
5
|
# Elements are located inside Sections
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
include FrameCalculatorMixin
|
8
|
+
include ElementContentPaddingMixin
|
9
|
+
|
10
|
+
def render!; end
|
8
11
|
|
9
12
|
def view
|
10
13
|
@view ||= section.container_view
|
11
14
|
end
|
12
15
|
|
13
|
-
def
|
14
|
-
view.bounds
|
15
|
-
end
|
16
|
-
|
17
|
-
def computed_max_height
|
18
|
-
view.bounds.size.height
|
19
|
-
end
|
20
|
-
|
21
|
-
def computed_padding_left
|
22
|
-
computed_options[:padding_left] ||
|
23
|
-
computed_options[:padding] || 0
|
24
|
-
end
|
25
|
-
|
26
|
-
def computed_padding_right
|
27
|
-
computed_options[:padding_right] ||
|
28
|
-
computed_options[:padding] || 0
|
29
|
-
end
|
30
|
-
|
31
|
-
def computed_padding_top
|
32
|
-
computed_options[:padding_top] ||
|
33
|
-
computed_options[:padding] || 0
|
34
|
-
end
|
35
|
-
|
36
|
-
def computed_padding_bottom
|
37
|
-
computed_options[:padding_bottom] ||
|
38
|
-
computed_options[:padding] || 0
|
39
|
-
end
|
40
|
-
|
41
|
-
def computed_width
|
42
|
-
@computed_width ||= begin
|
43
|
-
width = computed_options[:width]
|
44
|
-
width = 0.0 if width.nil?
|
45
|
-
|
46
|
-
# calculate width if width is relative, e.g 0.7
|
47
|
-
if width > 0 && width <= 1
|
48
|
-
width * computed_max_width
|
49
|
-
else
|
50
|
-
width > computed_max_width ? computed_max_width : width
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# content width + content padding
|
56
|
-
def computed_outer_width
|
57
|
-
@computed_outer_width ||= begin
|
58
|
-
computed_width + computed_padding_left + computed_padding_right
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def computed_height
|
63
|
-
@computed_height ||= begin
|
64
|
-
height = computed_options[:height]
|
65
|
-
height = 0.0 if height.nil?
|
66
|
-
|
67
|
-
# calculate height if height is relative, e.g 0.7
|
68
|
-
if height > 0 && height <= 1
|
69
|
-
height * computed_max_height
|
70
|
-
else
|
71
|
-
height > computed_max_height ? computed_max_height : height
|
72
|
-
end
|
73
|
-
end
|
16
|
+
def computed_frame
|
17
|
+
@computed_frame ||= calculate_frome_for(view.bounds, computed_options)
|
74
18
|
end
|
75
19
|
|
76
|
-
|
77
|
-
|
78
|
-
@computed_outer_height ||= begin
|
79
|
-
computed_height + computed_padding_top + computed_padding_bottom
|
80
|
-
end
|
20
|
+
def default_padding_for(side)
|
21
|
+
0
|
81
22
|
end
|
82
23
|
|
83
|
-
def
|
84
|
-
|
85
|
-
left = computed_options[:left]
|
86
|
-
right = computed_options[:right]
|
87
|
-
return left if left
|
88
|
-
return 0 if right.nil?
|
89
|
-
|
90
|
-
computed_max_width - (computed_width + right)
|
91
|
-
end
|
24
|
+
def computed_max_width
|
25
|
+
view.bounds.size.width
|
92
26
|
end
|
93
27
|
|
94
|
-
|
95
|
-
|
96
|
-
@computed_inner_left ||= begin
|
97
|
-
computed_left + computed_padding_left
|
98
|
-
end
|
28
|
+
def computed_max_height
|
29
|
+
view.bounds.size.height
|
99
30
|
end
|
100
31
|
|
101
|
-
def
|
102
|
-
|
103
|
-
top = computed_options[:top]
|
104
|
-
bottom = computed_options[:bottom]
|
105
|
-
return top if top
|
106
|
-
return 0 if bottom.nil?
|
32
|
+
def computed_outer_width; computed_frame.size.width end
|
33
|
+
def computed_width; computed_outer_width - content_padding_width end
|
107
34
|
|
108
|
-
|
109
|
-
|
110
|
-
end
|
35
|
+
def computed_outer_height; computed_frame.size.height end
|
36
|
+
def computed_height; computed_outer_height - content_padding_height end
|
111
37
|
|
112
|
-
|
113
|
-
def computed_inner_top
|
114
|
-
@computed_inner_top ||= begin
|
115
|
-
computed_top + computed_padding_top
|
116
|
-
end
|
117
|
-
end
|
38
|
+
def computed_top; computed_frame.origin.y end
|
39
|
+
def computed_inner_top; computed_top + content_padding_top end
|
118
40
|
|
119
|
-
def
|
120
|
-
|
121
|
-
end
|
41
|
+
def computed_left; computed_frame.origin.x end
|
42
|
+
def computed_inner_left; computed_left + content_padding_left end
|
122
43
|
|
123
|
-
def
|
124
|
-
|
125
|
-
end
|
44
|
+
def computed_bottom; computed_top + computed_outer_height end
|
45
|
+
def computed_inner_bottom; computed_bottom - content_padding_bottom end
|
126
46
|
|
127
|
-
def computed_right
|
128
|
-
|
129
|
-
end
|
47
|
+
def computed_right; computed_left + computed_width end
|
48
|
+
def computed_inner_right; computed_right - content_padding_right end
|
130
49
|
|
131
|
-
def computed_inner_right
|
132
|
-
computed_right + computed_padding_right
|
133
|
-
end
|
134
50
|
|
135
51
|
def reset_computed_values
|
136
|
-
|
137
|
-
instance_variable_set "@computed_#{key}", nil
|
138
|
-
instance_variable_set "@computed_inner_#{key}", nil
|
139
|
-
end
|
52
|
+
@computed_frame = nil
|
140
53
|
end
|
141
54
|
|
142
55
|
class << self
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module MotionPrime
|
2
|
+
module DrawBackgroundMixin
|
3
|
+
def draw_background_in(rect, options)
|
4
|
+
bg_color = options[:background_color]
|
5
|
+
border_radius = options[:layer].try(:[], :corner_radius)
|
6
|
+
border_width = options[:layer].try(:[], :border_width).to_f
|
7
|
+
border_color = options[:layer].try(:[], :border_color) || bg_color || :black
|
8
|
+
|
9
|
+
if bg_color || border_width > 0
|
10
|
+
context = UIGraphicsGetCurrentContext()
|
11
|
+
CGContextSetFillColorWithColor(context, bg_color.uicolor.cgcolor) if bg_color
|
12
|
+
CGContextSetLineWidth(context, border_width) if border_width > 0
|
13
|
+
CGContextSetStrokeColorWithColor(context, border_color.uicolor.cgcolor) if border_color
|
14
|
+
|
15
|
+
if border_radius
|
16
|
+
bezierPath = UIBezierPath.bezierPathWithRoundedRect rect, cornerRadius: border_radius
|
17
|
+
bezierPath.stroke if border_width > 0
|
18
|
+
bezierPath.fill if bg_color
|
19
|
+
else
|
20
|
+
CGContextStrokeRect(context, rect) if border_width > 0
|
21
|
+
CGContextFillRect(context, rect) if bg_color
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,15 +1,24 @@
|
|
1
1
|
motion_require '../draw.rb'
|
2
2
|
module MotionPrime
|
3
3
|
class ImageDrawElement < DrawElement
|
4
|
+
include DrawBackgroundMixin
|
4
5
|
attr_accessor :image_data
|
6
|
+
|
5
7
|
def draw_in(rect)
|
6
8
|
return if computed_options[:hidden]
|
9
|
+
options = computed_options
|
7
10
|
image_rect = CGRectMake(
|
8
11
|
computed_left,
|
9
12
|
computed_top,
|
10
13
|
computed_width,
|
11
14
|
computed_height
|
12
15
|
)
|
16
|
+
|
17
|
+
image_rect = CGRectInset(image_rect, -0.5, -0.5)
|
18
|
+
border_width = options[:layer].try(:[], :border_width).to_f
|
19
|
+
background_rect = CGRectInset(image_rect, -(border_width - 1)*0.5, -(border_width - 1)*0.5)
|
20
|
+
draw_background_in(background_rect, options)
|
21
|
+
|
13
22
|
# draw already initialized image
|
14
23
|
if image_data
|
15
24
|
draw_with_layer(image_data, image_rect)
|
@@ -48,8 +57,8 @@ module MotionPrime
|
|
48
57
|
layer.frame = CGRectMake(0, 0, image.size.width, image.size.height)
|
49
58
|
layer.contents = image.CGImage
|
50
59
|
|
60
|
+
layer.masksToBounds = computed_options[:layer][:masks_to_bounds] || computed_options[:clips_to_bounds]
|
51
61
|
if radius = computed_options[:layer][:corner_radius]
|
52
|
-
layer.masksToBounds = true
|
53
62
|
k = image.size.width / rect.size.width
|
54
63
|
radius = radius * k
|
55
64
|
layer.cornerRadius = radius
|