mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 03:21:04 +00:00
Make DnD follow mouse pointer in text view
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@21038 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
508987f93b
commit
c55a8d1a73
3 changed files with 101 additions and 21 deletions
|
@ -1,3 +1,11 @@
|
|||
2005-04-03 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/AppKit/NSTextView.h: Keep track of whether we are acting
|
||||
as a target for a DnD operation, and what the selected range was
|
||||
before the operation began.
|
||||
* Source/NSTextView.m: Display insertion point during DnD operation
|
||||
Fixes bug #9788
|
||||
|
||||
2005-04-02 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSTableView.m: ([-mouseDown:]) tweak vertical image
|
||||
|
|
|
@ -123,6 +123,8 @@ therefore be stored in the NSLayoutManager to avoid problems.
|
|||
/* YES if delegate responds to
|
||||
`textView:willChangeSelectionFromCharacterRange:toCharacterRange:' */
|
||||
unsigned delegate_responds_to_will_change_sel:1;
|
||||
/* YES if a DnD operation is in progress with this as the target view */
|
||||
unsigned isDragTarget:1;
|
||||
} _tf;
|
||||
|
||||
|
||||
|
@ -201,6 +203,10 @@ therefore be stored in the NSLayoutManager to avoid problems.
|
|||
*/
|
||||
int _currentInsertionPointMovementDirection;
|
||||
|
||||
/* Ivar to store the original range so it can be restored after a DnD
|
||||
* operation is cancelled (the mouse moves back out of the view).
|
||||
*/
|
||||
NSRange _dragTargetSelectionRange;
|
||||
/*
|
||||
TODO:
|
||||
Still need to figure out what "proper behavior" is when moving between two
|
||||
|
|
|
@ -3050,8 +3050,15 @@ Figure out how the additional layout stuff is supposed to work.
|
|||
{
|
||||
if (!_layoutManager)
|
||||
return NO;
|
||||
return (_layoutManager->_selected_range.length == 0) && _tf.is_editable
|
||||
&& [_window isKeyWindow] && ([_window firstResponder] == self);
|
||||
if (_layoutManager->_selected_range.length != 0)
|
||||
return NO;
|
||||
if (_tf.is_editable == NO)
|
||||
return NO;
|
||||
if (_tf.isDragTarget == YES)
|
||||
return YES;
|
||||
if ([_window isKeyWindow] == YES && [_window firstResponder] == self)
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3889,7 +3896,7 @@ right.)
|
|||
{
|
||||
// get default types, what are they?
|
||||
NSMutableArray *ret = [NSMutableArray arrayWithObjects: NSRulerPboardType,
|
||||
NSColorPboardType, NSFontPboardType, nil];
|
||||
NSColorPboardType, NSFontPboardType, nil];
|
||||
|
||||
if (_tf.imports_graphics)
|
||||
{
|
||||
|
@ -3898,8 +3905,9 @@ right.)
|
|||
[ret addObject: NSFileContentsPboardType];
|
||||
}
|
||||
if (_tf.is_rich_text)
|
||||
[ret addObject: NSRTFPboardType];
|
||||
|
||||
{
|
||||
[ret addObject: NSRTFPboardType];
|
||||
}
|
||||
[ret addObject: NSStringPboardType];
|
||||
|
||||
return ret;
|
||||
|
@ -4044,26 +4052,80 @@ other than copy/paste or dragging. */
|
|||
// dragging of text, colors and files
|
||||
- (unsigned int) draggingEntered: (id <NSDraggingInfo>)sender
|
||||
{
|
||||
NSPasteboard *pboard = [sender draggingPasteboard];
|
||||
NSString *type = [self preferredPasteboardTypeFromArray: [pboard types]
|
||||
restrictedToTypesFromArray: [self readablePasteboardTypes]];
|
||||
NSPasteboard *pboard = [sender draggingPasteboard];
|
||||
NSArray *types = [self readablePasteboardTypes];
|
||||
NSString *type = [self preferredPasteboardTypeFromArray: [pboard types]
|
||||
restrictedToTypesFromArray: types];
|
||||
unsigned int flags = [self dragOperationForDraggingInfo: sender type: type];
|
||||
|
||||
return [self dragOperationForDraggingInfo: sender
|
||||
type: type];
|
||||
if (flags != NSDragOperationNone)
|
||||
{
|
||||
NSPoint dragPoint;
|
||||
unsigned dragIndex;
|
||||
NSRange dragRange;
|
||||
NSRange range;
|
||||
|
||||
if (_tf.isDragTarget == NO)
|
||||
{
|
||||
_tf.isDragTarget = YES;
|
||||
_dragTargetSelectionRange = [self selectedRange];
|
||||
}
|
||||
|
||||
dragPoint = [sender draggingLocation];
|
||||
dragPoint = [self convertPoint: dragPoint fromView: nil];
|
||||
dragIndex = [self characterIndexForPoint: dragPoint];
|
||||
dragRange = NSMakeRange (dragIndex, 0);
|
||||
|
||||
range = [self selectionRangeForProposedRange: dragRange
|
||||
granularity: NSSelectByCharacter];
|
||||
[self setSelectedRange: range];
|
||||
[self displayIfNeeded];
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
- (unsigned int) draggingUpdated: (id <NSDraggingInfo>)sender
|
||||
{
|
||||
NSPasteboard *pboard = [sender draggingPasteboard];
|
||||
NSString *type = [self preferredPasteboardTypeFromArray: [pboard types]
|
||||
restrictedToTypesFromArray: [self readablePasteboardTypes]];
|
||||
NSPasteboard *pboard = [sender draggingPasteboard];
|
||||
NSArray *types = [self readablePasteboardTypes];
|
||||
NSString *type = [self preferredPasteboardTypeFromArray: [pboard types]
|
||||
restrictedToTypesFromArray: types];
|
||||
unsigned int flags = [self dragOperationForDraggingInfo: sender type: type];
|
||||
|
||||
return [self dragOperationForDraggingInfo: sender
|
||||
type: type];
|
||||
if (flags != NSDragOperationNone)
|
||||
{
|
||||
NSPoint dragPoint;
|
||||
unsigned dragIndex;
|
||||
NSRange dragRange;
|
||||
NSRange range;
|
||||
|
||||
if (_tf.isDragTarget == NO)
|
||||
{
|
||||
_tf.isDragTarget = YES;
|
||||
_dragTargetSelectionRange = [self selectedRange];
|
||||
}
|
||||
|
||||
dragPoint = [sender draggingLocation];
|
||||
dragPoint = [self convertPoint: dragPoint fromView: nil];
|
||||
dragIndex = [self characterIndexForPoint: dragPoint];
|
||||
dragRange = NSMakeRange (dragIndex, 0);
|
||||
|
||||
range = [self selectionRangeForProposedRange: dragRange
|
||||
granularity: NSSelectByCharacter];
|
||||
[self setSelectedRange: range];
|
||||
[self displayIfNeeded];
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
- (void) draggingExited: (id <NSDraggingInfo>)sender
|
||||
{
|
||||
if (_tf.isDragTarget == YES)
|
||||
{
|
||||
_tf.isDragTarget = NO;
|
||||
[self setSelectedRange: _dragTargetSelectionRange];
|
||||
[self displayIfNeeded];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) prepareForDragOperation: (id <NSDraggingInfo>)sender
|
||||
|
@ -4073,11 +4135,13 @@ other than copy/paste or dragging. */
|
|||
|
||||
- (BOOL) performDragOperation: (id <NSDraggingInfo>)sender
|
||||
{
|
||||
_tf.isDragTarget = NO;
|
||||
return [self readSelectionFromPasteboard: [sender draggingPasteboard]];
|
||||
}
|
||||
|
||||
- (void) concludeDragOperation: (id <NSDraggingInfo>)sender
|
||||
{
|
||||
_tf.isDragTarget = NO;
|
||||
}
|
||||
|
||||
- (void) cleanUpAfterDragOperation
|
||||
|
@ -4166,11 +4230,13 @@ other than copy/paste or dragging. */
|
|||
granularity = _layoutManager->_selectionGranularity;
|
||||
/* Compute the new selection */
|
||||
proposedRange = NSMakeRange (startIndex, 0);
|
||||
proposedRange = NSUnionRange (_layoutManager->_selected_range, proposedRange);
|
||||
proposedRange = NSUnionRange (_layoutManager->_selected_range,
|
||||
proposedRange);
|
||||
proposedRange = [self selectionRangeForProposedRange: proposedRange
|
||||
granularity: granularity];
|
||||
granularity: granularity];
|
||||
/* Merge it with the old one */
|
||||
proposedRange = NSUnionRange (_layoutManager->_selected_range, proposedRange);
|
||||
proposedRange = NSUnionRange (_layoutManager->_selected_range,
|
||||
proposedRange);
|
||||
/* Now decide what happens if the user shift-drags. The range
|
||||
will be based in startIndex, so we need to adjust it. */
|
||||
if (startIndex <= _layoutManager->_selected_range.location)
|
||||
|
@ -4309,9 +4375,9 @@ other than copy/paste or dragging. */
|
|||
while (currentEvent && [currentEvent type] != NSLeftMouseUp)
|
||||
{
|
||||
if ([currentEvent type] == NSPeriodic)
|
||||
{
|
||||
gotPeriodic = YES;
|
||||
}
|
||||
{
|
||||
gotPeriodic = YES;
|
||||
}
|
||||
else
|
||||
lastEvent = currentEvent;
|
||||
currentEvent = [_window nextEventMatchingMask: mask
|
||||
|
|
Loading…
Reference in a new issue