RSS Feed
online prescription solutions
online discount medstore
pills online
buy lorazepam without prescription
xanax for sale
buy xanax without prescription
buy ambien without prescription
ambien for sale
buy modafinil without prescription
buy phentermine without prescription
modafinil for sale
phentermine for sale
lorazepam for sale
buy lexotan without prescription
bromazepam for sale
xenical for sale
buy stilnox without prescription
valium for sale
buy prosom without prescription
buy mefenorex without prescription
buy sildenafil citrate without prescription
buy adipex-p without prescription
librium for sale
buy restoril without prescription
buy halazepam without prescription
cephalexin for sale
buy zoloft without prescription
buy renova without prescription
renova for sale
terbinafine for sale
dalmane for sale
buy lormetazepam without prescription
nobrium for sale
buy klonopin without prescription
priligy dapoxetine for sale
buy prednisone without prescription
buy aleram without prescription
buy flomax without prescription
imovane for sale
adipex-p for sale
buy niravam without prescription
seroquel for sale
carisoprodol for sale
buy deltasone without prescription
buy diazepam without prescription
zopiclone for sale
buy imitrex without prescription
testosterone anadoil for sale
buy provigil without prescription
sonata for sale
nimetazepam for sale
buy temazepam without prescription
buy xenical without prescription
buy famvir without prescription
buy seroquel without prescription
rivotril for sale
acyclovir for sale
loprazolam for sale
buy nimetazepam without prescription
buy prozac without prescription
mogadon for sale
viagra for sale
buy valium without prescription
lamisil for sale
camazepam for sale
zithromax for sale
buy clobazam without prescription
buy diflucan without prescription
modalert for sale
diflucan for sale
buy alertec without prescription
buy zyban without prescription
buy serax without prescription
buy medazepam without prescription
buy imovane without prescription
mefenorex for sale
lormetazepam for sale
prednisone for sale
ativan for sale
buy alprazolam without prescription
buy camazepam without prescription
buy nobrium without prescription
mazindol for sale
buy mazindol without prescription
buy mogadon without prescription
buy terbinafine without prescription
diazepam for sale
buy topamax without prescription
cialis for sale
buy tafil-xanor without prescription
buy librium without prescription
buy zithromax without prescription
retin-a for sale
buy lunesta without prescription
serax for sale
restoril for sale
stilnox for sale
lamotrigine for sale

Your first few days on RubyCocoa

Posted on Sunday, May 27, 2007 in General

I’ve been playing with RubyCocoa lately and really enjoying how easy it is to create OS X GUI apps with just a few lines of Ruby. After playing with this stuff for the past few days, I’m even more excited about Apple’s inclusion of Ruby for Cocoa Development officialy in Leopard.

This post will walk you through the first steps into the RubyCocoa world (frankly, I’m not much beyond the first steps myself!). Before we get to the codin’ let’s get everything set up.

Step 1: Get your Ruby Ready RubyCocoa requires the --enabled-shared configure flag (“build a shared library for Ruby.”) to work from the command line. I’m going to assume that if you’re reading this (and following along), you’re not using OS X’s default Ruby binary (1.8.2). I’m going to also assume you have the ruby source tree somewhere on your harddrive (~/src maybe?). If you have a different setup, adjust accordingly. Go into your source tree and re-configure with your previous ./configure command (which can be found at the top of config.log) while adding –enable-shared to it. Here’s how mine looked:


  ./configure --prefix=/usr/local --enable-pthread --with-readline-dir=/usr/local --enable-shared

When that’s all done, run make followed by sudo make install.

Step 2: Install RubyCocoa
Since your Ruby is in a different location than the OS X default (/usr/local/bin instead of /usr/bin), you need to compile RubyCocoa from source instead of using the binary release. Fetch the latest RubyCocoa version from source forge (0.11.0 as of this writing – 2007-05-28), or grab it from the RubyCocoa SVN.

Then configure, compile and install RubyCocoa:


  $ ruby install.rb config
  $ ruby install.rb setup
  $ sudo ruby install.rb install

Step 3: Install the newcocoa gem
Jumping head-first into the world of Xcode (and away from my beloved TextMate) was a bit too much for me. Justin Palmer’s pointer to newcocoa was the final piece I needed to really get into RubyCocoa. Get it like you would any other gem:

sudo gem install newcocoa

With all that out of the way, let’s get started with our first little app.

I made a short screencast of myself making this app.

Create the project with the newcocoa command

newcocoa HelloWorld

Edit the Rakefile. By default the Rakefile generated with newcocoa has targets to ppc and intel. I haven’t figured out how to make a universal binary yet, but for now remove the -arch (ppc in my case, this was made on a MacBook) line you don’t have.


  cd HelloWorld
  mate Rakefile

Edit the .nib with Interface Builder


  open English.lproj/Main.nib 

Subclass NSObject to create your controller
Subclass NSobject

Name the new Class “Controller”

Right-click on the newly created controller and instantiate it
Instantiate Controller
This gives you a cool icon in the “Instances” tab.

Add a button and text control to your window
Drag Button
(The text control is the same method – on the Cocoa-Text tab drag a “System Font Text” over to your window)
Double click your new button and change the text to “Hello World”. Then double click your text control and remove all the text.

Add 2 outlets and 1 action to your controller. Open the inspector window ( ⌘ ⇧ I) and select the connections page (⌘ 2). Double click the instance of your controller in the Main.nib floating window (it should be a blue cube). Under actions hit Add and type “sayHello:”. Then in the Outlets page add “helloButton” and “textString”.
Outlets

Link the controller’s outlets and action to the window
Linking Actions and Outlets
While holding down control, click on the Controller instance (blue cube) and drag up to your button. Then double click the “helloButton” outlet. Repeat for the text field (and double click textString). Then, while holding control, click on the Hello Button and drag down to your Controller instance. Now double click sayHello: under actions. This is how you define the connections between an interface (the VIEW) and an instance (the CONTROLLER). (Sidebar: Where are models? We’re not that far yet!)

Save your nib and go back to your terminal

run newcocoa -c
This command inspects your NIB files for subclasses and linked actions/outlets and creates skeleton files for them. Since you named your controller as “Controller”, you now have Controller.rb in your project directory.

Edit Controller.rb
Here is where the bulk of your code will go (or in this project, all of it). You have access to the full Ruby / Cocoa bridge, which has most (all?) of the cocoa API methods available. The only code you’ll be adding is:


@textString.setStringValue("HelloWorld")

inside of def sayHello. Pretty cool huh?

Run Rake. Click your button. Rejoice.

That’s it!

I like to clean up the generated controller file like so:

require 'osx/cocoa'
include OSX

class Controller < NSObject
  ib_outlets :helloButton, :textLine

  def sayHello(sender)
    @textLine.setStringValue("Hello, world!")
  end

  def awakeFromNib
  end
end

`rake` if $0 == __FILE__

The last line let’s me hit ⌘ R inside of textmate to launch my project -Agile!


Extra Credit.
Subclass NSWindow (call it MyWindow) and then set your windows “Custom Class” to “MyWindow”. Run newcocoa -c again (it skips Controller.rb this time) you’ll now have MyWindow.rb. Putting the following code in there will implement an “edge-snapping” effect.

require 'osx/cocoa'
include OSX

class MyWindow < NSWindow
  def awakeFromNib
    @moving = false
    
    NSNotificationCenter.defaultCenter.addObserver_selector_name_object(
      self,
      :window_moved,
      "NSWindowDidMoveNotification",
      self
    )
  end
  
  def window_moved(notification)
    unless @moving
      @moving = true

      pillow = 10 # how far from the edge before the "snap"
      
      # 0,0 in os x is the LOWER LEFT corner, not the upper left.
      
      # set up the objects to grab from
      origin = self.frame.origin
      window = self.frame.size
      screen = self.screen.frame.size
      
      # the ideals (set the allowances for messed up windows here)
      ideal_left = 0
      ideal_bottom = 0
      ideal_top = screen.height
      ideal_right = screen.width
      
      # current x and y
      x, y = origin.x, origin.y
      
      # current edges
      top     = origin.y + window.height
      right   = origin.x + window.width
      bottom  = origin.y
      left    = origin.x
  
      # the snapping code - set the paddings here
      x = ideal_left                    if ((ideal_left - 100)..(ideal_left + pillow)).include?(left)
      y = ideal_top - window.height     if ((ideal_top - pillow)..(ideal_top + 100)).include?(top)
      x = ideal_right - window.width    if ((ideal_right - pillow)..(ideal_right + 100)).include?(right)
      y = ideal_bottom                  if ((ideal_bottom - 100)..(ideal_bottom + pillow)).include?(bottom)
      
      setFrameOrigin(NSPoint.new(x, y)) if (x != origin.x or y != origin.y)
      
      @moving = false      
    end
  end
end

`rake` if $0 == __FILE__

Bring on the comments

  1. Dr Nic says:

    Very nice overview!

  2. Great article! Hopefully we get more of these in due time. It should be noted that you can use TextMate without newcocoa, I still do on occasions. It requires a little more leg work, but it’s definitely possible.

  3. Nice article :-)

    Would you be interested to contribute stuff like that to the new website? We really miss tutorials.

  4. kreat says:

    Cool! I’d love to see more. It’s not only the developers who are missing tutorials. :)

  5. Alan says:

    Great article, fantastically helpful!

    2 gotchas:

    1) From the gcc man page:

    -arch arch
    Compile for the specified target architecture arch. The allowable values are i386, ppc and ppc64. Multiple options work, and direct the compiler to produce “universal” binaries including object code for each architecture specified with -arch. This option only works if assembler and libraries are available for each architecture specified. (APPLE ONLY)

    So it looks like the multiple -arch options in the rakefile are correct to build a fat binary (if you have all the various libraries in both archs)

    2) I needed to select the attribute page on the inspector, rather than connections to add my actions/outlets

  6. Kastner says:

    Alan, thanks for looking up the -arch thing. I gotta find the libs so I can make universal binaries if I ever decide to distribute my apps!

  7. topfunky says:

    Thanks for the screencast!

    I’ve written some simple OpenGL apps in Objective-C but have never used Ruby for Mac OS X apps. I have some ideas that I would like to try out.

  8. [...] Erik Kastner has put together a great tutorial showing you how to build a graphical OS X app using Ruby and RubyCocoa. For a less wordy approach, there’s also a short screencast which shows you the whole process from start to finish. [...]

  9. [...] Your first few days on RubyCocoa at Meta | ateM (tags: mac osx programming cocoa ruby) [...]

  10. [...] Girovagando per la rete, in uno dei miei blog preferiti ho ho trovato questo articolo. Dato che la cosa mi è sembrata molto, ma molto interessante e dato che Apple in persona ha detto che implementerà questa tecnologia in Osx 10.5 ho deciso di seguire questo tutorial. Per prima cosa mi sono recato nel sito ufficiale di RubyCocoa . Step 1: Installazione RubyCocoa Bisogna abilitare il –enabled-share al nostro ruby. Quindi entriamo nella cartella contenente i sorgenti di ruby e riconfiguriamoli cosi: $ ./configure –prefix=/opt/local –enable-pthread –with-readline-dir=/opt/local –enable-shared Io ho usato il prefisso /opt/local perché uso i darwinports generalmente sono /usr/local. Ora compilate e installate ruby. $ make <br />$ sudo make install Scarichiamo ed installiamo rubycocoa, si può optare per due soluzioni: Scaricare l’ultima Build o l’ultimo Trunk via svn. Io ho optato per la prima $ wget http://easynews.dl.sourceforge.net/sourceforge/rubycocoa/RubyCocoa-0.11.0.tar.gz <br />$ tar xzvf RubyCocoa-0.11.0.tar.gz <br />$ cd RubyCocoa-0.11.0 <br />$ ruby install.rb config <br />$ ruby install.rb setup <br />$ sudo ruby install.rb install Step 2: Installazione gemma newcocoa Scaricare la gemma ed installare la gemma newcocoa, quindi da terminale: $ sudo gem install newcocoa Step 4: Creazione del progetto di test Ora abbiamo tutti gli ingredienti per poter eseguire alcuni test. Procediamo alla creazione del progetto, da terminale: $ newcocoa HelloWorld Entriamo nella directory del progetto appena creato: $ cd HelloWorld Step 5: Modifica del Rakefile Ora abbiamo creato il progetto, ma newcocoa crea “targets” sia per piattaforma ppc che per intel. Ora aprite il progetto col vostro editor preferito. Il mio è TextMate e quindi da terminale scrivo: $ mate . Dato che uso Intel devo rimuovere dal RakeFile: – arch ppc Step 6: Modificare Main.nib con l’Interface Builder Usando TextMate è possibile: [...]

  11. Tim Dysinger says:

    Awesome. I tried this a while back and not having developed cocoa apps before it took me a while to get a hello world app working from scratch on XCode and InterfaceBuilder. This is nice and simple. Thanks for pointing out the newcocoa gem.

  12. [...] Your first few days on RubyCocoa at Meta | ateM This post will walk you through the first steps into the RubyCocoa world (frankly, I’m not much beyond the first steps myself!). Before we get to the codin’ let’s get everything set up. (tags: ruby cocoa osx) [...]

  13. Neat run-though, Erik!

    Whilst i didn’t quite take the same path as you (as in, i downloaded the disk image and just used XCode), i still found it quite easy to pick up the RubyCocoa bindings. I was however a bit rusty on the Interface Builder stuff, but i more or less eventually figured it out.

    I was considering using the PyObjC bindings which are the Python equivalent of RubyCocoa, however after thinking about it i just decided to dive into RubyCocoa considering i have been doing a lot of RoR development (e.g. RailsCollab) recently. In a way i also enjoy Ruby more than Python, so i’ve more or less decided to stick with it for the while.

    In the future, be interesting to see how powerful RubyCocoa can be.

  14. Wicked Article.
    This has helped me get legs with cocoa (ok more like knees, buts legs will soon follow).

    I have managed to begin a simple relational db app using the models from a rails app ( Which I created for an active record demo within a rails presentation for my former technical school)

    I had hoped to demo some rubycocoa as well but i wasnt quite joining all the dots pilfering examples or harder still porting ideas from objc
    examples.

    So far I have managed to include all my models and initialize active record, do find and display operation with data from mysql

    Once my (barely started) site (dont look now its crap) it up and running I will post my endeavors grasping cocoa from ruby with lots of active record, (bloody AR junkie here, can’t get enough).

  15. [...] Aplicaciones GUI para OS X con Ruby y RubyCocoa Erik Kastner ha creado un buen tutorial mostrando como crear una aplicación gráfica para OS X usando Ruby y RubyCocoa. Además del tutorial hay un breve screencast que muestra el proceso completo. [...]