motion-prime 0.5.6 → 0.5.7
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 +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +8 -3
- data/bin/prime +1 -1
- data/doc/code/getting_started.rb +53 -11
- data/doc/code/models.rb +32 -0
- data/doc/code/screens.rb +25 -19
- data/doc/code/sections.rb +27 -3
- data/doc/docs/docco.css +116 -279
- data/doc/docs/getting_started.html +125 -141
- data/doc/docs/models.html +102 -0
- data/doc/docs/public/fonts/fleurons.eot +0 -0
- data/doc/docs/public/fonts/fleurons.ttf +0 -0
- data/doc/docs/public/fonts/fleurons.woff +0 -0
- data/doc/docs/public/images/gray.png +0 -0
- data/doc/docs/screens.html +114 -167
- data/doc/docs/sections.html +90 -93
- data/files/Gemfile +1 -1
- data/files/Gemfile.lock +2 -2
- data/files/app/screens/{application_screen.rb → application.rb} +0 -0
- data/files/app/screens/{help_screen.rb → help.rb} +0 -0
- data/files/app/screens/{home_screen.rb → home.rb} +0 -0
- data/files/app/screens/{sidebar_screen.rb → sidebar.rb} +0 -0
- data/motion-prime/core_ext/time.rb +10 -0
- data/motion-prime/models/_association_mixin.rb +4 -0
- data/motion-prime/models/_base_mixin.rb +12 -3
- data/motion-prime/models/_dirty_mixin.rb +7 -1
- data/motion-prime/models/_nano_bag_mixin.rb +9 -2
- data/motion-prime/models/_sync_mixin.rb +24 -19
- data/motion-prime/sections/base_section.rb +17 -10
- data/motion-prime/version.rb +1 -1
- metadata +13 -6
data/doc/docs/sections.html
CHANGED
@@ -4,56 +4,59 @@
|
|
4
4
|
<head>
|
5
5
|
<title>sections.rb</title>
|
6
6
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
7
|
-
<
|
7
|
+
<link rel="stylesheet" media="all" href="public/stylesheets/normalize.css" />
|
8
8
|
<link rel="stylesheet" media="all" href="docco.css" />
|
9
9
|
</head>
|
10
10
|
<body>
|
11
|
-
<div
|
12
|
-
<div
|
13
|
-
|
14
|
-
<
|
15
|
-
|
16
|
-
<
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
11
|
+
<div class="container">
|
12
|
+
<div class="page">
|
13
|
+
|
14
|
+
<div class="header">
|
15
|
+
|
16
|
+
<h1>sections.rb</h1>
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
<div class="toc">
|
21
|
+
<h3>Table of Contents</h3>
|
22
|
+
<ol>
|
23
|
+
|
24
|
+
|
25
|
+
<li>
|
26
|
+
<a class="source" href="getting_started.html">
|
27
|
+
getting_started.rb
|
28
|
+
</a>
|
29
|
+
</li>
|
30
|
+
|
31
|
+
|
32
|
+
<li>
|
33
|
+
<a class="source" href="models.html">
|
34
|
+
models.rb
|
35
|
+
</a>
|
36
|
+
</li>
|
21
37
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
38
|
+
|
39
|
+
<li>
|
40
|
+
<a class="source" href="screens.html">
|
41
|
+
screens.rb
|
42
|
+
</a>
|
43
|
+
</li>
|
26
44
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
45
|
+
|
46
|
+
<li>
|
47
|
+
<a class="source" href="sections.html">
|
48
|
+
sections.rb
|
49
|
+
</a>
|
50
|
+
</li>
|
31
51
|
|
32
|
-
|
33
|
-
sections.rb
|
34
|
-
</a>
|
35
|
-
|
52
|
+
</ol>
|
36
53
|
</div>
|
37
|
-
</li>
|
38
|
-
</ul>
|
39
|
-
|
40
|
-
<ul class="sections">
|
41
|
-
|
42
|
-
<li id="title">
|
43
|
-
<div class="annotation">
|
44
|
-
<h1>sections.rb</h1>
|
45
|
-
</div>
|
46
|
-
</li>
|
47
|
-
|
48
54
|
|
55
|
+
</div>
|
56
|
+
|
57
|
+
|
49
58
|
|
50
|
-
<
|
51
|
-
<div class="annotation">
|
52
|
-
|
53
|
-
<div class="pilwrap ">
|
54
|
-
<a class="pilcrow" href="#section-1">¶</a>
|
55
|
-
</div>
|
56
|
-
<p><strong> What is a Section? </strong></p>
|
59
|
+
<p><strong> What is a Section? </strong></p>
|
57
60
|
<p>"Section" is something like "partial" which you may know from RubyOnRails.
|
58
61
|
In the first look it's just a list of elements which will be added to the "Screen".
|
59
62
|
But the magic is inside.
|
@@ -61,74 +64,68 @@ When you add "Element" to a "Section", e.g. image or label,
|
|
61
64
|
it will try to draw it using CALayer/CGContext/etc, instead of adding new UIView.
|
62
65
|
That way increases application speed (especially on Table elements) by 5-10 times.</p>
|
63
66
|
<p>Let's get started.</p>
|
64
|
-
|
65
|
-
</div>
|
66
|
-
|
67
|
-
<div class="content"><div class='highlight'><pre>---</pre></div></div>
|
68
|
-
|
69
|
-
</li>
|
70
|
-
|
71
|
-
|
72
|
-
<li id="section-2">
|
73
|
-
<div class="annotation">
|
74
|
-
|
75
|
-
<div class="pilwrap ">
|
76
|
-
<a class="pilcrow" href="#section-2">¶</a>
|
77
|
-
</div>
|
78
|
-
<p><strong> Create a section. </strong></p>
|
67
|
+
<p><strong> Create a section. </strong></p>
|
79
68
|
<p>Just inherit it from <code>Prime::Section</code>.</p>
|
80
69
|
|
81
|
-
</div>
|
82
|
-
|
83
|
-
<div class="content"><div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">FooSection</span> <span class="inheritance">< <span class="parent">Prime::Section</span></span></span>
|
84
|
-
<span class="keyword">end</span></pre></div></div>
|
85
|
-
|
86
|
-
</li>
|
87
70
|
|
71
|
+
<div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">FooSection</span> <span class="inheritance">< <span class="parent">Prime::Section</span></span></span>
|
72
|
+
<span class="keyword">end</span></pre></div>
|
88
73
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
<p><strong> Add some elements to the section. </strong></p>
|
96
|
-
<p>Each element should have name and type: "image", "label", "button", etc.
|
97
|
-
When you send <code>:text</code> option, type will be "label" by default.
|
98
|
-
When you send <code>:image</code> option, type will be "image" by default.</p>
|
74
|
+
|
75
|
+
|
76
|
+
<p><strong> Add some elements to the section. </strong></p>
|
77
|
+
<p>Each element should have name and type: "image", "label", "button", etc. </p>
|
78
|
+
<p>When you send <code>:text</code> option, type will be "label" by default.</p>
|
79
|
+
<p>When you send <code>:image</code> option, type will be "image" by default.</p>
|
99
80
|
|
100
|
-
|
101
|
-
|
102
|
-
<div class="content"><div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">FooSection</span> <span class="inheritance">< <span class="parent">Prime::Section</span></span></span>
|
81
|
+
|
82
|
+
<div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">FooSection</span> <span class="inheritance">< <span class="parent">Prime::Section</span></span></span>
|
103
83
|
element <span class="symbol">:welcome</span>, <span class="symbol">text:</span> <span class="string">'Hello World!'</span>
|
104
84
|
element <span class="symbol">:avatar</span>, <span class="symbol">image:</span> <span class="string">'images/users/avatar.jpg'</span>
|
105
85
|
element <span class="symbol">:cheer</span>, <span class="symbol">type:</span> <span class="symbol">:button</span>
|
106
|
-
<span class="keyword">end</span></pre></div
|
107
|
-
|
108
|
-
</li>
|
86
|
+
<span class="keyword">end</span></pre></div>
|
109
87
|
|
88
|
+
|
110
89
|
|
111
|
-
<
|
112
|
-
|
113
|
-
|
114
|
-
<div class="pilwrap ">
|
115
|
-
<a class="pilcrow" href="#section-4">¶</a>
|
116
|
-
</div>
|
117
|
-
<p><strong> Render Section in Screen </strong></p>
|
118
|
-
<p>NOTE: You must send "screen" option on section initialization.</p>
|
90
|
+
<p><strong> Render Section to Screen </strong></p>
|
91
|
+
<p>NOTE: it's recommended to use instance variables for sections, e.g. <code>@main_section</code> instead of <code>main_section</code>.</p>
|
119
92
|
|
120
|
-
|
121
|
-
|
122
|
-
<div class="content"><div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">FooScreen</span> <span class="inheritance">< <span class="parent">Prime::Screen</span></span></span>
|
93
|
+
|
94
|
+
<div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">FooScreen</span> <span class="inheritance">< <span class="parent">Prime::Screen</span></span></span>
|
123
95
|
<span class="function"><span class="keyword">def</span> <span class="title">render</span></span>
|
124
96
|
<span class="variable">@main_section</span> = <span class="constant">FooSection</span>.new(<span class="symbol">screen:</span> <span class="keyword">self</span>)
|
125
97
|
<span class="variable">@main_section</span>.render
|
126
98
|
<span class="keyword">end</span>
|
127
|
-
<span class="keyword">end</span></pre></div
|
128
|
-
|
129
|
-
|
99
|
+
<span class="keyword">end</span></pre></div>
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
<p><strong> Add some styles for section </strong></p>
|
104
|
+
<p>Generally styles are just attributes of UIView elements.</p>
|
105
|
+
<p>Let's style the UILabel element (:welcome label element we added above.)</p>
|
106
|
+
<p>We send :foo parameter to <code>define</code>, because we have section named <code>foo</code> (FooSection)
|
107
|
+
and :welcome parameter to <code>style</code>, because the name of element is <code>welcome</code>.</p>
|
108
|
+
|
109
|
+
|
110
|
+
<div class='highlight'><pre><span class="constant">Prime::Styles</span>.define <span class="symbol">:foo</span> <span class="keyword">do</span>
|
111
|
+
style <span class="symbol">:welcome</span>,
|
112
|
+
<span class="symbol">text_color:</span> <span class="symbol">:black</span>,
|
113
|
+
<span class="symbol">top:</span> <span class="number">100</span>,
|
114
|
+
<span class="symbol">width:</span> <span class="number">320</span>,
|
115
|
+
<span class="symbol">left:</span> <span class="number">20</span>,
|
116
|
+
<span class="symbol">font:</span> proc { <span class="symbol">:system</span>.uifont(<span class="number">20</span>) },
|
117
|
+
<span class="symbol">size_to_fit:</span> <span class="keyword">true</span>,
|
118
|
+
<span class="keyword">end</span></pre></div>
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
<p><strong> Next </strong></p>
|
123
|
+
<p><a href="models.html">Read more about Models</a></p>
|
124
|
+
|
130
125
|
|
131
|
-
|
126
|
+
|
127
|
+
<div class="fleur">h</div>
|
128
|
+
</div>
|
132
129
|
</div>
|
133
130
|
</body>
|
134
131
|
</html>
|
data/files/Gemfile
CHANGED
@@ -5,7 +5,7 @@ gem 'motion-support', '~> 0.2.4'
|
|
5
5
|
gem 'sugarcube', '~> 1.3.7', require: 'sugarcube-classic'
|
6
6
|
gem 'bubble-wrap', '~> 1.4.0'
|
7
7
|
|
8
|
-
gem 'motion-prime', '~> 0.5.
|
8
|
+
gem 'motion-prime', '~> 0.5.6'
|
9
9
|
|
10
10
|
# add reside menu for sidebar support
|
11
11
|
gem 'prime_reside_menu', '~> 0.1.3'
|
data/files/Gemfile.lock
CHANGED
@@ -34,7 +34,7 @@ GEM
|
|
34
34
|
bundler
|
35
35
|
motion-cocoapods (1.4.0)
|
36
36
|
cocoapods (>= 0.26.2)
|
37
|
-
motion-prime (0.5.
|
37
|
+
motion-prime (0.5.6)
|
38
38
|
bubble-wrap
|
39
39
|
cocoapods
|
40
40
|
methadone
|
@@ -67,7 +67,7 @@ PLATFORMS
|
|
67
67
|
DEPENDENCIES
|
68
68
|
bubble-wrap (~> 1.4.0)
|
69
69
|
motion-cocoapods (~> 1.4.0)
|
70
|
-
motion-prime (~> 0.5.
|
70
|
+
motion-prime (~> 0.5.6)
|
71
71
|
motion-support (~> 0.2.4)
|
72
72
|
prime_reside_menu (~> 0.1.3)
|
73
73
|
sugarcube (~> 1.3.7)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -156,14 +156,23 @@ module MotionPrime
|
|
156
156
|
attributes << name
|
157
157
|
|
158
158
|
define_method(name) do |*args, &block|
|
159
|
-
self.info[name]
|
159
|
+
value = self.info[name]
|
160
|
+
case options[:type].to_s
|
161
|
+
when 'time'
|
162
|
+
value = Time.short_iso8601(value) if value
|
163
|
+
end
|
164
|
+
value
|
160
165
|
end
|
161
166
|
|
162
167
|
define_method((name + "=").to_sym) do |*args, &block|
|
163
168
|
value = args[0]
|
164
169
|
case options[:type].to_s
|
165
|
-
when 'integer'
|
166
|
-
|
170
|
+
when 'integer'
|
171
|
+
value = value.to_i
|
172
|
+
when 'float'
|
173
|
+
value = value.to_f
|
174
|
+
when 'time'
|
175
|
+
value = value.to_short_iso8601 unless value.is_a?(String)
|
167
176
|
end unless value.nil?
|
168
177
|
|
169
178
|
self.info[name] = value
|
@@ -11,8 +11,14 @@ module MotionPrime
|
|
11
11
|
old_attrs = self.info.clone
|
12
12
|
result = block.call
|
13
13
|
new_attrs = self.info.clone
|
14
|
+
new_bags = self._bags.clone
|
14
15
|
new_attrs.each do |key, value|
|
15
|
-
if value != old_attrs[key] &&
|
16
|
+
if value != old_attrs[key] && !@_changed_attributes.has_key?(key.to_s)
|
17
|
+
@_changed_attributes[key.to_s] = old_attrs[key]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
new_bags.each do |key, value|
|
21
|
+
if value.key != old_attrs[key] && !@_changed_attributes.has_key?(key.to_s)
|
16
22
|
@_changed_attributes[key.to_s] = old_attrs[key]
|
17
23
|
end
|
18
24
|
end
|
@@ -100,8 +100,15 @@ module MotionPrime
|
|
100
100
|
alias_method :clear, :delete_all
|
101
101
|
|
102
102
|
|
103
|
-
def store=(store)
|
104
|
-
store.addObject(self, error:nil)
|
103
|
+
def store=(store, retry_count = 0)
|
104
|
+
store.addObject(self, error: nil)
|
105
|
+
rescue Exception => e
|
106
|
+
sleep(0.1)
|
107
|
+
if retry_count == 3
|
108
|
+
raise StoreError, e.description
|
109
|
+
else
|
110
|
+
send (:store=, store, retry_count + 1)
|
111
|
+
end
|
105
112
|
end
|
106
113
|
|
107
114
|
def save
|
@@ -236,22 +236,24 @@ module MotionPrime
|
|
236
236
|
model_class = key.classify.constantize
|
237
237
|
self.store.save_interval = data.count
|
238
238
|
# Update/Create existing records
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
model
|
243
|
-
|
239
|
+
track_changed_attributes do
|
240
|
+
data.each do |attributes|
|
241
|
+
model = old_collection.detect{ |model| model.id == attributes[:id]}
|
242
|
+
unless model
|
243
|
+
model = model_class.new
|
244
|
+
self.send(:"#{key}_bag") << model
|
245
|
+
end
|
246
|
+
model.fetch_with_attributes(attributes, save_associations: sync_options[:save])
|
247
|
+
model.save if sync_options[:save] && model.has_changed?
|
244
248
|
end
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
unless model
|
251
|
-
old_model.delete
|
249
|
+
old_collection.each do |old_model|
|
250
|
+
model = data.detect{ |model| model[:id] == old_model.id}
|
251
|
+
unless model
|
252
|
+
old_model.delete
|
253
|
+
end
|
252
254
|
end
|
253
255
|
end
|
254
|
-
save if sync_options[:save]
|
256
|
+
save if sync_options[:save] && has_changed?
|
255
257
|
self.store.save_interval = 1
|
256
258
|
end
|
257
259
|
|
@@ -271,13 +273,16 @@ module MotionPrime
|
|
271
273
|
end
|
272
274
|
|
273
275
|
def fetch_has_one_with_attributes(key, data, sync_options = {})
|
274
|
-
|
275
|
-
|
276
|
-
model
|
277
|
-
|
276
|
+
track_changed_attributes do
|
277
|
+
model = self.send(key)
|
278
|
+
unless model
|
279
|
+
model = key.classify.constantize.new
|
280
|
+
self.send(:"#{key}_bag") << model
|
281
|
+
end
|
282
|
+
model.fetch_with_attributes(data)
|
283
|
+
model.save if sync_options[:save]
|
278
284
|
end
|
279
|
-
|
280
|
-
model.save if sync_options[:save]
|
285
|
+
save if sync_options[:save] && has_changed?
|
281
286
|
end
|
282
287
|
|
283
288
|
def filtered_updatable_attributes(options = {})
|
@@ -158,18 +158,22 @@ module MotionPrime
|
|
158
158
|
index = opts.delete(:at)
|
159
159
|
options = build_options_for_element(opts)
|
160
160
|
options[:name] ||= key
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
161
|
+
element = build_element(options)
|
162
|
+
if index
|
163
|
+
new_elements_array = elements.to_a.insert(index, [key, element])
|
164
|
+
self.elements = Hash[new_elements_array]
|
165
165
|
else
|
166
|
-
|
166
|
+
self.elements[key] = element
|
167
167
|
end
|
168
|
+
end
|
168
169
|
|
169
|
-
|
170
|
-
|
170
|
+
def build_element(options = {})
|
171
|
+
type = options.delete(:type)
|
172
|
+
render_as = options.delete(:as).to_s
|
173
|
+
if self.is_a?(BaseFieldSection) || self.is_a?(BaseHeaderSection) || render_as == 'view'
|
174
|
+
BaseElement.factory(type, options)
|
171
175
|
else
|
172
|
-
|
176
|
+
DrawElement.factory(type, options) || BaseElement.factory(type, options)
|
173
177
|
end
|
174
178
|
end
|
175
179
|
|
@@ -282,8 +286,11 @@ module MotionPrime
|
|
282
286
|
|
283
287
|
protected
|
284
288
|
def bind_keyboard_close
|
285
|
-
|
286
|
-
|
289
|
+
bindings = self.class.keyboard_close_bindings
|
290
|
+
return unless bindings.present?
|
291
|
+
bind_proc = bindings[:tap_on]
|
292
|
+
bind_views = instance_eval(&bind_proc)
|
293
|
+
Array.wrap(bind_views).each do |view|
|
287
294
|
gesture_recognizer = UITapGestureRecognizer.alloc.initWithTarget(self, action: :hide_keyboard)
|
288
295
|
view.addGestureRecognizer(gesture_recognizer)
|
289
296
|
gesture_recognizer.cancelsTouchesInView = false
|