Permalink
Browse files

fix everything

  • Loading branch information...
1 parent 7ecf2f9 commit 799bf44cd6d897dbf4e3528c2ea693398997905f @clayallsopp clayallsopp committed Jul 20, 2012
Showing with 10,276 additions and 287 deletions.
  1. BIN .DS_Store
  2. +3 −0 .gitignore
  3. +0 −5 0-in-motion/0-in-motion.md
  4. +27 −0 0-in-motion/in-motion.md
  5. BIN 1-hello-motion/images/0.png
  6. BIN 1-hello-motion/images/1.png
  7. +0 −98 1-hello/1-hello.md
  8. +0 −5 1-hello/ProvingGround/app/app_delegate.rb
  9. 0 {1-hello/ProvingGround → 10-api-driven-example/Colr}/.gitignore
  10. +9 −0 10-api-driven-example/Colr/Rakefile
  11. +12 −0 10-api-driven-example/Colr/app/app_delegate.rb
  12. +91 −0 10-api-driven-example/Colr/app/controllers/color_controller.rb
  13. +50 −0 10-api-driven-example/Colr/app/controllers/search_controller.rb
  14. +53 −0 10-api-driven-example/Colr/app/models/color.rb
  15. +14 −0 10-api-driven-example/Colr/app/models/tag.rb
  16. +1 −1 {1-hello/ProvingGround → 10-api-driven-example/Colr}/spec/main_spec.rb
  17. BIN 10-api-driven-example/images/0.png
  18. BIN 10-api-driven-example/images/1.png
  19. BIN 10-api-driven-example/images/2.png
  20. BIN 10-api-driven-example/images/3.png
  21. BIN 10-api-driven-example/images/4.png
  22. BIN 10-api-driven-example/images/5.png
  23. +0 −9 2-views/Views/app/app_delegate.rb
  24. BIN 2-views/images/1.png
  25. BIN 2-views/images/2.png
  26. +0 −93 3-controllers/3-controllers.md
  27. BIN 3-controllers/images/1.png
  28. BIN 3-controllers/images/2.png
  29. BIN 4-containers/images/1.png
  30. BIN 4-containers/images/2.png
  31. BIN 4-containers/images/3.png
  32. BIN 4-containers/images/4.png
  33. BIN 4-containers/images/nav_bar.png
  34. BIN 4-containers/images/tab_bar.png
  35. BIN 5-tables/images/1.png
  36. BIN 5-tables/images/2.png
  37. BIN 5-tables/images/3.png
  38. BIN 5-tables/images/table_view.png
  39. +5 −0 6-animations/Animations/.gitignore
  40. +1 −1 {1-hello/ProvingGround → 6-animations/Animations}/Rakefile
  41. +31 −0 6-animations/Animations/app/app_delegate.rb
  42. +9 −0 6-animations/Animations/spec/main_spec.rb
  43. BIN 6-animations/images/1.png
  44. +5 −0 7-models/KeyValueFun/.gitignore
  45. +9 −0 7-models/KeyValueFun/Rakefile
  46. +29 −0 7-models/KeyValueFun/app/app_delegate.rb
  47. +5 −0 7-models/KeyValueFun/app/user.rb
  48. +9 −0 7-models/KeyValueFun/spec/main_spec.rb
  49. BIN 7-models/images/0.png
  50. +5 −0 8-testing/Tests/.gitignore
  51. +8 −0 8-testing/Tests/Rakefile
  52. +18 −0 8-testing/Tests/app/ButtonController.rb
  53. +11 −0 8-testing/Tests/app/app_delegate.rb
  54. +18 −0 8-testing/Tests/spec/main_spec.rb
  55. BIN 8-testing/images/1.png
  56. BIN 8-testing/images/2.png
  57. +4 −0 _config.yml
  58. +90 −0 _layouts/default.html
  59. +57 −0 _layouts/splash.html
  60. +47 −0 _plugins/redcarpet2_markdown.rb
  61. +30 −0 _posts/chapters/1900-01-01-0-in-motion.md
  62. +142 −0 _posts/chapters/1900-01-01-1-hello-motion.md
  63. +37 −19 2-views/2-views.md → _posts/chapters/1900-01-02-2-views.md
  64. +109 −0 _posts/chapters/1900-01-03-3-controllers.md
  65. +42 −22 4-containers/4-containers.md → _posts/chapters/1900-01-04-4-containers.md
  66. +44 −34 5-tables/5-tables.md → _posts/chapters/1900-01-05-5-tables.md
  67. +119 −0 _posts/chapters/1900-01-06-6-animations.md
  68. +288 −0 _posts/chapters/1900-01-07-7-models.md
  69. +172 −0 _posts/chapters/1900-01-08-8-testing.md
  70. +52 −0 _posts/chapters/1900-01-09-9-http.md
  71. +479 −0 _posts/chapters/1900-01-10-10-api-driven-example.md
  72. +62 −0 css/blog/pygments.css
  73. +54 −0 css/blog/type.css
  74. +46 −0 css/blog/type_adjust.css
  75. +9 −0 css/bootstrap-responsive.min.css
  76. +9 −0 css/bootstrap.min.css
  77. +815 −0 css/bootstrap/bootstrap-responsive.css
  78. +4,983 −0 css/bootstrap/bootstrap.css
  79. +103 −0 css/chapter.css
  80. +29 −0 css/index.css
  81. +74 −0 css/patch.css
  82. BIN img/glyphicons-halflings-white.png
  83. BIN img/glyphicons-halflings.png
  84. +41 −0 index.html
  85. +1,825 −0 js/bootstrap.js
  86. +6 −0 js/bootstrap.min.js
  87. +11 −0 js/chapters.js
  88. +4 −0 js/jquery-1.7.2.min.js
  89. 0 js/splash.js
  90. +70 −0 js/superlink.jquery.js
  91. BIN more-tables/images/table_sections.png
View
BIN .DS_Store
Binary file not shown.
View
@@ -0,0 +1,3 @@
+_site
+_cache
+.DS_Store
@@ -1,5 +0,0 @@
-# In Motion
-
-You want to make iOS apps. It might be for your job, the focus of your startup, a school project, or just something you want to spend a weekend on. So you do a quick google and find out you write iOS apps in a reasonably esoteric language called Objective-C[1]. That could be a bummer.
-
-Then one day, along comes this thing called RubyMotion. It lets you write iOS apps in Ruby, which is not as uncommon.
View
@@ -0,0 +1,27 @@
+---
+layout: default
+title: In Motion
+---
+# Prologue: In Motion
+
+## In The Beginning
+
+iOS development has remained fundamentally unchanged over the past five years, yet the amount and variation of products created for the platform has increased expontentially. There have been welcome improvements to the Objective-C language (blocks, ARC, literals), but it's clear that Apple intends to stick with it for the long haul.
+
+That's not a bad thing at all. Objective-C really is great for what it tries to be: a dynamic, object-oriented superset of C. It will do compile-time type-checking while providing an introspective runtime with which you can do some really magical things.
+
+But even for all its strengths, many programmers balk at the prospect of learning a niche and odd-looking language just to make iOS software. Instead, they turn to familiar yet non-native technologies like HTML5, which ultimately produce a substandard user experience. Wouldn't it be wonderful if there was a more accessible language with which we could write native, performant iOS apps? *dun dun dun*
+
+## And Then There Was Motion
+
+[RubyMotion][motion] is such a solution. It allows you to write iOS apps in [Ruby][ruby] with no penalty to user experience. And it preserves the iOS SDK syntax as intended by Apple, so all exisiting code examples and tutorials are perfectly translateable.
+
+How does that work? Well, technically it's a *variant* of Ruby; you can't use some of Ruby's extremely dynamic methods like `eval` or `define_method`, and it adds some new features like `functions.with(some, named: parameters). This allows your Ruby code to be compiled to machine code that is identical to compiled Objective-C; in other words, the device can't tell the difference between RubyMotion and normal iOS apps.
+
+If you just don't like Ruby, RubyMotion won't change your mind. But if you aren't anti-Ruby, or you're just a developer who wants to write apps in a language farther away from the metal, I highly recommend you give RubyMotion a chance.
+
+[Head to the first chapter and get started!](/1-hello-motion)
+
+[motion]: http://rubymotion.com
+
+[ruby]: http://www.ruby-lang.org/en/
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
@@ -1,98 +0,0 @@
-# Hello Motion
-
-Navigate to where you want to create your RubyMotion projects and run:
-
-```
-motion create ProvingGround
-```
-
-which creates a `ProvingGround` folder and some files inside. `cd` into it (`cd ./ProvingGround`). You'll run all of the RubyMotion commands from this location, so definitely keep a terminal window/tab open to it.
-
-We'll talk about just two files it creates: `Rakefile` and `./app/app_delegate.rb`.
-
-`Rakefile` is where you do your app configuation (stuff like what the app's named, what resources to include, etc) and library imports (so 3rd-party gems or other local sources). As of RubyMotion 1.11, it will look like:
-
-```
-$:.unshift("/Library/RubyMotion/lib")
-require 'motion/project'
-
-Motion::Project::App.setup do |app|
- # Use `rake config' to see complete project settings.
- app.name = 'ProvingGround'
-end
-```
-
-If you're not intimately familar with Ruby, the first thing you may think is, "Wait...`$.unshift` who?" Strange indeed. What this line does is tell Ruby, "When we use `require`s, also look in the '/Library/RubyMotion/lib' directory to find what we're requiring". 'motion/project' resides there, and without the initial `$.unshift` nothing would be found!
-
-So we `require 'motion/project'`, which gives us proper access to RubyMotion and setting up our app in the `.setup` block. There are all sorts of available options, which as the auto-generated comment says can be listed using `rake config`. By default, RubyMotion sets the `.name` to our project's name, so that looks good.
-
-Wait, why do we have a `Rakefile` at all? Well, RubyMotion uses `rake` for all of it's functions, and by default the `rake` command runs the `Rakefile` in the current directory.
-
-Give it a go! Run `rake` in your terminal and you should have a blank iPhone simulator pop up. "Hooray!" you may exclaim...but how did that happen? How did we get from `app.name = 'ProvingGround'` to an iPhone popping up?
-
-Turns out RubyMotion's App object has some sensible defaults, such as (most importantly) recursively including all Ruby files in `./app`. Remember that `app_delegate.rb` I mentioned earlier? Because of this setting, that guy got included when we compiled our app! Let's take a look:
-
-```
-class AppDelegate
- def application(application, didFinishLaunchingWithOptions:launchOptions)
- true
- end
-end
-```
-
-Wait, all that did was define an `AppDelegate` class with one method. There's not even a superclass, how does this do anything?!
-
-Run that `rake config` command real quick. It'll spit out a bunch of settings and information, but what we're interested in is this:
-
-```
-...
-delegate_class : "AppDelegate"
-...
-```
-
-Whoa buddy, there's our "unimportant" AppDelegate! RubyMotion actually looks for a class with the value we assign as `delegate_class` and uses that in launching our app. We could've called our class `SuperAppDelegate` and changed our `Rakefile` as such:
-
-```
-Motion::Project::App.setup do |app|
- app.name = 'ProvingGround'
- app.delegate_class = "SuperAppDelegate"
-end
-```
-
-So...what is a delegate? In iOS-land, when the user launches our app the system sets up a bunch of stuff for us. We need to give the OS an object which can respond to different events during that process, called the "application delegate". It gets callbacks for when the app starts, pauses, ends, gets a push notification, all sorts of fun stuff.
-
-In the template code, we only implement the `application:didFinishLaunchingWithOptions:` method. This is called when the system finishes setting up the app and becomes ready for us to do our own setup:
-
-```
-def application(application, didFinishLaunchingWithOptions:launchOptions)
- true
-end
-```
-
-For now, just assume it will always return `true`. Some apps may want to use `launchOptions` to determine if the app should be started or not, but most of the time you won't do that.
-
-COOL. Now we understand how our app boots up and have our entry point. Let's...do something?
-
-Change your `application:didFinishLaunchingWithOptions:` to look like:
-
-```
-def application(application, didFinishLaunchingWithOptions:launchOptions)
- alert = UIAlertView.new
- alert.message = "Hello Motion!"
- alert.show
-
- true
-end
-```
-
-See what we added? Those three lines about a `UIAlertView`? `UIAlertView`s are the blue popups you see sometimes while using iOS (logging in to the iTunes Store, pre-iOS5 push notifications, etc). We create one, give it a message, then show it.
-
-Run `rake` again and...BAM, an unclossable blue popup! But...at least we know how it got there.
-
-
-What did we learn?
- - Create RubyMotion apps with `motion create <ProjectName>`
- - Configure your app and import libraries inside `Rakefile`
- - Apps need a delegate, and RubyMotion needs you to set it's value (or use the default) in the `Rakefile`
- - App delegates use `application:didFinishLaunchingWithOptions:` as the first entry point.
- - Run your app using `rake` while inside the project directory.
@@ -1,5 +0,0 @@
-class AppDelegate
- def application(application, didFinishLaunchingWithOptions:launchOptions)
- true
- end
-end
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+$:.unshift("/Library/RubyMotion/lib")
+require 'motion/project'
+require 'bubble-wrap'
+
+Motion::Project::App.setup do |app|
+ # Use `rake config' to see complete project settings.
+ app.name = 'Colr'
+end
@@ -0,0 +1,12 @@
+class AppDelegate
+ def application(application, didFinishLaunchingWithOptions:launchOptions)
+ @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
+
+ @search_controller = SearchController.alloc.initWithNibName(nil, bundle:nil)
+ @navigation_controller = UINavigationController.alloc.initWithRootViewController(@search_controller)
+
+ @window.rootViewController = @navigation_controller
+ @window.makeKeyAndVisible
+ true
+ end
+end
@@ -0,0 +1,91 @@
+class ColorController < UIViewController
+ attr_accessor :color
+
+ def initWithColor(color)
+ initWithNibName(nil, bundle:nil)
+ self.color = color
+ self
+ end
+
+ def viewDidLoad
+ super
+
+ self.title = self.color.hex
+
+ # A light grey background to separate the Tag table from the Color info
+ @info_container = UIView.alloc.initWithFrame [[0, 0], [self.view.frame.size.width, 110]]
+ @info_container.backgroundColor = UIColor.lightGrayColor
+ self.view.addSubview @info_container
+
+ # A visual preview of the actual color
+ @color_view = UIView.alloc.initWithFrame [[10, 10], [90, 90]]
+ @color_view.backgroundColor = String.new(self.color.hex).to_color
+ self.view.addSubview @color_view
+
+ # Displays the hex code of our color
+ @color_label = UILabel.alloc.initWithFrame [[110, 30], [0, 0]]
+ @color_label.text = self.color.hex
+ @color_label.sizeToFit
+ self.view.addSubview @color_label
+
+ # Where we enter the new tag
+ @text_field = UITextField.alloc.initWithFrame [[110, 60], [100, 26]]
+ @text_field.placeholder = "tag"
+ @text_field.textAlignment = UITextAlignmentCenter
+ @text_field.autocapitalizationType = UITextAutocapitalizationTypeNone
+ @text_field.borderStyle = UITextBorderStyleRoundedRect
+ self.view.addSubview @text_field
+
+ # Tapping this adds the tag.
+ @add = UIButton.buttonWithType(UIButtonTypeRoundedRect)
+ @add.setTitle("Add", forState:UIControlStateNormal)
+ @add.setTitle("Adding...", forState:UIControlStateDisabled)
+ @add.setTitleColor(UIColor.lightGrayColor, forState:UIControlStateDisabled)
+ @add.sizeToFit
+ @add.frame = [[@text_field.frame.origin.x + @text_field.frame.size.width + 10, @text_field.frame.origin.y],
+ @add.frame.size]
+ self.view.addSubview(@add)
+
+ @add.when(UIControlEventTouchUpInside) do
+ @add.enabled = false
+ @text_field.enabled = false
+ self.color.add_tag(@text_field.text) do
+ refresh
+ end
+ end
+
+ table_frame = [[0, @info_container.frame.size.height],
+ [self.view.bounds.size.width, self.view.bounds.size.height - @info_container.frame.size.height - self.navigationController.navigationBar.frame.size.height]]
+ @table_view = UITableView.alloc.initWithFrame(table_frame, style:UITableViewStylePlain)
+ self.view.addSubview(@table_view)
+
+ @table_view.dataSource = self
+ end
+
+ def refresh
+ Color.find(self.color.hex) do |color|
+ self.color = color
+
+ @table_view.reloadData
+
+ @add.enabled = true
+ @text_field.enabled = true
+ end
+ end
+
+ def tableView(tableView, numberOfRowsInSection:section)
+ self.color.tags.count
+ end
+
+ def tableView(tableView, cellForRowAtIndexPath:indexPath)
+ @reuseIdentifier ||= "CELL_IDENTIFIER"
+
+ cell = tableView.dequeueReusableCellWithIdentifier(@reuseIdentifier) || begin
+ UITableViewCell.alloc.initWithStyle(UITableViewCellStyleDefault, reuseIdentifier:@reuseIdentifier)
+ end
+
+ cell.textLabel.text = self.color.tags[indexPath.row].name
+
+ cell
+ end
+end
@@ -0,0 +1,50 @@
+class SearchController < UIViewController
+ def viewDidLoad
+ super
+
+ self.title = "Search"
+
+ self.view.backgroundColor = UIColor.whiteColor
+
+ @text_field = UITextField.alloc.initWithFrame [[0,0], [160, 26]]
+ @text_field.placeholder = "#abcabc"
+ @text_field.textAlignment = UITextAlignmentCenter
+ @text_field.autocapitalizationType = UITextAutocapitalizationTypeNone
+ @text_field.borderStyle = UITextBorderStyleRoundedRect
+ @text_field.center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2 - 100)
+ self.view.addSubview @text_field
+
+ @search = UIButton.buttonWithType(UIButtonTypeRoundedRect)
+ @search.setTitle("Search", forState:UIControlStateNormal)
+ @search.setTitle("Loading", forState:UIControlStateDisabled)
+ @search.setTitleColor(UIColor.lightGrayColor, forState:UIControlStateDisabled)
+ @search.sizeToFit
+ @search.center = CGPointMake(self.view.frame.size.width / 2, @text_field.center.y + 40)
+ self.view.addSubview @search
+
+ @search.when(UIControlEventTouchUpInside) do
+ @search.enabled = false
+ @text_field.enabled = false
+
+ hex = @text_field.text
+ # chop off any leading #s
+ hex = hex[1..-1] if hex[0] == "#"
+
+ Color.find(hex) do |color|
+ if color.nil?
+ @search.setTitle("None :(", forState: UIControlStateNormal)
+ else
+ @search.setTitle("Search", forState: UIControlStateNormal)
+ self.open_color(color)
+ end
+
+ @search.enabled = true
+ @text_field.enabled = true
+ end
+ end
+ end
+
+ def open_color(color)
+ self.navigationController.pushViewController(ColorController.alloc.initWithColor(color), animated:true)
+ end
+end
@@ -0,0 +1,53 @@
+class Color
+ PROPERTIES = [:timestamp, :hex, :id, :tags]
+ PROPERTIES.each { |prop|
+ attr_accessor prop
+ }
+
+ def initialize(hash = {})
+ hash.each { |key, value|
+ if PROPERTIES.member? key.to_sym
+ self.send((key.to_s + "=").to_s, value)
+ end
+ }
+ end
+
+ def tags
+ @tags ||= []
+ end
+
+ def tags=(tags)
+ if tags.first.is_a? Hash
+ tags = tags.collect { |tag| Tag.new(tag) }
+ end
+
+ tags.each { |tag|
+ if not tag.is_a? Tag
+ raise "Wrong class for attempted tag #{tag.inspect}"
+ end
+ }
+
+ @tags = tags
+ end
+
+ def add_tag(tag, &block)
+ BW::HTTP.post("http://www.colr.org/js/color/#{self.hex}/addtag/", payload: {tags: tag}) do |response|
+ block.call
+ end
+ end
+
+ def self.find(hex, &block)
+ BW::HTTP.get("http://www.colr.org/json/color/#{hex}") do |response|
+ result_data = BW::JSON.parse(response.body.to_str)
+ color_data = result_data["colors"][0]
+
+ # Colr will return a color with id == -1 if no color was found
+ color = Color.new(color_data)
+ if color.id.to_i == -1
+ block.call(nil)
+ else
+ block.call(color)
+ end
+ end
+ end
+end
@@ -0,0 +1,14 @@
+class Tag
+ PROPERTIES = [:timestamp, :id, :name]
+ PROPERTIES.each { |prop|
+ attr_accessor prop
+ }
+
+ def initialize(hash = {})
+ hash.each { |key, value|
+ if PROPERTIES.member? key.to_sym
+ self.send((key.to_s + "=").to_s, value)
+ end
+ }
+ end
+end
@@ -1,4 +1,4 @@
-describe "Application 'ProvingGround'" do
+describe "Application 'Colr'" do
before do
@app = UIApplication.sharedApplication
end
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.

0 comments on commit 799bf44

Please sign in to comment.