Drag and drop within a view? - macos

I've been experimenting with the drag-and-drop support in Cocoa - draggingEntered:withInfo:, draggedImage:beganAt:, etc. It looks like OS X only triggers "drag" events when you drag something out of one view and into another.
I have a very large view which I draw stuff inside, and I'm looking for a way to drag objects within it; the objects never leave the view, so the above messages don't seem to be generated, and no drag starts. Is there a way to do "drag and drop within a view", or do I have to implement it myself?

I'm pretty sure you can't do that with drag and drop. If the things you're trying to drag are objects (like NSBezier paths) you can do a hit test on them and then use mouseDown: and mouseDragged: to implement changing the origin of your object, but it's all up to you.

Related

drag and drop between different recyclerviews with animation

I'm creating a simple (or so I thought) app that allows a user to drag/drop/reorder items within one of two recyclerview lists, or from one list to another. It should animate as you are dragging items, opening gaps that help you easily drop the item into the target spot. This functionality needs to go both ways between the lists. And for extra fun, drag should start on touch, not long press.
In case it makes any difference I'm trying to stick to MVVM, and my 2 recyclerviews are in 2 different fragments, but combined in one screen for this activity.
I'm a relative newbie to android, and using kotlin.
What I have managed so far
I can achieve a nice animation within one recyclerview, using ItemTouchHelper.
OR
I can achieve drag and drop from one recyclerview to the other, and I can start that on touch rather than long press, using View.OnDragListener.
What I can't seem to do is get both of those working at once--drag to another view, but with those beautiful animations ItemTouchHelper provides as the drag is underway.
I have tested all kinds of combinations of attaching customized drag or touchlisteners to my viewholders or recyclerviews. The closest I've gotten to getting things working is attaching the draglistener to the recyclerviews only, in order to receive the dropped view. Then I have set draglisteners and touchhelpers on the viewholders (via the recyclerview adapter).
With this setup I can drag between or within recyclerviews on touch, and have managed to get an animation AFTER drop by calling onItemMove of my adapter (provided as a parameter in my custom draglistener) from within the ACTION_DROP of my dragListener.
I've been working on this for a VERY LONG TIME and googled the heck out of it without luck. Help deeply appreciated.

Cocoa Image Picker Popover

Several places in OS X (in this example, the Users & Groups pane in System Preferences) have circular image views that allow the user to either drag in an image, like in an editable NSImageView but also allow them to click to show a popover that allows various other choices of image sources.
I have checked the ImageKit framework, but the only thing I found similar is the image taking sheet.
How can I make use of this feature in my own Cocoa applications? I'd imagine it is implemented in some standard framework—but any pointers on implementing something like this would be quite appreciated.
You will have to go down the custom control root as this is not available as a stand alone control.
However you have all the prerequisites.
The circular image view
There a several ways to implement this. You could try using a standard Cocoa button and customise as needed. Although it might just be easier to build from scratch by subclassing NSView. This was you can avoid all the NSCell stuff. I would do the latter.
The popover
Roll your own master-details type view controller to be displayed as the popover's content. In the left have a NSTableView (the master), the right have a NSCollectionView (the details). Below the collection view add some buttons.

Move controls with the mouse in Cocoa

I want to build a simple forms designer in Cocoa and need to move controls around on a form using the mouse (click, hold, move around, release).
Do I need to inherit new classes from all control classes to intercept those events ? Is there a way to implement it generically for any control?
One way might be to have a single large custom view that fills all the space the controls will be in. Implement the necessary methods to implement mouse events in this view, doing hit detection on the control views and moving them around. This approach requires only 1 custom subclass of NSView, and you can use any views or controls you want to move around without subclassing them.
Write a custom view to contain the controls. Override -hitTest: to ignore the controls and return self instead. Then when you receive mouse events, figure out which control they apply to and move as appropriate.

Dragging from and to NSButton

I am trying to write an app. that will allow the user to drag from an NSButton to another. When dropped I would like the Title to be dropped onto the button.
I cannot find a way to make NSButton draggable. Is it possible?
First a warning: this sounds like it would be confusing to a user. Buttons are intended to emulate buttons in the real world. You push them rather than drag them around.
Having said that, it's certainly possible to do in a subclass of NSButton.
Drag source
Implement the dragging source method draggingSourceOperationMaskForLocal:. Sounds like you're copying the title, so you may want to use NSDragOperationCopy.
Call dragImage:at:offset:event:pasteboard:source:slideBack: in your mouseDragged: method. Use the drag pBoard ([NSPasteboard pasteboardWithName:NSDragPboard]) and copy your button title into it. For the image you can draw your button into an NSImage and use that as the drag image, or you might use an icon or even just the title.
Drag destination
Register your custom button to be able to accept the title string using registerForDraggedTypes:.
Implement the drag destination methods draggingEntered: and performDragOperation: to return appropriate values. There are several other methods including draggingUpdated: and draggingExited: among others that you can use to provide visual feedback.
There's lots of info out there on implementing drag & drop. Read Apple's docs: Drag & Drop Programming Topics and Pasteboard Programming Guide

Sizing a control to fit its container in Interface Builder

Let's say I have a split view, and I want to fill half of it with a table view (a fairly common use case, I would think). Is there any way to tell the table view to size itself to fit the split view or do I really have to size it manually?
I've done this, the way Jon Hess mentions first. Assuming you're using Interface Builder version 3:
Drag and resize your GUI (tableview from what I understand?) component to fit into the enclosing area the way you want it.
Click it to select it.
Press Command-Shift-I to open the inspector window for this GUI component. The inspector window should now actually show that you've selected a "Scroll View".
Click the "ruler" heading to be able to set the sizing. You'll see to the right an animated representation of how your GUI component will behave within its enclosing GUI component, and to the left another represenation of the same, without animation, but with four springs and two struts that you can turn on or off.
Turn all six things on, making them red.
Voilà :-)
It's generally easier to create the subviews first, then use the Layout/Embed Objects In/Split View menu item to create the split view around them.
As far as I know, doing it manually is the only way to go. However, if you turn on "snap to cocoa guidelines", the inner view will snap to the edges of the enclosing view as you drag towards them. This makes it easier than having to manually mouse the edges into place, or manually edit the sizes to match.
You can set all of the springs and struts of the table view to "on" in the size inspector and that will cause the table view to fill the split view. Alternatively, you can use the outline view in the main document window to place the tableview's enclosing scroll view directly into the splitview instead of in an intermediary custom view.

Resources