Holidays Preferences, First Pass

Holidays Preferences

This is my first pass at the holidays preference. I know it’s pretty plain, I also know that I can’t put a date spinner in the second column instead of the date formatter that’s already there. That’s due to a known bug in Interface Builder, or Cocoa, or something, somewhere *grumble*.

The good news is that it’s already localized, kinda. Instead of storing the holiday data in the main preferences file, it stores them in their own file called “HorizonHolidays.plist” in the user’s ‘Library/Preferences’ folder. This means I can make up default files for the US, Canada, the UK, and anywhere else where I know what the statutory holidays are, and users can even send me plists for the holidays in their country, and I can make them available from the web site.

So, what can I do to make form more appealing and easier to use? Suggestions, please. i know it’s not quite right yet, put I can’t put my finger on the solution.

… followed quickly by 1.2.6

Sorry about that. There’s a couple of bugs in 1.2.5 that I had to fix, even though they’re mostly cosmetic and/or minor annoyances. Also, my payment processor, esellerate, shipped a new version of their libraries which are supposed to provide some improvements, so I rolled those into 1.2.6 as well.

Unfortunately, it wasn’t a seamless transition, since esellerate decided to change the name of one of their header files. This broke the builds and screwed up the revision control system. Bad esellerate! No cookie!

I’ve also been having problems with customers activating their licenses. The esellerate engine is supposed to automatically install and register the serial number when you buy a license through the program, but it doesn’t always work. I’ve had a small number of people with this problem, and there’s an easy fix. I can send you a little program, customized with your name and serial number, to patch Horizon.

I’m hoping, though, that the new version of the esellerate libraries will make this unnecessary. But if you do have a problem with the program saying it’s still in trial mode after registering it, by all means let know know right away! The fix is quick and easy, and I want to make sure my customers are happy.

Version 1.2.5

A few bug fixes, (although the random crash associated with drag-and-drop is still out there. *Sigh*) and some pretty solid keyboard navigation shortcuts highlight this release.

There’s two new menu items on the ‘View’ menu, ‘Go to Today’ and ‘Go to Date…’ both blatantly stolen from the iCal interface. Hey, you know what they say about great artists, right?

The keyboard interface, however, is unique to Horizon. Here’s a rundown of the keystrokes and their functions:

  • Arrow keys move the selected date on the calendar.
  • Cmd + left arrow and Cmd + right arrow to change the month.
  • Cmd + Enter to add a cell, or edit existing cell, on the selected day.
  • Cmd + Delete to delete an existing cell on the selected day.
  • Alt+ Up arrow and Alt + down arrow changes the selected category.

So now you can zip around the calendar pretty easily, and your hands never have to leave the keyboard. This is good for the power-user types and those who have a lot of data to enter.

Thanks to Johan for suggesting this and testing this release.

Is This What They Call Guerilla Marketing?

I’ve uploaded the ‘Blooper’ reel of Horizon outtakes to YouTube. (Yes, they were faked. My real goofs were boring, not funny.)

On a more serious, painful note, I discovered something odd in the way Cocoa handles keyboard input. You can trap most keyboard events with the keyDown: method. I’m using that to catch the arrow keys for keyboard navigation on the calendar.

The next step was to catch Command (the Apple ‘cloverleaf’ key if you didn’t know the official name) plus the arrow keys to move through the months. Cmd (Command) + left arrow for the previous month, Cmd + right arrow for the next month. Using the event modifier flags I can catch the Command key and make that work. So far so good.

Next, I want Cmd + return to create a new cell or edit an existing cell, and Cmd + delete to delete and existing cell. The keycode for return is 13, just like the old ascii value. And delete is 127. But keyDown: just ignores return, Cmd+return, delete, and Cmd+delete.

The answer turns out to be a different method, performKeyEquivalent:. The documentation on this method is very poorly written, but the gist of it seems to be that the method is intended for custom implementation of keyboard equivalents of menu items. So I can trap Cmd+enter in that method, and Cmd+delete. All I have to do is look for the numeric codes for enter and delete, do my thing, and return YES. I don’t have to check for the modifier key, but I do have to use charactersIgnoringModifiers: instead of just characters: to get at the keycode. The only other odd thing is the Cmd+left arrow, and Cmd + right arrow are not handled here, but back in keyDown:.

If anyone can explain the logic behind this to me, I’d love to hear it.

Horizon 1.2.1

Hot on the heels of Version 1.2, Version 1.2.1 is available, as a DMG, or through the software update. This release fixes a number of bugs, including missing items on the French menus, and a rather annoying bug that would leave the intro video playing after you closed the Welcome Panel!
I’m surprised no one complained about it. Is everyone that enraptured with the sound of my voice? Nah.

And … I’m spent

Horizon 1.2 is out. The dmg is available from the Downloads page, and if you’re running an earlier version, you can update automatically, or use ‘Check For Updates’. I won’t go into the features here, because they’re covered on the main site.
I did manage to slip in one little extra, though. If you go to the ‘Screencasts’ page, and click on the last link in the sub-menu, well, I think you’re in for a bit of a surprise. ;)

Almost Ready!

Horizon 1.2 will be released tomorrow morning. I’ve done a lot to the program, and added some major features, but you’ll just have to wait a few hours to what I’ve done.

One feature I will tell you about because it’s not that big a deal, but it is fun. I’ve added the Mac ‘poof’ effect. Delete a cell from the calendar and it vanishes in a puff of smoke. Nothing earth-shattering, but it is a nice effect.

If anyone wants to implement this, ignore the antiquated Apple sample code and the other weird little samples floating around the ‘net, and just search the documentation for NSShowAnimationEffect. It’s a C function call with a lot of parameters, but for simple things most of them can be set to nil.

It’s also important to note that the NSPoint supplied to the function to center the effect is in screen coordinates, so you have to use a few methods to get from the View to the Window to the Screen, depending on what you’re doing.

It Slices! It Dices!

I just had a really odd thought. Horizon is a passable diet journal, as long as you weigh yourself no more than once a day.

The max, min, and average functions let you analyse your progress.
Sure you can buy programs that are designed for diets, but look at it this way: is there any other finance program out there that can help you lose weight?

Happy Canada Day!

I should have done that yesterday, but with the holiday falling on a Sunday, everyone is celebrating Canada’s 140th birthday today.

Anyway, the real point of this post is to ask for suggestions for Horizon. It really seems that once you ‘get’ Horizon you really get Horizon, and realize the power, depth, and potential of the program. The problem is the ‘barrier to entry’. Some people download the program, install the app, and double-click on it. They haven’t watched the screencasts, and they haven’t looked at the help. So they’ve got a blank calendar staring at them, and they don’t know where to start.

So, what can I do to lower the ‘barrier to entry’? I’m really looking for suggestions here. If you’re a current Horizon user, can you tell me how you got started? If you downloaded it and gave up on it, can you tell me what would make things easier for you?

Would the old Microsoft/Adobe ‘Tip of the Day’ window at start-up help? Would a starter document be useful? Is there any way I can build in a tutorial? Please let me know what you think is missing.

Who? What? When?

I found a problem with the new feature that required a couple of method calls when a new document is loaded. I figured the best place to put these was in the document class in the readFromData:ofType method.

No joy. It turns out the methods I’m calling need data from the sub-classed WindowController object, which hasn’t been instantiated yet. Okay, move the calls to the document’s makeDocumentControllers method, since it looks like the controller has been created and connected by then. Still no joy. I guess this happens asynchronously.

I ended up moving the calls to the windowDidLoad method, in the WindowController sub-class. It’s not as clean as I’d like, since I have to do some checks to see if it’s a brand-new document or a previously-saved document, but it works.

The thing is, this kind of problem has bitten me before. With an AppController, Window Controller, documents, windows, and custom views, I have no idea what happens when. I really need sort of life-cycle chart for the Cocoa document-based app, that tells me which objects are instantiated, and which methods are called, and in what order. Luckily, I don’t (yet?) have a custom NSDocumentController or things could get really messy.