Drag and Drop into Combo Box

Does anybody know how to make the text field of a combo box register for drag and drop operations?

If I add a handler for ‘drop’ to the combo box, only the border and drop down button become ‘sensitive’ for drop operations. Is there a way to explicitly tell the text field part to also register for the drop? I have tried ‘telling’ the text field

Iif I try:

tell text field “x” of combo box “x” of window “w”
register drag types {“file names”}
end tell

This actually works, but generates NSReceiverEvaluationScriptErrors which I would sort of expect because the text field of the combo box isn’t actually called “x”…

For the moment I am putting a try block around the statement and ignoring the error.

The only other solution I can find at the moment is to overlay the text field part of the combo box with another text field, which is pretty horrible…

My mistake, it’s not actually working - I was dropping on the blue border of the text box by mistake! So the original question still stands - how do I tell the text field to register for drops?

I’ve just noticed, that it does work but only when the combo box text field is not currently selected - ie if it doesn’t have the blue highlight…

Any ideas?

Greetings,

The first problem I see, is that you do not reference a combo box in the manner in which you’ve posted. In fact, a combobox IS a type of text field, so referencing it like you’ve done is redundant and incorrect. To reference the combo box, use something like…

tell combo box "myComboBox" of window "myWindow"...

To get an item to receive drag and drop’s you typically need to do two things. First, attach a launch-time handler like ‘awake from nib’ to the object and register your drag types. I use the ‘awake from nib’ handler of the combobox…

on awake from nib theObject
	tell theObject to register drag types {"file names"}
end awake from nib

This will let the application know when it starts up that when something is dropped on it, it should try to extract the paths of all the objects. Next, attach a ‘drop’ handler to the object and provide some code for doing something. The following code adds a new combo box item containing the path of the dropped file(s) to the combo box’s list…

on drop theObject drag info dragInfo
	set dataTypes to types of pasteboard of dragInfo
	if "file names" is in dataTypes then
		set preferred type of pasteboard of dragInfo to "file names"
		set thePaths to contents of pasteboard of dragInfo
		set preferred type of pasteboard of dragInfo to ""
		
		repeat with thePath in thePaths
			make new combo box item at end of combo box items of combo box "myComboBox" of window "myWindow" with data (thePath as string)
		end repeat
	end if
end drop

What seems to be your major problem here, is that for some reason (a bug?!) you cannot drop on any part of the combo box except the highlighted border when the combo box is first responder. You can drop normally on it when it’s not the focused object, but otherwise only the border is a valid drop target… as you’ve found.

I looked a bit and couldn’t find a documented way around this problem, so here’s a workaround I found to get the job done. Set up an extra object, like a horizontal line (technically a box). You could use another type of object, but it must be one that can be made first responder. You could also use an object that is already part of your interface, assuming that it does not cause undesired effects (like the object becoming highlighted when IT receives focus). That is why I find boxes to be particularly useful, as they do not have a highlighted border when focused. Place that object in a corner or off to the side of your window. I used a line object named “sponge”. Then, connect the ‘drag entered’ handler of your combo box to your script and enter this code…

on drag entered theObject drag info dragInfo
	tell window "myWindow"
		set first responder to box "sponge"
	end tell
end drag entered

What this will do is force the combo box to drop it’s focus every time something is dragged onto it and allow it’s entire text field to be a drop zone. As I said, the object you change focus to will become the first responder so make sure you select that object wisely to avoid unusual or unattractive results.

I can’t guarantee this will work under all circumstances, but it worked in my test project. Once your project is working good, or you have your drop working as desired, just move the sponge off of the screen or hide it behind another object and you should have a good workaround for this quirk.

Good luck,
j

Hi jobu - thanks for the response.

I knew that was not the correct way to reference the combo box, but I was just trying different things to see if they would work - and I fooled myself into thinking that this was working for some reason…

I also had all the drag and drop stuff working as you suggest, but as you say there appears to be a bug when the combo box is selected.

I’ve tried you solution and it works a treat!

Many Thanks!