[futurebasic] Re: [FB] Drag 'n Drop question

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : May 2013 : Group Archive : Group : All Groups

From: Bernie <fblist.bw@...>
Date: Fri, 17 May 2013 14:47:18 +0100
Walter wrote:

> It would be great to also be able to drag 
> the file's icon into the application's window, but I've not a clue 
> how to do this. I've seen programs that do it, and Rich alludes to it 
> above - does anybody have any suggestions?

I wouldn't have a clue how to do it with Carbon calls, but here's a novel workaround.

'---------------
/*
   DragDropView

   Bernie 20130517
*/

compile as "Objective-C"

include "Tlbx HIView.incl"
include "FBLog.incl"

BeginCDeclaration
#import <Cocoa/Cocoa.h>

typedef void (*DragDropViewCallbackType)(CFArrayRef,void*);

@interface DragDropView : NSView {
     DragDropViewCallbackType _callback;
     void *userData;
     BOOL dragInside;
}
@end

HIViewRef DragDropViewCreate( WindowRef w, HIRect r, void *callback, void *userData );
EndC

BeginCFunction
@implementation DragDropView

- (id)initWithFrame:(NSRect)frame {
     self = [super initWithFrame:frame];
     if (self) {
          [self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
     }
     return self;
}

- (void)setCallback:(DragDropViewCallbackType)callback userData:(void *)ud {
     _callback = callback;
     userData = ud;
}

- (void)drawRect:(NSRect)rect {
     if ( dragInside ) {
          NSRect focusRingFrame = [self frame];
          focusRingFrame.origin = NSZeroPoint;
          focusRingFrame.size.height -= 2.0;
          [NSGraphicsContext saveGraphicsState];
          NSSetFocusRingStyle(NSFocusRingOnly);
          [[NSBezierPath bezierPathWithRect: NSInsetRect(focusRingFrame, 4, 4)] fill];
          [NSGraphicsContext restoreGraphicsState];
     }
}                                      
     
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender {
     NSPasteboard *pboard = [sender draggingPasteboard];
     if ( [[pboard types] containsObject:NSFilenamesPboardType] ) {
          dragInside = YES;  
          [self setNeedsDisplay:YES];
          return NSDragOperationLink;
    }
    return NSDragOperationNone; 
}

- (void)draggingExited:(id <NSDraggingInfo>)sender {
     dragInside = NO;
     [self setNeedsDisplay:YES];
}

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
     [[NSCursor arrowCursor] set];
     NSPasteboard *pboard = [sender draggingPasteboard];
     if ([[pboard types] containsObject:NSFilenamesPboardType]) {
          NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
          if ( _callback != nil ) (*_callback)( (CFArrayRef)files, userData );
          [self draggingExited:sender];
          return YES;
     }
     return NO;
}
@end

HIViewRef DragDropViewCreate( WindowRef w, HIRect r, void *callback, void *userData )
{
     NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];
     NSApplicationLoad();
     HIObjectRef obj;
     HIViewRef contentView;
     HIViewFindByID( HIViewGetRoot( w ), kHIViewWindowContentID, &contentView );
     HIObjectCreate( CFSTR( "com.apple.HICocoaView" ), 0, &obj );
     DragDropView *ddView = [[DragDropView alloc] init];
     [ddView setCallback:callback userData:userData];
     [ddView initWithFrame:NSMakeRect( r.origin.x, r.origin.y, r.size.width, r.size.height )];
     HIViewRef view = (HIViewRef)obj;
     HICocoaViewSetView( view, ddView );
     HIViewSetFrame( view, &r );
     HIViewAddSubview( contentView, view );
     HIViewSetVisible( view, true );
     [localPool release];
     return view;
}
EndC

toolbox fn DragDropViewCreate( WindowRef w, HIRect r, ptr callback, ptr userData ) = HIViewRef


local fn MyDragDropViewCallback( array as CFArrayRef )
'~'1
dim as CFIndex   count, index

count = fn CFArrayGetCount( array )
for index = 0 to count - 1
FBLog( @"%@", fn CFArrayGetValueAtIndex( array, index ) )
next index
end fn


local fn BuildDragDropWindow
'~'1
appearance window 1, "DragDrop", (0,0)-(300,250), _kDocumentWindowClass, _kWindowCompositingAttribute
fn DragDropViewCreate( window( _wndRef ), fn CGRectMake( 0, 0, 300, 250 ), @fn MyDragDropViewCallback, NULL )
end fn

fn BuildDragDropWindow()

RunApplicationEventLoop()
'---------------