1
votes

I have an NSBox, and inside the NSBox is an NSImageView to display a placeholder picture. I have created a custom class, subclass of NSBox, and made it accept dragging for the files that i want. But when i drag over the NSImageView that is inside the NSBox, it exits the drag-area and i can't drop anything there.

I want to be able to tell both the NSBox and the NSImageView to use my dragging implementation so that i don't have to copy and paste code between two different classes.

I have not found a way to do this yet.

My understanding is that Categories can only extend a specific class, so that won't work.

And when testing Composition, I have not found anything that would work either.

And Posing is deprecated since long so i won't try that.

My thoughts are to create a class, subclass of NSView and put all con in that class implementation, and then try to inherit that class in my NSBox and NSImageView somehow. Like the following illustration (not actual code of course, just to illustrate what I am trying to do).

@interface MyClass : NSView <NSDraggingDestination>

@end

@interface MyClassBox : NSBox (Inherit implementation from MyClass)

@end

@interface MyClassImageView : NSImageView (Inherit implementation from MyClass)

@end
1

1 Answers

1
votes

I have the following code in a DND.m file that I #include in NSView(/NSControl) subclasses to which I want to add Drag-N-Drop support:

#pragma mark - NSDraggingDestination protocol methods

// ------------------------------------------------------
//  method called whenever a drag enters our drop zone
// ------------------------------------------------------
- (NSDragOperation) draggingEntered:(id <NSDraggingInfo> )sender {
    NSDragOperation result = NSDragOperationNone;

    id delegate = self.window.windowController;
    delegate = delegate ? delegate : self.window.delegate;
    if (delegate && [delegate respondsToSelector:_cmd]) {
        result = [delegate draggingEntered:sender];
    }

    return (result);
}   // draggingEntered

// ------------------------------------------------------
//  method called whenever a drag exits our drop zone
// ------------------------------------------------------
- (void) draggingExited:(id <NSDraggingInfo> )sender {
    id delegate = self.window.windowController;
    delegate = delegate ? delegate : self.window.delegate;
    if (delegate && [delegate respondsToSelector:_cmd]) {
        [delegate draggingExited:sender];
    }
}   // draggingExited

// ------------------------------------------------------
//  method to determine if we can accept the drop
// ------------------------------------------------------
- (BOOL) prepareForDragOperation:(id <NSDraggingInfo> )sender {
    BOOL result = NO;

    id delegate = self.window.windowController;
    delegate = delegate ? delegate : self.window.delegate;
    if (delegate && [delegate respondsToSelector:_cmd]) {
        result = [delegate prepareForDragOperation:sender];
    }

    return (result);
}   // prepareForDragOperation

// ------------------------------------------------------
//  method that should handle the drop data
// ------------------------------------------------------
- (BOOL) performDragOperation:(id <NSDraggingInfo> )sender {
    BOOL result = NO;

    id delegate = self.window.windowController;
    delegate = delegate ? delegate : self.window.delegate;
    if (delegate && [delegate respondsToSelector:_cmd]) {
        result = [delegate performDragOperation:sender];
    }

    return (result);
}   // performDragOperation

I then implement these same methods in the window controller or delegate (sub-)class with the real (shared) Drag-N-Drop code.