ProMotion 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ProMotion.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Jamon Holmgren
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/ProMotion/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Jamon Holmgren"]
6
+ gem.email = ["jamon@clearsightstudio.com"]
7
+ gem.description = "ProMotion is a new way to organize RubyMotion apps."
8
+ gem.summary = "ProMotion is a new way to organize RubyMotion apps. Instead of dealing
9
+ with UIViewControllers and UIViews, you work with Screens. Screens are
10
+ a logical way to think of your app."
11
+ gem.homepage = ""
12
+
13
+ gem.files = `git ls-files`.split($\)
14
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
+ gem.name = "ProMotion"
17
+ gem.require_paths = ["lib"]
18
+ gem.version = ProMotion::VERSION
19
+ end
@@ -0,0 +1,337 @@
1
+ # ProMotion
2
+
3
+ **Please note: this is a proof of concept and does not yet work.**
4
+
5
+ ProMotion is a new way to organize RubyMotion apps. Instead of dealing
6
+ with UIViewControllers and UIViews, you work with Screens. Screens are
7
+ a logical way to think of your app.
8
+
9
+ Typical /app file structure:
10
+
11
+ app
12
+ screens
13
+ photos
14
+ list_photos_screen.rb
15
+ show_photo_screen.rb
16
+ edit_photo_screen.rb
17
+ home_screen.rb
18
+ settings_screen.rb
19
+ models
20
+ views
21
+ app_delegate.rb
22
+
23
+ The "views" folder contains custom view components, written in normal RubyMotion. "models" can be whatever ORM you're using.
24
+
25
+ ### What about MVC?
26
+
27
+ I'm a big believer in MVC (I'm a Rails developer, too). I found that most of the time working in RubyMotion seems to happen
28
+ in the ViewControllers. This pattern may be best for simpler, smaller apps.
29
+
30
+ This is a proof of concept. I'd really appreciate feedback on it at my email address (jamon@clearsightstudio.com) or Twitter (@jamonholmgren).
31
+
32
+ ## Installation
33
+
34
+ Add this line to your application's Gemfile:
35
+
36
+ gem 'ProMotion'
37
+
38
+ And then execute:
39
+
40
+ $ bundle
41
+
42
+ Or install it yourself as:
43
+
44
+ $ gem install ProMotion
45
+
46
+ ## Usage
47
+
48
+ It's easy to load your first view with a navigation bar (the view is opened in a UINavigationController):
49
+
50
+ ```ruby
51
+ # In /app/app_delegate.rb:
52
+ class AppDelegate
53
+ def application(application, didFinishLaunchingWithOptions:launchOptions)
54
+ @window = HomeScreen.open_with_nav_bar
55
+
56
+ true
57
+ end
58
+ end
59
+ ```
60
+
61
+ Screens are pretty straightforward. You extend ProMotion::Screen and provide a title and an on_load method.
62
+
63
+ ```ruby
64
+ # In /app/screens/home_screen.rb:
65
+ class HomeScreen < ProMotion::Screen
66
+ # Set the title for use in nav bars and other containers
67
+ title "Home"
68
+
69
+ # Called when this view is first "opened" and allows you to set up your view
70
+ def on_load
71
+ @default_image = add_image(:default_image, src: "default.png", frame: [10, 50, 100, 100])
72
+ end
73
+ end
74
+ ```
75
+
76
+ In on_load, you can add images, buttons, labels, custom views to your screen.
77
+
78
+ ```ruby
79
+ # In /app/screens/home_screen.rb:
80
+ class HomeScreen < ProMotion::Screen
81
+ # Set the title for use in nav bars and other containers
82
+ title "Home"
83
+
84
+ # Called when this view is first "opened" and allows you to set up your view
85
+ def on_load
86
+ # Add view items as instance vars so you can access them in other methods
87
+
88
+ # This adds a right nav bar button. on_tap allows you to set a method to call when it's tapped.
89
+ @right_bar_button = add_right_nav_button(label: "Save", on_tap: :save)
90
+
91
+ # Helper function for adding a button
92
+ @settings_button = add_button(label: "Settings", frame: [10, 10, 100, 30])
93
+
94
+ # Helper function for adding an image
95
+ @default_image = add_image(:default_image, src: "default.png", frame: [10, 50, 100, 100])
96
+
97
+ # You can also add custom UIViews through the add_view method.
98
+ @custom_view = add_view(ChatView.alloc.initWithFrame(CGRectMake(10, 300, 40, 40)))
99
+ end
100
+ end
101
+ ```
102
+
103
+ View items can be bound to events (like jQuery) and run methods or run a block.
104
+
105
+ ```ruby
106
+ # settings_pushed is executed when the button is tapped
107
+ @settings_button = add_button(label: "Settings", frame: [10, 10, 100, 30])
108
+ @settings_button.on(:tap, :settings_pushed)
109
+
110
+ # This demonstrates a block
111
+ @settings_button.on(:tap) do
112
+ # Do something
113
+ end
114
+
115
+ # This button passes in arguments to the method when it's tapped
116
+ @edit_button = add_button(label: "Edit", frame: [10, 10, 100, 30])
117
+ @edit_button.on(:tap, :edit_pushed, id: 4)
118
+ ```
119
+
120
+ To open other screens, just call their "open" method:
121
+
122
+ ```ruby
123
+ def settings_button_tapped
124
+ SettingsScreen.open
125
+ end
126
+ ```
127
+
128
+ You can pass in arguments to those screens if they have accessors:
129
+
130
+ ```ruby
131
+ # /app/screens/settings_screen.rb
132
+ class SettingsScreen < ProMotion::Screen
133
+ attr_accessor :user_type
134
+
135
+ def on_load
136
+ if self.user_type == "Admin"
137
+ # Stuff
138
+ end
139
+ end
140
+
141
+ # ...
142
+ end
143
+
144
+ # /app/screens/home_screen.rb
145
+ class HomeScreen < ProMotion::Screen
146
+ # ...
147
+
148
+ def settings_button_tapped
149
+ SettingsScreen.open(user_type: "Admin")
150
+ end
151
+ end
152
+ ```
153
+
154
+ When you're done with a screen, just close it:
155
+
156
+ ```ruby
157
+ def save_and_close
158
+ if @model.save
159
+ self.close
160
+ end
161
+ end
162
+ ```
163
+
164
+ If you want to pass arguments back to the previous screen, go for it.
165
+
166
+ ```ruby
167
+ class SettingsScreen < ProMotion::Screen
168
+ # ...
169
+
170
+ def save_and_close
171
+ self.close(saved_changes: true)
172
+ end
173
+ end
174
+
175
+ class MainScreen < ProMotion::Screen
176
+ # ...
177
+
178
+ def on_return(args = {})
179
+ if args[:saved_changes]
180
+ self.reload_something
181
+ end
182
+ end
183
+ end
184
+ ```
185
+
186
+ You can create sectioned table screens easily.
187
+
188
+ ```ruby
189
+ class HomeScreen < ProMotion::Screen
190
+ title "Home"
191
+
192
+ # Defaults to :normal. :plain_table, :grouped_table are options.
193
+ screen_type :grouped_table
194
+
195
+ def on_load
196
+ # No need to set anything up, really
197
+ end
198
+
199
+ # If you define your screen_type as some sort of table, this gets called to get the data.
200
+ # You can also refresh the table data manually by calling `self.reload_table_data`
201
+ def table_data
202
+ # You can create a new table section here and add cells to it like so:
203
+ @account_section = add_section(label: "Your Account")
204
+ @account_section.add_cell(title: "Edit Profile", action: :edit_profile, arguments: { account_id: @account.id })
205
+ @account_section.add_cell(title: "Log Out", action: :log_out)
206
+
207
+ # Or just pass back an array with everything defined and we'll build it for you:
208
+ [{
209
+ title: "Your Account",
210
+ cells: [
211
+ { title: "Edit Profile", action: :edit_profile },
212
+ { title: "Log Out", action: :log_out },
213
+ { title: "Notification Settings", action: :notification_settings }
214
+ ]
215
+ }, {
216
+ title: "App Stuff",
217
+ cells: [
218
+ { title: "About", action: :show_about },
219
+ { title: "Feedback", action: :show_feedback }
220
+ ]
221
+ }]
222
+ end
223
+ end
224
+ ```
225
+
226
+ Here's a full demo of a screen:
227
+
228
+ ```ruby
229
+ # In /app/screens/home_screen.rb:
230
+
231
+ class HomeScreen < ProMotion::Screen
232
+ # Accessors allow screens to set parameters when opening this screen
233
+ attr_accessor :foo
234
+
235
+ # Set the title for use in nav bars and other containers
236
+ title "Home"
237
+
238
+ # Defaults to :normal. :plain_table, :grouped_table are options.
239
+ screen_type :plain_table
240
+
241
+ # Called when this view is first "opened" and allows you to set up your view
242
+ def on_load
243
+ # Add view items as instance vars so you can access them in other methods
244
+ # This adds a right nav bar button. on_tap allows you to set a method to call when it's tapped.
245
+ @right_bar_button = add_right_nav_button(label: "Save", on_tap: :save)
246
+
247
+ # Helper function for adding a button
248
+ @settings_button = add_button(label: "Settings", frame: [10, 10, 100, 30])
249
+
250
+ # View items can be bound to events (like jQuery) and run methods or run a block.
251
+ @settings_button.on(:tap, :settings_pushed)
252
+ @settings_button.on(:tapHold) do
253
+ # Do something
254
+ end
255
+
256
+ # Helper function for adding an image
257
+ @default_image = add_image(:default_image, src: "default.png", frame: [10, 50, 100, 100])
258
+
259
+ # This button passes in arguments to the method when it's tapped
260
+ @edit_button = add_button(label: "Edit", frame: [10, 10, 100, 30])
261
+ @edit_button.on(:tap, :edit_pushed, id: 4)
262
+
263
+ # You can also add custom UIViews through the add_view method.
264
+ @custom_view = add_view(ChatView.alloc.initWithFrame(CGRectMake(10, 300, 40, 40)))
265
+ end
266
+
267
+ # If you define your screen_type as some sort of table, this gets called to get the data.
268
+ # You can also refresh the table data manually by calling `self.reload_table_data`
269
+ def table_data
270
+ # You can create a new table section here and add cells to it like so:
271
+ @account_section = add_section(label: "Your Account")
272
+ @account_section.add_cell(title: "Edit Profile", action: :edit_profile, arguments: { account_id: @account.id })
273
+ @account_section.add_cell(title: "Log Out", action: :log_out)
274
+
275
+ # Or just pass back an array with everything defined and we'll build it for you:
276
+ [{
277
+ title: "Your Account",
278
+ cells: [
279
+ { title: "Edit Profile", action: :edit_profile },
280
+ { title: "Log Out", action: :log_out },
281
+ { title: "Notification Settings", action: :notification_settings }
282
+ ]
283
+ }, {
284
+ title: "App Stuff",
285
+ cells: [
286
+ { title: "About", action: :show_about },
287
+ { title: "Feedback", action: :show_feedback }
288
+ ]
289
+ }]
290
+ end
291
+
292
+ # Custom method, invoked when tapping something with this as the action
293
+ def save
294
+ # Assuming some sort of ORM, like ParseModel
295
+ @my_model.save
296
+
297
+ # When you want to close the current view (usually in a navigation controller), just run this.
298
+ self.close
299
+
300
+ # You can also pass back arguments to the previous view as you close.
301
+ # If the previous screen has an `on_return` method, this will be passed into that method
302
+ self.close(did_stuff: true)
303
+ end
304
+
305
+ # This is called any time a screen "above" this screen is closed. args = {} is required.
306
+ def on_return(args = {})
307
+ if args[:did_stuff]
308
+ # Refresh?
309
+ end
310
+ end
311
+
312
+ # Custom method
313
+ def settings_pushed
314
+ # Just open a settings screen
315
+ SettingsScreen.open
316
+ end
317
+
318
+ def close_pushed
319
+ self.close
320
+ end
321
+
322
+ # Custom method with passed in arguments
323
+ def edit_pushed(args)
324
+ # Open a screen and set some of its attributes
325
+ EditScreen.open(id: args[:id])
326
+ end
327
+ end
328
+ ```
329
+
330
+
331
+ ## Contributing
332
+
333
+ 1. Fork it
334
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
335
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
336
+ 4. Push to the branch (`git push origin my-new-feature`)
337
+ 5. Create new Pull Request
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,5 @@
1
+ require "ProMotion/version"
2
+
3
+ module ProMotion
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,3 @@
1
+ module ProMotion
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ProMotion
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jamon Holmgren
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-30 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: ProMotion is a new way to organize RubyMotion apps.
15
+ email:
16
+ - jamon@clearsightstudio.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - Gemfile
23
+ - LICENSE
24
+ - ProMotion.gemspec
25
+ - README.md
26
+ - Rakefile
27
+ - lib/ProMotion.rb
28
+ - lib/ProMotion/version.rb
29
+ homepage: ''
30
+ licenses: []
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ requirements: []
48
+ rubyforge_project:
49
+ rubygems_version: 1.8.24
50
+ signing_key:
51
+ specification_version: 3
52
+ summary: ProMotion is a new way to organize RubyMotion apps. Instead of dealing with
53
+ UIViewControllers and UIViews, you work with Screens. Screens are a logical way
54
+ to think of your app.
55
+ test_files: []