Moving to MarsEdit

September 5th, 2007 — 11:22am

Until now, I’ve always written up my blog posts in a combination of TextEdit for the initial draft and the WordPress web UI for subsequent drafts (mostly to get the formatting right) and final posting. Needless to say, it’s been painful. For a web app, WP isn’t so bad but, in the grand scheme of things, it’s lacking. I know this will probably draw the ire of all of you who think web apps are going to take over the desktop but seriously, it’s not going to happen with the current state of the art (unless users are willing to sacrifice a good bit of usability).

I am now switching over to MarsEdit. Resizable editing area. No html tag buttons whose key equivalents conflict with my use of emacs key bindings. No waiting 10 seconds to preview or save because of a laggy internet or server. The markup macros are editable (so I don’t keep having to type in target="_blank" on every link). The UI is quick and responsive. All the niceties of a native desktop app. Yeah, I’m sure I’ll bump into problems but at least a desktop app can fix most of those. With the web app, there are fundamental problems with the paradigm that make it clumsy and slow.

I know you’re thinking, “well, if the web app sucked so bad, why did you use it?” Simply enough, momentum, or lack thereof. Also, there is my ambivalence towards blogs. I resisted investing in any blogging tools as I didn’t want to admit that I was taking this seriously. I wanted to keep it painful so I would have a reason to hate it. Though now I’m still a bit of a curmudgeon when it comes to blogging, at least I’m willing to concede it’s not worth doing things the hard way.

In any case, MarsEdit 2 is out now. If the thought of writing up a blog post makes you wince, then you should check it out. Who knows, instead of hating it you might end up liking tolerating it.

Oh, and yes, the same Daniel Jalkut who convinced me to start this blog is also responsible for MarsEdit 2. So once again, this is all his fault.

2 comments » | OS X, Software

Animation in the Time of Tiger: Part 2

September 3rd, 2007 — 4:28pm

As promised, here’s part 2 of my animation miniseries. The topic for today: NSViewAnimation

In the last segment, we talked a bit about using NSWindow’s -setFrame:display:animate: method to do some window animations. In conjunction with setting the autoresize flags, you can get some nifty effects.

Many times, though, you need more control. Maybe you want to animate some views (not just windows) or maybe you want to change the rate of animation. For such cases, NSViewAnimation is the answer. NSViewAnimation allows you to set up dictionaries containing views or windows with their start and end states and then animate them. Since it is an NSAnimation subclass, you have control over whether it blocks, how long it takes, the animation curve, etc. If you aren’t familiar with NSViewAnimation, I suggest reading the docs and playing with it yourself.

Now, there are a couple quirks/bugs you need to keep in mind. Knowing these will save you some headaches:

  • If a view has a final frame with a zero dimension (width or height), NSViewAnimation will set it to be hidden when the animation finishes. If you use that view again in an animation (like doing a reverse animation of what you just did), NSViewAnimation will not unhide the view for you. You have to do setHidden:NO yourself before starting the animation. The exception to this is if you use a fade in effect, in which case, NSViewAnimation will unhide the view.
  • NSAnimationCurveEaseOut is broken. It seems to animate backwards. Yes, you can try and work around it and swap the beginning and end frames and such but, when Apple does fix it, you’ll be in for a surprise. I say just avoid using it.

For the purposes of this article, we will be using this project. It demonstrates animating between two views using a variety of basic transitions. If you use Keynote, these should be familiar (I’ve even used the Keynote names). The Dissolve transition needs little explanation; NSViewAnimation’s NSViewAnimationFadeInEffect and NSViewAnimationFadeOutEffect work as advertised. The other effects are variations on a right-to-left transition. They are different combinations of the views either moving in/out of bounds or being revealed or covered. This is achieved through use of clipping (via the view hierarchy) and the autoresizing masks.

viewport.png

Basically, we have two “viewport” views. In doing a transition from right to left, we shrink the left view while expanding the right. Their main job is to clip the view they contain. When used in conjunction with the resizing masks, you can get different effects, the diagram above showing a “Move In” transition.

springs-struts.png

In the diagram here, the blue rectangle is the superview (viewport) of the visible view. I’ve made the rect larger than the view to show the resizing springs/struts but in actuality the viewport is the same size as the view (i.e. its bounds are flush with the contained view). In this case, we have a viewport with a containing view whose left margin is resizable but the right margin is fixed.

reveal-transition.png

Now, let’s say the viewport starts at zero-width and expands out to the left while the view itself is positioned so that it’s right edge is flush with the viewport.

As you see, since the right margin is fixed, it appears as if the view is being revealed as the viewport expands to the left. Note that the autoresizing works just as well when the view is larger than its superview.

To make it appear as if the view is moving in towards the left instead (like in the “Move In” and “Push” transitions), make the left margin fixed and the right margin resizable.

Likewise, you can fiddle with the autoresize masks for the outgoing view to affect how it disappears (either pushed off or covered).

For those unable to compile the project, here’s what it all looks like:


<a href="https://www.noodlesoft.com/blog/uploads/2007/09/transitions.mov">Download movie</a>

As you can see, NSViewAnimation can be quite useful for when your animations involve moving and scaling views. In the next article, I’ll probably just go over some odds and ends such as optimizations and using Core Image transitions.

9 comments » | Cocoa, Downloads, Programming

Hazel on ScreenCastsOnline

August 27th, 2007 — 12:17pm

Noodlesoft is sponsoring the latest episode of ScreenCastsOnline. Don McAllister does a great job of guiding you through Hazel’s features. Nothing gets the point across like seeing it in action.

You can check it all out here.

Oh, and there’s a discount code in there, if you need any more enticement to watch it.

Comment » | Hazel, Noodlesoft, Software

Numbers and the Next Big Thing

August 15th, 2007 — 1:42pm

I’ve been waiting around for Numbers. Well, not Numbers specifically but for Apple to do a spreadsheet. Now that it’s out, I have to say that I’m disappointed. It’s not about features but about the base paradigm. I wanted Apple to revamp how spreadsheets are perceived and conceived. It may be a bit much to expect from Apple except that the new paradigm was already created some 20 years ago, and not only that, Steve Jobs had a hand in it.

Instead of explaining it all here, I suggest you read about Lotus Improv. Here’s a great article describing the history.

In short, Lotus came out with what is now known as the multidimensional spreadsheet. It was one of the first apps on the NeXT platform. It was also a revolutionary new way of doing spreadsheets.

It’s hard to really get a sense of how it works by reading about it. Quantrix has some great Flash presentations. I advise viewing those before reading on.

The main benefits of a multidimensional spreadsheet is that it actually knows about your model. When constructing a multidimensional spreadsheet, you are not constructing a visual structure so much as a semantic one. Those headers aren’t just for your benefit. The row and column headers are, in effect, axes in your multidimensional model. But you aren’t limited to two dimensions. You can define as many dimensions as you want and dynamically rearrange the axes as you see fit. The order of the axes (which axis is the column and which is the row) is just a part of the view and not the model itself. This also extends to charts. They are just graphical views of the same model and if your model changes, the charts can automatically update as well since they are based on the same semantic structure (i.e. the charts are not just one-offs).

The result of this is that the program makes many things natural and intuitive (it only sounds complicated). For instance, “pivot tables”. In the multidimensional model, it’s a natural extension of the paradigm (there’s no special marketing term for it) which makes pivot tables in traditional spreadsheets look like a hack. Natural language formulas also come, well, naturally. The generic headers and cell designations (A1, C5) are gone. You define the items in the headers so a cell is referenced as “Sales:1990” which makes tons more sense. Also, formulas are more based on the structure of the model and not on individual cells. This allows the formulas to be separated out so you can see (and edit) them all in one place (the formulas don’t go in the cells). Because it is a multidimensional model, extending any one dimension (i.e. adding rows or columns) will bring along any formulas with it. Again, this is hard to visualize if you haven’t seen it before so check out the Flash tours linked above.

So, where are the multidimensional spreadsheets now? Lotus did port Improv to Windows but Improv on both platforms ended up being abandoned. To fill the void, Lighthouse (the company I worked at) created a clone, Quantrix (which I worked on). As I’ve mentioned before, the Lighthouse apps were mothballed by Sun.

Since then, Pete Murray (one of the original authors of Quantrix) wrote it all over again, from scratch in Java, and has released it with his new company. He even got rights to the Quantrix name. As linked above, you can check it out at Quantrix (and thanks to Pete for allowing me to link to his demo presentations). Note that it is not priced for the casual user, being oriented more towards the enterprise customer but they do have educational pricing.

There’s also Flexisheet if you want something free, open source and/or native, though it does not seem to have been worked on in years.

• • •

iWork’s Numbers is fundamentally a 2D spreadsheet. It does some trickery with the headers to allow for some level of natural language formulas. It has some things here and there to simulate some of the aspects of a multidimensional spreadsheet but it’s still a traditional sheet underneath.

One subtle difference between the 2D and multidimensional models is that in the latter, the data model is expected to be dense. What this means you don’t really have unused cells; all cells are intended to have meaning in your model. It’s not a freeform grid but a packed model of data. For people used to sticking all sorts of random non-computational stuff into spreadsheets, this can be hard to adjust to. Basically, people are using spreadsheets not so much as computational tables but as a big piece of graph paper.

Numbers shifts this around a bit by making the tables a part of a larger freeform canvas. This is a big improvement from other traditional spreadsheets as I’ve always believed cells are for numbers. That clip art or paragraph of text you stuck in there is not a part of the model you are creating. It makes it such that the spreadsheet is used as it was intended and anything you attach to it, you put together with it and not in it. All in all, the separation of table and canvas is a welcome change.

Why wasn’t Numbers done as a multidimensional spreadsheet? Several factors come into play here. The main one is that multidimensional spreadsheets are quite different from traditional spreadsheets. If you’re an Excel user then you’d have to unlearn a lot of how you conceive of spreadsheets. In essence, it’s a hard sell to anyone that uses a traditional spreadsheet. The only market where it seems to stick is the financial market, which is not a market Apple is concerned with. It’s too bad, really, since I’ve always felt that the multidimensional model is actually more intuitive for the user who has never touched a spreadsheet. I felt a consumer-level multidimensional spreadsheet would have been the innovation the spreadsheet market needed.

Maybe in the end it was too much to expect of Apple. With innovation comes risk and it’s hard to bet on something that has already failed in the market once. Nonetheless, the innovation is there. The hard part is getting people to use it.

27 comments » | OS X, Software

2 C4 || ! 2 C4?

August 8th, 2007 — 9:27pm

Yes, I’m going to C4 this weekend. It was quite last minute as there was something casting a shadow over my schedule for the month of August. Luckily, that got cleared up at the end of July leaving me to decide whether I should bother scrambling. Considering that I also was prepping my Hazel 2 release, it probably wasn’t a good idea scouring travel sites trying to make arrangements and convincing Rentzsch that the check was in the mail. Hopefully, he won’t try cashing it until after the conference.

Luckily, a hotel room and a not-so-expensive flight to Chicago opened up, so hope to see many of you there. And my offer still stands: if you give me money, I will gracefully accept it.

Also, my official list of people to whom I owe drinks while in Chicago:

  • Daniel Jalkut
  • Gus Mueller
  • Oprah Winfrey

Don’t make me explain the first two.

Comment » | C4

Post Mortem 2.0

August 7th, 2007 — 4:50pm

Hazel 2 has been out for a few days and I’ve had a chance to sit back and reflect a bit. Of course, things are a bit different this time than when I was releasing 1.0. For one, I have users now. That meant that I had to split my time to do support in addition to development. But that also meant that I had more people giving me feedback and a larger pool of beta testers. Yes, it’s time consuming to process all that but it made for a better product in the end.

There were a couple decisions that weren’t applicable when doing a 1.0 that I had to deal with this time:

1.2 vs 2.0

When planning the next release, I went back and forth on whether it was 1.2 or 2.0. What’s in a version number anyways? Well, making it 1.2 would have made some things easier. It’s generally understood that point releases are free so there would have been less confusion on that point if it were 1.2. On the other hand, there were major chunks that were rewritten. The artwork was redone. I ended up labeling it 2.0 as it does indicate that it has significant improvements and that the product is more mature, which is the case here.

Why a free upgrade?

Several factors played a part in this. There were issues in 1.x that 2.0 addresses and they were the type of thing I wanted every user to have access to. Plus, I do feel grateful to all of you who took a chance with not just a new application. If I could, I’d meet with every one of you and shake your hand but I get the feeling that it would be unfeasible. In any case, I think you’d appreciate the free upgrade more. You don’t know where my hands have been.

• • • 

Overall, the pre-release went pretty smoothly. The one thing that was less than ideal was the timing and length of the prerelease period.

Because of issues with 1.x’s use of launchd, I had to write my own task runner/scheduler. Since some users were being affected by this, I released the alpha earlier so that they could have access to the new fixed version. Also, since it was a critical part of the system, I needed it to be tested for as long as possible. So, in retrospect, the alpha came out a bit earlier with fewer features ready than I would have liked but I felt it was necessary given the circumstances.

As for the length of the prerelease, it did run a bit longer than I wanted. A few factors came into play here including a good bit of contract work I was doing during the Spring and logistics concerning the business (including converting Noodlesoft to an LLC).

What surprised me this time around was the amount of attention my beta received. I had multiple articles in the press at each step of the way which was great. A big thanks to all of you who kept up with the pre-releases and sent in feedback and bug reports. I feel that 2.0 is pretty solid out of the gate as a result.

• • • 

In the end, I’m quite happy with how 2.0 turned out. There were some rough edges that I was finally able to polish and I feel like I’ve filled out the feature set while keeping it all cohesive.

What’s in store for the future? I’m still working that out but most likely, 2.1 will be focused on getting Hazel working properly on Leopard (without breaking it on Tiger, of course). I think the next major improvement won’t be in the product itself, but on the Noodlesoft site. People have been clamoring for some sort of repository of Hazel rules so I need to hunker down and figure out how that should work. As always, your feedback helps to shape the future direction of things so keep it coming.

Comment » | Hazel, Noodlesoft, Software

Hazel 2 out (finally)

August 2nd, 2007 — 11:21am

hazel2.png

After what ended up being a longer pre-release period than I anticipated, Hazel 2.0 final is out. Lots of new, neat stuff. Nifty, too. If you haven’t been keeping up with the betas then check it out. I feel it’s much closer to my vision of the product when I started down this path last year.

It’s a free upgrade for you registered 1.0 users because I love you all. Yes, there, I said it.

When the smoke clears, I’ll do another post-mortem but in the meantime, download it.

1 comment » | Hazel, Noodlesoft, Software

Unofficial Hazel Web Badge

July 20th, 2007 — 6:04pm

Hazel 2 is going to be released soon and our marketing manager thought that we should start a marketing campaign. When this happens, we usually sit down and look into how he escaped from his cell, but this time, we decided to give him a chance.

We here at Noodlesoft like to keep up with the latest currents and trends. With that in mind, we present our first unofficial web badge. We feel that it captures the spirit of today’s vibrant web youth culture.

Get Hazel

Feel free to adorn your web page with the badge. Consider this our trial balloon into the wonderful world of online marketing.

K. Bai!

2 comments » | Hazel, Noodlesoft, Software

NoodleLabs: Fix for Mac Pro headphone behavior

July 12th, 2007 — 12:52am

I’ve done it. I’ve joined the 8-core club. Historically, I always shoot for the sweet spot in terms of price/performance but this time I thought I’d splurge for once and get the octocore (or is it octacore?) Mac Pro. Realistically, it’s a bit overkill. Sure, Hazel now compiles 5x faster but it’s not like I’m doing full builds all the time and it didn’t take all that long before either. Nonetheless, it’s a great machine. There’s one thing about it that bugs me, though.

On my Powermac, when I plug in headphones, it automatically switches sound output to them, even if I have external speakers connected to line-out. Basically, the headphones, internal speaker and line-out are treated as three devices sharing a channel. To me, it makes sense. If I plug in my headphones, it’s because I want to listen through them. If I pull them out, it’s because I want audio to go back through the speakers. Most every piece of consumer audio equipment I’ve used operates like this.

On the Mac Pro, that has changed. The line-out is a separate output and is unaffected when you plug in headphones. So, if you are using external speakers, you have to go into System Preferences and manually change the output audio device to headphones. You could use something like Rogue Amoeba’s SoundSource to switch output devices in a more convenient fashion but nonetheless it’s a manual process. This Apple doc describes the change but it sounds like an engineering decision imposing itself on the user. I don’t care if it’s now orthogonal and consistent; I want it to be useful.

Well, the nice thing about being a programmer is that you can solve the problem yourself. So, I went ahead and created headphoned (read it as “headphone-d” like a unix daemon). All it does is sit there and watch for when the headphones are plugged in, at which point it switches audio output automatically. When the headphones are unplugged, output reverts back to whatever device was selected before.

I’ve never touched the CoreAudio API before so please excuse the naiveté of the implementation. Suggestions and improvements are most welcome. A big thanks to Vincent Gable, author of IMLocation for this article which gave me a big headstart.

There seems to be a problem where the audio will wedge when plugging/unplugging. I found that updating with Apple’s recent audio fix got rid of the problem (or maybe it’s wishful thinking on my part but I haven’t experienced it since). If you find it does happen, just plug the headphones in/out again as that usually unwedges things. Also let me know if you experience this even after updating with Apple’s fix.

And, of course, it’s free (MIT License). Do what you will. It’s a bit rough around the edges (no automatic install), but I figure if you are using a Mac Pro, you are less daunted by the command-line. I’ve included a launchd config. Install it in ~/Library/LaunchDaemons and edit it to reflect where you put the executable. Note that it doesn’t seem to work if it runs as root (I think it needs to run as the console user), so don’t bother installing it at the top level LaunchDaemons directories.

Enjoy.

Download headphoned-1.0.zip

Update [Sep. 5, 2007]:

Rogue Amoeba has now integrated this functionality into SoundSource. The announcement is here. You can grab it from their freebies page (and yes, it is free).

21 comments » | Downloads, OS X, Programming, Software

Animation in the Time of Tiger: Part 1

June 30th, 2007 — 3:12pm

One of the most touted APIs in Leopard is CoreAnimation. Soon, you will be able to easily put together animations with tons of crap flying around all over the place. And with the new APIs, it’ll be a snap! Ok, ok, so there are some nice, tasteful animations that can be done and with Leopard they can be done easily. Fact is, though, there’s a good bit of animation you can do right now in Tiger (or earlier).

Why bother? Well, not all of us are dumping our Tiger users come October plus you could stand to learn something if you follow along. So, over the next couple months, I’ll be doing sporadic installments in this series. I’m not sure how many as I haven’t thought that far ahead but let’s say at least two, probably three.

Now, I feel that it’s important to lay down some guidelines. Animation in applications is subject to severe abuse. What may seem neat the first time can quickly become tedious if you are using the app on a daily basis. Too much movement in the interface can make for a visually noisy user experience or cause annoying delays. For the most part, use animation sparingly and with a purpose. Good uses would be to draw a connection between the start and end states of a transformation or to draw the eye from one part of the UI to another. A rule of thumb: if you feel the need to provide a preference to turn your animation off, maybe the animation is too intrusive. Remember, with great power comes great responsibility.

Before we delve into things, I want to point out that most of the animation techniques I’m going to talk about here pertain to NSWindows and NSViews. For various reasons, it is much easier to do animations with views than with, say, NSCells. What this means is that if you have a list of items using an NSMatrix or NSTableView and want to animate them, you may want to consider converting them into a bunch of views. While it is possible to write a control that animates its cells, you have to do a bit more work. Most of the animation hooks available operate on the view level, something that is further emphasized in CoreAnimation.

NSWindow animation

In NSWindow, you already have a powerful method at your disposal. With -setFrame:display:animate: you can set a new frame for your window and by specifying YES to the animate flag, the window will animate from its current frame to the new frame. Not too exciting? Well, try this on for size:

This effect is similar to how windows animate when you use the “Scale Effect” instead of the “Genie Effect” when minimizing windows (check your Dock preferences). You can download the project here. This is all done in an NSWindow category using documented API. While there’s a little magic of getting the window’s pixels (will probably talk about view/window caching in a future installment), the animation itself is done via the setFrame:display:animate: call. Ok, I fudge things slightly by overriding -animationResizeTime: to make it animate faster but the point is that you can do some interesting things with a basic call.

Autoresizing

When you animate, another thing you can take advantage of is the autoresizing mechanism (those springs and struts you see in IB). By setting up the autoresizing flags on your views in creative ways, you can do some neat little animations without having to muck with specifying all the different frames.

In Hazel’s (as well as in Mail’s) rule interface, when you create a new row, notice how all the rows below the new row shift down as space for the new row “grows” in. This is all done via setting the autoresizing masks (at least that’s how I do it; I can’t speak for what actually happens in Mail). Note that the autoresizing masks don’t have to be something you set once in IB and never touch again. Here, I reset them on the fly as needed. For the rows above the inserted row, the bottom margin is set to sizable. For rows below the insertion point, the top margin is set to sizable.

autoresizeanimationdiagrama.png

You need to put the new view into the hierarchy at some point. If you add it before the animation, you need to tweak with its size and autoresizing (make it height sizable). If you add it after, the view “pops” in but it happens fast enough that users will probably not notice. Now, I just resize the window (with animation) and all the views fall into place:

autoresizeanimationdiagramb.png

You do something similar when a row is deleted. Note that this is mostly effective when only one view in the window is resizing (and the others just moving) in a particular dimension as the resizing mechanism produces less than ideal results when more than one view is resizing.

So, that’s it for now. In the next installment, we’ll dig into NSViewAnimation and also have some more fun with autosizing flags.

5 comments » | Cocoa, Downloads, Programming

Back to top