views:

73

answers:

2

Hi again,

in my app I want to have a light table to sort photos. Basically it's just a huge view with lots of photos in it and you can drag the photos around. Photos can overlap, they don't fall into a grid like in iPhoto.

So every photo needs to respond to mouse events. Do I make every photo into its own view? Or are views too expensive to create? I want to easily support 100+ photos or more.

Photos need to be in layers as well so I can change the stacking order. Do I use CoreAnimation for this?

I don't need finished source code just some pointers and general ideas. I will (try to) figure out the implementation myself.

Fwiw, I target 10.5+, I use Obj-C 2.0 and garbage collection.

Thanks in advance!

+2  A: 

The simplest method is to use NSImageViews. You can create a subclass that can be easily dragged scaled and rotated. A more complex but visually superior option would be to use Core Animation layers (CALayer).

As long as you maintain the photo representations as distinct objects (so you can manipulate individually) they will use quite a chunk of memory, no matter how you represent them. If you provide all the data available in the photos each one could take several megs. You probably will want to actually reduce the image's display quality i.e. size in pixels, fidelity etc except when the particular photo is being worked on in detail.

Remember, you don't have to treat the photos like the physical objects they mimic. You simply have to create the illusion of physical objects in the interface. We're theater stage designers, not architects. As long as you data model model remains rigorous to the task at hand, the interface can engage in all kinds of illusions for the benefit of the user.

TechZen
So using NSImageViews every photo would be it's own view. I read somewhere that creating many views would be expensive (on RAM and processor), is that true?I guess I should downsample the photos so that they use a sane amount of memory, right?Lastly, can CALayers respond to mouse events? Or would I put each NSImageView on its own CALayer? Thank you for your help!!
Ron
You can use CALayers as something like a view. They exist in an hierarchy and they respond to hits (although the grunt work to manage them like a view is more extensive compared to a view.) CALayers won't save you a lot of memory if you use them to display the full blown images. When you've got a 2meg file, the proportion of the memory overhead between a view and a layer is trivial. CALayers do take less processor time.
TechZen
In addition, like I said, you only need to create the illusion of fullblown photos and then only in the photos that are front most and active. Those in the background can be reduced in size and resolution. You should probably spend some time thinking about exactly what data you need to display and then test what solution works best. I imagine you fined that CALayers work best in the background and views work best in the foreground. Mix and match.
TechZen
+2  A: 

You should definitely use CALayer objects. Using a set of NSImageView subviews will very quickly become unmanageable performance-wise, especially if you have more than 100 images on screen. If you don't want to use Core Animation for some reason, you'd be much better off creating a single custom view and handling all the image drawing and hit testing yourself. This will be more efficient than instantiating many NSImageView objects.

However, Core Animation layers will give orders of magnitude improvement in performance over this approach, as each layer is buffered in the GPU so you can drag the layers around with virtually zero cost, and you only need to draw each image once rather than every time anything in the view changes. Core Animation will also handle layer stacking for you.

Have a look at the excellent CocoaSlides sample code which demonstrates a very similar application to what you describe, including hit testing and simple animation.

Rob Keniger