mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-30 07:00:37 +00:00
Dragging updates
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@4672 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
beb5bb3f28
commit
a8271413b9
10 changed files with 219 additions and 7 deletions
|
@ -85,6 +85,7 @@ NSMenuView.m \
|
|||
NSMenuItem.m \
|
||||
NSMenuItemCell.m \
|
||||
NSOpenPanel.m \
|
||||
NSObjectProtocols.m \
|
||||
NSPageLayout.m \
|
||||
NSPanel.m \
|
||||
NSParagraphStyle.m \
|
||||
|
|
|
@ -271,7 +271,7 @@ NSGraphicsContext *GSCurrentContext()
|
|||
{
|
||||
id o = [types objectAtIndex: i];
|
||||
|
||||
[old removeObject: o];
|
||||
[old addObject: o];
|
||||
}
|
||||
if ([old count] == originalCount)
|
||||
return NO;
|
||||
|
@ -323,6 +323,17 @@ NSGraphicsContext *GSCurrentContext()
|
|||
return (NSCountedSet*)NSMapGet(drag_types, (void*)winNum);
|
||||
}
|
||||
|
||||
- (id <NSDraggingInfo>)_dragInfo
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void) _postExternalEvent: (NSEvent *)event;
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
/*
|
||||
* Misc window management support.
|
||||
*/
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <Foundation/NSDictionary.h>
|
||||
#include <Foundation/NSConnection.h>
|
||||
#include <Foundation/NSDistantObject.h>
|
||||
#include <Foundation/NSMapTable.h>
|
||||
#include <Foundation/NSNotification.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSLock.h>
|
||||
|
@ -65,7 +66,7 @@
|
|||
static NSLock *dictionary_lock = nil;
|
||||
static NSMutableDictionary *pasteboards = nil;
|
||||
static id<GSPasteboardSvr> the_server = nil;
|
||||
|
||||
static NSMapTable *mimeMap = NULL;
|
||||
|
||||
//
|
||||
// Class methods
|
||||
|
@ -731,6 +732,60 @@ static id<GSPasteboardSvr> the_server = nil;
|
|||
}
|
||||
NS_ENDHANDLER
|
||||
}
|
||||
|
||||
+ (void) _initMimeMappings
|
||||
{
|
||||
mimeMap = NSCreateMapTable(NSObjectMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 0);
|
||||
NSMapInsert(mimeMap, (void *)NSStringPboardType, (void *)@"text/plain");
|
||||
NSMapInsert(mimeMap, (void *)NSFileContentsPboardType,
|
||||
(void *)@"text/plain");
|
||||
NSMapInsert(mimeMap, (void *)NSFilenamesPboardType,
|
||||
(void *)@"text/uri-list");
|
||||
NSMapInsert(mimeMap, (void *)NSPostScriptPboardType,
|
||||
(void *)@"application/postscript");
|
||||
NSMapInsert(mimeMap, (void *)NSTabularTextPboardType,
|
||||
(void *)@"text/tab-separated-values");
|
||||
NSMapInsert(mimeMap, (void *)NSRTFPboardType, (void *)@"text/richtext");
|
||||
NSMapInsert(mimeMap, (void *)NSTIFFPboardType, (void *)@"image/tiff");
|
||||
NSMapInsert(mimeMap, (void *)NSGeneralPboardType, (void *)@"text/plain");
|
||||
}
|
||||
|
||||
/* Return the mapping for pasteboard->mime, or return the original pasteboard
|
||||
type if no mapping is found */
|
||||
+ (NSString *) mimeTypeForPasteboardType: (NSString *)type
|
||||
{
|
||||
NSString *mime;
|
||||
if (mimeMap == NULL)
|
||||
[self _initMimeMappings];
|
||||
mime = NSMapGet(mimeMap, (void *)type);
|
||||
if (mime == nil)
|
||||
mime = type;
|
||||
return mime;
|
||||
}
|
||||
|
||||
/* Return the mapping for mime->pasteboard, or return the original pasteboard
|
||||
type if no mapping is found. This method may not have a one-to-one
|
||||
mapping */
|
||||
+ (NSString *) pasteboardTypeForMimeType: (NSString *)mimeType
|
||||
{
|
||||
BOOL found;
|
||||
NSString *type, *mime;
|
||||
NSMapEnumerator enumerator;
|
||||
|
||||
if (mimeMap == NULL)
|
||||
[self _initMimeMappings];
|
||||
enumerator = NSEnumerateMapTable(mimeMap);
|
||||
while ((found = NSNextMapEnumeratorPair(&enumerator,
|
||||
(void **)(&type), (void **)(&mime))))
|
||||
if ([mimeType isEqual: mime])
|
||||
break;
|
||||
|
||||
if (found == NO)
|
||||
type = mimeType;
|
||||
return type;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static NSString* contentsPrefix = @"NSTypedFileContentsPboardType: ";
|
||||
|
|
|
@ -2037,7 +2037,16 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level)
|
|||
pasteboard: (NSPasteboard*)pboard
|
||||
source: (id)sourceObject
|
||||
slideBack: (BOOL)slideFlag
|
||||
{}
|
||||
{
|
||||
NSView *dragView = (NSView *)[GSCurrentContext() _dragInfo];
|
||||
[dragView dragImage: anImage
|
||||
at: viewLocation
|
||||
offset: initialOffset
|
||||
event: event
|
||||
pasteboard: pboard
|
||||
source: sourceObject
|
||||
slideBack: slideFlag];
|
||||
}
|
||||
|
||||
- (void) registerForDraggedTypes: (NSArray*)types
|
||||
{
|
||||
|
|
|
@ -54,7 +54,10 @@
|
|||
#include <AppKit/NSView.h>
|
||||
#include <AppKit/NSCursor.h>
|
||||
#include <AppKit/PSOperators.h>
|
||||
#include <AppKit/NSDragging.h>
|
||||
#include <AppKit/NSPasteboard.h>
|
||||
|
||||
BOOL GSViewAcceptsDrag(NSView *v, id<NSDraggingInfo> dragInfo);
|
||||
|
||||
@interface GSWindowView : NSView
|
||||
{
|
||||
|
@ -1405,7 +1408,7 @@ static NSRecursiveLock *windowsLock;
|
|||
if (first_responder != v)
|
||||
{
|
||||
[self makeFirstResponder: v];
|
||||
if ([v acceptsFirstMouse: theEvent] == YES)
|
||||
if (is_key || [v acceptsFirstMouse: theEvent] == YES)
|
||||
[v mouseDown: theEvent];
|
||||
}
|
||||
else
|
||||
|
@ -1522,6 +1525,9 @@ static NSRecursiveLock *windowsLock;
|
|||
|
||||
case NSAppKitDefined:
|
||||
{
|
||||
id dragInfo;
|
||||
int action;
|
||||
NSEvent *e;
|
||||
GSAppKitSubtype sub = [theEvent subtype];
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
|
@ -1554,8 +1560,91 @@ static NSRecursiveLock *windowsLock;
|
|||
object: self];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
#define GSPerformDragSelector(view, sel, info, action) \
|
||||
if (view == content_view && delegate) \
|
||||
action = (int)[delegate performSelector: sel withObject: \
|
||||
info]; \
|
||||
else \
|
||||
action = (int)[view performSelector: sel withObject: info]
|
||||
#define GSPerformVoidDragSelector(view, sel, info) \
|
||||
if (view == content_view && delegate) \
|
||||
[delegate performSelector: sel withObject: info]; \
|
||||
else \
|
||||
[view performSelector: sel withObject: info]
|
||||
|
||||
case GSAppKitDraggingEnter:
|
||||
case GSAppKitDraggingUpdate:
|
||||
v = [content_view hitTest: [theEvent locationInWindow]];
|
||||
if (!v)
|
||||
v = content_view;
|
||||
dragInfo = [GSCurrentContext() _dragInfo];
|
||||
if (_lastDragView && _lastDragView != v && accepts_drag)
|
||||
GSPerformVoidDragSelector(_lastDragView,
|
||||
@selector(draggingExited:), dragInfo);
|
||||
accepts_drag = GSViewAcceptsDrag(v, dragInfo);
|
||||
if (_lastDragView != v && accepts_drag)
|
||||
GSPerformDragSelector(v, @selector(draggingEntered:),
|
||||
dragInfo, action);
|
||||
else
|
||||
GSPerformDragSelector(v, @selector(draggingUpdated:),
|
||||
dragInfo, action);
|
||||
e = [NSEvent otherEventWithType: NSAppKitDefined
|
||||
location: [theEvent locationInWindow]
|
||||
modifierFlags: 0
|
||||
timestamp: 0
|
||||
windowNumber: [self windowNumber]
|
||||
context: GSCurrentContext()
|
||||
subtype: GSAppKitDraggingStatus
|
||||
data1: [theEvent data1]
|
||||
data2: action];
|
||||
[GSCurrentContext() _postExternalEvent: e];
|
||||
_lastDragView = v;
|
||||
break;
|
||||
|
||||
case GSAppKitDraggingStatus:
|
||||
NSLog(@"Internal: dropped GSAppKitDraggingStatus event\n");
|
||||
break;
|
||||
|
||||
case GSAppKitDraggingExit:
|
||||
if (_lastDragView && accepts_drag)
|
||||
GSPerformDragSelector(_lastDragView,
|
||||
@selector(draggingExited:), dragInfo,
|
||||
action);
|
||||
break;
|
||||
|
||||
case GSAppKitDraggingDrop:
|
||||
if (_lastDragView && accepts_drag)
|
||||
{
|
||||
GSPerformDragSelector(_lastDragView,
|
||||
@selector(prepareForDragOperation:),
|
||||
dragInfo, action);
|
||||
if (action)
|
||||
GSPerformDragSelector(_lastDragView,
|
||||
@selector(performDragOperation:),
|
||||
dragInfo, action);
|
||||
if (action)
|
||||
GSPerformVoidDragSelector(_lastDragView,
|
||||
@selector(concludeDragOperation:),
|
||||
dragInfo);
|
||||
}
|
||||
e = [NSEvent otherEventWithType: NSAppKitDefined
|
||||
location: [theEvent locationInWindow]
|
||||
modifierFlags: 0
|
||||
timestamp: 0
|
||||
windowNumber: [self windowNumber]
|
||||
context: GSCurrentContext()
|
||||
subtype: GSAppKitDraggingFinished
|
||||
data1: [theEvent data1]
|
||||
data2: 0];
|
||||
[GSCurrentContext() _postExternalEvent: e];
|
||||
break;
|
||||
|
||||
case GSAppKitDraggingFinished:
|
||||
NSLog(@"Internal: dropped GSAppKitDraggingFinished event\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2056,3 +2145,12 @@ static NSRecursiveLock *windowsLock;
|
|||
}
|
||||
|
||||
@end
|
||||
|
||||
BOOL GSViewAcceptsDrag(NSView *v, id<NSDraggingInfo> dragInfo)
|
||||
{
|
||||
NSPasteboard *pb = [dragInfo draggingPasteBoard];
|
||||
if ([pb availableTypeFromArray: GSGetDragTypes(v)])
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue