<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Stompy.org &#187; Mac OS X</title>
	<atom:link href="http://www.stompy.org/category/mac-os-x/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.stompy.org</link>
	<description>Excuse me, I believe you have my stapler</description>
	<lastBuildDate>Fri, 19 Mar 2010 00:11:17 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>November NSCoder Night</title>
		<link>http://www.stompy.org/2009/11/13/november-nscoder-night/</link>
		<comments>http://www.stompy.org/2009/11/13/november-nscoder-night/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 22:15:11 +0000</pubDate>
		<dc:creator>stompy</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[googlewave]]></category>
		<category><![CDATA[london]]></category>
		<category><![CDATA[nscodernight]]></category>

		<guid isPermaLink="false">http://www.stompy.org/?p=194</guid>
		<description><![CDATA[This post has moved to http://abizern.org/2009/11/13/november-nscoder-night/
]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><strong>This post has moved to </strong><a class="aligncenter" title="November NSCoder Night on Abizern.org" href="http://abizern.org/2009/11/13/november-nscoder-night/" target="_blank"><strong>http://abizern.org/2009/11/13/november-nscoder-night/</strong></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.stompy.org/2009/11/13/november-nscoder-night/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some tips for lazy Xcoders</title>
		<link>http://www.stompy.org/2009/11/11/some-tips-for-lazy-xcoders/</link>
		<comments>http://www.stompy.org/2009/11/11/some-tips-for-lazy-xcoders/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 12:40:53 +0000</pubDate>
		<dc:creator>stompy</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[xcode]]></category>

		<guid isPermaLink="false">http://www.stompy.org/?p=177</guid>
		<description><![CDATA[This post has been moved to http://abizern.org/2009/11/11/some-tips-for-lazy-xcoders/
]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><strong>This post has been moved to </strong><a href="http://abizern.org/2009/11/11/some-tips-for-lazy-xcoders"><strong>http://abizern.org/2009/11/11/some-tips-for-lazy-xcoders/</strong></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.stompy.org/2009/11/11/some-tips-for-lazy-xcoders/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Integrating git with SubEthaEdit and Changes</title>
		<link>http://www.stompy.org/2009/11/08/integrating-git-with-subethaedit-and-changes/</link>
		<comments>http://www.stompy.org/2009/11/08/integrating-git-with-subethaedit-and-changes/#comments</comments>
		<pubDate>Sun, 08 Nov 2009 16:41:02 +0000</pubDate>
		<dc:creator>stompy</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[changes]]></category>
		<category><![CDATA[diff]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[mercurial]]></category>
		<category><![CDATA[subethaedit]]></category>
		<category><![CDATA[terminal]]></category>

		<guid isPermaLink="false">http://www.stompy.org/?p=160</guid>
		<description><![CDATA[This post has been moved
]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><strong>This post has been </strong><a title="http://abizern.org/2009/11/08/integrating-git-with-subethaedit-and-changes/" href="http://abizern.org/2009/11/08/integrating-git-with-subethaedit-and-changes/" target="_blank"><strong>moved</strong></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.stompy.org/2009/11/08/integrating-git-with-subethaedit-and-changes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NSCoder Night Wave</title>
		<link>http://www.stompy.org/2009/10/16/nscoder-night-wave/</link>
		<comments>http://www.stompy.org/2009/10/16/nscoder-night-wave/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 20:32:39 +0000</pubDate>
		<dc:creator>stompy</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[googlewave]]></category>
		<category><![CDATA[london]]></category>
		<category><![CDATA[nscodernight]]></category>

		<guid isPermaLink="false">http://www.stompy.org/?p=157</guid>
		<description><![CDATA[This post has been moved
]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><strong>This post has been </strong><a title="http://abizern.org/2009/10/16/nscoder-night-wave/" href="http://abizern.org/2009/10/16/nscoder-night-wave/" target="_blank"><strong>moved</strong></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.stompy.org/2009/10/16/nscoder-night-wave/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NSCoder Night London &#8211; Report</title>
		<link>http://www.stompy.org/2009/09/25/nscoder-night-london-report/</link>
		<comments>http://www.stompy.org/2009/09/25/nscoder-night-london-report/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 13:11:46 +0000</pubDate>
		<dc:creator>stompy</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[london]]></category>
		<category><![CDATA[nscodernight]]></category>

		<guid isPermaLink="false">http://www.stompy.org/?p=155</guid>
		<description><![CDATA[This post has been moved
]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><strong>This post has been </strong><a title="http://abizern.org/2009/09/25/nscoder-night-london-report/" href="http://abizern.org/2009/09/25/nscoder-night-london-report/" target="_blank"><strong>moved</strong></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.stompy.org/2009/09/25/nscoder-night-london-report/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>NSCoder Night London</title>
		<link>http://www.stompy.org/2009/09/21/nscoder-night-london/</link>
		<comments>http://www.stompy.org/2009/09/21/nscoder-night-london/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 22:02:08 +0000</pubDate>
		<dc:creator>stompy</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[london]]></category>
		<category><![CDATA[nscodernight]]></category>

		<guid isPermaLink="false">http://www.stompy.org/?p=151</guid>
		<description><![CDATA[This post has been moved
]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><strong>This post has been </strong><a title="http://abizern.org/2009/09/21/nscoder-night-london/" href="http://abizern.org/2009/09/21/nscoder-night-london/" target="_blank"><strong>moved</strong></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.stompy.org/2009/09/21/nscoder-night-london/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MacDev 2009 Announced</title>
		<link>http://www.stompy.org/2008/09/23/macdev-2009-announced/</link>
		<comments>http://www.stompy.org/2008/09/23/macdev-2009-announced/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 12:48:36 +0000</pubDate>
		<dc:creator>stompy</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[miniblog]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[Mac Dev]]></category>

		<guid isPermaLink="false">http://www.stompy.org/?p=122</guid>
		<description><![CDATA[The Mac Developer conference 2009 has been announced for the weekend of April 18-19, 2009.
This is great news for us who find  WWDC or C4 too much of a commitment.
]]></description>
			<content:encoded><![CDATA[<p>The Mac Developer conference 2009 has been <a href="http://www.mac-developer-network.com/conference/">announced</a> for the weekend of April 18-19, 2009.</p>
<p>This is great news for us who find  <a href="http://en.wikipedia.org/wiki/Worldwide_Developers_Conference">WWDC</a> or <a href="http://en.wikipedia.org/wiki/C4_(conference)">C4</a> too much of a commitment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stompy.org/2008/09/23/macdev-2009-announced/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Xcode and git &#8211; Another build script</title>
		<link>http://www.stompy.org/2008/08/14/xcode-and-git-another-build-script/</link>
		<comments>http://www.stompy.org/2008/08/14/xcode-and-git-another-build-script/#comments</comments>
		<pubDate>Thu, 14 Aug 2008 07:15:00 +0000</pubDate>
		<dc:creator>stompy</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[Mac Dev]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[xcode]]></category>

		<guid isPermaLink="false">http://www.stompy.org/?p=84</guid>
		<description><![CDATA[Update: 17Oct09
Since the CFBundleVersion is now presented within brackets, I&#8217;ve changed this again.
You can copy and paste the version below, or you can get it directly from Github where it is gist 208825
Update 25Nov08: The script is also available from Codecollector.net here
I&#8217;ve rewritten the script from Cocoa Is My Girlfriend in ruby to append the [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update: 17Oct09</strong></p>
<p>Since the CFBundleVersion is now presented within brackets, I&#8217;ve changed this again.</p>
<p>You can copy and paste the version below, or you can get it directly from <a href="http://github.com">Github</a> where it is <a href="http://gist.github.com/208825">gist 208825</a></p>
<p><strong>Update 25Nov08</strong>: The script is also available from Codecollector.net <a href="http://www.codecollector.net/view/D2330B49-A01F-420F-B2FC-EFE8937D6DB1">here</a></p>
<p>I&#8217;ve rewritten the script from <a href="http://www.cimgf.com/2008/04/13/git-and-xcode-a-git-build-number-script/">Cocoa Is My Girlfriend</a> in ruby to append the git commit hash into an application&#8217;s Info.plist file.</p>
<p>This way, it keeps the version string that is added in Xcode, so the default About panel looks like this:</p>
<p><img src="http://www.stompy.org/wp-content/uploads/2008/08/bonsoir.png" border="0" alt="Bonsoir.png" width="284" height="152" /></p>
<p>Here is the script</p>
<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "><span style="color:#236e25;">#!/usr/bin/env ruby<br />
</span><br />
<span style="color:#236e25;"># Xcode auto-versioning script for Subversion by Axel Andersson<br />
# Updated for git by Marcus S. Zarra and Matt Long<br />
# Converted to ruby by Abizer Nasir<br />
# Appends the git sha to the version number set in Xcode.<br />
# see </span><span style="color:#0000ff;">http://www.stompy.org/2008/08/14/xcode-and-git-another-build-script/</span><span style="color:#236e25;"> for more details<br />
</span><br />
<span style="color:#236e25;"># These are the common places where git is installed. <br />
# Change this if your path isn&#8217;t here<br />
</span>common_git_paths = <span style="color:#760f15;">%w[/usr/local/bin/git /usr/local/git/bin/git /opt/local/bin/git]</span><br />
git_path = <span style="color:#760f15;">&quot;&quot;</span></p>
<p>common_git_paths.each <span style="color:#881350;"><strong>do</strong></span> |<span style="color:#881350;">p</span>|<br />
&nbsp;&nbsp;<span style="color:#881350;"><strong>if</strong></span> <span style="color:#881350;"><strong>File</strong></span>.exist?(<span style="color:#881350;">p</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;git_path = <span style="color:#881350;">p</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;"><strong>break</strong></span><br />
&nbsp;&nbsp;<span style="color:#881350;"><strong>end</strong></span><br />
<span style="color:#881350;"><strong>end</strong></span></p>
<p><span style="color:#881350;"><strong>if</strong></span> git_path == <span style="color:#760f15;">&quot;&quot;</span><br />
&nbsp;&nbsp;<span style="color:#881350;">puts</span> <span style="color:#760f15;">&quot;Path to git not found&quot;</span><br />
&nbsp;&nbsp;<span style="color:#881350;">exit</span><br />
<span style="color:#881350;"><strong>end</strong></span></p>
<p>command_line = git_path + <span style="color:#760f15;">&quot; rev-parse &#8211;short HEAD&quot;</span><br />
sha = <span style="color:#b80f15;">`#{command_line}`</span>.<span style="color:#881350;">chomp</span><br />
<span style="color:#881350;">puts</span> sha</p>
<p>info_file = <span style="color:#a1617a;">ENV</span>[<span style="color:#760f15;">'BUILT_PRODUCTS_DIR'</span>] + <span style="color:#760f15;">&quot;/&quot;</span> + <span style="color:#a1617a;">ENV</span>[<span style="color:#760f15;">'INFOPLIST_PATH'</span>]</p>
<p>f = <span style="color:#881350;"><strong>File</strong></span>.<span style="color:#881350;">open</span>(info_file, <span style="color:#760f15;">&quot;r&quot;</span>).read<br />
re =<span style="color:#c700c2;"> /([\t ]+&lt;key&gt;CFBundleVersion&lt;\/key&gt;\n[\t ]+&lt;string&gt;)(.*?)(&lt;\/string&gt;)/</span><br />
f =~ re</p>
<p><span style="color:#236e25;"># Get the version info from the source Info.plist file<br />
# If the script has already been run we need to remove the git sha<br />
# from the bundle&#8217;s Info.plist.<br />
</span><span style="color:#881350;">open</span> = <span style="color:#a1617a;">$1</span><br />
orig_version = <span style="color:#a1617a;">$2</span><br />
close = <span style="color:#a1617a;">$3</span></p>
<p><span style="color:#236e25;"># If the git hash has not already been injected into the Info.plist, this will set version to nil<br />
</span>version = <span style="color:#a1617a;">$2</span>.<span style="color:#881350;">sub</span>!(<span style="color:#c700c2;">/\s*git sha [\w]+/</span>, <span style="color:#760f15;">&#8221;</span>)<br />
<span style="color:#881350;"><strong>if</strong></span> (!version)<br />
&nbsp;&nbsp;version = orig_version<br />
<span style="color:#881350;"><strong>end</strong></span></p>
<p><span style="color:#236e25;"># Inject the git hash into the bundle&#8217;s Info.plist<br />
</span><span style="color:#881350;">sub</span> = <span style="color:#760f15;">&quot;</span><span style="color:#3e5f5e;"><em>#{</em></span><span style="color:#881350;">open</span><span style="color:#3e5f5e;"><em>}#{version}</em></span><span style="color:#760f15;">git sha </span><span style="color:#3e5f5e;"><em>#{sha}#{close}</em></span><span style="color:#760f15;">&quot;</span><br />
<span style="color:#881350;">puts</span> <span style="color:#881350;">sub</span><br />
f.<span style="color:#881350;">gsub</span>!(re, <span style="color:#881350;">sub</span>)<br />
<span style="color:#881350;"><strong>File</strong></span>.<span style="color:#881350;">open</span>(info_file, <span style="color:#760f15;">&quot;w&quot;</span>) { |file| file.write(f) }</div>
<p>Make sure that the shell is set to <code>/usr/bin/ruby</code></p>
<p><img src="http://www.stompy.org/wp-content/uploads/2008/08/shell-setting.png" border="0" alt="Shell_setting.png" width="391" height="152" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.stompy.org/2008/08/14/xcode-and-git-another-build-script/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Bonsoir Redux</title>
		<link>http://www.stompy.org/2008/08/12/bonsoir-redux/</link>
		<comments>http://www.stompy.org/2008/08/12/bonsoir-redux/#comments</comments>
		<pubDate>Tue, 12 Aug 2008 21:20:29 +0000</pubDate>
		<dc:creator>stompy</dc:creator>
				<category><![CDATA[Bonsoir]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[Mac Dev]]></category>
		<category><![CDATA[xcode]]></category>

		<guid isPermaLink="false">http://www.stompy.org/?p=79</guid>
		<description><![CDATA[About 2 years ago R. Tyler Ballance went to BarCampTexas and, finding himself with no place to stay, holed himself up in a coffee shop for the night and knocked up a demo application Bonsoir in about six hours.
When this app is running, it uses Apple’s Bonjour service to find other running Bonsoir apps on [...]]]></description>
			<content:encoded><![CDATA[<p>About 2 years ago <a href="http://unethicalblogger.com">R. Tyler Ballance</a> went to BarCampTexas and, finding himself with no place to stay, holed himself up in a coffee shop for the night and knocked up a demo application <em>Bonsoir</em> in about <a href="http://bleepsoft.com/tyler/index.php?itemid=57">six hours</a>.</p>
<p>When this app is running, it uses Apple’s Bonjour service to find other running Bonsoir apps on the network and allows swapping of AddressBook cards. The idea is that it would be useful at get togethers such as BarCamp for people to swap contact details.</p>
<p>This code has been placed into the <a href="http://trac.geekisp.com/bleep/wiki/Bonsoir">public domain</a> but it doesn&#8217;t look like anybody is working on it. So I&#8217;ve put the code up on <a href="http://github.com/Abizern/bonsoir/tree/master">github</a> and I&#8217;ll see if I can&#8217;t make this a more polished app.</p>
<p>Actually, this is prompted a little by guilt. I was looking through my iChat transcripts the other day and I said I&#8217;d do some work on it &#8211; and that was back in 2006.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stompy.org/2008/08/12/bonsoir-redux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SOBezier &#8211; Getting started.</title>
		<link>http://www.stompy.org/2008/07/30/sobezier-getting-started/</link>
		<comments>http://www.stompy.org/2008/07/30/sobezier-getting-started/#comments</comments>
		<pubDate>Wed, 30 Jul 2008 22:00:55 +0000</pubDate>
		<dc:creator>stompy</dc:creator>
				<category><![CDATA[SOBezier]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[Mac Dev]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[screencast]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[xcode]]></category>

		<guid isPermaLink="false">http://www.stompy.org/?p=58</guid>
		<description><![CDATA[The first part of this demonstration will create an application that draws a predefined curve in a window that is not re-sizeable. The idea is to get a simple working version up and running in the first place which can then be built upon.
Create the Project
In Xcode, create a new project of type &#8220;Cocoa Document-based [...]]]></description>
			<content:encoded><![CDATA[<p>The first part of this demonstration will create an application that draws a predefined curve in a window that is not re-sizeable. The idea is to get a simple working version up and running in the first place which can then be built upon.</p>
<h3>Create the Project</h3>
<p>In Xcode, create a new project of type &#8220;Cocoa Document-based application&#8221;. Save it wherever you like and call it SOBezier. The only project setting that needs to be set is to make sure that Garbage collection is turned on.</p>
<p><img src="http://www.stompy.org/wp-content/uploads/2008/07/gc-on.png" alt="GC-on.png" border="0" width="439" height="151" /></p>
<h3>MVC Classes</h3>
<p>Cocoa makes extensive use of the Model-View-Controller (MVC) paradigm. <strong>Model</strong> objects are responsible for the data or state of the application. <strong>View</strong> objects are responsible for displaying the data and the <strong>Controller</strong> objects keep the two in sync. For this basic application, the model class is SOBezierCurve, a subclass of NSObject, which contains the points of the curve and also knows how to draw itself. The view class is SOBezierView, a subclass of NSView, in which the curve is drawn. These are co-ordinated by the MyDocument class, a subclass of NSDocument, which is the controller.</p>
<h3>SOBezierCurve &#8211; the model</h3>
<p>From the Xcode File menu, choose New File and then select a Cocoa Objective-C class. Call this SOBezier curve. This will create the header and the implementation files. Edit them to look like these code listings.</p>
<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "><span style="color:#236e25;">// &nbsp;SOBezierCurve.h<br />
</span><br />
<span style="color:#683821;">#import &lt;Cocoa/Cocoa.h&gt;<br />
</span></p>
<p><span style="color:#881350;">@interface</span> SOBezierCurve : <span style="color:#400080;">NSObject</span> {<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080;">NSPoint</span> pt1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080;">NSPoint</span> pt2;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080;">NSPoint</span> ControlPt1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080;">NSPoint</span> ControlPt2;<br />
}</p>
<p><span style="color:#881350;">@property</span><span style="color:#003369;"> </span>(<span style="color:#881350;">readwrite</span>) <span style="color:#400080;">NSPoint</span> pt1;<br />
<span style="color:#881350;">@property</span><span style="color:#003369;"> </span>(<span style="color:#881350;">readwrite</span>) <span style="color:#400080;">NSPoint</span> pt2;<br />
<span style="color:#881350;">@property</span><span style="color:#003369;"> </span>(<span style="color:#881350;">readwrite</span>) <span style="color:#400080;">NSPoint</span> ControlPt1;<br />
<span style="color:#881350;">@property</span><span style="color:#003369;"> </span>(<span style="color:#881350;">readwrite</span>) <span style="color:#400080;">NSPoint</span> ControlPt2;</p>
<p>- (<span style="color:#881350;">id</span>)<span style="color:#6c0540;">initWithPt1:</span>(<span style="color:#400080;">NSPoint</span>)point1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#6c0540;">Pt2:</span>(<span style="color:#400080;">NSPoint</span>)point2<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#6c0540;">ControlPt1:</span>(<span style="color:#400080;">NSPoint</span>)cPoint1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#6c0540;">ControlPt2:</span>(<span style="color:#400080;">NSPoint</span>)cPoint2;<br />
- (<span style="color:#881350;">void</span>)<span style="color:#6c0540;">drawCurve</span>;</p>
<p><span style="color:#881350;">@end</span></div>
<p>Here, the four points that define the curve are declared and I am using the Objective-C 2.0 @property syntax to make these properties. Two methods are declared. First, an initialiser that creates the curve based on the four points being passed in, and a method that draws the curve.</p>
<p>The implementation is quite simple:</p>
<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "><span style="color:#236e25;">// &nbsp;SOBezierCurve.m<br />
</span><br />
<span style="color:#683821;">#import &quot;SOBezierCurve.h&quot;<br />
</span><br />
<span style="color:#881350;">@implementation</span> SOBezierCurve<br />
<span style="color:#881350;">@synthesize</span> pt1, pt2, ControlPt1, ControlPt2;</p>
<p>- (<span style="color:#881350;">id</span>)<span style="color:#6c0540;">initWithPt1:</span>(<span style="color:#400080;">NSPoint</span>)point1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#6c0540;">Pt2:</span>(<span style="color:#400080;">NSPoint</span>)point2<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#6c0540;">ControlPt1:</span>(<span style="color:#400080;">NSPoint</span>)cPoint1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#6c0540;">ControlPt2:</span>(<span style="color:#400080;">NSPoint</span>)cPoint2<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// Designated initialiser.<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>(![<span style="color:#881350;">super</span> <span style="color:#6c0540;">init</span>]) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">return</span> <span style="color:#881350;">nil</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;pt1 = point1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;pt2 = point2;<br />
&nbsp;&nbsp;&nbsp;&nbsp;ControlPt1 = cPoint1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;ControlPt2 = cPoint2;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">return</span> <span style="color:#881350;">self</span>;<br />
}</p>
<p>- (<span style="color:#881350;">void</span>)drawCurve<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080;">NSBezierPath</span> *path = [<span style="color:#400080;">NSBezierPath</span> <span style="color:#6c0540;">bezierPath</span>];<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// Move to the first control point<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;[path <span style="color:#6c0540;">moveToPoint:</span>ControlPt1];<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// Add a line from the control point to the first point of the curve<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;[path <span style="color:#6c0540;">lineToPoint:</span>pt1];<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// Create the curve<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;[path <span style="color:#6c0540;">curveToPoint:</span>pt2 <span style="color:#6c0540;">controlPoint1:</span>ControlPt1 <span style="color:#6c0540;">controlPoint2:</span>ControlPt2];<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// Draw a line from the end of the curve to the second control point<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;[path <span style="color:#6c0540;">lineToPoint:</span>ControlPt2];<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// Now draw the curve<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;[[<span style="color:#400080;">NSColor</span> <span style="color:#6c0540;">blackColor</span>] <span style="color:#6c0540;">set</span>];<br />
&nbsp;&nbsp;&nbsp;&nbsp;[path <span style="color:#6c0540;">stroke</span>];<br />
}</p>
<p><span style="color:#881350;">@end</span></div>
<p>The initialiser just sets the points of the curve to the points that are passed in. the <code>@sythesize</code> directive lets Objective-C 2.0 create accessors for the properties that are Key Value Coding (KVC) compliant.</p>
<p>The <code>DrawCurve:</code> method is responsible for drawing the curve represented by these points. This is where the terminology becomes confusing with the term &#8216;bezier&#8217; appearing everywhere. The NSBezierPath class is used extensively in Cocoa graphics, (which is why it is so easy to draw bezier curves), so to draw the curve a series of bezier paths are linked together as a single path and then drawn on the view by stroking this single path.</p>
<h3>SOBezierView &#8211; the view</h3>
<p>This class needs to be creates as we did with the SOBezierCurve class. From the Xcode File menu, choose New File and then select a Cocoa Objective-C NSView subclass. Call this file SOBezierView. This will create the header and the implementation files. Edit them to look like these code listings.</p>
<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "><span style="color:#236e25;">// &nbsp;SOBezierView.h<br />
</span><br />
<span style="color:#683821;">#import &lt;Cocoa/Cocoa.h&gt;<br />
</span><span style="color:#881350;">@class</span> MyDocument;</p>
<p><span style="color:#881350;">@interface</span> SOBezierView : <span style="color:#400080;">NSView</span> {<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">IBOutlet</span> MyDocument *doc;<br />
}</p>
<p><span style="color:#881350;">@end</span></div>
<p>This class doesn&#8217;t do much at the moment so it is quite small. The interface file just declares an outlet called <code>doc</code> to the controller, which is the MyDocument object in this case.</p>
<p>The implementation file only has two methods, both of which come from the superclass so they don&#8217;t need to be declared in the header file.</p>
<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "><span style="color:#236e25;">// &nbsp;SOBezierView.m<br />
</span><br />
<span style="color:#683821;">#import &quot;SOBezierView.h&quot;<br />
#import &quot;MyDocument.h&quot;<br />
#import &quot;SOBezierCurve.h&quot;<br />
</span><br />
<span style="color:#881350;">@implementation</span> SOBezierView</p>
<p>- (<span style="color:#881350;">id</span>)<span style="color:#6c0540;">initWithFrame:</span>(<span style="color:#400080;">NSRect</span>)frame {<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">self</span> = [<span style="color:#881350;">super</span> <span style="color:#6c0540;">initWithFrame:</span>frame];<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>(<span style="color:#881350;">self</span>) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// Initialization code here.<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">return</span> <span style="color:#881350;">self</span>;<br />
}</p>
<p>- (<span style="color:#881350;">void</span>)<span style="color:#6c0540;">drawRect:</span>(<span style="color:#400080;">NSRect</span>)rect {<br />
&nbsp;&nbsp;&nbsp;&nbsp;[[<span style="color:#400080;">NSColor</span> <span style="color:#6c0540;">yellowColor</span>] <span style="color:#6c0540;">set</span>];<br />
&nbsp;&nbsp;&nbsp;&nbsp;[<span style="color:#400080;">NSBezierPath</span> <span style="color:#6c0540;">fillRect:</span>[<span style="color:#881350;">self</span> <span style="color:#6c0540;">bounds</span>]];<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;[[doc <span style="color:#6c0540;">curve</span>] <span style="color:#6c0540;">drawCurve</span>];<br />
}</p>
<p><span style="color:#881350;">@end</span></div>
<p>The <code>initWithFrame:</code> method is where the initialisation code will go. But the important method is the <code>drawRect:</code> method which is invoked whenever the view needs to draw itself.</p>
<p>The first thing that the <code>drawRect:</code> method does is set the colour to be used and then calls the NSBezierPath <code>fillRect:</code> method to fill the entire view window with this colour. The <code>rect</code> paramater that is passed into the <code>drawRect:</code> method is the rectangle that is &#8216;dirty&#8217; and needs to be redrawn, but to keep things simple, this implementation just fills in the whole view. If the view was drawing a number of curves, this dirty rectangle could be used to determine which curves are within this rectangle and the drawing code could be optimised to only draw those curves. The method then uses the outlet to the MyDocument object outlet <code>doc</code> to access curve object which is then asked to draw itself.</p>
<h3>MyDocument &#8211; the controller</h3>
<p>The MyDocument class was created by Xcode as part of the project.</p>
<p>Edit the header file so that it looks like this listing.</p>
<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "><span style="color:#236e25;">// &nbsp;MyDocument.h<br />
// &nbsp;SOBezier<br />
</span><br />
<span style="color:#683821;">#import &lt;Cocoa/Cocoa.h&gt;<br />
</span><span style="color:#881350;">@class</span> SOBezierCurve; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// 1<br />
</span><br />
<span style="color:#881350;">@interface</span> MyDocument : <span style="color:#400080;">NSDocument</span><br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;SOBezierCurve *curve; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// 2<br />
</span>}<br />
<span style="color:#881350;">@property</span><span style="color:#003369;"> </span>(<span style="color:#881350;">readwrite</span>) SOBezierCurve *curve; &nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// 3<br />
</span><span style="color:#881350;">@end</span></div>
<ol>
<li>Here SOBezierCurve is declared to be a class.</li>
<li>The <code>curve</code> attribute is declared as a pointer to an SOBezierCurve object.</li>
<li>This attribute is declared as a property.</li>
</ol>
<p>The MyDocument.m file contains a lot of generated code. For now the only changes need to be made to the beginning of the file. Edit the code so it looks like this listing.</p>
<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "><span style="color:#236e25;">// &nbsp;MyDocument.m<br />
// &nbsp;SOBezier<br />
</span><br />
<span style="color:#683821;">#import &quot;MyDocument.h&quot;<br />
#import &quot;SOBezierCurve.h&quot; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:#236e25;">// 1</span><span style="color:#683821;"><br />
</span><br />
<span style="color:#881350;">@implementation</span> MyDocument<br />
<span style="color:#881350;">@synthesize</span> curve; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// 2<br />
</span><br />
- (<span style="color:#881350;">id</span>)init &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// 3<br />
</span>{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">self</span> = [<span style="color:#881350;">super</span> <span style="color:#6c0540;">init</span>];<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>(<span style="color:#881350;">self</span>) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080;">NSPoint</span> p1 = <span style="color:#400080;">NSMakePoint</span>(<span style="color:#0000ff;">100</span>, <span style="color:#0000ff;">150</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080;">NSPoint</span> p2 = <span style="color:#400080;">NSMakePoint</span>(<span style="color:#0000ff;">300</span>, <span style="color:#0000ff;">150</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080;">NSPoint</span> cP1 = <span style="color:#400080;">NSMakePoint</span>(<span style="color:#0000ff;">100</span>, <span style="color:#0000ff;">225</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080;">NSPoint</span> cP2 = <span style="color:#400080;">NSMakePoint</span>(<span style="color:#0000ff;">300</span>, <span style="color:#0000ff;">75</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curve = [[SOBezierCurve <span style="color:#ff0000;">alloc</span>] <span style="color:#6c0540;">initWithPt1:</span>p1 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#6c0540;">Pt2:</span>p2 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#6c0540;">ControlPt1:</span>cP1 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#6c0540;">ControlPt2:</span>cP2];<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">return</span> <span style="color:#881350;">self</span>;<br />
}</p>
<p>.<br />
.<br />
.</p>
<p><span style="color:#881350;">@end</span></div>
<ol>
<li>Import the header file for the SOBezierCurve class.</li>
<li>This creates <span class="caps">KVC</span> compliant accessors for the <code>curve</code> attribute.</li>
<li>The <code>init</code> method, called when the object is created, sets up the points to be used for the default curve and then creates an SOBezierCurve object with these points.</li>
</ol>
<h3>Create the User Interface</h3>
<p>Here&#8217;s a short screencast of how the UI is created. (If a picture is worth a thousand words, how many more is a video worth?).</p>
<p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="545" height="451" id="viddler_abb2009b"><param name="movie" value="http://www.viddler.com/player/abb2009b/" /><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /><embed src="http://www.viddler.com/player/abb2009b/" width="545" height="451" type="application/x-shockwave-flash" allowScriptAccess="always" allowFullScreen="true" name="viddler_abb2009b" ></embed></object></p>
<p>Once that is done, you can click build and go to see a simple bezier curve drawn on a yellow background. Not very interesting so far, but it&#8217;s a good starting point.</p>
<h3>Next Steps</h3>
<p>The next step will be to add handles to the points so they can be moved around the view causing the curve to change. </p>
<p>Finally, thanks for your attention and I&#8217;d appreciate any comments you have, particularly about things you don&#8217;t like, so that I can improve this demonstration.</p>
<h3>Resources</h3>
<p>You can get the source code up to this point from the project&#8217;s git repository <a href="http://github.com/Abizern/sobezier/tree/master">here</a>. A checkout of the Stage1_1 tag will get the code up to this point.</p>
<p>Alternatively, you can download a zip file of the completed version up to this point here: <a href="http://www.stompy.org/wp-content/uploads/2008/07/sobezier-01.zip" title="SOBezier_01.zip">SOBezier_01.zip (60 kb)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.stompy.org/2008/07/30/sobezier-getting-started/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.421 seconds -->
