<?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>toxicsoftware.com &#187; Cocoa</title>
	<atom:link href="http://toxicsoftware.com/tag/cocoa/feed/" rel="self" type="application/rss+xml" />
	<link>http://toxicsoftware.com</link>
	<description>RANDOMIZE USR 0</description>
	<lastBuildDate>Thu, 17 Dec 2009 15:12:37 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Key-Value Observing Done Right (again)</title>
		<link>http://toxicsoftware.com/kvoblocks/</link>
		<comments>http://toxicsoftware.com/kvoblocks/#comments</comments>
		<pubDate>Sun, 16 Aug 2009 15:36:49 +0000</pubDate>
		<dc:creator>schwa</dc:creator>
				<category><![CDATA[Default]]></category>
		<category><![CDATA[blocks]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[KVO]]></category>
		<category><![CDATA[snow leopard]]></category>

		<guid isPermaLink="false">http://toxicsoftware.com/?p=417</guid>
		<description><![CDATA[Mike Ash posted a great article about problems with Cocoa&#8217;s Key Value Observing and provided a better set of classes to work with KVO: MAKVONotificationCenter. I&#8217;ve been using Mike&#8217;s code in various projects over the last few months and am a big fan.

When I started development on MOO I knew I wanted the project to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.mikeash.com/">Mike Ash</a> posted a <a href="http://www.mikeash.com/?page=pyblog/key-value-observing-done-right.html">great article</a> about problems with Cocoa&#8217;s Key Value Observing and provided a better set of classes to work with KVO: <a href="http://www.mikeash.com/svn/MAKVONotificationCenter/">MAKVONotificationCenter</a>. I&#8217;ve been using Mike&#8217;s code in various projects over the last few months and am a big fan.</p>

<p>When I <a href="http://twitter.com/moodevdiary/">started development</a> on <a href="http://bitbucket.org/schwa/moo/">MOO</a> I knew I wanted the project to use Mike&#8217;s code but I also wanted to take advantage of Cocoa&#8217;s Garbage Collection and Snow Leopard&#8217;s blocks. I originally tried to retrofit MAKVONotificationCenter to work with GC and with blocks but it rapidly become a very difficult task. So I wrote my own KVO Notification class that was fully GC compatible and worked purely with blocks (no delegate methods at all).</p>

<p>Jumping as quickly into the code as I can, here is an example showing a KVO block that modifies a CoreAnimation layer&#8217;s position in responses to changes in the application&#8217;s model (example code adapted from MOO&#8217;s <a href="http://bitbucket.org/schwa/moo/src/9779be0cd8f8/Source/CGameView/CGameMapView.m">CGameMapView.m</a>):</p>

<pre><code>void *theBlock = ^(NSString *keyPath, CALayer *self, NSDictionary *change, id identifier)
    {
    self.position = CGPointMake(self.viewPoint.scale * self.modelObject.position.x, self.viewPoint.scale * self.modelObject.position.y);
    };

CALayer *theLayer = ...;
[theLayer addKVOBlock:theBlock forKeyPath:@"modelObject.position" options:0 identifier:@"KVO_IDENTIFIER_1"];
[theLayer addKVOBlock:theBlock forKeyPath:@"viewPoint.scale" options:0 identifier:@"KVO_IDENTIFIER_2"];
</code></pre>

<p>I find this, blocks based, style of KVO handling much cleaner and easier to both code and maintain. No worrying about selectors and targets and passing whatever data you need into the delegate method. You just declare your block and register it with the KVO Notification Center.</p>

<p>Clean-up (unregistration) is also straight-forward, although with Garbage Collection enabled applications this isn&#8217;t usually even necessary.</p>

<p>If you&#8217;re sharp-eyed you might notice that I&#8217;ve called one of the block parameters &#8220;self&#8221;. By providing my own &#8217;self&#8217; parameter I am obscuring and prevent access to the parent method&#8217;s &#8217;self&#8217; parameter. The reason I am doing this is because I&#8217;ve found it is very common to register for notifications for &#8220;self&#8221; and unless you&#8217;re very careful you can end up with a horrible retain cycle caused memory leak. By providing my own self parameter I obscure the parent method&#8217;s self and make sure these kind of retains cycles don&#8217;t happen.</p>

<p>The code is released under the BSD License on bitbucket (mercurial): <a href="http://bitbucket.org/schwa/kvoblocknotificationcenter/">http://bitbucket.org/schwa/kvoblocknotificationcenter/</a>. You&#8217;ll obviously need use this on Snow Leopard or possibly with Landon Fuller&#8217;s <a href="http://code.google.com/p/plblocks/">plblocks toolchain</a> (although I haven&#8217;t tried that myself).</p>

<p>(Update: I&#8217;ve posted <a href="http://www.flickr.com/photos/jwight/3826876252/?likes_hd=1">a movie on flickr</a> of KVO Block Observing in action)
(update 2: Joachim Bengtsson has posted a great <a href="http://thirdcog.eu/pwcblocks/">HOWTO guide</a> for blocks. It also goes into some detail about the &#8220;self&#8221; problem I mentioned and a better solution (__block variables)</p>
]]></content:encoded>
			<wfw:commentRss>http://toxicsoftware.com/kvoblocks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TouchMap</title>
		<link>http://toxicsoftware.com/touchmap/</link>
		<comments>http://toxicsoftware.com/touchmap/#comments</comments>
		<pubDate>Mon, 06 Oct 2008 00:31:21 +0000</pubDate>
		<dc:creator>schwa</dc:creator>
				<category><![CDATA[Default]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iphone development]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[TouchMap]]></category>
		<category><![CDATA[virtual earth]]></category>

		<guid isPermaLink="false">http://toxicsoftware.com/?p=385</guid>
		<description><![CDATA[I was going to make a more in-depth posting about TouchMap, but then something kind of big happened. The code is however in the TouchCode google code repository. So have at it. (You&#8217;ll probably want to check out all of TouchCode, TouchMap currently depends on other code within the repository).
]]></description>
			<content:encoded><![CDATA[<p>I was going to make a more in-depth posting about <a href="http://toxicsoftware.com/touchmap-teaser/">TouchMap</a>, but then something <a href="http://toxicsoftware.com/obama08/">kind of big</a> happened. <a href="http://touchcode.googlecode.com/svn/trunk/Experimental/TouchMap/">The code</a> is however in the TouchCode google code repository. So have at it. (You&#8217;ll probably want to check out all of TouchCode, TouchMap currently depends on other code within the repository).</p>
]]></content:encoded>
			<wfw:commentRss>http://toxicsoftware.com/touchmap/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>TouchMap Teaser</title>
		<link>http://toxicsoftware.com/touchmap-teaser/</link>
		<comments>http://toxicsoftware.com/touchmap-teaser/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 20:58:20 +0000</pubDate>
		<dc:creator>schwa</dc:creator>
				<category><![CDATA[Default]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[touchcode]]></category>
		<category><![CDATA[TouchMap]]></category>

		<guid isPermaLink="false">http://toxicsoftware.com/?p=374</guid>
		<description><![CDATA[A quick teaser for TouchMap. I&#8217;m hoping to release this on TouchCode later today.

TouchMap.mov
]]></description>
			<content:encoded><![CDATA[<p>A quick teaser for TouchMap. I&#8217;m hoping to release this on <a href="http://code.google.com/p/touchcode/">TouchCode</a> later today.</p>

<p><a href="http://toxicsoftware.com/uploads/TouchMap/TouchMap.mov">TouchMap.mov</a></p>
]]></content:encoded>
			<wfw:commentRss>http://toxicsoftware.com/touchmap-teaser/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
<enclosure url="http://toxicsoftware.com/uploads/TouchMap/TouchMap.mov" length="269" type="video/quicktime" />
		</item>
		<item>
		<title>AcornImage</title>
		<link>http://toxicsoftware.com/acornimage/</link>
		<comments>http://toxicsoftware.com/acornimage/#comments</comments>
		<pubDate>Tue, 19 Feb 2008 15:05:58 +0000</pubDate>
		<dc:creator>schwa</dc:creator>
				<category><![CDATA[Default]]></category>
		<category><![CDATA[Acorn]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Flying Meat]]></category>
		<category><![CDATA[gus mueller has a posse]]></category>
		<category><![CDATA[Source Code]]></category>

		<guid isPermaLink="false">http://toxicsoftware.com/acornimage/</guid>
		<description><![CDATA[It was just your typical InterfaceBuilder 3 window&#8230;



with your vanilla NSImageView&#8230;



referring to an image file within an Xcode project&#8230;



Holy Cow! An Acorn file? Does that mean I can use Acorn files directly in Interface Builder 3? Does that mean you&#8217;ve written an NSCustomImageRep that understands the Acorn file format? Does that mean I can use [...]]]></description>
			<content:encoded><![CDATA[<p>It was just your typical InterfaceBuilder 3 window&#8230;</p>

<p><a href="/uploads/acornimageib3.png&quot;"><img src="/uploads/acornimageib3.thumbnail.png" alt="AcornImageIB3.png" /></a></p>

<p>with your vanilla NSImageView&#8230;</p>

<p><a href="/uploads/acornimageview.png"><img src="/uploads/acornimageview.thumbnail.png" alt="AcornImageView.png" /></a></p>

<p>referring to an image file within an Xcode project&#8230;</p>

<p><a href="/uploads/acorninxcode.png"><img src="/uploads/acorninxcode.thumbnail.png" alt="AcornInXcode.png" /></a></p>

<p><a href="http://www.hospitalgowns.com/Buy_Bouffant_Pages/A0822b.htm">Holy Cow!</a> An <a href="http://www.flyingmeat.com/acorn/">Acorn</a> file? Does that mean I can use Acorn files directly in Interface Builder 3? Does that mean you&#8217;ve written an NSCustomImageRep that understands the Acorn file format? Does that mean I can use Acorn files directly in my Cocoa projects? And that means I no longer have to keep exporting these bloody files as pngs so I can use them in Cocoa, right? Will this give rixstep some ammunition to go apeshit insane about?</p>

<p>Yes! Yes!! Yes!!! Yes!!!! Yes!!!!! Almost certainly.</p>

<p>Not only does Gus Mueller generously provide details about the <a href="http://flyingmeat.com/wikka/AcornFileFormat">Acorn file format</a>, he has even released the source code to his Acorn Quicklook plugin. This gives me everything I need to convince NSImage to load Acorn files.</p>

<p>You might well be asking yourself why. I was getting annoyed with having to constantly keep exporting original Acorn images as pngs or TIFFs so I could use them in Xcode. I&#8217;m prototyping a new application that uses a lot of custom UI elements. These elements are made up of one or more pngs, some of which needed a lot of tweaking and attention to detail to get right. Acorn is perfect for UI work (although it needs more than 2000% zoom! <em>cough</em>) but having to export as png (or another format that Cocoa understands natively) and manage two sets of images (original Acorn, exported png) was turning into a pain.</p>

<p>I&#8217;ve taken Gus&#8217; QuickLook code and wrapped a small <a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSCustomImageRep_Class/Reference/Reference.html">NSCustomImageRep</a> around it. Very small. I&#8217;ve repackaged it up as a Framework so you can refer to it from an Interface Builder 3 plugin. This gives you the ability to do this:</p>

<pre><code>[NSImage imageNamed:@"IAmAnAcornFile"];
</code></pre>

<p>You should be able to use Acorn files anywhere an NSImage is used. Just embed your Acorn files in your XCode project resources and refer to them by name in your NIBs or in code.</p>

<p>I&#8217;ve put the code on my public googlecode.com subversion <a href="http://toxic-public.googlecode.com/svn/tags/BlogTag_20080219_785/Projects/Acorn/AcornImageFramework">repository</a>.</p>

<p>I&#8217;m currently on the fence about whether it is a good idea or not to ship your application with Acorn images. It certainly makes sense to me to use them during the interface design stage of application development. Once the user interface churn settles down I should be able to finalize the images and convert them to pngs or whatever (keeping the originals of course).</p>

<p>A best of both worlds solution might be to make a little command line tool that can convert Acorn files:</p>

<pre><code>#!/usr/bin/python
from AcornImage import *
# Everything else is an exercise for the reader.
</code></pre>

<p>And then automatically convert from Acorn to whatever during the Xcode build process. I might investigate this technique at a later date. But for now &#8211; have at it.</p>
]]></content:encoded>
			<wfw:commentRss>http://toxicsoftware.com/acornimage/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>R.I.P Toxic Progress Indicator</title>
		<link>http://toxicsoftware.com/rip_toxic_progress_indicator/</link>
		<comments>http://toxicsoftware.com/rip_toxic_progress_indicator/#comments</comments>
		<pubDate>Tue, 30 Oct 2007 13:17:26 +0000</pubDate>
		<dc:creator>schwa</dc:creator>
				<category><![CDATA[Default]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Source Code]]></category>
		<category><![CDATA[toxic progress indicator]]></category>

		<guid isPermaLink="false">http://toxicsoftware.com/rip_toxic_progress_indicator/</guid>
		<description><![CDATA[Thanks to Matt Gemmell for pointing out that Apple has finally provided a pie chart style NSProgressIndicator for the circular/determinate modes. This style is new to Leopard. This means my Toxic Progress Indicator class can be retired, at least for 10.5+ only applications. Leopard has really helped to retire a lot of my code (for [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to <a href="http://mattgemmell.com/2007/10/28/get-rid-of-your-code-with-leopard">Matt Gemmell</a> for pointing out that Apple has finally provided a pie chart style NSProgressIndicator for the circular/determinate modes. This style is new to Leopard. This means my <a href="http://toxicsoftware.com/toxic_progress_indicator/">Toxic Progress Indicator</a> class can be retired, at least for 10.5+ only applications. Leopard has really helped to retire a lot of my code (for example my QuickTime Sequence Grabber code can probably be retired too) and I expect this trend to continue.</p>

<p>Toxic Progress Indicator should still be used on apps that need to run on 10.4, but I wont be supporting the class any more (not that it is really needed any support&#8230;)</p>

<div style="text-align:center;"><img src="http://toxicsoftware.com/wordpress//uploads/cocoapiechart.png" alt="CocoaPieChart.png" border="0" width="429" height="407" /></div>
]]></content:encoded>
			<wfw:commentRss>http://toxicsoftware.com/rip_toxic_progress_indicator/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>SpaceNavigator controlled Lego Mindstorms NXT</title>
		<link>http://toxicsoftware.com/spacenavigatornxt/</link>
		<comments>http://toxicsoftware.com/spacenavigatornxt/#comments</comments>
		<pubDate>Thu, 27 Sep 2007 02:50:04 +0000</pubDate>
		<dc:creator>schwa</dc:creator>
				<category><![CDATA[Default]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Lego]]></category>
		<category><![CDATA[Links]]></category>
		<category><![CDATA[Mindstorms]]></category>
		<category><![CDATA[NXT]]></category>
		<category><![CDATA[Source Code]]></category>
		<category><![CDATA[SpaceNavigator]]></category>

		<guid isPermaLink="false">http://toxicsoftware.com/spacenavigatornxt/</guid>
		<description><![CDATA[It&#8217;s my second year of coaching a First Lego League team. The experience has been fantastic, I&#8217;m teaching 4th and 5th grade children about robots and computers, and teaching them to build and program their own robots. This year the kids are going to be learning how to use the new Lego Mindstorms NXT robot; [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s my second year of coaching a <a href="http://www.firstlegoleague.org/">First Lego League</a> team. The experience has been fantastic, I&#8217;m teaching 4th and 5th grade children about robots and computers, and teaching them to build and program their own robots. This year the kids are going to be learning how to use the new <a href="http://www.amazon.com/gp/product/B000E4FDAE?ie=UTF8&amp;tag=toxicsoftware-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B000E4FDAE">Lego Mindstorms NXT</a> robot; therefore I happen to have an NXT robot in the house. One of the cool features of the NXT is that it can communicate to a Mac (or even another NXT robot) via Bluetooth. So I thought it might be fun to take the <a href="http://www.amazon.com/gp/product/B000LB41BM?ie=UTF8&amp;tag=toxicsoftware-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B000LB41BM">3Dconnexion SpaceNavigator</a> controller device I used in my <a href="/the-intersection-of-cool-and-awesome">previous blog post</a> and use it to control an NXT Robot. Here is the result:</p>

<p><a href="http://s3.amazonaws.com/uploads.toxicsoftware.com/SpaceNavigatorNXT.mp4"><img src="http://toxicsoftware.com/wordpress/uploads/spacenavigatornxtpreview.png" alt="SpaceNavigatorNXTPreview.png" border="0" width="320" height="248" /></a></p>

<p>Although the SpaceNavigator support six degrees of freedom, I&#8217;m only using two (Y axis for forwards/reverse and RZ for turning), that leaves plenty of room for expansion (perhaps hooking up a third motor to another controller axis).</p>

<p>Although the video doesn&#8217;t show it too well, the SpaceNavigator does allow for very fine grained control over the robot (as long as the robot has fresh batteries!). The controller is extremely sensitive and with practice the robot can be controlled quite delicately.</p>

<p>Currently only one axis is dominant at a time (that&#8217;s actually a preference in the SpaceController System Preferences screen) but it is be possible to control robot steering and speed/direction at the same time. I&#8217;ll be trying that out soon.</p>

<p>There doesn&#8217;t seem to be much in the way of Mac OS X APIs for controlling NXT via Bluetooth, so I&#8217;m putting my code onto my <a href="http://toxic-public.googlecode.com/svn/tags/BlogTag_20070927_743/Projects/NXTTest/">public subversion server</a> and releasing it (like everything else in my public repository) under the <a href="http://en.wikipedia.org/wiki/Bsd_license">BSD License</a>. The code is Leopard only (although all I&#8217;m using are some <a href="http://developer.apple.com/leopard/overview/tools.html">Objective-C 2.0</a> features, such as properties and the new for loop). The code uses Cocoa bindings/KVC and has a rather simple interface:</p>

<pre><code>robot = [[[CNXTRobot alloc] init] autorelease];
((CNXTMotor *)[robot.ports objectForKey:@"B"]).power = (int)(theMotor1 * 100.0);
((CNXTMotor *)[robot.ports objectForKey:@"C"]).power = (int)(theMotor2 * 100.0);
</code></pre>

<p>The sample NXT project relies on my <a href="http://toxic-public.googlecode.com/svn/tags/BlogTag_20070927_743/Frameworks/ToxicWarped/">ToxicWarped</a> framework. ToxicWarped was originally created for my <a href="/">Geode</a> project and is designed to help write simple but flexible Object Oriented protocol stacks.</p>

<p>The NXT code is barely a day old, so it is very rough and ready but I&#8217;ll be tinkering with the NXT and SpaceNavigator code over the next few weeks (in my spare time) but if anyone has a use for the code and would like to contribute back that would be fantastic.</p>

<p>Update: Couldn&#8217;t stand awful <a href="http://www.youtube.com/watch?v=H4zct49Dv6Y">Youtube</a> image quality any longer. Videos are now on amazon s3.</p>
]]></content:encoded>
			<wfw:commentRss>http://toxicsoftware.com/spacenavigatornxt/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
<enclosure url="http://s3.amazonaws.com/uploads.toxicsoftware.com/SpaceNavigatorNXT.mp4" length="2233920" type="audio/mp4" />
<enclosure url="http://s3.amazonaws.com/uploads.toxicsoftware.com/SpaceNavigatorNXT/SpaceNavigatorNXT.mov" length="296" type="video/quicktime" />
		</item>
		<item>
		<title>The Intersection of Cool and Awesome</title>
		<link>http://toxicsoftware.com/the-intersection-of-cool-and-awesome/</link>
		<comments>http://toxicsoftware.com/the-intersection-of-cool-and-awesome/#comments</comments>
		<pubDate>Tue, 25 Sep 2007 17:37:24 +0000</pubDate>
		<dc:creator>schwa</dc:creator>
				<category><![CDATA[Default]]></category>
		<category><![CDATA[3Dconnexion]]></category>
		<category><![CDATA[Acorn]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Flying Meat]]></category>
		<category><![CDATA[Source Code]]></category>
		<category><![CDATA[SpaceNavigator]]></category>

		<guid isPermaLink="false">http://toxicsoftware.com/the-intersection-of-cool-and-awesome/</guid>
		<description><![CDATA[3Dconnexion (a division of Logitech) produces the coolest named device ever: The 3Dconnexion SpaceNavigator
. This is a 3D input device with 6 degrees of freedom, meaning you can move and rotate it through the X, Y and Z planes. I bought it originally on a whim (hey only 50 bucks!) for use with Google Sketchup [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.3dconnexion.com/">3Dconnexion</a> (a division of <a href="http://logitech.com/">Logitech</a>) produces the coolest named device ever: The <a href="http://www.amazon.com/gp/product/B000LB41BM?ie=UTF8&amp;tag=toxicsoftware-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B000LB41BM">3Dconnexion SpaceNavigator</a>
. This is a 3D input device with <a href="http://en.wikipedia.org/wiki/6_Degrees_Of_Freedom">6 degrees of freedom</a>, meaning you can move and rotate it through the X, Y and Z planes. I bought it originally on a whim (hey only 50 bucks!) for use with <a href="http://sketchup.google.com/">Google Sketchup</a> and <a href="http://earth.google.com/">Google Earth</a>. It took about twenty minutes to get competent with the device and I was soon whizzing around Manhattan inside Google Earth. The device is designed to use in your off hand with a mouse in your primary hand. This gives you a fantastic level of control in 3D applications.</p>

<p><img src="http://toxicsoftware.com/wordpress/uploads/3dx-spacenavigator.jpg" alt="3dx_spacenavigator.jpg" border="0" width="207" height="208" /></p>

<p>The software that comes with the SpaceNavigator is functional, but like a lot of hardware related software is rough around the edges. You can provide customised settings for specific applications or use global settings. You can set up macros to fire when either of the SpaceNavigator&#8217;s two buttons are pressed. Understandibly the SpaceNavigator will not appear to applications as a standard input device, so 3Dconnexion provide an <a href="http://www.3dconnexion.com/docs/3DxMacWareSDK.dmg">API</a> to allow 3rd party developers to use the device. This opens up a host of opportunities for 3rd party developers. The Space Navigator could be used in third-party applications as a jog wheel, kind of like the <a href="http://www.griffintechnology.com/products/powermate/">Griffin Powermate</a> and also as a 2D scroll wheel at the same time.</p>

<p>This leads me onto <a href="http://flyingmeat.com/acorn/">Acorn</a>, Acorn is <a href="http://gusmueller.com/">Gus Mueller&#8217;s</a> newest application. It is an awesome 2D image editor, with a healthy list of features. I consider it to be a &#8220;Photoshop for the rest of us&#8221;, and has quickly become my image editor of choice. Like Gus&#8217; <a href="http://www.flyingmeat.com/voodoopad/">VoodooPad</a>, Acorn also supports a <a href="http://flyingmeat.com/acorn/plugin.shtml">plug-in architecture</a>. This allow developers to extend the applications in ways Gus wouldn&#8217;t have dreamt of (although considering Gus wrote FlyGesture I&#8217;m sure he has some pretty funky dreams). I&#8217;ve created a plug-in for Acorn that uses the SpaceNavigator API to zoom and scroll around the image you&#8217;re editing. Rotating the SpaceNavigator causes the image to rotate (using the CoreImage affine transformation filter). This just touches the surface of the cool things you can do with the SpaceNavigator and an application that supports plug-ins.</p>

<p>Now for the money shots, two movies of the plug-in in action:</p>

<p><a href="http://s3.amazonaws.com/uploads.toxicsoftware.com/SpaceNavigatorAcorn.mp4"><img src="http://toxicsoftware.com/wordpress//uploads/spacenabvigatoracornpreview.png" alt="SpaceNabvigatorAcornPreview.png" border="0" width="293" height="248" /></a></p>

<p><a href="http://s3.amazonaws.com/uploads.toxicsoftware.com/SpaceNavigatorAcorn2.mp4"><img src="http://toxicsoftware.com/wordpress//uploads/spacenabvigatoracorn2preview.png" alt="SpaceNabvigatorAcorn2Preview.png" border="0" width="277" height="248" /></a></p>

<p>Source code for the plug-in is on my Google public repository <a href="http://toxic-public.googlecode.com/svn/tags/BlogTag_20070927_743/Projects/Acorn/AcornSpaceNavigator/">link</a>, I&#8217;ve also written a Cocoa wrapper for the 3Dconnextion API (required by the Acorn plug-in): <a href="http://toxic-public.googlecode.com/svn/tags/BlogTag_20070927_743/Projects/SpaceControllerTest/">link</a>. My Cocoa wrapper provides a much simpler interface to the device, and also provides more functionality (such as emulating a scroll wheel). I&#8217;ll be working on the wrapper more in the future.</p>

<p>All this code is a work in progress and you will probably need to massage the Xcode project to get it to compile. You&#8217;ll also need the 3Dconnexion API (and of course a SpaceController).</p>

<p>And hey look &#8211; I&#8217;m blogging again!</p>

<hr />

<p>Update: I got daringfireballed, so I&#8217;ve moved the movies onto youtube &#8211; quality sucks, but now the server seems responsive again. Links to source code fixed.</p>

<hr />

<p>Update: Movies now on Amazon S3. Youtube quality sucks so much. (videos still on Youtube <a href="http://www.youtube.com/watch?v=mad0UJOlo9Y">here</a> and <a href="http://www.youtube.com/watch?v=SQKb4qM3D5U">here</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://toxicsoftware.com/the-intersection-of-cool-and-awesome/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
<enclosure url="http://toxicsoftware.com/wordpress/uploads/SpaceNavigatorAcorn.mp4" length="2489441" type="video/mp4" />
<enclosure url="http://toxicsoftware.com/wordpress/uploads/SpaceNavigatorAcorn2.mp4" length="870846" type="video/mp4" />
<enclosure url="http://s3.amazonaws.com/uploads.toxicsoftware.com/SpaceNavigatorAcorn.mp4" length="2489441" type="audio/mp4" />
<enclosure url="http://s3.amazonaws.com/uploads.toxicsoftware.com/SpaceNavigatorAcorn2.mp4" length="870846" type="audio/mp4" />
		</item>
		<item>
		<title>&#8216;Discrete&#8217; NSLevelIndicatorCell too slow</title>
		<link>http://toxicsoftware.com/discrete-nslevelindicatorcell-too-slow/</link>
		<comments>http://toxicsoftware.com/discrete-nslevelindicatorcell-too-slow/#comments</comments>
		<pubDate>Sat, 24 Jun 2006 16:30:44 +0000</pubDate>
		<dc:creator>schwa</dc:creator>
				<category><![CDATA[Default]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[NSLevelIndicatorCell]]></category>
		<category><![CDATA[Shark]]></category>
		<category><![CDATA[Source Code]]></category>

		<guid isPermaLink="false">http://toxicsoftware.com/discrete-nslevelindicatorcell-too-slow/</guid>
		<description><![CDATA[I recently needed to embed the &#8216;Discrete&#8217; variant of the NSLevelIndicatorCell into an NSTableView. The discrete cell looks like this:

 Unfortunately adding the cell caused drawing of the table&#8217;s window to slow to crawl. The spinning beachball of death would often appear when I was merely resizing the window. After some quick experimented I narrowed [...]]]></description>
			<content:encoded><![CDATA[<p>I recently needed to embed the &#8216;Discrete&#8217; variant of the <a href="http://www.devworld.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSLevelIndicatorCell_Class/Reference/Reference.html">NSLevelIndicatorCell</a> into an NSTableView. The discrete cell looks like this:</p>

<p><img src="http://toxicsoftware.com/wordpress//uploads//Discrete.png" alt="Discrete.png" /> Unfortunately adding the cell caused drawing of the table&#8217;s window to slow to crawl. The spinning beachball of death would often appear when I was merely resizing the window. After some quick experimented I narrowed it down to something within the &#8216;Discrete&#8217; variant of the NSLevelIndicatorCell, the other variants had no such performance problems.</p>

<p>It didn&#8217;t take an expert in <a href="http://developer.apple.com/tools/sharkoptimize.html">Shark</a> to realise what was going on:</p>

<p><img src="http://toxicsoftware.com/wordpress//uploads//Shark.png" alt="" /> It looked like NSLevelIndicatorCell was perform an expensive gaussian blur per cell, possibly even for each discrete block within each cell. For a single NSLevelIndicatorCell that shouldn&#8217;t be a real problem, but for a whole table column full of them it could create major performance problems.</p>

<p>Some quick google searches showed that people had complained about poor NSLevelIndicatorCell performance before but failed to find a solution.</p>

<p>Switching to another variant of NSLevelIndicatorCell wasn&#8217;t an option, the &#8216;Discrete&#8217; variant was just too sexy. So the obvious solution was to create a subclass of NSLevelIndicatorCell that posed as the real thing, but cached the drawing code of its parent class into NSImages. So I present to the the world the imaginatively titled <a href="http://toxic-public.googlecode.com/svn/tags/BlogTag_20070927_729/Misc/CachingLevelIndicator/">CCachingLevelIndicatorCell</a>.</p>

<p>CCachingLevelIndicatorCell is designed to pose as NSLevelIndicatorCell but shouldn&#8217;t require any other configuration. The class will only cache images for the &#8216;Discrete&#8217; variant and will use a dictionary of NSImage objects to cache the drawing (one image per discrete value the cell can display). If any other attribute of the cell is changed the class will discard the cache and attempt to recache the drawing at the next opportunity.</p>

<p>Just so you can compare the differences in speed I&#8217;ve created two stand-alone test applications so you can compare the speed without CCachingLevelIndicatorCell and with it posing as NSLevelIndicatorCell. The binaries are checked into my <a href="http://toxic-public.googlecode.com/svn/tags/BlogTag_20070927_729/Misc/CachingLevelIndicator//Output/">public subversion</a>.</p>

<p>Radar bug: <a href="rdar://problem/4601201">rdar://problem/4601201</a></p>
]]></content:encoded>
			<wfw:commentRss>http://toxicsoftware.com/discrete-nslevelindicatorcell-too-slow/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Grab that Invocation</title>
		<link>http://toxicsoftware.com/grab-that-invocation/</link>
		<comments>http://toxicsoftware.com/grab-that-invocation/#comments</comments>
		<pubDate>Sat, 24 Jun 2006 00:25:43 +0000</pubDate>
		<dc:creator>schwa</dc:creator>
				<category><![CDATA[Default]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[NSInvocation]]></category>
		<category><![CDATA[Source]]></category>

		<guid isPermaLink="false">http://toxicsoftware.com/grab-that-invocation/</guid>
		<description><![CDATA[CInvocationGrabber is a Cocoa class to help with creating NSInvocation objects.

NSInvocation objects are Cocoa&#8217;s equivalent of &#8220;functors&#8221; and are extremely handy. But unfortunately creating them is often a pain. For example, take the following code showing how to create a simple NSInvocation:

NSInvocation *theInvocation = [NSInvocation invocationWithMethodSignature:[theString methodSignatureForSelector:@selector(insertString:atIndex:)]];
[theInvocation setSelector:@selector(insertString:atIndex:)];
[theInvocation setTarget:theString];
NSString *theFirstArgument = &#34;Hello World&#34;;
[theInvocation setArgument:&#38;theFirstArgument atIndex:2];
unsigned [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://toxic-public.googlecode.com/svn/tags/BlogTag_20070927_729/Projects/Misc/InvocationGrabber/">CInvocationGrabber</a> is a Cocoa class to help with creating <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSInvocation_Class/index.html#//apple_ref/doc/uid/TP40003671">NSInvocation</a> objects.</p>

<p>NSInvocation objects are Cocoa&#8217;s equivalent of &#8220;<a href="http://en.wikipedia.org/wiki/Function_object">functors</a>&#8221; and are extremely handy. But unfortunately creating them is often a pain. For example, take the following code showing how to create a simple NSInvocation:</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:#400080;">NSInvocation</span> *theInvocation = [<span style="color:#400080;">NSInvocation</span> <span style="color:#6c0540;">invocationWithMethodSignature:</span>[theString <span style="color:#6c0540;">methodSignatureForSelector:</span><span style="color:#881350;">@selector</span>(insertString:atIndex:)]];<br />
[theInvocation <span style="color:#6c0540;">setSelector:</span><span style="color:#881350;">@selector</span>(insertString:atIndex:)];<br />
[theInvocation <span style="color:#6c0540;">setTarget:</span>theString];<br />
<span style="color:#400080;">NSString</span> *theFirstArgument = <span style="color:#760f15;">&quot;Hello World&quot;</span>;<br />
[theInvocation <span style="color:#6c0540;">setArgument:</span>&amp;theFirstArgument <span style="color:#6c0540;">atIndex:</span><span style="color:#0000ff;">2</span>];<br />
<span style="color:#881350;">unsigned</span> theSecondArgument = <span style="color:#0000ff;">42</span>;<br />
[theInvocation <span style="color:#6c0540;">setArgument:</span>&amp;theFirstArgument <span style="color:#6c0540;">atIndex:</span><span style="color:#0000ff;">3</span>];</div>

<p>The code to create the same NSInvocation using my CInvocationGrabber class looks like this:</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; ">CInvocationGrabber *theGrabber = [CInvocationGrabber <span style="color:#6c0540;">invocationGrabber</span>];<br />
[[theGrabber <span style="color:#6c0540;">prepareWithInvocationTarget:</span>theString] <span style="color:#6c0540;">insertString:</span><span style="color:#760f15;">@&quot;Hello World&quot;</span> <span style="color:#6c0540;">atIndex:</span><span style="color:#0000ff;">42</span>];<br />
<span style="color:#400080;">NSInvocation</span> *theInvocation = [theGrabber <span style="color:#6c0540;">invocation</span>]</div>

<p>Obviously the primary benefit is that there is a lot less code. A secondary benefit is that you don&#8217;t have to store your parameters on the heap and can just pass them into the &#8216;grabbed&#8217; method.</p>

<p>Now that I&#8217;ve been using CInvocationGrabber for a few months I find I am using NSInvocations more and more. I&#8217;m using them in places where I would normally have written a little delegate method. For example just today I needed to write code that called a method after a time delay. Normally I would have wrapped it up in a NSTimer delegate method, but with CInvocationHelper I just used the invocation variant of NSTimer. Although I wasn&#8217;t saving many lines of code in this example, I was reducing the clutter in the class.</p>

<p>Cocoa developers with a keen eye might spot the similarity between CInvocationGrabber and Cocoa&#8217;s NSUndoManager APIs. This code is directly inspired by NSUndoManager&#8217;s prepareWithInvocation method.</p>
]]></content:encoded>
			<wfw:commentRss>http://toxicsoftware.com/grab-that-invocation/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Toxic Progress Indicator Updated</title>
		<link>http://toxicsoftware.com/toxic-progress-indicator-updated/</link>
		<comments>http://toxicsoftware.com/toxic-progress-indicator-updated/#comments</comments>
		<pubDate>Wed, 21 Jun 2006 14:37:27 +0000</pubDate>
		<dc:creator>schwa</dc:creator>
				<category><![CDATA[Default]]></category>
		<category><![CDATA[bork]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[ToxicProgressIndicator]]></category>

		<guid isPermaLink="false">http://toxicsoftware.com/toxic-progress-indicator-updated/</guid>
		<description><![CDATA[Thanks to Daniel Jalkut for submitting a patch to Toxic Progress Indicator. The patches fixes a couple of silly bugs with setMinValue/setMaxValue and also makes the code a little bit more generic. I&#8217;ve updated subversion with the patch, which is recommended for all uses of ToxicProgressIndicator (both of you).
]]></description>
			<content:encoded><![CDATA[<p>Thanks to <a href="http://red-sweater.com/blog/">Daniel Jalkut</a> for submitting a patch to <a href="/toxic_progress_indicator/">Toxic Progress Indicator</a>. The patches fixes a couple of silly bugs with setMinValue/setMaxValue and also makes the code a little bit more generic. I&#8217;ve updated <a href="http://toxic-public.googlecode.com/svn/tags/BlogTag_20070927_729/Widgets/ToxicProgressIndicator/">subversion</a> with the patch, which is recommended for all uses of ToxicProgressIndicator (both of you).</p>
]]></content:encoded>
			<wfw:commentRss>http://toxicsoftware.com/toxic-progress-indicator-updated/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
