Back with more drag and drop! I want to have a drop zone and when a file is dropped on it have a text filed and imageView show the path and icon for the file. I have seen this in several apps where there is a “drop zone”, often with the little hash marks around it, and after dropping the file it becomes a nice image with the path and other details. I can get a normal text field to accept drops fine but want the zone to be bigger than that.
But how would I set the text and image fields from within the subclass? Can I call up to the superclass somehow?
Or could this be done in some much better way?
The script is the NSBox subclass and does show the drop handlers being called and file path logged.
Cheers, Rob
script BoxView
property parent : class "NSBox"
property dropBox : missing value
property txtField : missing value
on awakeFromNib()
log "awakefromnib"
dropBox's registerForDraggedTypes_({current application's NSFilenamesPboardType})
end awakeFromNib
on draggingEntered_(info)
log "entered"
dropBox's becomeFirstResponder()
return current application's NSDragOperationCopy
end draggingEntered_
on performDragOperation_(info)
log "perform drop"
set pb to info's draggingPasteboard()
set theFiles to (pb's propertyListForType_("NSFilenamesPboardType"))
set theFile to theFiles's objectAtIndex_(0)
log theFile
-- how to access outlets outside the subclass?
txtField's setStringValue_(theFile as string)
return true
end performDragOperation_
end script
You connect the properties as outlets the same as any other class. Control-click on your box and the HUD panel will come up, ready to make connections.
Oh yes - it’s all connected. I can call the outlet from the Awake handler no problem. It just won’t do anything from the drop handlers. i also tried perform-selector-after-delay and moving the references to the drop-concluded handler but no luck. I also tried this in another app in my OBJ-c subclasses and there is no communication outside the subclassed object. Am I missing something? I googled around and there were some suggestions about this, notifications etc.
It seems like there is no connection except with the subclassed object itself.
There’s something I don’t understand in your code – why do you have an outlet to dropBox? You can’t connect an outlet from this script to the box if you have set its class to boxView, which you should have done. Have you done that? I pasted your code into a new project, set the box’s class to boxView, connected the text field to textField, and deleted the “dropBox’s” in your code (since the box is an instance of your script, you don’t need to address the message to anything, you just write “registerForDraggedTypes_({current application’s NSFilenamesPboardType})”). Everything worked fine then – I got the file’s path in the text field when I dropped it in the box.
Ric
After edit: Did you put in a blue cube and change its class to boxView (as well as setting the class of your box to boxView)? I tried that, and got the behavior that I think you’re seeing – the drop worked, I got the log messages, but nothing showed up in the text field. If that’s what you did, that’s what’s wrong. By putting in a blue cube, you now have two instances of your boxView class. You shouldn’t have the blue cube – get rid of it. If you right click on your box, you will see your textField outlet, and you should connect it from there. By the way, you don’t need the “becomeFirstResponder” line, and in fact the docs say never to invoke this method directly.
I’ll reconfigure and see. I thought there was something I was missing!
The next thing I need to do is get the box to highlight as for a textField drop. And I don’t know if it is possible to enable the little green + sign when the user drags over the space or if that is part of NSTextField built in drag/drop. The box highlight may require custom drawing which I am not up to par with yet.
That did it. I hadn’t done much subclassing and didn’t think that I could then link the box itself (it’s own instance) to the text field. I got in the habit of always creating those cubes for linking! I’ve learned a bit more today.
If you or anyone has any ideas about getting a highlight for the box when dropping that would be appreciated too.
I’m not sure if I can invoke the mouse-over methods but will check that out.
I think you have to draw your own focus ring in a drawRect method if you’re using a view (like a box) that doesn’t do this for you. How do you plan on getting the icon into your box (or do you have a separate image view to do that)?
Depending on what kind of effect you want, it would be easier to use an NSButton for your drop box. If you choose the bevel button, you can size it to what you want, and you can use setImage to put the icon into it. You can get highlighting ( by default it darkens) by using highlight_(true) in your draggingEntered method and highlight_(false) in your performDragOperation method.
I heard of someone using a button for a file drop - interesting. I actually don’t need the file path or image to show up in the drop zone itself. That’s what the text field is for. My goal is to have a nice drop area and the drop then sets up an image of the icon (or associated disk) in an image view and the path in the text field.
Another somewhat related question about the NSbox itself.
I found I can customize my drop zone NSBox ( I left out the drop handlers for clarity ) and even change the border color to simulate a nice dragging highlight. Here I can set the options for the box fine but the title doesn’t show above the box or at all. Do I have to then get into drawRect? I don’t have any experience yet with drawing but it seems like it should be easy to get the title to show up too.
Any thoughts appreciated.
Thanks, Rob
script CustomBox
property parent : class "NSBox"
on awakeFromNib()
setCornerRadius_(5.0)
setBorderWidth_(2.0)
setBorderColor_(current application's class "NSColor"'s grayColor)
” this has no effect, the title is set in IB too but no show
setTitle_("Hello there")
end awakeFromNib
end script
Is your box the custom type? If so, it doesn’t have a title, and the primary type which does have a title can’t be made a different color, so I don’t think you can get what you want with just a box (without drawing everything yourself). I think it would be easier to put a label (with no border) just above the box to put the title in.