diff options
author | petasis <petasis@f3661a36-4baa-549a-d6c7-40e0ffef350e> | 2009-12-09 21:00:34 (GMT) |
---|---|---|
committer | petasis <petasis@f3661a36-4baa-549a-d6c7-40e0ffef350e> | 2009-12-09 21:00:34 (GMT) |
commit | c80f725cf708460935311c056d5ada6a39a2ac1a (patch) | |
tree | bd4371cbf3eb27d1548ad69507bfc40c485c0721 | |
parent | 97696624c65652b5fe47c8c30ab0056b2e591824 (diff) | |
download | tkdnd-c80f725cf708460935311c056d5ada6a39a2ac1a.zip tkdnd-c80f725cf708460935311c056d5ada6a39a2ac1a.tar.gz tkdnd-c80f725cf708460935311c056d5ada6a39a2ac1a.tar.bz2 |
MAC OS X updates
-rw-r--r-- | library/tkdnd_macosx.tcl | 11 | ||||
-rw-r--r-- | macosx/macdnd.m | 134 |
2 files changed, 120 insertions, 25 deletions
diff --git a/library/tkdnd_macosx.tcl b/library/tkdnd_macosx.tcl index 0e7d1e2..0e007d7 100644 --- a/library/tkdnd_macosx.tcl +++ b/library/tkdnd_macosx.tcl @@ -60,9 +60,9 @@ namespace eval macdnd { };# namespace macdnd # ---------------------------------------------------------------------------- -# Command macdnd::_HandleXdndEnter +# Command macdnd::_HandleEnter # ---------------------------------------------------------------------------- -proc macdnd::_HandleXdndEnter { path drag_source typelist } { +proc macdnd::_HandleEnter { path drag_source typelist } { variable _typelist; set _typelist $typelist variable _pressedkeys; set _pressedkeys 1 variable _action; set _action {} @@ -73,10 +73,11 @@ proc macdnd::_HandleXdndEnter { path drag_source typelist } { variable _drop_target; set _drop_target {} variable _actionlist; set _actionlist \ {copy move link ask private} - # puts "macdnd::_HandleXdndEnter: path=$path, drag_source=$drag_source,\ - # typelist=$typelist" + puts "macdnd::_HandleEnter: path=$path, drag_source=$drag_source,\ + typelist=$typelist" update -};# macdnd::_HandleXdndEnter + return default +};# macdnd::_HandleEnter # ---------------------------------------------------------------------------- # Command macdnd::_HandleXdndPosition diff --git a/macosx/macdnd.m b/macosx/macdnd.m index 6869ee0..dc4cf61 100644 --- a/macosx/macdnd.m +++ b/macosx/macdnd.m @@ -18,11 +18,42 @@ #import <tkMacOSXInt.h> #import <Cocoa/Cocoa.h> +#define TkDND_TkWin(x) \ + (Tk_NameToWindow(interp, Tcl_GetString(x), Tk_MainWindow(interp))) + +#define TkDND_Eval(objc) \ + for (i=0; i<objc; ++i) Tcl_IncrRefCount(objv[i]);\ + if (Tcl_EvalObjv(interp, objc, objv, TCL_EVAL_GLOBAL) != TCL_OK) \ + Tk_BackgroundError(interp); \ + for (i=0; i<objc; ++i) Tcl_DecrRefCount(objv[i]); + +#define TkDND_Status_Eval(objc) \ + for (i=0; i<objc; ++i) Tcl_IncrRefCount(objv[i]);\ + status = Tcl_EvalObjv(interp, objc, objv, TCL_EVAL_GLOBAL);\ + if (status != TCL_OK) Tk_BackgroundError(interp); \ + for (i=0; i<objc; ++i) Tcl_DecrRefCount(objv[i]); + +#ifndef Tk_Interp +/* + * Tk 8.5 has a new function to return the interpreter that is associated with a + * window. Under 8.4 and earlier versions, simulate this function. + */ +#import "tkInt.h" +Tcl_Interp * TkDND_Interp(Tk_Window tkwin) { + if (tkwin != NULL && ((TkWindow *)tkwin)->mainPtr != NULL) { + return ((TkWindow *)tkwin)->mainPtr->interp; + } + return NULL; +}; /* Tk_Interp */ +#define Tk_Interp TkDND_Interp +#endif /* Tk_Interp */ + + //Here we need to wrap Cocoa methods in Cocoa class: methods for initiating, tracking, and terminating drag from inside and outside the application. @interface DNDView : NSView { - - NSPasteboard *dragpasteboard; + NSDragOperation sourceDragMask; + NSPasteboard *sourcePasteBoard; NSMutableArray *draggedtypes; } @@ -46,20 +77,82 @@ TkWindow* TkMacOSXGetTkWindow(NSWindow *w) { } -//We are only implementing dragging destination methods here: widget is drop target. Making a Tk widget a drag source under Cocoa is more complex because mouse events are defined at the Objective-C level. +/* + * We are only implementing dragging destination methods here: + * widget is drop target. Making a Tk widget a drag source under + * Cocoa is more complex because mouse events are defined at the + * Objective-C level. + */ -//standard Cocoa method for entering drop target; generate <<MacDragEnter>> event for Tk callback +/* + * Standard Cocoa method for entering drop target; + * Calls tkdnd::macdnd::_HandleEnter + */ - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender { - - dragpasteboard = [sender draggingPasteboard]; - - //create Tk virtual event - XVirtualEvent event; - int x, y; - - TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); - Tk_Window tkwin = (Tk_Window) winPtr; - + static char *DropActions[] = { + "copy", "move", "link", "ask", "private", "refuse_drop", "default", + (char *) NULL + }; + enum dropactions { + ActionCopy, ActionMove, ActionLink, ActionAsk, ActionPrivate, + refuse_drop, ActionDefault + }; + + TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); + Tk_Window tkwin = (Tk_Window) winPtr; + Tcl_Interp *interp = Tk_Interp(tkwin); + sourceDragMask = [sender draggingSourceOperationMask]; + sourcePasteBoard = [sender draggingPasteboard]; + + Tcl_Obj* objv[4], *element, *result; + int i, index, status; + + objv[0] = Tcl_NewStringObj("tkdnd::macdnd::_HandleEnter", -1); + objv[1] = Tcl_NewStringObj(Tk_PathName(tkwin), -1); + objv[2] = Tcl_NewLongObj(0); + objv[3] = Tcl_NewListObj(0, NULL); + /* + * Search for known types... + */ + if ([[sourcePasteBoard types] containsObject:NSStringPboardType]) { + element = Tcl_NewStringObj("NSStringPboardType", -1); + Tcl_ListObjAppendElement(NULL, objv[3], element); + } + if ([[sourcePasteBoard types] containsObject:NSFilenamesPboardType]) { + element = Tcl_NewStringObj("NSFilenamesPboardType", -1); + Tcl_ListObjAppendElement(NULL, objv[3], element); + } + /* Evaluate the command and get the result...*/ + TkDND_Status_Eval(4); + printf("Status=%d (%d)\n", status, TCL_OK);fflush(0); + if (status != TCL_OK) { + /* An error has happened. Cancel the drop! */ + return NSDragOperationNone; + } + /* We have a result: the returned action... */ + result = Tcl_GetObjResult(interp); Tcl_IncrRefCount(result); + status = Tcl_GetIndexFromObj(interp, result, (const char **) DropActions, + "dropactions", 0, &index); + Tcl_DecrRefCount(result); + if (status != TCL_OK) index = refuse_drop; + switch ((enum dropactions) index) { + case ActionDefault: + case ActionCopy: + return NSDragOperationCopy; + case ActionMove: + return NSDragOperationMove; + case ActionAsk: + return NSDragOperationGeneric; + case ActionPrivate: + return NSDragOperationPrivate; + case ActionLink: + return NSDragOperationLink; + case refuse_drop: { + return NSDragOperationNone; /* Refuse drop. */ + } + } + return NSDragOperationNone; +#if 0 bzero(&event, sizeof(XVirtualEvent)); event.type = VirtualEvent; event.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); @@ -78,11 +171,12 @@ TkWindow* TkMacOSXGetTkWindow(NSWindow *w) { //return valid NSDragOperations return NSDragOperationEvery; +#endif } //prepare to perform drag operation - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender { - dragpasteboard = [sender draggingPasteboard]; + sourcePasteBoard = [sender draggingPasteboard]; return YES; } @@ -91,18 +185,18 @@ TkWindow* TkMacOSXGetTkWindow(NSWindow *w) { // NSArray types; - dragpasteboard = [sender draggingPasteboard]; + sourcePasteBoard = [sender draggingPasteboard]; //retrieve string data from clipboard - NSArray *types = [dragpasteboard types]; + NSArray *types = [sourcePasteBoard types]; NSString *pasteboardvalue = nil; for (NSString *type in types) { //string type if ([type isEqualToString:NSStringPboardType]) { - pasteboardvalue = [dragpasteboard stringForType:NSStringPboardType]; + pasteboardvalue = [sourcePasteBoard stringForType:NSStringPboardType]; //file array, convert to string } else if ([type isEqualToString:NSFilenamesPboardType]) { - NSArray *files = [dragpasteboard propertyListForType:NSFilenamesPboardType]; + NSArray *files = [sourcePasteBoard propertyListForType:NSFilenamesPboardType]; NSString *filename; filename = [files componentsJoinedByString:@"\t"]; pasteboardvalue = filename; @@ -143,7 +237,7 @@ TkWindow* TkMacOSXGetTkWindow(NSWindow *w) { //drop target exited: generate <<MacDragExit>> virtual event - (void)draggingExited:(id < NSDraggingInfo >)sender { - dragpasteboard = [sender draggingPasteboard]; + sourcePasteBoard = [sender draggingPasteboard]; XVirtualEvent event; int x, y; |