Because SourceTree has continued to support versions of Mac OS X back to 10.6 (Snow Leopard), we’ve still been using the ‘springs and struts’ approach to user interface layout up to now; we couldn’t adopt the newer Auto Layout without restricting support to 10.7+. So I’ve only just started experimenting with Auto Layout recently, and I ended up getting stuck for a while on something that seemed like it should be really simple, and yet I couldn’t find any hard information about it on Stack Overflow or via Google: how to specify tab ordering.
I’ve had a fair amount of experience with Windows-based installers in the past, including non-Microsoft Installer based systems like NSIS and the open source WiX, but most of the time I’d been working with one-off installers for native code projects, like the Ogre3D SDKs. I pride myself in not pre-judging the best toolset to use for any given problem - which is why I switch languages a lot - so when I came to write SourceTree for Windows, which is based on .
How often do you stop and think about why it is you do what you do for a living? Maybe it’s a mid-life crisis thing, but of late I’m acutely aware of the finite nature of time, and that there are an infinite number of ways I could spend that time. I’m also aware that ‘software developers’ are a quite diverse bunch of people, despite the persistent stereotype of math geeks huddled around technical toys talking in obscure acronyms (OK, we do that too).
I posted a few months ago about the problems I’d encountered with performing privileged actions from a Mac OS X app - in my case, installing a command line utility in /usr/local/bin - and that all the examples of this that I’d come across used an approach which was now deprecated. You can find my original post here: Escalating privileges on Mac OS X securely, and without using deprecated methods.
These days I’m a free agent, and I’m lucky enough to be able to choose what projects I work on, but in a past life, I was what I suppose is properly referred to as an ‘enterprise software developer’. Yes, I once functioned in an environment where terms like ‘mission-critical’, ‘project life-cycle’, ‘stakeholders’ and ‘change management’ came up quite a lot. I’m grateful for the experience I gained over 12 years of doing that, but I’m also very glad to be free of it now.
Since I’m trying to spread this news as far and wide as I can, I might as well say it here too 😀 Since the approval light just went green on the Mac App Store, I’m happy to announce the launch of SourceTree 1.2! In celebration, I’m having a crazy-bonkers 40% off sale just for one week, so get it while it’s hot! There’s loads of things that are new or improved in this release, but here are the headlines:
As many of you probably know, almost a year ago now I decided to take the plunge and move my primary development activities to the Mac. I taught myself Objective-C, got properly to grips with Cocoa at last, and started a new Mac OS X-specific project which would eventually become SourceTree, learning a ton along the way (a process which is by no means complete!). Happily, things have turned out very well - SourceTree continues to sell, reassuring me that there’s enough interest out there for me to keep expanding and improving it (I’m looking forward to getting the next major release in people’s hands soon), and I’ve also been getting some Mac/Ogre-based contract work which I’ve enjoyed a great deal.
I’m pleased to announce that I’m finally ready to make my first fully-fledged commercial Mac OS X application available to the world! SourceTree is a user-friendly Mac OS X front-end for Mercurial and Git, the two most popular distributed version control systems used today. The goal was to create a single tool which could deal with both systems efficiently, and to give a developer quick and intuitive access to the things (s)he needs to just get on with building software.
I’m 37, and I’ve been a (professional) developer for 16 years. You would have thought that in that time, I’d have figured out an effective work style which delivered the desired outcomes (code cut, products shipped etc) without causing detrimental knock-on effects - but, sadly, you’d be wrong. I think the style in which I practiced my craft for the first 15 years of my career was much the same as every other enthusiastic developer: you put a ton of hours in.
I only started learning Objective-C and Cocoa in mid-May, and for the first time I think I actually have a tip to contribute to the wider community. It’s about using custom cells in NSOutlineView, but those which you want to design inside Interface Builder rather than drawing manually.
If you’re an iOS developer, you’ll be wondering why this deserves a blog post - it’s easy to do in Cocoa Touch! Well, yes it is easy on iOS, because Apple have specifically allowed you to design table view cells in Interface Builder. When targetting Mac OS X though, it’s actually pretty awkward, and here’s why: in Cocoa Touch, the class which draws the cells in a table is UITableViewCell, which is a subclass of UIView - meaning you can drag one onto the canvas in Interface Builder and lay stuff out right there. In Cocoa, in contrast, the cell is simply represented by NSCell, which is not an NSView subclass. This means Interface Builder will not let you play with them, you draw them by implementing drawWithFrame:inView: instead. I think Apple realised the problem with this design in time for Cocoa Touch but obviously felt they couldn’t break the existing Cocoa interfaces. There are also many differences between the instantiation of NSCell versus UITableViewCell - there’s only one NSCell for all rows in a table / outline view, compared to a type-indexed pool in Cocoa Touch.
The problem boiled down to this: if the contents of your table / outline cell is non-trivial, or if you just don’t want to write a bunch of layout code, it’s a PITA to implement a custom look in NSOutlineView, such as the one in the picture, especially if you want custom controls embedded in it. For my current Cocoa app, I really wanted to design my cells (and I have 2 different styles for group levels and detail levels) in Interface Builder to save me hassle, including using Cocoa Bindings to hook up some dynamic fields within. Many internet searches later, and mostly the answer I found was that it couldn’t be done. Luckily, I’m too stubborn to take no for an answer, and eventually I figured out a way to do it. Details are after the jump, with an example project to show it in action.