<?xml version="1.0" encoding="UTF-8"?><feed
  xmlns="http://www.w3.org/2005/Atom"
  xmlns:thr="http://purl.org/syndication/thread/1.0"
  xml:lang="en"
  >
  <id>http://livingcode.org/feed/atom</id>
  <updated>2009-11-13T19:33:25Z</updated>
  <title type="text">Living Code</title>
  <subtitle type="text">Programming for the Fun of It</subtitle>
  <link rel="self" type="application/atom+xml" href="http://livingcode.org/feed" />
  <link rel="alternate" href="http://livingcode.org" />
  <rights type="text">Copyright 2009</rights>
  <generator uri="http://wordpress.org/" version="2.8.6">WordPress</generator>
      <entry>
    <id>http://livingcode.org/2004/52</id>
    <title type="html"><![CDATA[Small Nerd Example Chapter 2]]></title>
    <updated>2008-01-26T05:57:29Z</updated>
    <published>2004-11-06T05:32:58Z</published>
    <author>
      <name>Dethe</name>
      <email>delza@livingcode.org</email>
<uri>http://livingcode.org/</uri>    </author>
    <link rel="replies" type="application/atom+xml" href="http://livingcode.org/2004/11/05/52/feed" thr:count="0"  />
    <link rel="alternate" href="http://livingcode.org/2004/11/05/52" />
    <category scheme="http://livingcode.org" term="Python" />
    <summary type="html"><![CDATA[Aaron Hillegass&#8217; book, &#8220;Cocoa Programmig for Mac OS X&#8221; is a great way to learn Cocoa, Objective-C and Interface Builder, and I highly recommend you buy it to understand OS X programming (of course, you&#8217;ll be buying the new, improved Second Edition, and I&#8217;m working off the first edition here, so things may not completely [...]]]></summary>
      <content type="html" xml:base="http://livingcode.org/2004/11/05/52"><![CDATA[<p>Aaron Hillegass&#8217; book, &#8220;Cocoa Programmig for Mac OS X&#8221; is a great way to learn Cocoa, Objective-C and Interface Builder, and I highly recommend you buy it to understand OS X programming (of course, you&#8217;ll be buying the new, improved Second Edition, and I&#8217;m working off the first edition here, so things may not completely match up). In order to demonstrate how compact, yet readable, Renaissance + Python can be, I&#8217;m going to convert the example programs from this book. Aaron&#8217;s company is called Big Nerd Ranch, and I was trying to find something to show which postings were examples from the book, so readers can follow along, but without implying in any way that Aaron has approved of these conversions in any way, so I&#8217;m going to call them the Small Nerd Examples (The small nerd being me).</p>
<p>Note that while you are developing, it is inconvenient to have to build the project every time you touch a file, so you can use <span class="code">python setup.py py2app &#8211;alias</span> to build it once, then you can edit your files normally and the changes will be reflected when you run your application. Just remember to re-run this when you add a new file, and to re-run it without the alias flag when you&#8217;re building any version to be distributed.</p>
<p>Like the previous example, Hello World, this one contains four files. The setup.py file will look radically similar to the Hello World version. The program itself is simple: A window with two buttons, one which seeds the random number generator with the current time, and another which generates and displays a random number between 1 and 100 in a text field.</p>
<p><strong>MainMenu.gsmarkup </strong></p>
<pre class="code">&lt;?xml version="1.0"?&gt;</pre>
<pre class="code">&lt;!DOCTYPE gsmarkup&gt;</pre>
<pre class="code">&lt;gsmarkup&gt;</pre>
<pre class="code">    &lt;objects&gt;</pre>
<pre class="code">        &lt;menu type="main"&gt;</pre>
<pre class="code">            &lt;menu title="ch02" type="apple"&gt;</pre>
<pre class="code">                &lt;menuItem title="About ch02" action="orderFrontStandardAboutPanel:"/&gt;</pre>
<pre class="code">                &lt;menuSeparator/&gt;</pre>
<pre class="code">                &lt;menu title="Services" type="services"/&gt;</pre>
<pre class="code">                &lt;menuSeparator/&gt;</pre>
<pre class="code">                &lt;menuItem title="Hide ch02" action="hide:" key="h"/&gt;</pre>
<pre class="code">                &lt;menuItem title="Hide Others" action="hideOtherApplications:"/&gt;</pre>
<pre class="code">                &lt;menuItem title="Show All" action="unhideAllApplications:"/&gt;</pre>
<pre class="code">                &lt;menuSeparator/&gt;</pre>
<pre class="code">                &lt;menuItem title="Quit ch02" action="terminate:" key="q"/&gt;</pre>
<pre class="code">            &lt;/menu&gt;</pre>
<pre class="code">            &lt;menu title="Window" type="windows"&gt;</pre>
<pre class="code">                &lt;menuItem title="Minimize Window"</pre>
<pre class="code">                    action="performMiniaturize:" key="m"/&gt;</pre>
<pre class="code">                &lt;menuSeparator/&gt;</pre>
<pre class="code">                &lt;menuItem title="Bring All to Front"</pre>
<pre class="code">                    action="arrangeInFront:"/&gt;</pre>
<pre class="code">            &lt;/menu&gt;</pre>
<pre class="code">            &lt;/menu&gt;</pre>
<pre class="code">                &lt;menu title="Help" type="help"&gt;</pre>
<pre class="code">                &lt;menuItem title="ch02 Help" keys="?"/&gt;</pre>
<pre class="code">        &lt;/menu&gt;</pre>
<pre class="code">    &lt;/objects&gt;</pre>
<pre class="code">&lt;/gsmarkup&gt;</pre>
<p><strong>MainWindow.gsmarkup</strong></p>
<pre class="code">&lt;?xml version="1.0"?&gt;</pre>
<pre class="code">&lt;!DOCTYPE gsmarkup&gt;</pre>
<pre class="code">&lt;gsmarkup&gt;</pre>
<pre class="code">    &lt;objects&gt;</pre>
<pre class="code">        &lt;window delegate="#NSOwner" resizable="no"&gt;</pre>
<pre class="code">            &lt;vbox&gt;</pre>
<pre class="code">                &lt;button target="#NSOwner" action="seed"</pre>
<pre class="code">                    title="Seed random number generator with time"/&gt;</pre>
<pre class="code">                &lt;button target="#NSOwner" action="generate"</pre>
<pre class="code">                    title="Generate random number"/&gt;</pre>
<pre class="code">                &lt;textField editable="no" id="text" align="center"/&gt;</pre>
<pre class="code">            &lt;/vbox&gt;</pre>
<pre class="code">        &lt;/window&gt;</pre>
<pre class="code">    &lt;/objects&gt;</pre>
<pre class="code">    &lt;connectors&gt;</pre>
<pre class="code">        &lt;outlet source="#NSOwner" target="text" key="outputNum"/&gt;</pre>
<pre class="code">    &lt;/connectors&gt;</pre>
<pre class="code">&lt;/gsmarkup&gt;</pre>
<p><strong>ch02.py </strong></p>
<pre class="code">'''</pre>
<pre class="code">Hillegass Example, Ch. 02</pre>
<pre class="code">'''</pre>
<pre class="code">from Foundation import *</pre>
<pre class="code">from AppKit import *</pre>
<pre class="code">from Renaissance import *</pre>
<pre class="code">import random</pre>
<pre class="code">class AppDelegate(NSObject):</pre>
<pre class="code">    outputNum = None</pre>
<pre class="code"></pre>
<pre class="code">    def windowWillClose_(self, notification):</pre>
<pre class="code">        NSApp().terminate_(self)</pre>
<pre class="code"></pre>
<pre class="code">    def quit_(self, notification):</pre>
<pre class="code">        NSApp().terminate_(self)</pre>
<pre class="code"></pre>
<pre class="code">    def close_(self, notification):</pre>
<pre class="code">        NSApp().terminate_(self)</pre>
<pre class="code"></pre>
<pre class="code">    def applicationDidFinishLaunching_(self, notification):</pre>
<pre class="code">        NSBundle.loadGSMarkupNamed_owner_('MainWindow', self)</pre>
<pre class="code"></pre>
<pre class="code">    def seed(self):</pre>
<pre class="code">        random.seed()</pre>
<pre class="code"></pre>
<pre class="code">    def generate(self):</pre>
<pre class="code">        self.outputNum.setStringValue_(str(random.randint(1,100)))</pre>
<pre class="code"></pre>
<pre class="code">def main():</pre>
<pre class="code">    app = NSApplication.sharedApplication()</pre>
<pre class="code">    delegate = AppDelegate.alloc().init()</pre>
<pre class="code">    app.setDelegate_(delegate)</pre>
<pre class="code">    NSBundle.loadGSMarkupNamed_owner_('MainMenu', delegate)</pre>
<pre class="code">    NSApp().run()</pre>
<pre class="code">if __name__ == '__main__': main()</pre>
<p><strong>setup.py </strong></p>
<pre class="code">'''</pre>
<pre class="code">Run with:</pre>
<pre class="code">% python setup.py py2app</pre>
<pre class="code">or</pre>
<pre class="code">% python setup.py py2app --alias # while developing</pre>
<pre class="code">'''</pre>
<pre class="code">from distutils.core import setup</pre>
<pre class="code">import py2app</pre>
<pre class="code">setup(</pre>
<pre class="code">    data_files = ['MainMenu.gsmarkup', 'MainWindow.gsmarkup'],</pre>
<pre class="code">    app = ['ch02.py'],</pre>
<pre class="code">)</pre>
<p>OK, this time out we&#8217;ve got about 52 lines of XML markup and 44 lines of Python. Of course, the program doesn&#8217;t really do much more than Hello World, but we&#8217;re getting somewhere. If anyone has questions about the code, or want more explanatory text around the Renaissance markup, please let me know in the comments or by email.</p>
]]></content>
        </entry>
  </feed>
