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
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZmRjMGMyMTFiMjJjYjBjYmY4OGMyMDM1YjJiZDRlYTNhMWI0NGJlMw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MGEzNDAwZDRmZTI1OGJmNGZiM2Y2ODhiMzJlYjAzNjBjYzljYmZmYw==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OGFkMjM1MGQ3ZjhhOWU2NTY4ZGU4MWI5YjRhYzhkMDZjYmExODYyNjQxMmY4
|
10
|
+
MTE2NDM1NzhjNDAzNTRiZGFmZWQyNDE1YWNhYjQwODZiMGRmZmUyZDUwZmJk
|
11
|
+
Y2VhODNiYWJjMjRlZGI2Y2Y5NDI5NjdmOThjYjNhNmRiYWUyZWI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
OWRhNzY3MjQ1NzY1M2I5MWEwOGYwOTdiZjI4YzdhOTU0Zjc2YzkyYjdlNzc3
|
14
|
+
MmFkNzFlZDFjMDg1ODYwMjUyYWMwM2E3ZGVlMzQ1ZDAxOGZiZDFjOWRhZWNh
|
15
|
+
ZjIxMTJjOGJlNjQ2NTk3ZGY3MDEzNWE0YWM4MmRkMDdhNWZjMDk=
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/ROADMAP.md
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
=== 0.
|
1
|
+
=== 0.5.0
|
2
2
|
* rename support/dm_* to support/mp_*
|
3
3
|
* "id" attribute should always be added to model by default
|
4
4
|
* add DSL for ViewStyles#setValue conditions
|
5
5
|
* add auto-symbol-value for Prime::Config.color items
|
6
6
|
|
7
|
-
=== 0.
|
7
|
+
=== 0.6.0
|
8
8
|
* add testing framework
|
9
9
|
* add auth backends to ApiClient: password auth and facebook auth
|
10
10
|
|
11
|
-
=== 0.
|
11
|
+
=== 0.7.0
|
12
12
|
* add sections/screens/models generator
|
data/doc/code/getting_started.rb
CHANGED
@@ -21,13 +21,14 @@ end
|
|
21
21
|
# **3. Create the main screen.**
|
22
22
|
#
|
23
23
|
# You should rewrite the `render` method, which will be runned after opening screen.
|
24
|
+
# Note: you must always pass `screen` option, which points to screen to render
|
24
25
|
|
25
26
|
class MainScreen < Prime::BaseScreen
|
26
27
|
title 'Main screen'
|
27
28
|
|
28
29
|
def render
|
29
|
-
@main_section = MyProfileSection.new(model: User.first)
|
30
|
-
@main_section.render
|
30
|
+
@main_section = MyProfileSection.new(screen: self, model: User.first)
|
31
|
+
@main_section.render
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
@@ -35,7 +36,7 @@ end
|
|
35
36
|
#
|
36
37
|
# "Section" is something like helper, which contains "Elements".
|
37
38
|
#
|
38
|
-
# Each element will be added to the parent screen when you run `section.render
|
39
|
+
# Each element will be added to the parent screen when you run `section.render`
|
39
40
|
|
40
41
|
class MyProfileSection < Prime::BaseSection
|
41
42
|
element :title, text: "Hello World"
|
@@ -44,10 +45,10 @@ end
|
|
44
45
|
|
45
46
|
# **5. Create your first stylesheet file.**
|
46
47
|
#
|
47
|
-
# Styles will be applied to each element in section.
|
48
|
+
# Styles will be applied to each element in section.
|
48
49
|
# The simplest rule by default is: `:section-name_:element-name`.
|
49
50
|
#
|
50
|
-
# E.g. if you have 'MyProfileSection' (the name for section by default will be - `my_profile`)
|
51
|
+
# E.g. if you have 'MyProfileSection' (the name for section by default will be - `my_profile`)
|
51
52
|
# and 'title' element, then you should use `my_profile_title` style name.
|
52
53
|
|
53
54
|
Prime::Styles.define do
|
data/motion-prime/api_client.rb
CHANGED
@@ -32,16 +32,24 @@ module MotionPrime
|
|
32
32
|
content_padding_left + content_padding_right
|
33
33
|
end
|
34
34
|
|
35
|
-
def content_outer_height
|
36
|
-
height = content_padding_height + content_height
|
35
|
+
def content_outer_height(cached = false)
|
36
|
+
height = content_padding_height + (cached ? cached_content_height : content_height)
|
37
37
|
[[height, computed_options[:min_outer_height]].compact.max, computed_options[:max_outer_height]].compact.min
|
38
38
|
end
|
39
39
|
|
40
|
-
def
|
41
|
-
|
40
|
+
def cached_content_outer_height
|
41
|
+
content_outer_height(true)
|
42
|
+
end
|
43
|
+
|
44
|
+
def content_outer_width(cached = false)
|
45
|
+
width = content_padding_width + (cached ? cached_content_width : content_width)
|
42
46
|
[[width, computed_options[:min_outer_width]].compact.max, computed_options[:max_outer_width]].compact.min
|
43
47
|
end
|
44
48
|
|
49
|
+
def cached_content_outer_width
|
50
|
+
content_outer_width(true)
|
51
|
+
end
|
52
|
+
|
45
53
|
def default_padding_for(side)
|
46
54
|
view_class.constantize.send(:"default_padding_#{side}")
|
47
55
|
end
|
@@ -13,14 +13,22 @@ module MotionPrime
|
|
13
13
|
return min if content_text.blank?
|
14
14
|
|
15
15
|
rect = get_content_rect(Float::MAX)
|
16
|
-
[[rect.size.width.ceil, max].compact.min, min].max.ceil
|
16
|
+
@content_width = [[rect.size.width.ceil, max].compact.min, min].max.ceil
|
17
|
+
end
|
18
|
+
|
19
|
+
def cached_content_width
|
20
|
+
@content_width ||= content_width
|
17
21
|
end
|
18
22
|
|
19
23
|
def content_height
|
20
24
|
min, max = computed_options[:min_height].to_f, computed_options[:max_height]
|
21
25
|
return min if content_text.blank?
|
22
26
|
rect = get_content_rect(computed_options[:width])
|
23
|
-
[[rect.size.height.ceil, max].compact.min, min].max.ceil
|
27
|
+
@content_height = [[rect.size.height.ceil, max].compact.min, min].max.ceil
|
28
|
+
end
|
29
|
+
|
30
|
+
def cached_content_height
|
31
|
+
@content_height ||= content_height
|
24
32
|
end
|
25
33
|
|
26
34
|
private
|
@@ -16,23 +16,25 @@ module MotionPrime
|
|
16
16
|
|
17
17
|
def initialize(options = {})
|
18
18
|
@options = options
|
19
|
+
@screen = options[:screen]
|
19
20
|
@section = options[:section]
|
20
21
|
@name = options[:name]
|
21
22
|
@block = options[:block]
|
22
23
|
@view_class = options[:view_class] || "UIView"
|
23
|
-
@view_name = self.class_name_without_kvo.demodulize.underscore.gsub(
|
24
|
+
@view_name = self.class_name_without_kvo.demodulize.underscore.gsub(/(_draw)?_element/, '')
|
24
25
|
end
|
25
26
|
|
26
27
|
def render(options = {}, &block)
|
27
|
-
@screen = options[:to]
|
28
28
|
run_callbacks :render do
|
29
29
|
render!(&block)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
33
|
def render!(&block)
|
34
|
-
|
35
|
-
|
34
|
+
screen.add_view view_class.constantize, computed_options do |view|
|
35
|
+
@view = view
|
36
|
+
block.try(:call, view, self)
|
37
|
+
end
|
36
38
|
end
|
37
39
|
|
38
40
|
# Lazy-computing options
|
@@ -45,7 +47,7 @@ module MotionPrime
|
|
45
47
|
@computed_options ||= {}
|
46
48
|
block_options = compute_block_options || {}
|
47
49
|
compute_style_options(options, block_options)
|
48
|
-
@computed_options.merge!(options.except(:
|
50
|
+
@computed_options.merge!(options.except(:screen, :name, :block, :view_class))
|
49
51
|
@computed_options.merge!(block_options)
|
50
52
|
normalize_options(@computed_options, section, %w[text placeholder font title_label padding padding_left padding_right min_width min_outer_width max_width max_outer_width width left right])
|
51
53
|
end
|
@@ -60,7 +62,7 @@ module MotionPrime
|
|
60
62
|
|
61
63
|
def compute_style_options(*style_sources)
|
62
64
|
has_errors = section.respond_to?(:observing_errors?) && observing_errors? && has_errors?
|
63
|
-
is_cell_section = section.
|
65
|
+
is_cell_section = section.respond_to?(:cell_name)
|
64
66
|
|
65
67
|
@styles = []
|
66
68
|
if is_cell_section
|
@@ -132,7 +134,7 @@ module MotionPrime
|
|
132
134
|
compute_options!
|
133
135
|
view.try(:removeFromSuperview)
|
134
136
|
@view = nil
|
135
|
-
render
|
137
|
+
render
|
136
138
|
end
|
137
139
|
|
138
140
|
def hide
|
@@ -143,6 +145,13 @@ module MotionPrime
|
|
143
145
|
view.hidden = false
|
144
146
|
end
|
145
147
|
|
148
|
+
def bind_gesture(action, receiver = nil)
|
149
|
+
receiver ||= self
|
150
|
+
single_tap = UITapGestureRecognizer.alloc.initWithTarget(receiver, action: action)
|
151
|
+
view.addGestureRecognizer single_tap
|
152
|
+
view.setUserInteractionEnabled true
|
153
|
+
end
|
154
|
+
|
146
155
|
class << self
|
147
156
|
def factory(type, options = {})
|
148
157
|
class_name = "#{type.classify}Element"
|
@@ -1,23 +1,34 @@
|
|
1
1
|
module MotionPrime
|
2
2
|
module DrawBackgroundMixin
|
3
|
-
def draw_background_in(
|
3
|
+
def draw_background_in(draw_rect, options)
|
4
|
+
|
4
5
|
bg_color = options[:background_color]
|
5
6
|
border_radius = options[:layer].try(:[], :corner_radius)
|
6
7
|
border_width = options[:layer].try(:[], :border_width).to_f
|
7
8
|
border_color = options[:layer].try(:[], :border_color) || bg_color || :black
|
8
9
|
|
9
|
-
|
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
|
10
|
+
rect = CGRectInset(draw_rect, -(border_width - 1)*0.5, -(border_width - 1)*0.5)
|
14
11
|
|
12
|
+
if bg_color || border_width > 0
|
15
13
|
if border_radius
|
16
14
|
bezierPath = UIBezierPath.bezierPathWithRoundedRect rect, cornerRadius: border_radius
|
17
|
-
|
18
|
-
|
15
|
+
if border_width > 0
|
16
|
+
bezierPath.lineWidth = border_width
|
17
|
+
border_color.uicolor.setStroke
|
18
|
+
bezierPath.stroke
|
19
|
+
end
|
20
|
+
if bg_color
|
21
|
+
bg_color.uicolor.setFill
|
22
|
+
bezierPath.fill
|
23
|
+
end
|
19
24
|
else
|
20
|
-
|
25
|
+
context = UIGraphicsGetCurrentContext()
|
26
|
+
if border_width > 0 && border_color
|
27
|
+
CGContextSetLineWidth(context, border_width)
|
28
|
+
CGContextSetStrokeColorWithColor(context, border_color.uicolor.cgcolor)
|
29
|
+
CGContextStrokeRect(context, rect)
|
30
|
+
end
|
31
|
+
CGContextSetFillColorWithColor(context, bg_color.uicolor.cgcolor) if bg_color
|
21
32
|
CGContextFillRect(context, rect) if bg_color
|
22
33
|
end
|
23
34
|
end
|
@@ -16,8 +16,8 @@ module MotionPrime
|
|
16
16
|
|
17
17
|
image_rect = CGRectInset(image_rect, -0.5, -0.5)
|
18
18
|
border_width = options[:layer].try(:[], :border_width).to_f
|
19
|
-
|
20
|
-
draw_background_in(
|
19
|
+
|
20
|
+
draw_background_in(image_rect, options)
|
21
21
|
|
22
22
|
# draw already initialized image
|
23
23
|
if image_data
|
@@ -10,10 +10,11 @@ module MotionPrime
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def draw_in(rect)
|
13
|
-
return if computed_options[:hidden]
|
14
13
|
size_to_fit_if_needed or set_text_position
|
15
14
|
options = computed_options
|
16
15
|
|
16
|
+
return if computed_options[:hidden]
|
17
|
+
|
17
18
|
# render background and border
|
18
19
|
background_rect = CGRectMake(computed_left, computed_top, computed_outer_width, computed_outer_height)
|
19
20
|
draw_background_in(background_rect, options)
|
@@ -22,8 +23,8 @@ module MotionPrime
|
|
22
23
|
color = (options[:text_color] || :black).uicolor
|
23
24
|
font = (options[:font] || :system).uifont
|
24
25
|
alignment = (options.has_key?(:text_alignment) ? options[:text_alignment] : :left).uitextalignment
|
25
|
-
line_break_mode = (options.has_key?(:line_break_mode) ? options[:line_break_mode] : :
|
26
|
-
label_text = options[:text].to_s
|
26
|
+
line_break_mode = (options.has_key?(:line_break_mode) ? options[:line_break_mode] : :tailtruncation).uilinebreakmode
|
27
|
+
label_text = options[:text].to_s.gsub(/^[\n\r]+/, '')
|
27
28
|
|
28
29
|
top_left_corner = CGPointMake(computed_inner_left, computed_inner_top)
|
29
30
|
if options[:number_of_lines].to_i.zero?
|
@@ -66,9 +67,9 @@ module MotionPrime
|
|
66
67
|
|
67
68
|
def size_to_fit_if_needed
|
68
69
|
if computed_options[:size_to_fit]
|
69
|
-
|
70
|
+
computed_options[:width] ||= cached_content_outer_width
|
70
71
|
if computed_options[:width]
|
71
|
-
|
72
|
+
computed_options[:height] ||= cached_content_outer_height
|
72
73
|
end
|
73
74
|
reset_computed_values
|
74
75
|
true
|
@@ -78,7 +79,7 @@ module MotionPrime
|
|
78
79
|
def set_text_position
|
79
80
|
if computed_options.slice(:padding_top, :padding_bottom, :padding).none?
|
80
81
|
computed_options[:width] ||= computed_width
|
81
|
-
@padding_top = (computed_outer_height -
|
82
|
+
@padding_top = (computed_outer_height - cached_content_height)/2
|
82
83
|
# @padding_top += 1 unless @padding_top.zero?
|
83
84
|
end
|
84
85
|
end
|
@@ -47,13 +47,18 @@ module MotionPrime
|
|
47
47
|
def computed_right; computed_left + computed_width end
|
48
48
|
def computed_inner_right; computed_right - content_padding_right end
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
@computed_frame = nil
|
50
|
+
def bind_gesture(action, receiver = nil)
|
51
|
+
section.bind_gesture_on_container_for(self, action, receiver)
|
53
52
|
end
|
54
53
|
|
54
|
+
private
|
55
|
+
def reset_computed_values
|
56
|
+
@computed_frame = nil
|
57
|
+
end
|
58
|
+
|
55
59
|
class << self
|
56
60
|
def factory(type, options = {})
|
61
|
+
return unless %w[View Label Image].include?(type.classify)
|
57
62
|
class_name = "#{type.classify}DrawElement"
|
58
63
|
"MotionPrime::#{class_name}".constantize.new(options)
|
59
64
|
end
|
@@ -13,7 +13,7 @@ module MotionPrime
|
|
13
13
|
def size_to_fit
|
14
14
|
if computed_options[:size_to_fit] || style_options[:size_to_fit]
|
15
15
|
if computed_options[:width]
|
16
|
-
view.setHeight([
|
16
|
+
view.setHeight([cached_content_outer_height, computed_options[:height]].compact.min)
|
17
17
|
else
|
18
18
|
view.sizeToFit
|
19
19
|
# we should re-set values, because sizeToFit do not use padding
|
@@ -25,7 +25,7 @@ module MotionPrime
|
|
25
25
|
|
26
26
|
def size_to_fit_if_needed
|
27
27
|
if computed_options[:size_to_fit] && computed_options[:width]
|
28
|
-
@computed_options[:height_to_fit] =
|
28
|
+
@computed_options[:height_to_fit] = cached_content_outer_height
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -4,13 +4,7 @@ module MotionPrime
|
|
4
4
|
colors = options[:colors].map(&:uicolor).map(&:cgcolor)
|
5
5
|
locations = options[:locations] if options[:locations]
|
6
6
|
|
7
|
-
if self.is_a?(
|
8
|
-
color_space = CGColorSpaceCreateDeviceRGB()
|
9
|
-
locations_pointer = Pointer.new(:float, 2)
|
10
|
-
locations.each_with_index { |loc, id| locations_pointer[id] = loc }
|
11
|
-
gradient = CGGradientCreateWithColors(color_space, colors, locations_pointer)
|
12
|
-
# CGColorSpaceRelease(color_space)
|
13
|
-
else
|
7
|
+
if self.is_a?(ViewStyler)
|
14
8
|
gradient = CAGradientLayer.layer
|
15
9
|
|
16
10
|
gradient.frame = if options[:frame_width]
|
@@ -21,6 +15,12 @@ module MotionPrime
|
|
21
15
|
|
22
16
|
gradient.colors = colors
|
23
17
|
gradient.locations = locations
|
18
|
+
else
|
19
|
+
color_space = CGColorSpaceCreateDeviceRGB()
|
20
|
+
locations_pointer = Pointer.new(:float, 2)
|
21
|
+
locations.each_with_index { |loc, id| locations_pointer[id] = loc }
|
22
|
+
gradient = CGGradientCreateWithColors(color_space, colors, locations_pointer)
|
23
|
+
# CGColorSpaceRelease(color_space)
|
24
24
|
end
|
25
25
|
gradient
|
26
26
|
end
|
@@ -31,7 +31,7 @@ module MotionPrime
|
|
31
31
|
if has_attribute?(k)
|
32
32
|
assign_attribute(k, v) unless options[:skip_nil_values] && v.nil?
|
33
33
|
elsif options[:check_attribute_presence]
|
34
|
-
|
34
|
+
NSLog("unknown attribute: #{k}")
|
35
35
|
else
|
36
36
|
raise(NoMethodError, "unknown attribute: #{k}")
|
37
37
|
end
|
data/motion-prime/models/sync.rb
CHANGED
@@ -56,18 +56,18 @@ module MotionPrime
|
|
56
56
|
|
57
57
|
fetch_with_url url do |data, status_code|
|
58
58
|
save if sync_options[:save]
|
59
|
-
block.call(data, status_code) if use_callback
|
59
|
+
block.call(data, status_code, data) if use_callback
|
60
60
|
end if should_fetch
|
61
61
|
|
62
62
|
update_with_url url, sync_options do |data, status_code|
|
63
63
|
save if sync_options[:save] && status_code.to_s =~ /20\d/
|
64
64
|
# run callback only if it wasn't run on fetch
|
65
|
-
block.call(data, status_code) if use_callback && !should_fetch
|
65
|
+
block.call(data, status_code, data) if use_callback && !should_fetch
|
66
66
|
end if should_update
|
67
67
|
|
68
68
|
fetch_associations(sync_options) do |data, status_code|
|
69
69
|
# run callback only if it wasn't run on fetch or update
|
70
|
-
block.call(data, status_code) if use_callback && !should_fetch && !should_update
|
70
|
+
block.call(data, status_code, data) if use_callback && !should_fetch && !should_update
|
71
71
|
end if should_fetch_associations
|
72
72
|
end
|
73
73
|
|
@@ -76,7 +76,7 @@ module MotionPrime
|
|
76
76
|
use_callback = block_given?
|
77
77
|
api_client.get(url) do |data, status_code|
|
78
78
|
fetch_with_attributes(data, &block) if data.present?
|
79
|
-
block.call(data, status_code) if use_callback
|
79
|
+
block.call(data, status_code, data) if use_callback
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
@@ -98,7 +98,7 @@ module MotionPrime
|
|
98
98
|
if update_from_response && status_code.to_s =~ /20\d/ && data.is_a?(Hash)
|
99
99
|
set_attributes_from_response(data)
|
100
100
|
end
|
101
|
-
block.call(data, status_code) if use_callback
|
101
|
+
block.call(data, status_code, data) if use_callback
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
@@ -153,7 +153,7 @@ module MotionPrime
|
|
153
153
|
old_collection = self.send(key)
|
154
154
|
|
155
155
|
use_callback = block_given?
|
156
|
-
|
156
|
+
NSLog("SYNC: started sync for #{key} in #{self.class_name_without_kvo}")
|
157
157
|
api_client.get normalize_sync_url(options[:sync_url]) do |response, status_code|
|
158
158
|
data = options[:sync_key] && response ? response[options[:sync_key]] : response
|
159
159
|
if data
|
@@ -174,10 +174,10 @@ module MotionPrime
|
|
174
174
|
end
|
175
175
|
end
|
176
176
|
save if sync_options[:save]
|
177
|
-
|
177
|
+
NSLog("SYNC: finished sync for #{key} in #{self.class_name_without_kvo}")
|
178
178
|
block.call(data, status_code, response) if use_callback
|
179
179
|
else
|
180
|
-
|
180
|
+
NSLog("SYNC ERROR: failed sync for #{key} in #{self.class_name_without_kvo}")
|
181
181
|
block.call(data, status_code, response) if use_callback
|
182
182
|
end
|
183
183
|
end
|
@@ -185,7 +185,7 @@ module MotionPrime
|
|
185
185
|
|
186
186
|
def fetch_has_one(key, options = {}, &block)
|
187
187
|
use_callback = block_given?
|
188
|
-
|
188
|
+
NSLog("SYNC: started sync for #{key} in #{self.class_name_without_kvo}")
|
189
189
|
api_client.get normalize_sync_url(options[:sync_url]) do |response, status_code|
|
190
190
|
data = options.has_key?(:sync_key) ? response[options[:sync_key]] : response
|
191
191
|
if data.present?
|
@@ -198,7 +198,7 @@ module MotionPrime
|
|
198
198
|
model.save if sync_options[:save]
|
199
199
|
block.call(data, status_code, response) if use_callback
|
200
200
|
else
|
201
|
-
|
201
|
+
NSLog("SYNC ERROR: failed sync for #{key} in #{self.class_name_without_kvo}")
|
202
202
|
block.call(data, status_code, response) if use_callback
|
203
203
|
end
|
204
204
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module MotionPrime
|
2
|
+
module DrawMixin
|
3
|
+
include HasStyles
|
4
|
+
attr_accessor :container_element, :container_gesture_recognizers
|
5
|
+
|
6
|
+
def container_view
|
7
|
+
container_element.try(:view)
|
8
|
+
end
|
9
|
+
|
10
|
+
def draw_in(rect)
|
11
|
+
draw_background(rect)
|
12
|
+
draw_elements(rect)
|
13
|
+
end
|
14
|
+
|
15
|
+
def bind_gesture_on_container_for(element, action, receiver = nil)
|
16
|
+
self.container_gesture_recognizers ||= begin
|
17
|
+
set_container_gesture_recognizer
|
18
|
+
[]
|
19
|
+
end
|
20
|
+
self.container_gesture_recognizers << {element: element, action: action, receiver: receiver}
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def set_container_gesture_recognizer
|
25
|
+
single_tap = UITapGestureRecognizer.alloc.initWithTarget(self, action: 'on_container_tap_gesture:')
|
26
|
+
single_tap.cancelsTouchesInView = false
|
27
|
+
container_view.addGestureRecognizer single_tap
|
28
|
+
container_view.setUserInteractionEnabled true
|
29
|
+
end
|
30
|
+
|
31
|
+
def on_container_tap_gesture(recognizer)
|
32
|
+
target = Array.wrap(container_gesture_recognizers).detect do |gesture_data|
|
33
|
+
CGRectContainsPoint(gesture_data[:element].computed_frame, recognizer.locationInView(container_view))
|
34
|
+
end
|
35
|
+
(target[:receiver] || self).send(target[:action], recognizer, target[:element]) if target
|
36
|
+
end
|
37
|
+
|
38
|
+
def draw_elements(rect)
|
39
|
+
elements_to_draw.each do |key, element|
|
40
|
+
element.draw_in(rect)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def view_style_options
|
45
|
+
@view_style_options ||= begin
|
46
|
+
options = Styles.for(container_options[:styles])
|
47
|
+
normalize_options(options)
|
48
|
+
options
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def draw_background(rect)
|
53
|
+
options = container_element.computed_options
|
54
|
+
|
55
|
+
if gradient_options = options[:gradient]
|
56
|
+
start_point = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect))
|
57
|
+
end_point = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect))
|
58
|
+
|
59
|
+
context = UIGraphicsGetCurrentContext()
|
60
|
+
# CGContextSaveGState(context)
|
61
|
+
CGContextAddRect(context, rect)
|
62
|
+
CGContextClip(context)
|
63
|
+
gradient = prepare_gradient(gradient_options)
|
64
|
+
CGContextDrawLinearGradient(context, gradient, start_point, end_point, 0)
|
65
|
+
# CGContextRestoreGState(context)
|
66
|
+
elsif background_color = options[:background_color]
|
67
|
+
unless background_color.uicolor == :clear.uicolor
|
68
|
+
background_color.uicolor.setFill
|
69
|
+
UIRectFill(rect)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|