README.md in ProMotion-0.6.5 vs README.md in ProMotion-0.7.0
- old
+ new
@@ -2,24 +2,24 @@
## A new way to easily build RubyMotion apps.
ProMotion is a RubyMotion gem that makes iOS development more like Ruby and less like Objective-C.
+Featured on the RubyMotion blog: [http://blog.rubymotion.com/post/50523137515/introducing-promotion-a-full-featured-rubymotion](http://blog.rubymotion.com/post/50523137515/introducing-promotion-a-full-featured-rubymotion)
+
**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*
- [ProMotion ](#promotion-)
- [A new way to easily build RubyMotion apps.](#a-new-way-to-easily-build-rubymotion-apps)
- [Tutorials](#tutorials)
- [Screencasts](#screencasts)
- [Sample Apps](#sample-apps)
- [Apps Built With ProMotion](#apps-built-with-promotion)
- - [BigDay! Reminder App](#bigday-reminder-app)
- - [TipCounter App](#tipcounter-app)
- [Getting Started](#getting-started)
- [Setup](#setup)
- [What's New?](#whats-new)
- - [Version 0.6](#version-06)
+ - [Version 0.7](#version-07)
- [Usage](#usage)
- [Creating a basic screen](#creating-a-basic-screen)
- [Loading your first screen](#loading-your-first-screen)
- [Creating a split screen (iPad apps only)](#creating-a-split-screen-ipad-apps-only)
- [Creating a tab bar](#creating-a-tab-bar)
@@ -27,15 +27,11 @@
- [Opening and closing screens](#opening-and-closing-screens)
- [Note about split screens and universal apps](#note-about-split-screens-and-universal-apps)
- [Adding view elements](#adding-view-elements)
- [Table Screens](#table-screens)
- [Using your own UIViewController](#using-your-own-uiviewcontroller)
-- [Reference](#reference)
- - [Screen](#screen)
- - [TableScreen](#tablescreen)
- - [Logger](#logger)
- - [Console [deprecated]](#console-deprecated)
+- [API Reference](#api-reference)
- [Help](#help)
- [Contributing](#contributing)
- [Working on Features](#working-on-features)
- [Submitting a Pull Request](#submitting-a-pull-request)
- [Primary Contributors](#primary-contributors)
@@ -55,20 +51,12 @@
[https://github.com/jamonholmgren/promotion-demo](https://github.com/jamonholmgren/promotion-demo)
## Apps Built With ProMotion
-### BigDay! Reminder App
-Check out the free [BigDay! Reminder app](https://itunes.apple.com/us/app/bigday!/id571756685?ls=1&mt=8) on the
-App Store to see what's possible. ClearSight Studio built the app for Kijome Software, a small app investment company.
+[View apps built with ProMotion (feel free to submit yours in a pull request!)](https://github.com/clearsightstudio/ProMotion/blob/master/PROMOTION_APPS.md)
-### TipCounter App
-[TipCounter](http://www.tipcounterapp.com) was built by [Matt Brewer](https://github.com/macfanatic/) for bartenders and servers to easily track their tips. Used ProMotion and the development was a lot of fun!
-
-### Winston-Salem Crime Map
-Have an interest in crime statistics and locations? Live in Winston-Salem, NC? This hyper-local and [open source](https://github.com/markrickert/WSCrime) RubyMotion app uses a mixture custom UIViewControllers and ProMotion for ease of attribute setting and adding views. Check it out [on the App Store](http://www.mohawkapps.com/winston-salem-crime-map/download/) or [fork it and contribute](https://github.com/markrickert/WSCrime)!
-
# Getting Started
ProMotion is designed to be as intuitive and Ruby-like as possible. For example, here is a
typical app folder structure:
@@ -106,34 +94,39 @@
Create a Gemfile and add the following lines:
```ruby
source 'https://rubygems.org'
-gem "ProMotion", "~> 0.6.2"
+gem "ProMotion", "~> 0.7.0"
```
Run `bundle install` in Terminal to install ProMotion.
Go into your app/app_delegate.rb file and replace everything with the following:
```ruby
-class AppDelegate < ProMotion::Delegate
+class AppDelegate < PM::Delegate
def on_load(app, options)
open HomeScreen.new(nav_bar: true)
end
end
```
+Note: You can use other keys in `on_load` when you open a new screen:
+
+* `modal: ` [`true` | `false`]
+* `toolbar:` [`true` | `false`]
+
Make sure you remove the `didFinishLoadingWithOptions` method or call `super` in it. Otherwise
ProMotion won't get set up and `on_load` won't be called.
Create a folder in `/app` named `screens`. Create a file in that folder named `home_screen.rb`.
Now drop in this code:
```ruby
-class HomeScreen < ProMotion::Screen
+class HomeScreen < PM::Screen
title "Home"
def will_appear
set_attributes self.view, {
backgroundColor: UIColor.whiteColor
@@ -148,28 +141,32 @@
![ProMotion Home Screen](http://clearsightstudio.github.com/ProMotion/img/ProMotion/home-screen.png)
# What's New?
-## Version 0.6
+## Version 0.7
-* Will auto-detect if you've loaded [motion-xray](https://github.com/colinta/motion-xray) and enable it.
-* Added `open_split_screen` for iPad-supported apps (thanks @rheoli for your contributions to this)
-* Added `refreshable` to TableScreens (thanks to @markrickert) for pull-to-refresh support.
-* `ProMotion::AppDelegateParent` renamed to `ProMotion::Delegate` (`AppDelegateParent` is an alias)
-* `set_attributes` and `add` now apply nested attributes recursively
-* `set_attributes` and `add` now accept snake_case instead of camelCase methods (e.g., background_color)
-* Added `add_to` method for adding views to any parent view. `remove` works with this normally.
-* Deprecated Console.log and replaced with PM::Logger
-* Many improvements to how screens and navigation controllers are loaded, tests
+* Added [Teacup](https://github.com/rubymotion/teacup) support! Just specify `stylename:` in your `add:` or `set_attributes:` property hash.
+* Added `PM::FormotionScreen` for easy [Formotion](https://github.com/clayallsopp/formotion) compatibility.
+* Massive refactor of `PM::TableScreen` to make it more reliable and testable. Deprecated some old stuff in there.
+* Made a new `TableViewCellModule` that makes it easy to set up custom cells.
+* Refactored the `PM::Delegate` class to make it cleaner and more testable.
+* Added `PM::PushNotification` class (this needs more work and testing) and some nice `PM::Delegate` methods for registering and handling them.
+* `set_nav_bar_left_button` and `set_nav_bar_right_button` are now just `set_nav_bar_button`. See API reference.
+* Speaking of API reference, [we now have one](https://github.com/clearsightstudio/ProMotion/wiki/_pages). We've moved the bulk of the info to the wiki.
+* Added `open_modal` alias for `open @screen, modal: true`
+* Added functional (interactive) tests and lots of unit tests. Run `rake spec:functional` or `rake spec:unit` to run them individually.
+* Renamed `is_modal?` to `modal?`, `has_nav_bar?` to `nav_bar?` in screens.
+* Removed MotionTable references.
+* Lots of small improvements and bugfixes.
# Usage
## Creating a basic screen
```ruby
-class HomeScreen < ProMotion::Screen
+class HomeScreen < PM::Screen
title "Home"
def on_load
# Load data
end
@@ -187,22 +184,22 @@
## Loading your first screen
```ruby
# In app/app_delegate.rb
-class AppDelegate < ProMotion::Delegate
+class AppDelegate < PM::Delegate
def on_load(app, options)
open MyHomeScreen.new(nav_bar: true)
end
end
```
## Creating a split screen (iPad apps only)
```ruby
# In app/app_delegate.rb
-class AppDelegate < ProMotion::Delegate
+class AppDelegate < PM::Delegate
def on_load(app, options)
open_split_screen MenuScreen, DetailScreen
end
end
```
@@ -242,30 +239,34 @@
end
```
## Add navigation bar buttons
-These two methods add the buttons to the top navigation bar of a screen. The `action:` lets you specify a method to
+This method adds the buttons to the top navigation bar of a screen. The `action:` lets you specify a method to
call when that button is tapped, and you can pass in a UIBarButton style using `type:`.
```ruby
-set_nav_bar_right_button "Save", action: :save_something, type: UIBarButtonItemStyleDone
-set_nav_bar_left_button "Cancel", action: :return_to_some_other_screen, type: UIBarButtonItemStylePlain
+set_nav_bar_button :right, title: "Save", action: :save_something, type: UIBarButtonItemStyleDone
+set_nav_bar_button :left, title: "Cancel", action: :return_to_some_other_screen, type: UIBarButtonItemStylePlain
```
-If you pass an instance of a `UIImage`, the `UIBarButton` will automatically display with that image instead of text. *Don't forget retina and landscape versions of your image!*
+You can pass in an image with `image:`. *Don't forget retina and landscape versions of your image!*
-If you pass `:system` for the title, then you can get a system item. E.g.:
+```ruby
+set_nav_bar_button :left, image: UIImage.imageNamed("cancel-button"), action: :cancel_something
+```
+You can also pass in a `system_icon` instead.
+
```ruby
-set_nav_bar_right_button nil, action: :add_something, system_icon: UIBarButtonSystemItemAdd
+set_nav_bar_button :right, system_icon: UIBarButtonSystemItemAdd, action: :add_something
```
Additionally, if you pass an instance of a `UIBarButtonItem`, the `UIBarButton` will automatically display that particular button item.
```ruby
-set_nav_bar_left_button self.editButtonItem
+set_nav_bar_button :left, button: UIBarButtonItem.alloc.initWithCustomView(button)
```
## Opening and closing screens
If the user taps something and you want to open a new screen, it's easy. Just use `open` and pass in the screen class
@@ -284,24 +285,28 @@
You can also open a screen as a modal.
```ruby
open SettingsScreen.new, modal: true
+
+# Or... (this is equivalent)
+
+open_modal SettingsScreen.new
```
You can pass in arguments to other screens if they have accessors:
```ruby
-class HomeScreen < ProMotion::Screen
+class HomeScreen < PM::Screen
# ...
def settings_button_tapped
open ProfileScreen.new(user: some_user)
end
end
-class ProfileScreen < ProMotion::Screen
+class ProfileScreen < PM::Screen
attr_accessor :user
def on_load
self.user # => some_user instance
end
@@ -318,20 +323,20 @@
```
You can close a screen (modal or in a nav controller) and pass back arguments to the previous screen's "on_return" method:
```ruby
-class ItemScreen < ProMotion::Screen
+class ItemScreen < PM::Screen
# ...
def save_and_close
if @model.save
close(model_saved: true)
end
end
end
-class MainScreen < ProMotion::Screen
+class MainScreen < PM::Screen
# ...
def on_return(args = {})
if args[:model_saved]
self.reload_something
end
@@ -343,11 +348,11 @@
It's common to want to open a screen in the same navigation controller if on iPhone but
in a separate detail view when on iPad. Here's a good way to do that.
```ruby
-class MenuScreen < ProMotion::TableScreen
+class MenuScreen < PM::TableScreen
# ...
def some_action
open SomeScreen.new, in_detail: true
end
end
@@ -357,60 +362,65 @@
if it's available. If not, open normally. This also works for `in_master:`.
## Adding view elements
Any view item (UIView, UIButton, custom UIView subclasses, etc) can be added to the current view with `add`.
-`add` accepts a second argument which is a hash of attributes that get applied to the element before it is
+`add` accepts a second argument which is a hash of attributes that get applied to the element right after it is
dropped into the view.
`add(view, attr={})`
```ruby
-@label = add UILabel.new, {
+add UILabel.new, {
text: "This is awesome!",
font: UIFont.systemFontOfSize(18),
resize: [ :left, :right, :top, :bottom, :width, :height ], # autoresizingMask
left: 5, # These four attributes are used with CGRectMake
top: 5,
width: 20,
height: 20
}
+```
-@element = add UIView.alloc.initWithFrame(CGRectMake(0, 0, 20, 20)), {
- backgroundColor: UIColor.whiteColor
-}
+Using Teacup? Just provide a `stylename`.
+
+```ruby
+@element = UIView.alloc.initWithFrame(CGRectMake(0, 0, 20, 20))
+add @element, stylename: :my_custom_view
```
The `set_attributes` method is identical to add except that it does not add it to the current view.
If you use snake_case and there isn't an existing method, it'll try camelCase. This allows you to
use snake_case for Objective-C methods.
`set_attributes(view, attr={})`
```ruby
-@element = set_attributes UIView.alloc.initWithFrame(CGRectMake(0, 0, 20, 20)), {
+set_attributes UIView.new, {
# `background_color` is translated to `backgroundColor` automatically.
- background_color: UIColor.whiteColor
+ background_color: UIColor.whiteColor,
+ frame: CGRectMake(0, 0, 20, 20)
}
```
You can use `add_to` to add a view to any other view, not just the main view.
`add_to(parent_view, new_view, attr={})`
```ruby
-add_to @some_parent_view, UIView.alloc.initWithFrame(CGRectMake(0, 0, 20, 20)), {
+add_to @some_parent_view, UIView.new, {
+ frame: CGRectMake(0, 0, 20, 20),
backgroundColor: UIColor.whiteColor
}
```
## Table Screens
You can create sectioned table screens easily with TableScreen, SectionedTableScreen, and GroupedTableScreen.
```ruby
-class SettingsScreen < ProMotion::GroupedTableScreen
+class SettingsScreen < PM::GroupedTableScreen
title "Settings"
def on_load
set_nav_bar_right_button("Save", action: :save)
set_tab_bar_item(title: "Settings", icon: "settings.png")
@@ -448,465 +458,31 @@
puts args[:id] # => 3
end
end
```
-You can provide remotely downloaded images for cells by including the CocoaPod "SDWebImage" in
-your Rakefile and doing this:
-
-```ruby
- cells: [
- {
- title: "Cell with image",
- remote_image: { url: "http://placekitten.com/200/300", placeholder: "some-local-image" }
- }
- ]
-```
-
## Using your own UIViewController
-Sometimes you want to inherit from a different UIViewController other than that provided by ProMotion,
-such as when using [Formotion](https://github.com/clayallsopp/formotion). **RubyMotion doesn't currently
-allow us to override built-in methods when including them as a module.** And we really need to override
-`viewDidLoad` and others.
+### [Usage: Formotion or other custom UIViewControllers](https://github.com/clearsightstudio/ProMotion/wiki/Usage:-Formotion-or-other-custom-UIViewControllers)
-Fortunately, there's a workaround for that.
+# API Reference
-```ruby
-class EventsScreen < Formotion::FormController # Can also be < UIViewController
- include ProMotion::ScreenModule # Not TableScreenModule since we're using Formotion for that
+We've created a fairly comprehensive wiki with code examples, usage examples, and API reference.
- # Required functions for ProMotion to work properly
+### [ProMotion API Reference](https://github.com/clearsightstudio/ProMotion/wiki/_pages)
- def viewDidLoad
- super
- self.view_did_load if self.respond_to?(:view_did_load)
- end
-
- def viewWillAppear(animated)
- super
- self.view_will_appear(animated) if self.respond_to?("view_will_appear:")
- end
-
- def viewDidAppear(animated)
- super
- self.view_did_appear(animated) if self.respond_to?("view_did_appear:")
- end
-
- def viewWillDisappear(animated)
- self.view_will_disappear(animated) if self.respond_to?("view_will_disappear:")
- super
- end
-
- def viewDidDisappear(animated)
- self.view_did_disappear(animated) if self.respond_to?("view_did_disappear:")
- super
- end
-
- def shouldAutorotateToInterfaceOrientation(orientation)
- self.should_rotate(orientation)
- end
-
- def shouldAutorotate
- self.should_autorotate
- end
-
- def willRotateToInterfaceOrientation(orientation, duration:duration)
- self.will_rotate(orientation, duration)
- end
-
- def didRotateFromInterfaceOrientation(orientation)
- self.on_rotate
- end
-end
-```
-
-# Reference
-
-## Screen
-
-<table>
- <tr>
- <th>Method</th>
- <th>Description</th>
- </tr>
- <tr>
- <td>is_modal?</td>
- <td>Returns if the screen was opened in a modal window.</td>
- </tr>
- <tr>
- <td>self</td>
- <td>Returns the Screen which is a subclass of UIViewController or UITableViewController</td>
- </tr>
- <tr>
- <td>has_nav_bar?</td>
- <td>Returns if the screen is contained in a navigation controller.</td>
- </tr>
- <tr>
- <td>set_tab_bar_item(args)</td>
- <td>
- Creates the tab that is shown in a tab bar item.<br />
- Arguments: <code>{ icon: "imagename", systemIcon: UISystemIconContacts, title: "tabtitle" }</code>
- </td>
- </tr>
- <tr>
- <td>on_appear</td>
- <td>
- Callback for when the screen appears.<br />
- </td>
- </tr>
- <tr>
- <td>will_appear</td>
- <td>
- Callback for before the screen appears.<br />
- This is a good place to put your view constructors, but be careful that
- you don't add things more than on subsequent screen loads.
- </td>
- </tr>
- <tr>
- <td>will_disappear</td>
- <td>
- Callback for before the screen disappears.<br />
- </td>
- </tr>
- <tr>
- <td>will_rotate(orientation, duration)</td>
- <td>
- Callback for before the screen rotates.<br />
- </td>
- </tr>
- <tr>
- <td>on_opened **Deprecated**</td>
- <td>
- Callback when screen is opened via a tab bar. Please don't use this, as it will be removed in the future<br />
- Use will_appear
- </td>
- </tr>
- <tr>
- <td>set_nav_bar_left_button(title, args = {})</td>
- <td>
- Set a left nav bar button.<br />
- `title` can be a `String` or a `UIImage`.
- </td>
- </tr>
- <tr>
- <td>set_nav_bar_right_button(title, args = {})</td>
- <td>
- Set a right nav bar button.<br />
- `title` can be a `String` or a `UIImage`.<br />
- <img src="http://i.imgur.com/whbkc.png" />
- </td>
- </tr>
- <tr>
- <td>should_autorotate</td>
- <td>
- (iOS 6) return true/false if screen should rotate.<br />
- Defaults to true.
- </td>
- </tr>
- <tr>
- <td>should_rotate(orientation)</td>
- <td>
- (iOS 5) Return true/false for rotation to orientation.<br />
- </td>
- </tr>
- <tr>
- <td>title</td>
- <td>
- Returns title of current screen.<br />
- </td>
- </tr>
- <tr>
- <td>title=(title)</td>
- <td>
- Sets title of current screen.<br />
- You can also set the title like this (not in a method, though):<br />
-<pre><code>
-class SomeScreen
- title "Some screen"
-
- def on_load
- # ...
- end
-end
-</code></pre>
- </td>
- </tr>
- <tr>
- <td>add(view, attrs = {})</td>
- <td>
- Adds the view to the screen after applying the attributes.<br />
- (alias: `add_element`, `add_view`)<br />
- Example:
- <code>
- add UIInputView.alloc.initWithFrame(CGRectMake(10, 10, 300, 40)), {
- backgroundColor: UIColor.grayColor
- }
- </code>
- </td>
- </tr>
- <tr>
- <td>remove(view)</td>
- <td>
- Removes the view from the superview and sets it to nil<br />
- (alias: `remove_element`, `remove_view`)
- </td>
- </tr>
- <tr>
- <td>bounds</td>
- <td>
- Accessor for self.view.bounds<br />
- </td>
- </tr>
- <tr>
- <td>frame</td>
- <td>
- Accessor for self.view.frame<br />
- </td>
- </tr>
- <tr>
- <td>view</td>
- <td>
- The main view for this screen.<br />
- </td>
- </tr>
- <tr>
- <td>ios_version</td>
- <td>
- Returns the iOS version that is running on the device<br />
- </td>
- </tr>
- <tr>
- <td>app_delegate</td>
- <td>
- Returns the AppDelegate<br />
- </td>
- </tr>
- <tr>
- <td>close(args = {})</td>
- <td>
- Closes the current screen, passes args back to the previous screen's <code>on_return</code> method<br />
- </td>
- </tr>
- <tr>
- <td>open_root_screen(screen)</td>
- <td>
- Closes all other open screens and opens <code>screen</code> as the root view controller.<br />
- </td>
- </tr>
- <tr>
- <td>open(screen, args = {})</td>
- <td>
- Pushes the screen onto the navigation stack or opens in a modal<br />
- Argument options:<br />
- <code>nav_bar: true|false</code><br />
- <code>hide_tab_bar: true|false</code><br />
- <code>modal: true|false</code><br />
- <code>close_all: true|false</code> (closes all open screens and opens as root...same as open_root_screen)<br />
- <code>animated: true:false</code> (currently only affects modals)<br />
- <code>in_tab: "Tab name"</code> (if you're in a tab bar)<br />
- Any accessors in <code>screen</code> can also be set in this hash.
- </td>
- </tr>
- <tr>
- <td>open_split_screen(master, detail)</td>
- <td>
- *iPad apps only*
- Opens a UISplitScreenViewController with the specified screens as the root view controller of the current app<br />
- </td>
- </tr>
- <tr>
- <td>open_tab_bar(*screens)</td>
- <td>
- Opens a UITabBarController with the specified screens as the root view controller of the current app<br />
- </td>
- </tr>
- <tr>
- <td>open_tab(tab)</td>
- <td>
- Opens the tab where the "string" title matches the passed in tab<br />
- </td>
- </tr>
-</table>
-
-## TableScreen
-
-*Has all the methods of Screen*
-
-<table>
- <tr>
- <th>Method</th>
- <th>Description</th>
- </tr>
- <tr>
- <td>searchable(placeholder: "placeholder text")</td>
- <td>Class method to make the current table searchable.</td>
- </tr>
- <tr>
- <td><pre><code>refreshable(
- callback: :on_refresh,
- pull_message: "Pull to refresh",
- refreshing: "Refreshing data…",
- updated_format: "Last updated at %s",
- updated_time_format: "%l:%M %p"
-)</code></pre></td>
- <td>Class method to make the current table refreshable.
- <p>All parameters are optional. If you do not specify a a callback, it will assume you've implemented an <code>on_refresh</code> method in your tableview.</p>
- <pre><code>def on_refresh
- # Code to start the refresh
-end</code></pre>
- <p>And after you're done with your asyncronous process, call <code>end_refreshing</code> to collapse the refresh view and update the last refreshed time and then <code>update_table_data</code>.</p></td>
- <img src="https://f.cloud.github.com/assets/139261/472574/af268e52-b735-11e2-8b9b-a9245b421715.gif" />
- </tr>
- <tr>
- <td colspan="2">
- <h3>table_data</h3>
- Method that is called to get the table's cell data and build the table.<br />
- Example format using nearly all available options.<br />
- <strong>Note...</strong> if you're getting crazy deep into styling your table cells,
- you really should be subclassing them and specifying that new class in <code>:cell_class</code>
- and then providing <code>:cell_class_attributes</code> to customize it.<br /><br />
- <strong>Performance note...</strong> It's best to build this array in a different method
- and store it in something like <code>@table_data</code>. Then your <code>table_data</code>
- method just returns that.
-
-<pre><code>
-def table_data
- [{
- title: "Table cell group 1",
- cells: [{
- title: "Simple cell",
- action: :this_cell_tapped,
- arguments: { id: 4 }
- }, {
- title: "Crazy Full Featured Cell",
- subtitle: "This is way too huge..see note",
- arguments: { data: [ "lots", "of", "data" ] },
- action: :tapped_cell_1,
- height: 50, # manually changes the cell's height
- cell_style: UITableViewCellStyleSubtitle,
- cell_identifier: "Cell",
- cell_class: ProMotion::TableViewCell,
- masks_to_bounds: true,
- background_color: UIColor.whiteColor,
- selection_style: UITableViewCellSelectionStyleGray,
- cell_class_attributes: {
- # any Obj-C attributes to set on the cell
- backgroundColor: UIColor.whiteColor
- },
- accessory: :switch, # currently only :switch is supported
- accessory_view: @some_accessory_view,
- accessory_type: UITableViewCellAccessoryCheckmark,
- accessory_checked: true, # whether it's "checked" or not
- image: { image: UIImage.imageNamed("something"), radius: 15 },
- remote_image: { # remote image, requires SDWebImage CocoaPod
- url: "http://placekitten.com/200/300", placeholder: "some-local-image",
- size: 50, radius: 15
- },
- subviews: [ @some_view, @some_other_view ] # arbitrary views added to the cell
- }]
- }, {
- title: "Table cell group 2",
- cells: [{
- title: "Log out",
- action: :log_out
- }]
- }]
-end
-</code></pre>
- <img src="http://clearsightstudio.github.com/ProMotion/img/ProMotion/full-featured-table-screen.png" />
- </td>
- </tr>
- <tr>
- <td>update_table_data</td>
- <td>
- Causes the table data to be refreshed, such as when a remote data source has
- been downloaded and processed.<br />
- </td>
- </tr>
-</table>
-
-## Logger
-
-*Accessible from ProMotion.logger or PM.logger ... you can also set a new logger by setting `PM.logger = MyLogger.new`*
-
-<table>
- <tr>
- <th>Method</th>
- <th>Description</th>
- </tr>
- <tr>
- <td>log(label, message_text, color)</td>
- <td>
- Output a colored console message.<br />
- Example: <code>PM.logger.log("TESTING", "This is red!", :red)</code>
- </td>
- </tr>
- <tr>
- <td>error(message)</td>
- <td>
- Output a red colored console error.<br />
- Example: <code>PM.logger.error("This is an error")</code>
- </td>
- </tr>
- <tr>
- <td>deprecated(message)</td>
- <td>
- Output a yellow colored console deprecated.<br />
- Example: <code>PM.logger.deprecated("This is a deprecation warning.")</code>
- </td>
- </tr>
- <tr>
- <td>warn(message)</td>
- <td>
- Output a yellow colored console warning.<br />
- Example: <code>PM.logger.warn("This is a warning")</code>
- </td>
- </tr>
- <tr>
- <td>debug(message)</td>
- <td>
- Output a purple colored console debug message.<br />
- Example: <code>PM.logger.debug(@some_var)</code>
- </td>
- </tr>
- <tr>
- <td>info(message)</td>
- <td>
- Output a green colored console info message.<br />
- Example: <code>PM.logger.info("This is an info message")</code>
- </td>
- </tr>
-</table>
-
-## Console [deprecated]
-
-<table>
- <tr>
- <th>Method</th>
- <th>Description</th>
- </tr>
- <tr>
- <td>log(log, with_color:color)<br />
- [DEPRECATED] -- use Logger
- </td>
- <td>
- Class method to output a colored console message.<br />
- Example: <code>ProMotion::Console.log("This is red!", with_color: ProMotion::Console::RED_COLOR)</code>
- </td>
- </tr>
-</table>
-
# Help
-If you need help, feel free to ping me on twitter @jamonholmgren or open a ticket on GitHub.
-Opening a ticket is usually the best and we respond to those pretty quickly.
+If you need help, feel free to ping me on twitter [@jamonholmgren](http://twitter.com/jamonholmgren)
+or open an issue on GitHub. Opening an issue is usually the best and we respond to those pretty quickly.
# Contributing
I'm very open to ideas. Tweet me with your ideas or open a ticket (I don't mind!)
-and let's discuss.
+and let's discuss. **It's a good idea to run your idea by the committers before creating
+a pull request.** We'll always consider your ideas carefully but not all ideas will be
+incorporated.
## Working on Features
1. Clone the repos into `Your-Project/Vendor/ProMotion`
2. Update your `Gemfile`to reference the project as `gem 'ProMotion', :path => "vendor/ProMotion/"`
@@ -917,17 +493,18 @@
## Submitting a Pull Request
1. Fork the project
2. Create a feature branch
3. Code
-4. Update or create new specs
-5. Make sure tests are passing by running `rake spec`
+4. Update or create new specs ** NOTE: your PR is far more likely to be merged if you include comprehensive tests! **
+5. Make sure tests are passing by running `rake spec` *(you can run functional and unit specs separately with `rake spec:functional` and `rake spec:unit`)*
6. Submit pull request
-7. Fame, adoration, kudos everywhere
+7. Make a million little nitpicky changes that @jamonholmgren wants
+8. Merged, then fame, adoration, kudos everywhere
## Primary Contributors
* Jamon Holmgren: [@jamonholmgren](https://twitter.com/jamonholmgren)
* Silas Matson: [@silasjmatson](https://twitter.com/silasjmatson)
* Matt Brewer: [@macfanatic](https://twitter.com/macfanatic)
-
+* [Many others](https://github.com/clearsightstudio/ProMotion/graphs/contributors)