Sunday, August 23, 2020


Tags

Building a better Mac App with Xojo

Illustrating that an area can accept a droped item

Sunday, August 23, 2020 - Sam Rowlands

It is no secret that for the last few months, I've been hard at work on App Wrapper 4. I came across an interesting scenario, something which I appear to have forgotten in recent years. The correct way to highlight an area or control which can accept a dropped item.

So taking a trip over to the Apple documentation, finds me what I need. https://developer.apple.com/design/human-interface-guidelines/macos/user-interaction/drag-and-drop/

In my case, I want to ensure that I am drawing the highlight ring (from left image) and providing a cursor that will match the action (right side image).

Highlight Ring

With version 1.0.6 of the Ohanaware App Kit I've added a new control, which I've dubbed "OWDropRing". Simply add this control to your window (or container control) and call it on DragEnter. dropRing.showInControl me The control takes care of the rest, following the guidelines and drawing the drop highlight on the control.

ImageWells need a little bit more code. dropRing.cornerRadius = 8 dropRing.inset = 3 dropRing.showInControl meMoves the ring inside the control by the inset and rounds the corners.

On dragExit or dropObject, we want to remove the drop ring, dropRing.hide

Listboxes already draw this "ring".

Great, so that's the highlight ring handled, now what about the cursor?

Providing a drop action cursor

I apologize in advance, as hard as I tried to screengrab the cursors, macOS Catalina point blank refused to include the cursor in the screenshot, even when enabled in the command-shift-5 options.

Xojo has the capabilities for setting the cursor and I thought it would be as easy as setting the cursor on dragEnter. I couldn't get it to work.

Digging into Apple's documentation, I was able to move on by writing declares. I wrapped it up into a function.

dropRing.setCursorToDragCopy

While the "dragCopy" cursor might work, I wanted to see if there was a better choice, the "dragLink" cursor .

dropRing.setCursorToDragLink

And the infamous operation not permitted cursor dropRing.setCursorToOperationNotAllowed

The cursor is automatically removed, when "dropRing.hide" is called.

What about just wanting the cursor and not the highlight ring?

The methods above for setting the cursor are shared methods, which can be called anywhere. OWDropRing.setCursorToDragCopy

There's a matching function for removing the cursor too, which is also a shared method. OWDropRing.clearCursor

ImageWells

ImageWells steal the dragging events. Which creates a weird situation if you use a ImageWell as part of a drop area. To avoid this, add the following code to the "Open" event. That is unless you want the ImageWell to be a separate drop zone.

#if targetMacOS then NSViewUnregisterDraggedTypes( me.handle ) #endIf