<?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>James Van Dyne &#187; Hacking</title>
	<atom:link href="http://www.james-vandyne.com/category/hacking/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.james-vandyne.com</link>
	<description>The Life and Times</description>
	<lastBuildDate>Sat, 08 Oct 2011 16:11:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>How to Test File Upload Parsing in Django</title>
		<link>http://www.james-vandyne.com/how-to-test-file-upload-parsing-in-django/</link>
		<comments>http://www.james-vandyne.com/how-to-test-file-upload-parsing-in-django/#comments</comments>
		<pubDate>Sat, 30 Apr 2011 04:04:48 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.james-vandyne.com/?p=191</guid>
		<description><![CDATA[I didn&#8217;t start testing software until recently. Of course I tested my software to make sure it works and is stable, but it was a very manual process. This was very time consuming and sometimes subtle bugs were let through &#8230; <a href="http://www.james-vandyne.com/how-to-test-file-upload-parsing-in-django/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I didn&#8217;t start testing software until recently. Of course I tested my software to make sure it works and is stable, but it was a very manual process. This was very time consuming and sometimes subtle bugs were let through or re-introduced in large codebase changes.</p>

<p>I didn&#8217;t start unit-testing for a long time because I didn&#8217;t really know where to begin. Especially with an existing codebase. I&#8217;ve been working on a project and part of the project includes a file upload that needs to be parsed. I couldn&#8217;t stomach the thought of clicking, browsing, submitting and waiting each time just to test a few changes.</p>

<h3>Problem</h3>

<p>Testing uploaded file parsing in a manual fashion is very time consuming and takes a long time. If the parsing breaks, we won&#8217;t know unless we upload each test file after every change. We can do better than this.</p>

<p>We need to utilize the testing framework in Django to help us automate this process a bit more.</p>

<h3>Solution</h3>

<p>The first thing we want to do is make an example file that a user may upload in our fixtures directory. Keeping the test upload files in our fixtures has a number of advantages. It allows us to keep them in our version control and lets all of our testing be portable.</p>

<p>For the example let&#8217;s pretend we are parsing an excel file of some kind.</p>

<p><img src="http://www.james-vandyne.com/wp-content/images/2011/fixture.png" title="Our test file in the fixtures dir"/></p>

<p>The next step is to prepare our test. While we are only testing a single file upload, you may want to add in corrupted files or perhaps expand to different versions. So, lets setup our test with a single test &#8220;runner&#8221; test that will run the tests.</p>

<p>Also note that by keeping the import statements using a localized path instead of a full package sitename.app.file, we can further improve portability.</p>

<pre code="python">
from django.test import TestCase
from utils import parse_excel_upload
import os

class ExcelParseTest(TestCase):
    
    test_upload_path = 'fixtures/test_upload.xls'
    
    def test_parse(self):
      self.parse(self.test_upload_path)
</pre>

<p>The above is straight forward, we have our excel test parse class, and a method named test_parse that will call a method named parse that takes a filename and will run all the actual tests.</p>

<p>Next, let&#8217;s setup our actual parse method:</p>

<pre code="python">
 def parse(self,file_location):
        """
        Tests that we can parse our excel files
        """
        
        #setup
        path = os.path.join(os.path.split(__file__)[0],file_location)

        elements = parse_excel_upload(path)
        
        #Assert that we have something returned as expected
        self.assertNotEqual(elements,None)
        # continue doing more specific tests here
</pre>

<p>Note that I am using self.assertNotEqual. If you are running Python 2.7 or later, you can use self.assertNotNone(elements) for the same functionality. Using assertNotEqual simply allows us to run a older versions of python as well.</p>

<p>If we wanted to test our method with more files, perhaps some corrupted files, we simply need to add another test file in our fixture and then modify our runner to include parse the new file.</p>

<h3>Conclusion</h3>

<p>Testing requires a small initial time investment to get started. If it&#8217;s your first time testing, there are a few mental gymnastics to get used to for writing code that is testable.</p>

<p>After the initial investment, which becomes less and less each time do it, we can vastly improve the reliability of our code and catch subtle bugs that may crop up during development or future releases.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.james-vandyne.com/how-to-test-file-upload-parsing-in-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Create Realistic Buttons with CSS3</title>
		<link>http://www.james-vandyne.com/creating-realistic-buttons-with-css3/</link>
		<comments>http://www.james-vandyne.com/creating-realistic-buttons-with-css3/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 04:51:42 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[CSS3]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.james-vandyne.com/?p=168</guid>
		<description><![CDATA[In a modern web application we don&#8217;t really use buttons (ala the input tag) so much. More often than not, we use some kind of div or link that when combined with some javascript behaves as a button. I&#8217;m not &#8230; <a href="http://www.james-vandyne.com/creating-realistic-buttons-with-css3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In a modern web application we don&#8217;t really use buttons (ala the input tag) so much. More often than not, we use some kind of div or link that when combined with some javascript behaves as a button. I&#8217;m not going to cover how to hook this all up into your application, but rather just the styling of buttons.</p>

<h3>Problem</h3>

<p>Traditionally, web developers have had to create graphics for every non-standard button they used on their site. This is expensive in terms of time, money, and usability. It takes extra work for our buttons to be assessable, increases load times, and if we ever want to change the wording of our button, we have to start all over again.</p>

<p>Using various features afforded in css3, we can remove the need for images altogether, lower load times (and save bandwidth) while gaining scalability of our user interface, full accessibility, and never have something that is completely reusable throughout our site without any extra work.</p>

<p>We are going to go from the one on the left to the one on the right.</p>

<p><img src="http://www.james-vandyne.com/wp-content/uploads/2011/03/before-after.png"/></p>

<h3>Solution</h3>

<p>First, we need to begin with our basic markup.</p>


<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;a href=&quot;#&quot;&gt;My Button&lt;/a&gt;</pre></div></div>


<p><img src="http://www.james-vandyne.com/wp-content/uploads/2011/03/no-style.png"/></p>

<p>Because we want to style it and reuse said styles more than once on a page (potentially), we&#8217;re going to want to add a css class name.</p>


<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;a href=&quot;#&quot; class=&quot;gradient_button&quot;&gt;My Button&lt;/a&gt;</pre></div></div>


<p>That&#8217;s all the html markup we will use. From here on out, we will just be adding styles to our stylesheet. The first thing we need to do is decide which color our button needs to be. We need a minimum of 2 colors: one lighter color for the top of the button and one darker color (of the same shade) for the button of the button.</p>

<p>I used the <a href="http://gradients.glrzad.com/" target="_blank">CSS3 Gradient Generator</a> to select my colors and generate the rules. I&#8217;ve picked a grey color for this tutorial. Feel free to pick anything you like. Let&#8217;s set it as the background for our button. Let&#8217;s create our gradient_button selector and add our gradient background</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">a<span style="color: #6666ff;">.gradient_button</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">background-image</span><span style="color: #00AA00;">:</span> -webkit-gradient<span style="color: #00AA00;">&#40;</span>linear<span style="color: #00AA00;">,</span><span style="color: #000000; font-weight: bold;">left</span> <span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">,</span><span style="color: #000000; font-weight: bold;">left</span> <span style="color: #000000; font-weight: bold;">bottom</span><span style="color: #00AA00;">,</span>color-stop<span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">0.43</span><span style="color: #00AA00;">,</span> <span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">234</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">,</span>color-stop<span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">0.72</span><span style="color: #00AA00;">,</span> <span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">background-image</span><span style="color: #00AA00;">:</span> -moz-linear-gradient<span style="color: #00AA00;">&#40;</span><span style="color: #993333;">center</span> <span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">,</span><span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">234</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">&#41;</span> <span style="color: #933;">43%</span><span style="color: #00AA00;">,</span><span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">&#41;</span> <span style="color: #933;">72%</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>


<p><img src="http://www.james-vandyne.com/wp-content/uploads/2011/03/gradient.png"/></p>

<p>It&#8217;s ugly, but we&#8217;re getting closer. Next, let&#8217;s add some padding around our button, create a border, and give it rounded corners. Add the following to the gradient_button selector.</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">border</span><span style="color: #00AA00;">:</span><span style="color: #993333;">solid</span> <span style="color: #933;">1px</span> <span style="color: #cc00cc;">#111</span><span style="color: #00AA00;">;</span>
-webkit-border-radius<span style="color: #00AA00;">:</span><span style="color: #933;">3px</span><span style="color: #00AA00;">;</span>
-moz-border-radius<span style="color: #00AA00;">:</span><span style="color: #933;">3px</span><span style="color: #00AA00;">;</span>
<span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span><span style="color: #933;">5px</span><span style="color: #00AA00;">;</span></pre></div></div>


<p><img src="http://www.james-vandyne.com/wp-content/uploads/2011/03/rounded.png"/></p>

<p>Already we are looking much better and more realistic. However, the text completely throws the button off. It looks like it&#8217;s just pasted on there. We want our text to be a part of the button. We can do that by insetting the text with a shadow. So, next, let&#8217;s remove the text decoration, change the color, and inset that text.</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span><span style="color: #cc00cc;">#111</span><span style="color: #00AA00;">;</span>
<span style="color: #000000; font-weight: bold;">font-weight</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">bold</span><span style="color: #00AA00;">;</span>
<span style="color: #000000; font-weight: bold;">text-shadow</span><span style="color: #00AA00;">:</span><span style="color: #cc00cc;">#ffe</span> <span style="color: #933;">0px</span> <span style="color: #933;">1px</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">,</span> <span style="color: #cc00cc;">#333</span> <span style="color: #cc66cc;">0</span> <span style="color: #933;">-1px</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
<span style="color: #000000; font-weight: bold;">text-decoration</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span></pre></div></div>


<p><img src="http://www.james-vandyne.com/wp-content/uploads/2011/03/inset.png"/></p>

<p>Already, you can see our button finally looks like a button. We could stop there, but we should go the extra mile for that last bit of polish. Especially considering how much time we can save because we never have to visit photoshop to make a button again.</p>

<p>First, we need to recognize that objects are never flat. Everything casts a shadow. Our buttons are no different. Remember to try and keep a consistent light source when implementing shadows on your website, my light source is directly above, so I only want to cast a shadow below my button. Add the following to the selector:</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">-moz-box-shadow<span style="color: #00AA00;">:</span>  <span style="color: #933;">0px</span> <span style="color: #933;">2px</span> <span style="color: #933;">5px</span> <span style="color: #cc00cc;">#999</span><span style="color: #00AA00;">;</span>
-webkit-box-shadow<span style="color: #00AA00;">:</span>  <span style="color: #933;">0px</span> <span style="color: #933;">2px</span> <span style="color: #933;">5px</span> <span style="color: #cc00cc;">#999</span><span style="color: #00AA00;">;</span>
box-shadow<span style="color: #00AA00;">:</span> <span style="color: #933;">0px</span> <span style="color: #933;">2px</span> <span style="color: #933;">5px</span> <span style="color: #cc00cc;">#999</span><span style="color: #00AA00;">;</span></pre></div></div>


<p><img src="http://www.james-vandyne.com/wp-content/uploads/2011/03/shadow.png"/></p>

<p>Our button now looks great. Try clicking on it. Notice that? It maybe look like a button, but it surely doesn&#8217;t behave like a button. We can fix that by adding one more selector. We need to style the :active state of the link, which is displayed when a button is pressed.</p>

<p>When picturing a physical button pressed, what sort of changes we see? I imagine that the shadow would disappear, as the button is now becoming flat with the surface from which it protrudes. Also, I imagine that the shine of our gradient would change. I think that it would become almost a solid color, but not quite. Let&#8217;s one last style to make our button behave a lot more naturally when clicked.</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">a<span style="color: #3333ff;">:active</span><span style="color: #6666ff;">.gradient_button</span> <span style="color: #00AA00;">&#123;</span>
	-webkit-box-shadow<span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
	-moz-box-shadow<span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
	box-shadow<span style="color: #00AA00;">:</span><span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">background-image</span><span style="color: #00AA00;">:</span> -webkit-gradient<span style="color: #00AA00;">&#40;</span>linear<span style="color: #00AA00;">,</span><span style="color: #000000; font-weight: bold;">left</span> <span style="color: #000000; font-weight: bold;">bottom</span><span style="color: #00AA00;">,</span><span style="color: #000000; font-weight: bold;">left</span> <span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">,</span>color-stop<span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">0.18</span><span style="color: #00AA00;">,</span> <span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">234</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">,</span>color-stop<span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">0.59</span><span style="color: #00AA00;">,</span> <span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">,</span>color-stop<span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">0.8</span><span style="color: #00AA00;">,</span> <span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">234</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">background-image</span><span style="color: #00AA00;">:</span> -moz-linear-gradient<span style="color: #00AA00;">&#40;</span><span style="color: #993333;">center</span> <span style="color: #000000; font-weight: bold;">bottom</span><span style="color: #00AA00;">,</span> <span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">234</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">&#41;</span> <span style="color: #933;">18%</span><span style="color: #00AA00;">,</span><span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">&#41;</span> <span style="color: #933;">59%</span><span style="color: #00AA00;">,</span><span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">234</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">&#41;</span> <span style="color: #933;">80%</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
	<span style="color: #00AA00;">&#125;</span></pre></div></div>


<p><img src="http://www.james-vandyne.com/wp-content/uploads/2011/03/pushed.png"></p>

<p>There we have it. A completely realistic button using nothing but CSS3 and a hyperlink.</p>

<h3>Conclusion</h3>

<p>CSS3 buttons allows us to save time (and therefore money) when developing a modern web application. Moreover, we get fringe benefits such as being able to make our website more accessible and fully scalable for free.</p>

<p><a href="http://www.james-vandyne.com/wp-content/uploads/2011/03/gradient_button.html" target="_blank">View Realistic CSS3 Button</a></p>

<h3>Update:</h3>

<p>This doesn&#8217;t work in IE. If you&#8217;d like to use a similar effect for the gradient, you can use the IE filter styles. The major caveat is that IE only seems to render these with a div wrapper or an absolute position. The div wrapper really kills the elegance of being able to have any link suddenly look and behave like a regular button with a single style. I recommend a graceful-degradation in IE, and just set the background color to a be solid.</p>

<p>The css for getting the same gradient effect in IE is as follows:</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">	<span style="color: #808080; font-style: italic;">/* For Internet Explorer 5.5 - 7 */</span>
	filter<span style="color: #00AA00;">:</span> progid<span style="color: #3333ff;">:DXImageTransform</span><span style="color: #6666ff;">.Microsoft</span>.gradient<span style="color: #00AA00;">&#40;</span>startColorstr<span style="color: #00AA00;">=</span><span style="color: #cc00cc;">#EDEAED</span><span style="color: #00AA00;">,</span> endColorstr<span style="color: #00AA00;">=</span><span style="color: #cc00cc;">#B0B0B0</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
	<span style="color: #808080; font-style: italic;">/* For Internet Explorer 8 */</span>
	-ms-filter<span style="color: #00AA00;">:</span> <span style="color: #ff0000;">&quot;progid:DXImageTransform.Microsoft.gradient(startColorstr=#EDEAED, endColorstr=#B0B0B0)&quot;</span><span style="color: #00AA00;">;</span>
	<span style="color: #808080; font-style: italic;">/* graceful-degradation when the filter doesn't work */</span>
	<span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span><span style="color: #cc00cc;">#EDEAED</span><span style="color: #00AA00;">;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.james-vandyne.com/creating-realistic-buttons-with-css3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How to Make an Accessible Multiline NSMenuItem (without any custom drawing)</title>
		<link>http://www.james-vandyne.com/how-to-make-an-accessible-multiline-nsmenuitem-without-a-custom-view/</link>
		<comments>http://www.james-vandyne.com/how-to-make-an-accessible-multiline-nsmenuitem-without-a-custom-view/#comments</comments>
		<pubDate>Fri, 11 Feb 2011 05:57:15 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.james-vandyne.com/?p=159</guid>
		<description><![CDATA[In developing a new application, I ran into the need for a NSPopupButton for selecting a preference. The menu that you see popup when you click on a NSPopupButton is really just an NSMenu full of NSMenuItems. The same menu &#8230; <a href="http://www.james-vandyne.com/how-to-make-an-accessible-multiline-nsmenuitem-without-a-custom-view/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In developing a new application, I ran into the need for a NSPopupButton for selecting a preference. The menu that you see popup when you click on a NSPopupButton is really just an NSMenu full of NSMenuItems. The same menu items that you might see in a contextual menu or even from the main menu at the top of the screen.</p>

<p>I was looking for some way to display a Title as regular, then right under it some kind of subtitle. Naturally, NSMenuItems are designed to handle just a single title. It seemed like if I wanted to display anything other than a single title, I was going to have to take advantage of NSMenuItem&#8217;s new ability to host a generic NSView.</p>

<h3>Problem</h3>

<p>Getting your custom NSView in to a NSMenuItem is easy. I actually got it displaying rather nicely. The problems came when I wanted my NSView and NSMenuItem to behave like they would as per regular.</p>

<ol>
<li><p>Passing clicks from my NSView to the NSPopupButton proved to be rather difficult. Moreover, it felt like a huge kludge as it tied these items to a single control. I also wanted to reuse these in the menu up top.</p></li>
<li><p>Even with the kludge, I decided to proceed on. Next up was displaying the checkbox (NSOnState) image. For some reason, the checkbox image returned by [NSImage imageNamed:NSOnStateImage] is different from the checkbox image used in the rest of the system. It was skinner and looked out of place.</p></li>
</ol>

<p>Overall, making a custom view with this much kludge and not quite feeling right grated on me. I wasted 2 days to get this far, but it doesn&#8217;t live up to the user experience that I want to give users and expect from software on the Mac.</p>

<h3>Solution</h3>

<p>In my rush to get my NSMenuItem running, I overlooked a a critical feature: NSMenuItem titles can take an NSAttributedString.</p>

<p>When initializing your NSMenuItem we can use an attributed string to set our colors. \n also works for creating new lines.</p>

<pre class="objc">
// assume we have an NSMenuItem alloc'ed/init'ed named item.
// we also have a model objected that responds to the "title" and "subtitle" messages 
// named myObject

NSString *title = [NSString stringWithFormat:@"%@\n%@",[myObject title],[myObject subtitle]];
NSMutableAttributedString *attributed_title = [[NSMutableAttributedString alloc] initWithString:title];
        
// This is the system default for controls. anything else and it looks off
NSDictionary *title_options = [NSDictionary dictionaryWithObjectsAndKeys:[NSFont fontWithName:@"Lucida Grande" size:13.0f],NSFontAttributeName,nil];

//make our subtitle a different color as it is just auxillary information 
NSDictionary *sub_title_options = [NSDictionary dictionaryWithObjectsAndKeys:[NSColor disabledControlTextColor],NSForegroundColorAttributeName,nil];

// apply our color attributes to the ranges of the string they are applicable to...
[attributed_title addAttributes:title_options range:[title rangeOfString:[myObject title]]];
[attributed_title addAttributes:sub_title_options range:[title rangeOfString:[myObject subtitle]]];

// finally set our attributed to the menu item
[item setAttributedTitle:attributed_title];
[item setRepresentedObject:myObject];

// clean up
[attributed_title release];
</pre>

<p>With the above in place we are halfway there. Our new shiny menu item looks great and it fits in. Most importantly there is zero kludge. Actions go where we want them when we want them. The NSOnState image looks like it does in the rest of the system. Life is hunky-dory.</p>

<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.james-vandyne.com/wp-content/uploads/2011/02/nsmenuitem_no_highlight.png" alt="Our multiline NSMenuItem" title="Our multiline NSMenuItem" border="0" width="193" height="44" /></p>

<p>Until we highlight it.</p>

<p>Our title and state images turn white when highlighted as expected. However, our subtitle&#8230;not so much.</p>

<p>Luckily we can fix this without too much trouble. NSMenu&#8217;s has a lovely delegate that tells us when it is about to highlight something with it&#8217;s menu:willHighlightItem: call. &#8220;Will&#8221; is the keyword that we tips us of we can use this. It means that our currently highlighted item is still selected, so we can revert any changes made.</p>

<p>*Update: * I had left a huge block of code that smelled bad and left it as an exercise to the reader to clean it up. I decided to remove some of the smell myself. If you have ideas on how the code below could be refactored even better, please let a comment below.</p>

<pre class="objc">
// set our controller to be the delegate of our NSMenu. In the case of a NSPopupButton, 
// you can access it with the [myButton menu] method.

- (void)setForegroundColor:(NSColor *)foregroundColor 
    onAttributedString:(NSMutableAttributedString *)attributedString 
    forRangeOfString:(NSString *)string {

    NSRange range = [[attributedString mutableString] rangeOfString:string];
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:foregroundColor,NSForegroundColorAttributeName,nil];
    
    [attributedString setAttributes:attributes range:range];
    
}

- (void)willHighlightItem:(NSMenuItem *)item currentlyHighlightedItem:(NSMenuItem *)currentItem {
    
    if (currentItem != nil) {
        NSString *subtitle = [(MyModelObject *)[currentItem representedObject] subtitle];
        NSMutableAttributedString *attributedString = [[currentItem attributedTitle] mutableCopy];

        [self setForegroundColor:[NSColor disabledControlTextColor] onAttributedString:attributedString forRangeOfString:subtitle];
                
        [currentItem setAttributedTitle:attributedString];
        [attributedString release];
    }
    
    NSString *subtitle = [(MyModelObject *)[item representedObject] subtitle];
    NSMutableAttributedString *attributedString = [[item attributedTitle] mutableCopy];
    
    [self setForegroundColor:[NSColor selectedMenuItemTextColor] onAttributedString:attributedString forRangeOfString:subtitle];

    [item setAttributedTitle:attributedString];
    [attributedString release];
}

</pre>

<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://james-vandyne.com/wp-content/uploads/2011/02/nsmenuitem_highlight.png" alt="Our nicely highlighted NSMenuItem"/></p>

<h3>Conclusion</h3>

<p>With just the few lines of code above, we can create a custom looking NSMenuItem that behaves exactly as we would expect it to. What&#8217;s more by using an NSAttributedString isntead of a custom view, our &#8220;custom control&#8221;  get accessibility for free. This means users with impaired sight get the same first-class experience as everyone else. Talk about a win-win-win.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.james-vandyne.com/how-to-make-an-accessible-multiline-nsmenuitem-without-a-custom-view/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Choose the Right Tool (Everything is not a nail)</title>
		<link>http://www.james-vandyne.com/choose-the-right-tool-everything-is-not-a-nail/</link>
		<comments>http://www.james-vandyne.com/choose-the-right-tool-everything-is-not-a-nail/#comments</comments>
		<pubDate>Thu, 27 Jan 2011 02:37:30 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.james-vandyne.com/?p=152</guid>
		<description><![CDATA[Picking the right tool for the job is often rather difficult for software developers. As software developers,We tend to find a hammer we like and treat everything like a nail, even if it&#8217;s a screw. Sometimes we&#8217;re reluctant to learn &#8230; <a href="http://www.james-vandyne.com/choose-the-right-tool-everything-is-not-a-nail/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Picking the right tool for the job is often rather difficult for software developers. As software developers,We tend to find a hammer we like and treat everything like a nail, even if it&#8217;s a screw. Sometimes we&#8217;re reluctant to learn new and different tools or ways of hammering.</p>

<p>When I first started writing <a href="http://www.sugoisoft.com/jisho">Jisho</a>, my hammer of choice was Objective-C. All projects, no matter their suitability, were developed in Objective-C. I even wished that Apple would have continued NeXT&#8217;s support for <a href="http://en.wikipedia.org/wiki/WebObjects">WebObjects</a> in Objective-C. Afterall, everything is nail.</p>

<p>This meant that things that probably should have never been written in Objective-C were written in Objective-C. That&#8217;s not to say that the things I wrote couldn&#8217;t be written in Objective-C, indeed, they could, but that it would have been better to pick a different tool. A rock can break a piece of wood in two, which is great if you just need two random lengths of wood, but if you need any more precision, you should use a saw. Objective-C and Python can both parse xml, but the former takes a lot more effort than the later.</p>

<p>I eventually came to my senses and realized that my supporting application was not scaling the way I had hoped. It needed to be rewritten. What did I do? I picked the same hammer again, foolishly expecting different results.</p>

<p>It worked great for a while &#8211; until it didn&#8217;t. Features only came after great reluctance if at all. I knew it needed to be rewritten, again.</p>

<p>This time around, I have a wider skillset than I did when I first started Jisho. I know a few more scripting languages reasonably well. Some <a href="http://www.python.org">I like a lot more</a> than <a href="http://www.php.net" title="Not a big fan">others</a>.</p>

<p>While I am still in the process of writing the parser, it&#8217;s coming together much quicker than the old versions ever did. More importantly, it doesn&#8217;t read like a bunch of voodoo magic. These tools excel for things like this. We should use them.</p>

<p>Today, Objective-C is still one of the most important hammers in my toolbox &#8211; perhaps even my favourite. But sometimes you need a saw.</p>

<p>As a software developer if you think something would be easier with a different tool, try it and find out. Best case scenerio you&#8217;re right and you&#8217;ve learned a new tool. Worst case scenario is you&#8217;ve learned a new tool and expanded your skillset. You can&#8217;t lose.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.james-vandyne.com/choose-the-right-tool-everything-is-not-a-nail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>8 Things I Learned About Software Development (Without writing code)</title>
		<link>http://www.james-vandyne.com/8-things-i-learned-about-software-development-without-writing-code/</link>
		<comments>http://www.james-vandyne.com/8-things-i-learned-about-software-development-without-writing-code/#comments</comments>
		<pubDate>Wed, 12 Jan 2011 09:02:26 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Hacking]]></category>

		<guid isPermaLink="false">http://www.james-vandyne.com/?p=146</guid>
		<description><![CDATA[In 2009 I set out to make a major elease of my Japanese-English dictionary Jisho 4.0. Jisho 4.0 was to be a complete overhaul of the existing codebase and a 100% new interface. After a scrapped interface and a few &#8230; <a href="http://www.james-vandyne.com/8-things-i-learned-about-software-development-without-writing-code/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In 2009 I set out to make a major elease of my Japanese-English dictionary <a title="Japanese English Dictionary Jisho" href="http://www.sugoisoft.com/jisho/">Jisho 4.0</a>. Jisho 4.0 was to be a complete overhaul of the existing codebase and a 100% new interface.</p>

<p>After a scrapped interface and a few delays, I forced myself stop adding new features and move the &#8220;nice to haves&#8221; into a future release. Jisho 4.0 was shipped in December 2009.</p>

<p>Soon after the 4.0 release I began work on Jisho 4.1 to take care of these issues. Jisho 4.1 was released in January 2011. The development time was quite long, but most of it was not spent writing code. Below are some lessons I learned while developing Jisho 4.1.</p>

<h2>Define the scope of the release</h2>

<p>Define features or fixes in a given release and stick to it. With a proper scope written there will be no second guessing if your program is ready to ship. Have you implemented the planned changes? Yes? Ship.</p>

<h2>Keep it limited</h2>

<p>If it sounds like it could be broken into multiple releases, it probably should be. Try to keep releases small. I made the mistake of trying to refactor the backend to improve search and add in some new UI features for a single release. The end result was looking 3 major undertakings directly after a major release was paralyzing.</p>

<h2>Fully plan an interface before committing to development of a feature</h2>

<p>Fully plan how a feature is going to work and integrate with the rest of the application before committing to develop it for a particular release.</p>

<p>With Jisho 4.1, I wanted to refine the interface so the user could see kanji in a larger view. I hadn&#8217;t planned the interaction properly and a clean design was not forth coming.</p>

<p>I spent the majority of development time trying various interactions that inevitably felt unnatural. Simply planning this refinement more completely would have told me it&#8217;s enough for it&#8217;s own release.</p>

<h2>Push features to if it means you can release</h2>

<p>If you have a feature that is sapping development time and holding up bug fixes or already completed features, push it. There&#8217;s no shame in pushing a feature to a future release so your users can get better software today.</p>

<p>Users tend to get upset if you promise a feature for a given release and then pull it. So, this lesson is most applicable if you don&#8217;t promise particular features while they are still in development or even before they are released.</p>

<h2>Git (or your scm of choice) is a good thing</h2>

<p>Creating a branch for development of a new feature is a great way to make it easy to revert to a prior version so you can release. If you only merge branches once the fix or feature is stable and complete, you will always have a stable version ready.</p>

<p>I just started using Git before the development of 4.0. Before that I was coding dangerously with random zip archives of the code, usually at each point release, and a changelog that only mentioned the changes the end-user would see.</p>

<h2>Lower the barrier</h2>

<p>The more steps required when releasing a piece of software has the same effect as adding steps during checkout. You&#8217;re going to lose a lot of people (or in our case inertia) towards making an actual release. Simply your release process as much as possible.</p>

<p>Until 4.1, Jisho was distributed as a dmg for new users. This dmg had a custom background, readme, shortcut to the applications folder. Each release was built by hand. I would spend a good hour crafting this dmg for each release.</p>

<p>Now Jisho 4.1 is simply distributed as a zip file of the application. I still have to zip / upload it manually at this point, which takes 2 minutes, but that&#8217;s still an extra step. Future plans include automating the entire process from within Xcode.</p>

<h2>Release something</h2>

<p>Releasing is like software food. Software lives by releasing new versions. The quickest way to kill a software project is to get weighed down by a single non-critical feature of fix.</p>

<p>The guilt associated with keeping fixes out of the hands of your users in the name of an unannounced feature will only grow with time. Assuming you haven&#8217;t pre-announced the feature, users won&#8217;t know what they&#8217;re missing. If you have, they might complain a bit, but most users would rather have something new rather than nothing.</p>

<h2>It&#8217;s not too late</h2>

<p>If you find yourself agreeing with any of this, stop reading this and figure out the fastest way to get a release out the door. It&#8217;s not to late to release something.</p>

<p>Jisho was well on it&#8217;s way to death by starvation. By reverting to the latest stable version and cutting the features that were holding up release I was able to breath life back into Jisho.</p>

<p>Was the release technically what one would consider a release worthy of a new sub-number version release? By itself &#8211; probably not*. However, the principal still stands &#8211; if your software looks like it&#8217;s starving, cut whatever you need to and feed it now. Failing to do so may inadvertently cause the death of your project.</p>

<hr />

<p><small>
* There were <a href="http://www.sugoisoft.com/blog/2011/01/09/jisho-4-1-and-the-mac-app-store/">other factors at play</a> with the version number, which I written about on the  <a href="http://www.sugoisoft.com/blog/">Sugoi Software blog</a>.
</small></p>
]]></content:encoded>
			<wfw:commentRss>http://www.james-vandyne.com/8-things-i-learned-about-software-development-without-writing-code/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

