Cocoa: How to morph a drag image while dragging - objective-c

In Interface Builder.app (and some other cocoa apps), image dragging has a very nice/sexy effect of morphing the drag image while you drag a draggable item out of its window.
For example in Interface Buildler.app:
Show the Library Palette (⇧⌘L, or Tools Menu -> Library)
Drag an item out of the Library palette
NOTE: as you drag the item out of the Library Palette window, it morphs from an image of the original list item to an image of the icon of the dragged item.
I have fully implemented drag and drop in my Application using the normal Cocoa NSDragSource/NSDragDestination facilities.
However, I can't find a hook for doing this image morph while dragging. I'm returning the initial drag image by overriding
-[NSView dragImage:at:offset:event:pasteboard:source:slideBack:]
But this is only called at the beginning of the drag.
How do you signal that you would like to replace the current drag image (ideally using the sexy morph effect).

You guys beat me to it. :-)
Yes, JLNDragEffectManager is open source (with attribution in your apps, please) and available on my blog. It should work fine as-is with no modification back to 10.5, but I'm not sure back any further. Others linked to it (and it's easily googleable), so to avoid self-congratulatory blog linking, I'll leave it at that.
Issues: One developer commented on (and submitted code to fix) the lack of dragging offset support. I've just not gotten around to posting the update. That's the only outstanding issue I'm aware of.
Improvements: I'd like to add multiple "zones" (say, one per document, so dragging from doc to doc keeps table rows looking like table rows, but anywhere outside doc windows turns them into a file icon a la HFS Promise Drag). Some day ...
Design: The post itself details the reasoning behind the design and the relatively simple morphing effect (cross-fade plus size are animated using basic NSAnimation, etc.). The code (the class as well as the demo app) is thoroughly blocked out and commented.
Won't link to my own post but would love the karma of upvotes for my effort. ;-)
UPDATE: Similar (but better-integrated) functionality is available as of 10.7. If you are targeting 10.7 or higher, it's best to use the new API. JLNDragEffectManager works fine on 10.7, so it can be used for earlier-targeted versions.

JNLDragEffectManager does exactly that. :)

The API does not support this well. Joshua Nozzi gives a method that looks reasonable in this weblog post.
IB's effect isn't that fancy. It's a crossfade and scale. Hold down shift to see it more clearly.

As of 10.7+ the current approach is to use the
enumerateDraggingItemsWithOptions:
forView:
classes:
searchOptions:
usingBlock:
API on NSDraggingInfo. The documentation is really poor but the ADC samples like MultiPhotoFrame or TableViewPlayground can give a good idea on how to use the new mechanism.

Related

NSMenuItem with Image and text

I have a question regarding NSMenuItems.
What I'm trying to do is replicate a java GUI using native OS X components, therefore the language I am using is Cocoa. What I am trying to do is to get every menu item to have an image and then, beside it, some text.
I have already done some research into it and my first port of call (as always it seems lol) was the apple docs which had this handy example which illustrates how to embed views inside menuitems:
https://developer.apple.com/library/mac/#samplecode/MenuItemView/Listings/MyWindowController_m.html#//apple_ref/doc/uid/DTS10004136-MyWindowController_m-DontLinkElementID_8
Being relatively new to cocoa, I was thinking I would have to override one of the drawing methods from NSMenuItem. Not really sure though.
Another idea that I was toying with was creating a custom view that held a image and some text.
Any other ideas/validation or discussion would be most appreciated.
Thanks all!
Oh and the GUI creation is being done by hand no interface builder.
Okay, so I now have menu items with icons beside them. For anyone who is interested here it is ( i've not done a leak analysis on it or anything).
First things first, put all of the images you want into the "Resources" folder (thats what its called in xcode 3.1.4).
Now, for example, after we have all the images, we want to use images called "eraser.png" and "eraser_on.png" and I want to attach these to the 3rd menu item. In order to achieve this we do the following :
The code below will get the menu item at position 3 in the menu
NSMenuItem *item = [ nameOfPopUpButton itemAtIndex:2];
The code below will set the image for the menu item to be "eraser.png"
[ item setImage: [ NSImage imageNamed:#"eraser"] ];
That's you set the image for the menu item (which will be on the left hand side of the text aka before the text).
If you want different images for the different states, eg when the user presses it, use this method (not tested myself but its sounds sensible :D and the function is straight out the api)
[item setOnStateImage: [ NSImage imageNamed:#"eraser_on" ] ]
You can however leave it nil or not set it at all and it will go the default color
Hope this helps someone.
Pieced this together from: https://developer.apple.com/library/mac/#samplecode/MenuMadness/Listings/Controller_m.html#//apple_ref/doc/uid/DTS40008870-Controller_m-DontLinkElementID_4
Thanks :)
If you need to do this you have the right idea in creating a view with image and label subviews.
BUT: don't do this. Creating a "native" application is not primarily about your choice of language (which is Objective-C, btw, not Cocoa; the latter is a collection of development frameworks implemented in Objective-C). It's about conforming to the platform.
On OS X (and iOS), more than probably any other platform, consistency in UI design is paramount. Users know when an application looks strange, and having icons next to each menu item (something I certainly have seen in Java apps) is definitely strange and unnatural on OS X. Users will be irritated at best, confused at worst.
So my advice is to either follow the Human Interface Guidelines (and save yourself a lot of work as a nice side effect) or just stick with your existing Java application.
If you want to provide quick iconic access to common functions, the recommended approach on OS X is to use a toolbar.

General design for a Mac app, document based versus?

I am learning cocoa, and I am creating an application that will require similiar layout to the screenshot below (this seems like a very common layout approach).
What kind of controls/architecture would this type of Cocoa application be?
I'm still in my early stages of learning/reading, and I know of document based applications only so far, but this type of layout doesn't seem to look like a document based app since it doesn't really require multiple windows opened.
If it isn't document, is there a name for other design patters or layouts?
From what I now so far, I would describe this like:
I would be grateful if someone could give me a detailed overview of the high level design for an app like this i.e. things like: # of panels, views used, controls, controllers etc?
Also, a few quick sub-questions:
what kind of menu controls are those in the left pane, then expand and display sub elements?
When preferences windows are displayed, what is that effect called that makes it display in an animated way (like the address book does), where it is a small window that expands to its correct size in an animated fashion.
You are right that this is probably not a document based application, as they open documents in new windows by default.
To layout the window like that, there’d be an NSSplitView that contains the 3 panes. Each pane may optionally contain a view loaded from an NSViewController, which can help keep the code modularised, but it depends on what you’re trying to do if this is appropriate.
The left pane would be an NSOutlineView (a NSTableView subclass), the middle an NSTableView, but I’m not sure exactly how the right-hand side view would be created (lots of custom NSViews and other things, possibly WebView)
That popover options window is possibly a NSPopover (which contains an NSViewController), but that’s only compatible with OS X 10.7, so may also be totally custom for backwards compatibility and easier customisation.
Also note this is a fairly complicated example you’ve given, with lots of custom controls that are probably harder to create than they look:
To get the outline views on the left to have unread counts and icons (from memory) is not built into AppKit, so was all custom created. To do things like that, you’ll need a solid understanding of NSCell vs NSView, and ideally also know about Core Animation layer backed views, and what to use for different aspects.
The window has a taller-than usual title bar. This means the developer probably had to do some crazy stuff to get it to work, if not create the whole window from scratch.
That’s just the start. There’s lots of really nice design in there that’s custom and done from scratch.
Designing Mac apps can be hard sometimes. AppKit is pretty old (back from the NEXT days), and has lots of legacy stuck in it. UIKit on iOS on the other hand is quite nice – Apple clearly learned from their past and made things much better.
I’ve hardly touched on the controllers and model behind all that. There’s lots of different ways you could do it. For persistence, you could use CoreData, sqlite, NSKeyedArchived, just to name a few. Brent Simmons (past developer of another RSS reader, NetNewsWire) wrote some interesting blog posts about that:
http://inessential.com/2010/02/26/on_switching_away_from_core_data
http://inessential.com/2011/09/22/core_data_revisited
The way you design your model & controllers really depends on the specific problem. Cocoa really forces you to stick to MVC though – if you don’t, things are guaranteed to end up messy.
I hope that all helps! I’m really only just learning myself too.
Apple refers to this type of application design as Single-window, library- (or “shoebox”) style and gives a number of recommendations for this design choice in the docs.
(see Mac App Programming Guide)

Cocoa + CoreAnimation: Animated List of Custom Subviews

I've been trying to get this right for weeks now, and though I've learned a lot through my misfires, at this point, I just need a solution. The issue is with unpacking the seemingly overlapping graphics and UI APIs included in Cocoa, many of which produce similar effects, but feature unique limitations that I've often discovered only after investing many hours into an implementation.
I'm new to Cocoa, but not to programming, and I'm trying to create a Mac app with a very customized UI – think Capo, Garageband, or Billings. One view in my window will display an ordered list of subviews, each of which does a lot of custom drawing, and each must support a "selected" state and drag-reordering. The subviews do not need to support being dragged outside of their superview.
Ideally, a drag will give animated feedback as it happens, pushing neighboring sibling views to make space, e.g. toolbar icons or the Safari bookmarks bar. The trouble is, I can't seem to land on the right pack of technologies to get this right. I've done the subviews as NSView subclasses in an NSCollectionView and also as CALayers in a custom CollectionView-like NSView, and neither seems to offer the perfect solution. That said, the first option seems the better of the two for its superior handling of mouse events.
I've not yet tried doing this as a TableView, and I don't want to go down that path without some indication I'm on the right track. Extensive Googling has shown only that there aren't any up-to-date resources on CoreAnimation-enabled reordering or dragging. As such a standard feature of the OS X UI, I feel like this should be easier!
Any help from anyone on what the right tools are for this job would be greatly appreciated. TIA.

Apple Magic Mouse Api

I just bought a Magic Mouse and I like it pretty much. But as a Mac Developer it's even cooler. But there's one problem: is there already an API available for it? I want to use it for one of my applications. For, example, detect the user's finger positions, swipe or stretch gestures etc...
Does anyone know if there's an API for it (and how to use it)?
The Magic Mouse does not use the NSTouch API. I have been experimenting with it and attempting to capture touch information. I've had no luck so far. The only touch method that is common to both the mouse and the trackpad is the swipeWithEvent: method. It is called for a two finger swipe on the device only.
It seems the touch input from the mouse is being interpreted somewhere else, then forwarded on to the public API. I have yet to find the private API that is actually doing the work.
get a look here: http://www.iphonesmartapps.org/aladino/?a=multitouch
there's a full working proof-of-concept using the CGEventPost method.
--
all the best!
I have not tested, but I would be shocked if it didn't use NSTouch. NSTouch is the API you use to interact with the multi-touch trackpads on current MacBook Pros (and the new MacBooks that came out this week). You can check out the LightTable sample project to see how it is used.
It is part of AppKit, but it is a Snow Leopard only API.
I messed around with the below app before getting my magic mouse. I was surprised to find that the app also tracked the multi touch points on the mouse.
There is a link in the comments to some source that gets the raw data similarly, but there is no source to this actual app.
http://lericson.blogg.se/code/2009/november/multitouch-on-unibody-macbooks.html

Creating a Quartz Composer Style interface

I'm wanting to add a Quartz Composer "patch editor" style interface element to my Cocoa/Objective C(++) application. For those unfamiliar with QC, the patch editor is a visual representation of the patch graph: effectively showing each node and it's properties, and providing a mouse driven select/click/drag interface. It looks like...
Quartz Composer Example http://files.me.com/archgrove/ya1xhh
I'll be using it to render a specific type of multi-rooted tree, where each node has some associated text and an arc joining it to its children. Users will be clicking on the tree nodes to select them, as well as dragging them around.
At the moment, I'm using a custom NSView inside a scroll view that Quartz draws each node, the arcs etc at each render, and processes mouse and keyboard input by hand (including hit testing, movement and so forth). This seems brutally wheel reinventive, and doesn't interact all that well with Core Animation. I'm hoping someone has some general alternative advice. I'm pondering along the lines of...
An existing control/3rd party library I've overlooked
Make each node in the tree an NSView, and use the normal view structure to handle the input, whilst drawing the graphics in the same way. But then, the inter-node arc rendering doesn't seem to fit naturally into the design
Something using a single NSView still, but making each tree node and arc an individual layer
Something else
Thanks kindly,
adamw
You might want to give EFLaceView a look: FlowChartView on CocoaDev
Edit: download link on page above is dead. There is a version of EFLaceView on github.