motion-prime 0.4.4 → 0.4.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/doc/code/getting_started.rb +7 -4
- data/doc/code/screens.rb +33 -15
- data/doc/docs/getting_started.html +6 -5
- data/doc/docs/screens.html +53 -25
- data/files/Gemfile.lock +2 -2
- data/motion-prime/api_client.rb +2 -1
- data/motion-prime/app_delegate.rb +0 -19
- data/motion-prime/elements/base_element.rb +9 -3
- data/motion-prime/models/association_collection.rb +8 -11
- data/motion-prime/screens/_navigation_mixin.rb +2 -4
- data/motion-prime/screens/base_screen.rb +7 -5
- data/motion-prime/screens/extensions/_navigation_bar_mixin.rb +1 -1
- data/motion-prime/sections/_cell_section_mixin.rb +1 -1
- data/motion-prime/sections/_draw_section_mixin.rb +1 -1
- data/motion-prime/sections/base_section.rb +4 -4
- data/motion-prime/sections/form.rb +6 -37
- data/motion-prime/sections/form/base_field_section.rb +1 -1
- data/motion-prime/sections/form/form_delegate.rb +49 -0
- data/motion-prime/sections/table.rb +18 -10
- data/motion-prime/sections/table/refresh_mixin.rb +1 -1
- data/motion-prime/sections/table/table_delegate.rb +7 -0
- data/motion-prime/support/mp_cell_with_section.rb +3 -1
- data/motion-prime/support/tab_bar_controller.rb +2 -2
- data/motion-prime/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e3edc8658a85c7184310acc029dc5a710be493f
|
4
|
+
data.tar.gz: a76dab2b6f08031d9edbd8c23e730a5cc061ac46
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c55504663d7c290007e2d81c04dd28f1633827ab4605c9c23a1480b736324b734bdfde29212072b03f77b13970a69cb274a648ba14e2ad86ba4d3e0071f4b61b
|
7
|
+
data.tar.gz: 12d135885f5dffa9a9017d5f0df862c846a5d5dc3e4ea9b29777a1b6046f97f3052b5558f77ac75a17e972bfec8369899e81311ebf1ec79b79b8c833a785435d
|
data/Gemfile.lock
CHANGED
data/doc/code/getting_started.rb
CHANGED
@@ -10,7 +10,8 @@ Visit http://www.rubymotion.com
|
|
10
10
|
# **2. Create application delegate.**
|
11
11
|
#
|
12
12
|
# You should rewrite the `on_load` method, which will be runned after starting application.
|
13
|
-
#
|
13
|
+
#
|
14
|
+
# NOTE: you should always use AppDelegate class name.
|
14
15
|
|
15
16
|
class AppDelegate < Prime::BaseAppDelegate
|
16
17
|
def on_load(app, options)
|
@@ -21,6 +22,8 @@ end
|
|
21
22
|
# **3. Create the main screen.**
|
22
23
|
#
|
23
24
|
# You should rewrite the `render` method, which will be runned after first opening screen.
|
25
|
+
#
|
26
|
+
# NOTE: it's recommended to use instance variables for sections, e.g. `@main_section` instead of `main_section`.
|
24
27
|
|
25
28
|
class MainScreen < Prime::BaseScreen
|
26
29
|
title 'Main screen'
|
@@ -47,14 +50,14 @@ end
|
|
47
50
|
# Styles will be applied to each element in section.
|
48
51
|
# The simplest rule by default is: `:section-name_:element-name`.
|
49
52
|
#
|
50
|
-
# E.g. if you have
|
51
|
-
# and
|
53
|
+
# E.g. if you have "MyProfileSection" (the name for section by default will be - `my_profile`)
|
54
|
+
# and "title" element, then you should use `my_profile_title` style name.
|
52
55
|
|
53
56
|
Prime::Styles.define do
|
54
57
|
style :my_profile_title, width: 300, height: 20
|
55
58
|
end
|
56
59
|
|
57
|
-
#
|
60
|
+
# You can pass namespace to `define` method.
|
58
61
|
|
59
62
|
Prime::Styles.define :my_profile do
|
60
63
|
style :title, width: 300, height: 20
|
data/doc/code/screens.rb
CHANGED
@@ -1,8 +1,15 @@
|
|
1
|
+
# ** What is a Screen? **
|
2
|
+
#
|
3
|
+
# "Screen" is the most common class in MotionPrime, you can create entire application using only "Screens".
|
4
|
+
# Generally it's just a "UIViewController" wrapper with some syntax sugar.
|
5
|
+
# For RubyOnRails developers the nearest analogy would be "Controllers".
|
6
|
+
---
|
7
|
+
|
1
8
|
# ** Render the screen. **
|
2
9
|
#
|
3
|
-
# You should rewrite the `render` method of Prime::BaseScreen
|
10
|
+
# You should rewrite the `render` method of `Prime::BaseScreen`, which will be runned after first opening screen.
|
4
11
|
|
5
|
-
class
|
12
|
+
class FooScreen < Prime::BaseScreen
|
6
13
|
def render
|
7
14
|
@main_section = MyProfileSection.new(screen: self, model: User.first)
|
8
15
|
@main_section.render
|
@@ -11,44 +18,55 @@ end
|
|
11
18
|
|
12
19
|
# ** Set screen's title **
|
13
20
|
#
|
14
|
-
#
|
21
|
+
# Title will be used in screen's navigation controller and will be shown on top of screen.
|
22
|
+
#
|
23
|
+
# NOTE: screen should be created with enabled navigation (see "Initialize screen" block).
|
15
24
|
|
16
|
-
class
|
17
|
-
title '
|
25
|
+
class FooScreen < Prime::BaseScreen
|
26
|
+
title 'Foo screen'
|
18
27
|
end
|
19
28
|
|
20
|
-
#
|
29
|
+
# You can pass block to define screen's title
|
21
30
|
|
22
|
-
class
|
31
|
+
class FooScreen < Prime::BaseScreen
|
23
32
|
title { params[:title] }
|
24
33
|
end
|
25
34
|
|
26
35
|
# ** Initialize screen. **
|
27
36
|
#
|
28
37
|
# Available options:
|
29
|
-
# *
|
38
|
+
# * `:navigation`. When this options is true, screen will be created with navigation support: it will allow adding title and left/right buttons.
|
30
39
|
# This option is false by default.
|
31
40
|
|
32
|
-
|
41
|
+
def open_foo_screen
|
42
|
+
foo_screen = FooScreen.new(navigation: true)
|
43
|
+
end
|
33
44
|
|
34
45
|
# ** Open screen: using app delegate. **
|
35
46
|
|
36
|
-
# Opening screen using app delegate is the most basic way, you would
|
47
|
+
# Opening screen using app delegate is the most basic way, you would use it at least on app load.
|
37
48
|
#
|
38
49
|
# Available options:
|
39
|
-
# *
|
50
|
+
# * `:root`. When this option is true, screen will not be in content controller and will create new root screen.
|
40
51
|
# You can use root: true when you have already opened screen with sidebar, and you want to open new screen without sidebar.
|
41
52
|
# This option is false by default if you already have root screen and true if not.
|
42
53
|
#
|
43
|
-
# *
|
44
|
-
#
|
54
|
+
# * `:sidebar`. Send `Prime::BaseScreen` instance to this option if you want to create root screen with sidebar.
|
55
|
+
# Value of this options will be used as sidebar controller.
|
45
56
|
|
46
|
-
|
57
|
+
def open_foo_screen
|
58
|
+
foo_screen = FooScreen.new(navigation: true)
|
59
|
+
sidebar = MySidebar.new
|
60
|
+
app_delegate.open_screen foo_screen, sidebar: sidebar
|
61
|
+
end
|
47
62
|
|
48
63
|
# ** Open screen: using parent screen. **
|
49
64
|
|
50
65
|
# Opening screen using parent screen is usefull if you want to create inherited screen.
|
51
66
|
# Parent screen should have been initialized with navigation support.
|
52
67
|
|
53
|
-
|
68
|
+
def open_second_screen
|
69
|
+
second_screen = SecondScreen.new(navigation: true)
|
70
|
+
foo_screen.open_screen second_screen
|
71
|
+
end
|
54
72
|
|
@@ -98,8 +98,8 @@
|
|
98
98
|
<a class="pilcrow" href="#section-4">¶</a>
|
99
99
|
</div>
|
100
100
|
<p><strong>2. Create application delegate.</strong></p>
|
101
|
-
<p>You should rewrite the <code>on_load</code> method, which will be runned after starting application
|
102
|
-
|
101
|
+
<p>You should rewrite the <code>on_load</code> method, which will be runned after starting application.</p>
|
102
|
+
<p>NOTE: you should always use AppDelegate class name.</p>
|
103
103
|
|
104
104
|
</div>
|
105
105
|
|
@@ -120,6 +120,7 @@ Note: you should always use AppDelegate class name.</p>
|
|
120
120
|
</div>
|
121
121
|
<p><strong>3. Create the main screen.</strong></p>
|
122
122
|
<p>You should rewrite the <code>render</code> method, which will be runned after first opening screen.</p>
|
123
|
+
<p>NOTE: it's recommended to use instance variables for sections, e.g. <code>@main_section</code> instead of <code>main_section</code>.</p>
|
123
124
|
|
124
125
|
</div>
|
125
126
|
|
@@ -164,8 +165,8 @@ Note: you should always use AppDelegate class name.</p>
|
|
164
165
|
<p><strong>5. Create your first stylesheet file.</strong></p>
|
165
166
|
<p>Styles will be applied to each element in section.
|
166
167
|
The simplest rule by default is: <code>:section-name_:element-name</code>.</p>
|
167
|
-
<p>E.g. if you have
|
168
|
-
and
|
168
|
+
<p>E.g. if you have "MyProfileSection" (the name for section by default will be - <code>my_profile</code>)
|
169
|
+
and "title" element, then you should use <code>my_profile_title</code> style name.</p>
|
169
170
|
|
170
171
|
</div>
|
171
172
|
|
@@ -182,7 +183,7 @@ and 'title' element, then you should use <code>my_profile_title</code> s
|
|
182
183
|
<div class="pilwrap ">
|
183
184
|
<a class="pilcrow" href="#section-8">¶</a>
|
184
185
|
</div>
|
185
|
-
<p>
|
186
|
+
<p>You can pass namespace to <code>define</code> method.</p>
|
186
187
|
|
187
188
|
</div>
|
188
189
|
|
data/doc/docs/screens.html
CHANGED
@@ -48,12 +48,30 @@
|
|
48
48
|
<div class="pilwrap ">
|
49
49
|
<a class="pilcrow" href="#section-1">¶</a>
|
50
50
|
</div>
|
51
|
+
<p><strong> What is a Screen? </strong></p>
|
52
|
+
<p>"Screen" is the most common class in MotionPrime, you can create entire application using only "Screens".
|
53
|
+
Generally it's just a "UIViewController" wrapper with some syntax sugar.
|
54
|
+
For RubyOnRails developers the nearest analogy would be "Controllers".</p>
|
55
|
+
|
56
|
+
</div>
|
57
|
+
|
58
|
+
<div class="content"><div class='highlight'><pre>---</pre></div></div>
|
59
|
+
|
60
|
+
</li>
|
61
|
+
|
62
|
+
|
63
|
+
<li id="section-2">
|
64
|
+
<div class="annotation">
|
65
|
+
|
66
|
+
<div class="pilwrap ">
|
67
|
+
<a class="pilcrow" href="#section-2">¶</a>
|
68
|
+
</div>
|
51
69
|
<p><strong> Render the screen. </strong></p>
|
52
|
-
<p>You should rewrite the <code>render</code> method of Prime::BaseScreen
|
70
|
+
<p>You should rewrite the <code>render</code> method of <code>Prime::BaseScreen</code>, which will be runned after first opening screen.</p>
|
53
71
|
|
54
72
|
</div>
|
55
73
|
|
56
|
-
<div class="content"><div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">
|
74
|
+
<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::BaseScreen</span></span></span>
|
57
75
|
<span class="function"><span class="keyword">def</span> <span class="title">render</span></span>
|
58
76
|
<span class="variable">@main_section</span> = <span class="constant">MyProfileSection</span>.new(<span class="symbol">screen:</span> <span class="keyword">self</span>, <span class="symbol">model:</span> <span class="constant">User</span>.first)
|
59
77
|
<span class="variable">@main_section</span>.render
|
@@ -63,92 +81,99 @@
|
|
63
81
|
</li>
|
64
82
|
|
65
83
|
|
66
|
-
<li id="section-
|
84
|
+
<li id="section-3">
|
67
85
|
<div class="annotation">
|
68
86
|
|
69
87
|
<div class="pilwrap ">
|
70
|
-
<a class="pilcrow" href="#section-
|
88
|
+
<a class="pilcrow" href="#section-3">¶</a>
|
71
89
|
</div>
|
72
90
|
<p><strong> Set screen's title </strong></p>
|
73
|
-
<p>
|
91
|
+
<p>Title will be used in screen's navigation controller and will be shown on top of screen.</p>
|
92
|
+
<p>NOTE: screen should be created with enabled navigation (see "Initialize screen" block).</p>
|
74
93
|
|
75
94
|
</div>
|
76
95
|
|
77
|
-
<div class="content"><div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">
|
78
|
-
title <span class="string">'
|
96
|
+
<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::BaseScreen</span></span></span>
|
97
|
+
title <span class="string">'Foo screen'</span>
|
79
98
|
<span class="keyword">end</span></pre></div></div>
|
80
99
|
|
81
100
|
</li>
|
82
101
|
|
83
102
|
|
84
|
-
<li id="section-
|
103
|
+
<li id="section-4">
|
85
104
|
<div class="annotation">
|
86
105
|
|
87
106
|
<div class="pilwrap ">
|
88
|
-
<a class="pilcrow" href="#section-
|
107
|
+
<a class="pilcrow" href="#section-4">¶</a>
|
89
108
|
</div>
|
90
|
-
<p>
|
109
|
+
<p>You can pass block to define screen's title</p>
|
91
110
|
|
92
111
|
</div>
|
93
112
|
|
94
|
-
<div class="content"><div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">
|
113
|
+
<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::BaseScreen</span></span></span>
|
95
114
|
title { params[<span class="symbol">:title</span>] }
|
96
115
|
<span class="keyword">end</span></pre></div></div>
|
97
116
|
|
98
117
|
</li>
|
99
118
|
|
100
119
|
|
101
|
-
<li id="section-
|
120
|
+
<li id="section-5">
|
102
121
|
<div class="annotation">
|
103
122
|
|
104
123
|
<div class="pilwrap ">
|
105
|
-
<a class="pilcrow" href="#section-
|
124
|
+
<a class="pilcrow" href="#section-5">¶</a>
|
106
125
|
</div>
|
107
126
|
<p><strong> Initialize screen. </strong></p>
|
108
127
|
<p>Available options:</p>
|
109
128
|
<ul>
|
110
|
-
<li>:navigation
|
129
|
+
<li><code>:navigation</code>. When this options is true, screen will be created with navigation support: it will allow adding title and left/right buttons.
|
111
130
|
This option is false by default.</li>
|
112
131
|
</ul>
|
113
132
|
|
114
133
|
</div>
|
115
134
|
|
116
|
-
<div class="content"><div class='highlight'><pre
|
135
|
+
<div class="content"><div class='highlight'><pre><span class="function"><span class="keyword">def</span> <span class="title">open_foo_screen</span></span>
|
136
|
+
foo_screen = <span class="constant">FooScreen</span>.new(<span class="symbol">navigation:</span> <span class="keyword">true</span>)
|
137
|
+
<span class="keyword">end</span></pre></div></div>
|
117
138
|
|
118
139
|
</li>
|
119
140
|
|
120
141
|
|
121
|
-
<li id="section-
|
142
|
+
<li id="section-6">
|
122
143
|
<div class="annotation">
|
123
144
|
|
124
145
|
<div class="pilwrap ">
|
125
|
-
<a class="pilcrow" href="#section-
|
146
|
+
<a class="pilcrow" href="#section-6">¶</a>
|
126
147
|
</div>
|
127
148
|
<p><strong> Open screen: using app delegate. </strong></p>
|
128
|
-
<p>Opening screen using app delegate is the most basic way, you would
|
149
|
+
<p>Opening screen using app delegate is the most basic way, you would use it at least on app load.</p>
|
129
150
|
<p>Available options:</p>
|
130
151
|
<ul>
|
131
|
-
<li><p>:root
|
152
|
+
<li><p><code>:root</code>. When this option is true, screen will not be in content controller and will create new root screen.
|
132
153
|
You can use root: true when you have already opened screen with sidebar, and you want to open new screen without sidebar.
|
133
154
|
This option is false by default if you already have root screen and true if not.</p>
|
134
155
|
</li>
|
135
|
-
<li><p>:sidebar
|
136
|
-
|
156
|
+
<li><p><code>:sidebar</code>. Send <code>Prime::BaseScreen</code> instance to this option if you want to create root screen with sidebar.
|
157
|
+
Value of this options will be used as sidebar controller.</p>
|
137
158
|
</li>
|
138
159
|
</ul>
|
139
160
|
|
140
161
|
</div>
|
141
162
|
|
142
|
-
<div class="content"><div class='highlight'><pre
|
163
|
+
<div class="content"><div class='highlight'><pre><span class="function"><span class="keyword">def</span> <span class="title">open_foo_screen</span></span>
|
164
|
+
foo_screen = <span class="constant">FooScreen</span>.new(<span class="symbol">navigation:</span> <span class="keyword">true</span>)
|
165
|
+
sidebar = <span class="constant">MySidebar</span>.new
|
166
|
+
app_delegate.open_screen foo_screen, <span class="symbol">sidebar:</span> sidebar
|
167
|
+
<span class="keyword">end</span></pre></div></div>
|
143
168
|
|
144
169
|
</li>
|
145
170
|
|
146
171
|
|
147
|
-
<li id="section-
|
172
|
+
<li id="section-7">
|
148
173
|
<div class="annotation">
|
149
174
|
|
150
175
|
<div class="pilwrap ">
|
151
|
-
<a class="pilcrow" href="#section-
|
176
|
+
<a class="pilcrow" href="#section-7">¶</a>
|
152
177
|
</div>
|
153
178
|
<p><strong> Open screen: using parent screen. </strong></p>
|
154
179
|
<p>Opening screen using parent screen is usefull if you want to create inherited screen.
|
@@ -156,7 +181,10 @@ Parent screen should have been initialized with navigation support.</p>
|
|
156
181
|
|
157
182
|
</div>
|
158
183
|
|
159
|
-
<div class="content"><div class='highlight'><pre
|
184
|
+
<div class="content"><div class='highlight'><pre><span class="function"><span class="keyword">def</span> <span class="title">open_second_screen</span></span>
|
185
|
+
second_screen = <span class="constant">SecondScreen</span>.new(<span class="symbol">navigation:</span> <span class="keyword">true</span>)
|
186
|
+
foo_screen.open_screen second_screen
|
187
|
+
<span class="keyword">end</span></pre></div></div>
|
160
188
|
|
161
189
|
</li>
|
162
190
|
|
data/files/Gemfile.lock
CHANGED
@@ -32,7 +32,7 @@ GEM
|
|
32
32
|
bundler
|
33
33
|
motion-cocoapods (1.4.0)
|
34
34
|
cocoapods (>= 0.26.2)
|
35
|
-
motion-prime (0.4.
|
35
|
+
motion-prime (0.4.4)
|
36
36
|
bubble-wrap
|
37
37
|
cocoapods
|
38
38
|
methadone
|
@@ -59,6 +59,6 @@ PLATFORMS
|
|
59
59
|
DEPENDENCIES
|
60
60
|
bubble-wrap (~> 1.3.0)
|
61
61
|
motion-cocoapods (~> 1.4.0)
|
62
|
-
motion-prime (~> 0.4.
|
62
|
+
motion-prime (~> 0.4.4)
|
63
63
|
motion-support (~> 0.2.4)
|
64
64
|
sugarcube (~> 1.3.7)
|
data/motion-prime/api_client.rb
CHANGED
@@ -53,7 +53,8 @@ class ApiClient
|
|
53
53
|
|
54
54
|
def resource_url(path)
|
55
55
|
# return if path.blank?
|
56
|
-
|
56
|
+
base = Prime::Config.api.resource_base.present? ? Prime::Config.api.resource_base : Prime::Config.api.base
|
57
|
+
"#{base}#{path}"
|
57
58
|
end
|
58
59
|
|
59
60
|
def request(method, path, params = {}, &block)
|
@@ -32,7 +32,6 @@ module MotionPrime
|
|
32
32
|
|
33
33
|
# TODO: move to private methods
|
34
34
|
def open_root_screen(screen)
|
35
|
-
close_current_screens
|
36
35
|
screen.send(:on_screen_load) if screen.respond_to?(:on_screen_load)
|
37
36
|
screen.wrap_in_navigation if screen.respond_to?(:wrap_in_navigation)
|
38
37
|
|
@@ -47,7 +46,6 @@ module MotionPrime
|
|
47
46
|
# TODO: move to private methods
|
48
47
|
def open_content_screen(screen)
|
49
48
|
if sidebar?
|
50
|
-
close_current_screens
|
51
49
|
sidebar_container.content_controller = screen
|
52
50
|
else
|
53
51
|
open_root_screen(screen)
|
@@ -85,24 +83,7 @@ module MotionPrime
|
|
85
83
|
NSNotificationCenter.defaultCenter.postNotificationName(:on_current_user_reset, object: user_was)
|
86
84
|
end
|
87
85
|
|
88
|
-
def close_screens(screens)
|
89
|
-
Array.wrap(screens).each { |screen| screen.on_destroy if screen.respond_to?(:on_destroy) }
|
90
|
-
end
|
91
|
-
|
92
86
|
private
|
93
|
-
def close_current_screens
|
94
|
-
return unless self.window
|
95
|
-
|
96
|
-
screens = if sidebar? && sidebar_container.content_controller.is_a?(UINavigationController)
|
97
|
-
sidebar_container.content_controller.childViewControllers
|
98
|
-
elsif sidebar?
|
99
|
-
sidebar_container.content_controller
|
100
|
-
else
|
101
|
-
window.rootViewController
|
102
|
-
end
|
103
|
-
close_screens(screens)
|
104
|
-
end
|
105
|
-
|
106
87
|
def create_tab_bar(screens)
|
107
88
|
MotionPrime::TabBarController.new(screens)
|
108
89
|
end
|
@@ -18,6 +18,7 @@ module MotionPrime
|
|
18
18
|
define_callbacks :render
|
19
19
|
|
20
20
|
def initialize(options = {})
|
21
|
+
options[:screen] = options[:screen].try(:weak_ref)
|
21
22
|
@options = options
|
22
23
|
@screen = options[:screen]
|
23
24
|
@section = options[:section]
|
@@ -27,9 +28,14 @@ module MotionPrime
|
|
27
28
|
@view_name = self.class_name_without_kvo.demodulize.underscore.gsub(/(_draw)?_element/, '')
|
28
29
|
end
|
29
30
|
|
30
|
-
def dealloc
|
31
|
-
|
32
|
-
|
31
|
+
# def dealloc
|
32
|
+
# pp 'deallocating elemenet', self.name, self.to_s, section.to_s
|
33
|
+
# super
|
34
|
+
# end
|
35
|
+
|
36
|
+
def add_target(target = nil, action = 'on_click:', event = :touch)
|
37
|
+
return false unless self.view
|
38
|
+
self.view.addTarget(target || section, action: action, forControlEvents: event.uicontrolevent)
|
33
39
|
end
|
34
40
|
|
35
41
|
def render(options = {}, &block)
|
@@ -41,19 +41,17 @@ module MotionPrime
|
|
41
41
|
|
42
42
|
def all(*args)
|
43
43
|
return [] unless bag.store.present?
|
44
|
-
|
44
|
+
find_options = find_options(args[0])
|
45
|
+
sort_options = sort_options(args[1])
|
46
|
+
data = if sort_options.present? # TODO: check bag items count
|
47
|
+
bag.find(find_options, sort_options)
|
48
|
+
else
|
49
|
+
bag.to_a.select { |entity| find_options.all? { |field, value| entity.send(field) == value } }
|
50
|
+
end
|
45
51
|
set_inverse_relation_for(data)
|
46
52
|
data
|
47
53
|
end
|
48
54
|
|
49
|
-
def last
|
50
|
-
all.last
|
51
|
-
end
|
52
|
-
|
53
|
-
def first
|
54
|
-
all.first
|
55
|
-
end
|
56
|
-
|
57
55
|
def set_inverse_relation_for(models)
|
58
56
|
[*models].each do |model|
|
59
57
|
model.send("#{inverse_relation_name}=", inverse_relation)
|
@@ -71,8 +69,7 @@ module MotionPrime
|
|
71
69
|
end
|
72
70
|
|
73
71
|
def sort_options(options)
|
74
|
-
|
75
|
-
{sort: model_class.default_sort_options}
|
72
|
+
options || {sort: model_class.default_sort_options}
|
76
73
|
end
|
77
74
|
|
78
75
|
def model_class
|
@@ -74,7 +74,7 @@ module MotionPrime
|
|
74
74
|
screen = screen.new if screen.respond_to?(:new)
|
75
75
|
|
76
76
|
# Set parent, title & modal properties
|
77
|
-
screen.parent_screen = self if screen.respond_to?("parent_screen=")
|
77
|
+
screen.parent_screen = self.weak_ref if screen.respond_to?("parent_screen=")
|
78
78
|
screen.title = args[:title] if args[:title] && screen.respond_to?("title=")
|
79
79
|
screen.modal = args[:modal] if args[:modal] && screen.respond_to?("modal=")
|
80
80
|
|
@@ -98,13 +98,11 @@ module MotionPrime
|
|
98
98
|
|
99
99
|
def close_screen_navigational(args = {})
|
100
100
|
if args[:to_screen] && args[:to_screen].is_a?(UIViewController)
|
101
|
-
self.parent_screen = args[:to_screen]
|
101
|
+
self.parent_screen = args[:to_screen].weak_ref
|
102
102
|
|
103
103
|
screens = self.navigation_controller.childViewControllers
|
104
|
-
app_delegate.close_screens(screens[screens.index(parent_screen)+1..-1])
|
105
104
|
self.navigation_controller.popToViewController(args[:to_screen], animated: args[:animated])
|
106
105
|
else
|
107
|
-
app_delegate.close_screens(self)
|
108
106
|
self.navigation_controller.popViewControllerAnimated(args[:animated])
|
109
107
|
end
|
110
108
|
send_on_return(args)
|
@@ -34,11 +34,13 @@ module MotionPrime
|
|
34
34
|
@on_appear_happened = true
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
# def dealloc
|
38
|
+
# pp 'Deallocating Screen'
|
39
|
+
# super
|
40
|
+
# end
|
41
|
+
|
42
|
+
def visible?
|
43
|
+
self.isViewLoaded && view.window
|
42
44
|
end
|
43
45
|
end
|
44
46
|
end
|
@@ -41,7 +41,7 @@ module MotionPrime
|
|
41
41
|
|
42
42
|
def create_navigation_button(title, args = {})
|
43
43
|
args[:style] ||= UIBarButtonItemStylePlain
|
44
|
-
args[:target]
|
44
|
+
args[:target] = (args[:target] || self).weak_ref
|
45
45
|
args[:action] ||= nil
|
46
46
|
# TODO: Find better place for this code, may be just create custom control
|
47
47
|
if args[:image]
|
@@ -20,7 +20,7 @@ module MotionPrime
|
|
20
20
|
render_image_elements
|
21
21
|
elsif prerender_enabled?
|
22
22
|
prerender_elements_for_state(state)
|
23
|
-
draw_in(rect, state)
|
23
|
+
draw_in(rect, state) if cached_draw_image[state]
|
24
24
|
else
|
25
25
|
draw_background_in_context(UIGraphicsGetCurrentContext(), rect)
|
26
26
|
draw_elements(rect)
|
@@ -25,16 +25,16 @@ module MotionPrime
|
|
25
25
|
define_callbacks :render
|
26
26
|
|
27
27
|
def initialize(options = {})
|
28
|
+
options[:screen] = options[:screen].try(:weak_ref)
|
28
29
|
@options = options
|
29
|
-
self.screen = options[:screen]
|
30
|
+
self.screen = options[:screen]
|
30
31
|
@model = options[:model]
|
31
32
|
@name = options[:name] ||= default_name
|
32
33
|
@options_block = options[:block]
|
33
34
|
end
|
34
35
|
|
35
36
|
def dealloc
|
36
|
-
pp 'deallocating section. elements count: ', self.elements.try(:count)
|
37
|
-
self.elements = nil
|
37
|
+
# pp 'deallocating section. elements count: ', self.elements.try(:count), self.to_s
|
38
38
|
|
39
39
|
NSNotificationCenter.defaultCenter.removeObserver self
|
40
40
|
self.delegate = nil if self.respond_to?(:delegate)
|
@@ -237,7 +237,7 @@ module MotionPrime
|
|
237
237
|
# in next element with same name in another class
|
238
238
|
options = opts.clone
|
239
239
|
options[:type] ||= (options[:text] || options[:attributed_text_options]) ? :label : :view
|
240
|
-
options.merge(screen: screen
|
240
|
+
options.merge(screen: screen, section: self.weak_ref)
|
241
241
|
end
|
242
242
|
|
243
243
|
private
|
@@ -133,48 +133,17 @@ module MotionPrime
|
|
133
133
|
table_view.contentInset = current_inset
|
134
134
|
end
|
135
135
|
|
136
|
+
def table_delegate
|
137
|
+
@table_delegate ||= FormDelegate.new(section: self)
|
138
|
+
end
|
139
|
+
|
136
140
|
# ALIASES
|
137
141
|
def on_input_change(text_field); end
|
138
|
-
def
|
142
|
+
def on_input_edit_begin(text_field); end
|
143
|
+
def on_input_edit_end(text_field); end
|
139
144
|
def on_input_return(text_field)
|
140
145
|
text_field.resignFirstResponder
|
141
146
|
end
|
142
|
-
def textFieldShouldReturn(text_field)
|
143
|
-
on_input_return(text_field)
|
144
|
-
end
|
145
|
-
def textFieldShouldBeginEditing(text_field)
|
146
|
-
text_field.respond_to?(:readonly) ? !text_field.readonly : true
|
147
|
-
end
|
148
|
-
def textFieldDidBeginEditing(text_field)
|
149
|
-
on_input_edit(text_field)
|
150
|
-
end
|
151
|
-
def textViewDidBeginEditing(text_view)
|
152
|
-
on_input_edit(text_view)
|
153
|
-
end
|
154
|
-
def textViewDidChange(text_view) # bug in iOS 7 - cursor is out of textView bounds
|
155
|
-
line = text_view.caretRectForPosition(text_view.selectedTextRange.start)
|
156
|
-
overflow = line.origin.y + line.size.height -
|
157
|
-
(text_view.contentOffset.y + text_view.bounds.size.height - text_view.contentInset.bottom - text_view.contentInset.top)
|
158
|
-
if overflow > 0
|
159
|
-
offset = text_view.contentOffset
|
160
|
-
offset.y += overflow + text_view.textContainerInset.bottom
|
161
|
-
UIView.animate(duration: 0.2) do
|
162
|
-
text_view.setContentOffset(offset)
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
def textView(text_view, shouldChangeTextInRange:range, replacementText:string)
|
168
|
-
textField(text_view, shouldChangeCharactersInRange:range, replacementString:string)
|
169
|
-
end
|
170
|
-
|
171
|
-
def textField(text_field, shouldChangeCharactersInRange:range, replacementString:string)
|
172
|
-
limit = (self.class.text_field_limits || {}).find do |field_name, limit|
|
173
|
-
view("#{field_name}:input") == text_field
|
174
|
-
end.try(:last)
|
175
|
-
return true unless limit
|
176
|
-
allow_string_replacement?(text_field, limit, range, string)
|
177
|
-
end
|
178
147
|
|
179
148
|
def allow_string_replacement?(target, limit, range, string)
|
180
149
|
if string.length.zero? || (range.length + limit - target.text.length) >= string.length
|
@@ -0,0 +1,49 @@
|
|
1
|
+
motion_require '../table/table_delegate.rb'
|
2
|
+
module MotionPrime
|
3
|
+
class FormDelegate < TableDelegate
|
4
|
+
def textFieldShouldReturn(text_field)
|
5
|
+
table_section.on_input_return(text_field)
|
6
|
+
end
|
7
|
+
def textFieldShouldBeginEditing(text_field)
|
8
|
+
text_field.respond_to?(:readonly) ? !text_field.readonly : true
|
9
|
+
end
|
10
|
+
def textFieldDidBeginEditing(text_field)
|
11
|
+
table_section.on_input_edit_begin(text_field)
|
12
|
+
end
|
13
|
+
def textFieldDidEndEditing(text_field)
|
14
|
+
table_section.on_input_edit_end(text_field)
|
15
|
+
end
|
16
|
+
|
17
|
+
def textField(text_field, shouldChangeCharactersInRange:range, replacementString:string)
|
18
|
+
limit = (table_section.class.text_field_limits || {}).find do |field_name, limit|
|
19
|
+
table_section.view("#{field_name}:input") == text_field
|
20
|
+
end.try(:last)
|
21
|
+
return true unless limit
|
22
|
+
table_section.allow_string_replacement?(text_field, limit, range, string)
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def textViewDidBeginEditing(text_view)
|
27
|
+
table_section.on_input_edit_begin(text_view)
|
28
|
+
end
|
29
|
+
def textViewDidEndEditing(text_view)
|
30
|
+
table_section.on_input_edit_end(text_view)
|
31
|
+
end
|
32
|
+
def textViewDidChange(text_view) # bug in iOS 7 - cursor is out of textView bounds
|
33
|
+
line = text_view.caretRectForPosition(text_view.selectedTextRange.start)
|
34
|
+
overflow = line.origin.y + line.size.height -
|
35
|
+
(text_view.contentOffset.y + text_view.bounds.size.height - text_view.contentInset.bottom - text_view.contentInset.top)
|
36
|
+
if overflow > 0
|
37
|
+
offset = text_view.contentOffset
|
38
|
+
offset.y += overflow + text_view.textContainerInset.bottom
|
39
|
+
UIView.animate(duration: 0.2) do
|
40
|
+
text_view.setContentOffset(offset)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def textView(text_view, shouldChangeTextInRange:range, replacementText:string)
|
46
|
+
textField(text_view, shouldChangeCharactersInRange:range, replacementString:string)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -7,17 +7,18 @@ module MotionPrime
|
|
7
7
|
include HasStyleChainBuilder
|
8
8
|
include HasSearchBar
|
9
9
|
|
10
|
-
class_attribute :async_data_options, :section_header_options
|
10
|
+
class_attribute :async_data_options, :section_header_options, :pull_to_refresh_block
|
11
|
+
|
11
12
|
attr_accessor :table_element, :did_appear, :section_headers, :section_header_options
|
12
13
|
attr_reader :decelerating
|
13
14
|
before_render :render_table
|
15
|
+
after_render :init_pull_to_refresh
|
16
|
+
delegate :init_pull_to_refresh, to: :table_delegate
|
14
17
|
|
15
|
-
def dealloc
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
super
|
20
|
-
end
|
18
|
+
# def dealloc
|
19
|
+
# pp 'deallocating table. sections count:', @data.try(:count)
|
20
|
+
# super
|
21
|
+
# end
|
21
22
|
|
22
23
|
def table_data
|
23
24
|
[]
|
@@ -107,12 +108,15 @@ module MotionPrime
|
|
107
108
|
styles
|
108
109
|
end
|
109
110
|
|
111
|
+
def table_delegate
|
112
|
+
@table_delegate ||= TableDelegate.new(section: self)
|
113
|
+
end
|
114
|
+
|
110
115
|
def render_table
|
111
|
-
delegate = TableDelegate.new(section: self)
|
112
116
|
options = {
|
113
117
|
styles: table_styles.values.flatten,
|
114
|
-
delegate:
|
115
|
-
data_source:
|
118
|
+
delegate: table_delegate,
|
119
|
+
data_source: table_delegate,
|
116
120
|
style: (UITableViewStyleGrouped unless flat_data?)
|
117
121
|
}
|
118
122
|
if async_data? && self.class.async_data_options.has_key?(:estimated_row_height)
|
@@ -390,6 +394,10 @@ module MotionPrime
|
|
390
394
|
section = options.delete(:id)
|
391
395
|
self.section_header_options[section] = options
|
392
396
|
end
|
397
|
+
|
398
|
+
def pull_to_refresh(&block)
|
399
|
+
self.pull_to_refresh_block = block
|
400
|
+
end
|
393
401
|
end
|
394
402
|
end
|
395
403
|
end
|
@@ -3,7 +3,7 @@ module MotionPrime
|
|
3
3
|
def add_pull_to_refresh(options = {}, &block)
|
4
4
|
screen.automaticallyAdjustsScrollViewInsets = false
|
5
5
|
|
6
|
-
table_view.addPullToRefreshWithActionHandler(block)
|
6
|
+
table_view.addPullToRefreshWithActionHandler(block) # block must be a variable
|
7
7
|
screen.setup table_view.pullToRefreshView, styles: [:base_pull_to_refresh]
|
8
8
|
end
|
9
9
|
|
@@ -5,6 +5,13 @@ module MotionPrime
|
|
5
5
|
self.table_section = options[:section].try(:weak_ref)
|
6
6
|
end
|
7
7
|
|
8
|
+
def init_pull_to_refresh
|
9
|
+
return unless block = table_section.class.pull_to_refresh_block
|
10
|
+
table_section.add_pull_to_refresh do
|
11
|
+
table_section.instance_eval(&block)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
8
15
|
def numberOfSectionsInTableView(table)
|
9
16
|
table_section.number_of_sections(table)
|
10
17
|
end
|
@@ -3,6 +3,7 @@ class MPCellWithSection < UITableViewCell
|
|
3
3
|
|
4
4
|
def setSection(section)
|
5
5
|
@section = section.try(:weak_ref)
|
6
|
+
@section_name = section.name
|
6
7
|
end
|
7
8
|
|
8
9
|
def drawRect(rect)
|
@@ -11,6 +12,7 @@ class MPCellWithSection < UITableViewCell
|
|
11
12
|
end
|
12
13
|
|
13
14
|
def draw_in(rect)
|
14
|
-
|
15
|
+
return unless section
|
16
|
+
section.draw_in(rect) if section.respond_to?(:draw_in)
|
15
17
|
end
|
16
18
|
end
|
@@ -7,7 +7,7 @@ module MotionPrime
|
|
7
7
|
|
8
8
|
screens.each_with_index do |screen, index|
|
9
9
|
if screen.is_a?(Hash)
|
10
|
-
screen, image, title = screen[:screen], screen[:image], screen[:title]
|
10
|
+
screen, image, title = screen[:screen].try(:weak_ref), screen[:image], screen[:title]
|
11
11
|
title ||= screen.title
|
12
12
|
image = image.uiimage if image
|
13
13
|
screen.tabBarItem = UITabBarItem.alloc.initWithTitle title, image: image, tag: index
|
@@ -24,7 +24,7 @@ module MotionPrime
|
|
24
24
|
controller.viewControllers = view_controllers
|
25
25
|
controller
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def open_tab(tab)
|
29
29
|
controller = viewControllers[tab]
|
30
30
|
if controller
|
data/motion-prime/version.rb
CHANGED
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.
|
4
|
+
version: 0.4.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Iskander Haziev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-01-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -268,6 +268,7 @@ files:
|
|
268
268
|
- motion-prime/sections/form/base_field_section.rb
|
269
269
|
- motion-prime/sections/form/base_header_section.rb
|
270
270
|
- motion-prime/sections/form/date_field_section.rb
|
271
|
+
- motion-prime/sections/form/form_delegate.rb
|
271
272
|
- motion-prime/sections/form/password_field_section.rb
|
272
273
|
- motion-prime/sections/form/select_field_section.rb
|
273
274
|
- motion-prime/sections/form/string_field_section.rb
|