GreenWave Software
© Copyright 2003-2010, Chip Cooons

Trac on Snow Leopard

Chip | Cocoa | Thursday, March 4th, 2010

I love Trac, but am moving my scm to git (instead of Subversion). My problem is getting a functional install of Trac with the git-Trac plugin working on my remote server. To solve that problem, I’m going to make sure first that I can get a fully functional version running locally. Here are my notes…. (more…)

Updating to 10.6SDK part II

Chip | Cocoa | Tuesday, March 2nd, 2010

I thought I was ready to dive into the functionality changes/fixes around views, but discovered an incompatibility in saving images in different formats that needed to be corrected first.

(more…)

Updating to 10.6SDK

Chip | Cocoa | Tuesday, November 17th, 2009

After completing the conversion to 64-bit, MagicBrush-Photo is “broken” since it also relies on the 10.4 SDK and some behavior has changed in 10.6. Here are a few of the issues and problems that had to be overcome. (more…)

Converting to 64 bits

Chip | Cocoa | Saturday, October 17th, 2009

It’s time to spend a little quality time with MagicBrush-Photo and start getting it ready for Snow Leopard. Step one is getting it ready to handle 64-bit addressing. (more…)

Image Uploading

Chip | Cocoa | Saturday, April 12th, 2008

One of the features that has always been planned for MagicBrush-Photo has been the ability to upload or publish images to Picasa and Flickr.

Right now I’m in the midst of incorporating this feature into the release plan. The GData APIs for cocoa are making this straight forward enough, but the tricky part is making the experience fit in with the overall Mac user expectation.

For instance, a user has a reasonable expectation of being able to store their account information for Picasa or Flickr in their keychain.

Once you can authenticate to either site, you need to present the complex behavior of the web application in a simplified manner. Should users be able to only upload? Should they be able to view previously uploaded images (to ensure they’re not duplicating things)? Should they be able to edit tags and descriptions for images already uploaded, or just when they initially upload them? Complexity grows quickly.

Stay tuned to see how MagicBrush-Photo handles these. If you are interested in helping beta test these features, give me a shout.

Moving Toward 1.2

Chip | Cocoa | Wednesday, April 9th, 2008

MagicBrush-Photo was stalled slightly at version 1.1.5. I knew what I wanted to add by way of features, and had a development branch working, but unfortunately my “paying job” was consuming more of my time and energy than I planned.

An Aside

I should probably caveat that I’m not your typical programmer (at least I like to think I’m not). I’ve got a full-time non-programming management job at a fortune 500 company within the IT organization. For the past year I’ve been loaned out on a special project team doing a bunch of neat things within a couple of our markets. I’ve run the gamut from launching new products and services to implementing different business model pilots and a slew of other cool things.

It’s been fun (mostly), and a lot of hard work.

But it has seriously diminished my free time to program and enhance my software. At the same time, Leopard has been released, and the niche I had targeted is beginning to transform into a very competitive landscape. It would be easy to back off and let MagicBrush-Photo languish.

But that’s not what I want to do.

Why I Program

1. I like to solve interesting problems.
2. I like to have control of how I work.
3. I like the Macintosh platform.
4. I like the idea of “not working for the man”.
5. I like being able to keep my coding skills fresh.

While my morale regarding GreenWave Software was a little down early in the year, I’ve found it helps to remember why I enjoy programming in the first place. I don’t get to use this set of skills much at work (and frankly don’t think I would enjoy it if I had to code in a corporate environment).

When I stop and think about these reasons, I find I am more focused on moving the needle with MagicBrush-Photo and a few other projects I have in the hopper.

Now, back to coding ;-)

Updating Philosophy

Chip | Cocoa,Strategy,Uncategorized | Wednesday, April 9th, 2008

Developers are told repeatedly to “ship code to real users” and get feedback. How does this translate into the customer experience and their update cycle?

What do you think?

I’ve decided recently to move away from packaging up point releases and instead ship more frequent updates via the Sparkle+ framework. This will allow me to keep my motivation and engagement up, but could impact the user who will see more frequent updates. Which is a better approach for customers? Post a comment or ping-back with your thoughts.

On a related note

I’m working on several new features in MagicBrush-Photo that will be developed incrementally over time. In parallel there are bug fixes and minor tweaks occurring within the code.

In a multi-developer group, a more rigorous release plan and management would be a given (I hope). But for a single developer, do I really want to spend time maintaining branched code (current and development) and merging things back together for a release?

I’ve decided to not keep code merged and instead created a framework for setting a flag within the preferences of the application to enable development/partially complete features. This way, I can send a stand-alone script to testers to turn-on features within the current release.

Hopefully, these two changes in my approach will help me drive some significant new features more quickly to the users of MagicBrush-Photo

MagicBrush-Photo has been updated to Version 1.1

Chip | Uncategorized | Tuesday, October 30th, 2007
    New features in this version: 
  • Added ability to access image metaData via info toolbar item.
  • Added ability to back-up effects in application.
  • Added ability to restore effects from back-up in application.
  • Added ability to import and export custom effects for sharing.

The full changelog can be reviewed here.We also have introductory pricing. Use coupon code CPN4050708079 when purchasing and receive 50% off the purchase price.In addition to new features in MagicBrush-Photo, I have just redone my website. Check it out and post any feedback in the forums.

The Tao of Mac – Apple Shoots Self In Foot With iMovie’08

Chip | Uncategorized | Monday, August 20th, 2007

The Tao of Mac – Apple Shoots Self In Foot With iMovie’08: “This newfound myopia in software design (let’s make it cooler, flashier and more fun, never mind substance or completeness) is why I think iPhoto will never be as remotely useful as Aperture, nor will we ever see a ‘middle-of-the-road” photography product from Apple.After all, they just torpedoed their video equivalent by competing with themselves and failing.”(Via .)I hope not. I don’t want Apple to compete with MagicBrush-Photo.Try it now. If you are one of the first 100 people to purchase using coupon code: CPN5059878658 you’ll get introductory pricing at 50% off.

A more complex Undo/Redo example

Chip | Cocoa | Monday, July 2nd, 2007

One of the issues I was having with MagicBrush-Photo concerned improper behavior of undo/redo functionality.

Undo/Redo is fully described in the Apple documentation and there are lots of samples available, usually highlighting what developers “get for free” when they follow standard practices in Cocoa development. Of course, since these samples are “selling” Cocoa development, they are often not the most complex examples of behavior. For example, it will be a simple setting of a value/property on an object either directly or using bindings.

Naturally, it was one of these more complicated scenarios I was running up against.

Within MagicBrush-Photo, the application of a brush effect to an image (or layer) is not as simple as setting a property. The edit/brush cycle begins with the mouseDown event, and ends with the mouseUp event. So the functionality to undo is any changes to the image or layer from mouseDown to mouseUp. Following the documentation, I got that working pretty easily. Here is some code to show how it works….

The document’s (IBAction)mouseDown:(id)sender method calls tailored methods based on the layer type being edited. Here is the method for an image layer:

- (void)mouseDownImageLayer:(NSEvent*)theEvent;
{
NSDictionary *undoState = [NSDictionary dictionaryWithObjectsAndKeys:
[self activeLayer], @”activeLayer”,
[[self activeLayer] getLayerImage], @”layerImage”,
nil];
[[self undoManager] registerUndoWithTarget:self selector:@selector(undoDrag:) object:undoState];
[[self undoManager] setActionName:NSLocalizedString(@”Brush Stroke”, @”undo (brush stroke)”)];
[_mask setValue:[[GWBrushesController sharedBrushesController] imageForBrush] forKey:@”inputImage”];
[self mouseDragged:theEvent];
}

This code takes the current layer image and “snaps” a copy to register with the NSUndoManager for the document. It also sets what selector to use to perform the undo operation when invoked.

And here is the undoDrag method:

- (void)undoDrag:(id)undoState
{
id theLayer = [undoState valueForKey:@"activeLayer"];
CIImage *theImage = [undoState valueForKey:@"layerImage"];
[theLayer setLayerImage:theImage];
[self refresh];
}

This code is straight forward and works for undoing a brush stroke.

My issue came with redo, which according to the documentation should “just happen:”

NSUndoManager is a general-purpose recorder of operations for undo and redo. You register an undo operation by specifying the object that is changing (or the owner of that object), along with a method to invoke to revert its state, and the arguments for that method. NSUndoManager groups all operations within a single cycle of the run loop, so that performing an undo reverts all changes that occurred during the loop. Also, when performing undo an NSUndoManager saves the operations reverted so that you can redo the undos.”

Unfortunately, that was not the case. Instead, the “Redo” item in the edit menu would remain grayed out and unavailable after an Undo was performed.

So what was causing my strange behavior? It took a discussion with an Apple Engineer at WWDC to determine. Of course, it only took them five minutes to identify the issue ;-)

Since I am directly invoking the undo manager and managing the undo stack for each document, I have to register the redo action from within the method referenced by the undo selector. So, my undoDrag method needs to becomes:

- (void)undoDrag:(id)undoState
{
id theLayer = [undoState valueForKey:@"activeLayer"];
CIImage *theImage = [undoState valueForKey:@"layerImage"];
NSDictionary *redoState = [NSDictionary dictionaryWithObjectsAndKeys:
[self activeLayer], @”activeLayer”,
[[self activeLayer] getLayerImage], @”layerImage”,
nil];

[[self undoManager] registerUndoWithTarget:self
selector:@selector(undoDrag:)
object:redoState];

[[self undoManager] setActionName:NSLocalizedString(@”Brush Stroke”, @”redo (brush stroke)”)];
[theLayer setLayerImage:theImage];
[self refresh];
}

In hindsight, the solution seems very obvious. However, I know from pouring over the documents and second guessing myself to no end, it was not that simple. That’s why I’m posting it here, so some other poor coder might save themselves the anguish of beating their head against the wall.

I hope it helps someone.

Next Page »

Powered by WordPress | Theme by Roy Tanck