mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 07:00:46 +00:00
Rewrite implementation of drag and drop on a NSTextView so that the
target view is scrolled even when it does not accept the drag operation. This is useful, e.g., when a subclass considers parts of the text read only and does not accept a drop in those regions. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@31796 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
07e61a136c
commit
41923d49c8
2 changed files with 84 additions and 90 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2010-12-29 Wolfgang Lux <wolfgang.lux@gmail.com>
|
||||
|
||||
* Source/NSTextView.m (-_updateDragTargetLocation:operation:,
|
||||
-draggingEntered:, -draggingUpdated:, -draggingExited:,
|
||||
-prepareForDragOperation:):
|
||||
Rewrite implementation so that the target view is scrolled even
|
||||
when it does not accept the drag operation. This is useful, e.g.,
|
||||
when a subclass considers parts of the text read only and does not
|
||||
accept a drop in those regions.
|
||||
|
||||
2010-12-29 Wolfgang Lux <wolfgang.lux@gmail.com>
|
||||
|
||||
* configure.ac:
|
||||
|
|
|
@ -4913,12 +4913,11 @@ other than copy/paste or dragging. */
|
|||
/**** Drag and drop handling ****/
|
||||
|
||||
/*
|
||||
* TODO: Dragging should use a transient insertion point distinct from the
|
||||
* text view's current selection. This allows subclasses of NSTextView to
|
||||
* determine the origin of the dragged selection during a drag operation and
|
||||
* provides better visual feedback for users, since the origin of the dragged
|
||||
* selection remains visible. Note that -rangeForUserTextChange will have to
|
||||
* be changed to take this transient insertion point into account.
|
||||
* Note: Dragging uses a transient insertion point distinct from the text
|
||||
* view's current selection. This allows subclasses of NSTextView to determine
|
||||
* the origin of the dragged selection during a drag operation and provides
|
||||
* better visual feedback for users, since the origin of the dragged selection
|
||||
* remains visible.
|
||||
*/
|
||||
|
||||
// dragging of text, colors and files
|
||||
|
@ -4927,16 +4926,35 @@ other than copy/paste or dragging. */
|
|||
return (NSDragOperationGeneric | NSDragOperationCopy);
|
||||
}
|
||||
|
||||
- (void)_draggingHijackInsertionPoint: (unsigned int)dragIndex
|
||||
- (void) _updateDragTargetLocation: (id <NSDraggingInfo>)sender
|
||||
operation: (unsigned int *)flags
|
||||
{
|
||||
_dragTargetLocation = dragIndex;
|
||||
[self updateInsertionPointStateAndRestartTimer: NO];
|
||||
[self displayIfNeeded];
|
||||
}
|
||||
if (*flags != NSDragOperationNone)
|
||||
{
|
||||
NSPoint dragPoint;
|
||||
unsigned dragIndex;
|
||||
|
||||
- (void)_draggingReleaseInsertionPoint
|
||||
{
|
||||
_dragTargetLocation = NSNotFound;
|
||||
dragPoint = [sender draggingLocation];
|
||||
dragPoint = [self convertPoint: dragPoint fromView: nil];
|
||||
dragIndex = [self _characterIndexForPoint: dragPoint
|
||||
respectFraction: YES];
|
||||
|
||||
if ([sender draggingSource] != self ||
|
||||
dragIndex <= [self selectedRange].location ||
|
||||
dragIndex >= NSMaxRange([self selectedRange]))
|
||||
{
|
||||
_dragTargetLocation = dragIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
_dragTargetLocation = NSNotFound;
|
||||
*flags = NSDragOperationNone;
|
||||
}
|
||||
}
|
||||
else if (_dragTargetLocation != NSNotFound)
|
||||
{
|
||||
_dragTargetLocation = NSNotFound;
|
||||
}
|
||||
[self updateInsertionPointStateAndRestartTimer: NO];
|
||||
[self displayIfNeeded];
|
||||
}
|
||||
|
@ -4949,29 +4967,10 @@ other than copy/paste or dragging. */
|
|||
restrictedToTypesFromArray: types];
|
||||
unsigned int flags = [self dragOperationForDraggingInfo: sender type: type];
|
||||
|
||||
if (flags != NSDragOperationNone
|
||||
&& ![type isEqual:NSColorPboardType])
|
||||
if (![type isEqual: NSColorPboardType])
|
||||
{
|
||||
NSPoint dragPoint;
|
||||
unsigned dragIndex;
|
||||
|
||||
dragPoint = [sender draggingLocation];
|
||||
dragPoint = [self convertPoint: dragPoint fromView: nil];
|
||||
dragIndex = [self _characterIndexForPoint: dragPoint
|
||||
respectFraction: YES];
|
||||
|
||||
if ([sender draggingSource] != self ||
|
||||
dragIndex <= [self selectedRange].location ||
|
||||
dragIndex >= NSMaxRange([self selectedRange]))
|
||||
[self _draggingHijackInsertionPoint: dragIndex];
|
||||
else
|
||||
{
|
||||
[self _draggingReleaseInsertionPoint];
|
||||
flags = NSDragOperationNone;
|
||||
}
|
||||
[self _updateDragTargetLocation: sender operation: &flags];
|
||||
}
|
||||
else if (_dragTargetLocation != NSNotFound)
|
||||
[self _draggingReleaseInsertionPoint];
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
@ -4983,74 +4982,59 @@ other than copy/paste or dragging. */
|
|||
restrictedToTypesFromArray: types];
|
||||
unsigned int flags = [self dragOperationForDraggingInfo: sender type: type];
|
||||
|
||||
if (flags != NSDragOperationNone && ![type isEqual: NSColorPboardType])
|
||||
{
|
||||
NSPoint dragPoint;
|
||||
unsigned dragIndex;
|
||||
NSRect vRect;
|
||||
NSPoint dragPoint;
|
||||
NSRect vRect;
|
||||
|
||||
dragPoint = [sender draggingLocation];
|
||||
dragPoint = [self convertPoint: dragPoint fromView: nil];
|
||||
dragIndex = [self _characterIndexForPoint: dragPoint
|
||||
respectFraction: YES];
|
||||
dragPoint = [sender draggingLocation];
|
||||
dragPoint = [self convertPoint: dragPoint fromView: nil];
|
||||
|
||||
/* Note: Keep DRAGGING_SCROLL_BORDER in sync with a similar value used
|
||||
* in -draggingUpdated: of NSOutlineView and NSTableView.
|
||||
* FIXME: Is the value of DRAGGING_SCROLL_DIST reasonable?
|
||||
*/
|
||||
/* Note: Keep DRAGGING_SCROLL_BORDER in sync with a similar value used
|
||||
* in -draggingUpdated: of NSOutlineView and NSTableView.
|
||||
* FIXME: Is the value of DRAGGING_SCROLL_DIST reasonable?
|
||||
*/
|
||||
#define DRAGGING_SCROLL_BORDER 3
|
||||
#define DRAGGING_SCROLL_DIST 10
|
||||
vRect = [self visibleRect];
|
||||
if (dragPoint.x <= NSMinX(vRect) + DRAGGING_SCROLL_BORDER)
|
||||
{
|
||||
vRect.origin.x -= DRAGGING_SCROLL_DIST;
|
||||
if (NSMinX(vRect) < NSMinX(_bounds))
|
||||
vRect.origin.x = NSMinX(_bounds);
|
||||
}
|
||||
else if (dragPoint.x >= NSMaxX(vRect) - DRAGGING_SCROLL_BORDER)
|
||||
{
|
||||
vRect.origin.x += DRAGGING_SCROLL_DIST;
|
||||
if (NSMaxX(vRect) > NSMaxX(_bounds))
|
||||
vRect.origin.x = NSMaxX(_bounds) - NSWidth(vRect);
|
||||
}
|
||||
vRect = [self visibleRect];
|
||||
if (dragPoint.x <= NSMinX(vRect) + DRAGGING_SCROLL_BORDER)
|
||||
{
|
||||
vRect.origin.x -= DRAGGING_SCROLL_DIST;
|
||||
if (NSMinX(vRect) < NSMinX(_bounds))
|
||||
vRect.origin.x = NSMinX(_bounds);
|
||||
}
|
||||
else if (dragPoint.x >= NSMaxX(vRect) - DRAGGING_SCROLL_BORDER)
|
||||
{
|
||||
vRect.origin.x += DRAGGING_SCROLL_DIST;
|
||||
if (NSMaxX(vRect) > NSMaxX(_bounds))
|
||||
vRect.origin.x = NSMaxX(_bounds) - NSWidth(vRect);
|
||||
}
|
||||
|
||||
if (dragPoint.y <= NSMinY(vRect) + DRAGGING_SCROLL_BORDER)
|
||||
{
|
||||
vRect.origin.y -= DRAGGING_SCROLL_DIST;
|
||||
if (NSMinY(vRect) < NSMinY(_bounds))
|
||||
vRect.origin.y = NSMinY(_bounds);
|
||||
}
|
||||
else if (dragPoint.y >= NSMaxY(vRect) - DRAGGING_SCROLL_BORDER)
|
||||
{
|
||||
vRect.origin.y += DRAGGING_SCROLL_DIST;
|
||||
if (NSMaxY(vRect) > NSMaxY(_bounds))
|
||||
vRect.origin.y = NSMaxY(_bounds) - NSHeight(vRect);
|
||||
}
|
||||
[self scrollPoint: vRect.origin];
|
||||
if (dragPoint.y <= NSMinY(vRect) + DRAGGING_SCROLL_BORDER)
|
||||
{
|
||||
vRect.origin.y -= DRAGGING_SCROLL_DIST;
|
||||
if (NSMinY(vRect) < NSMinY(_bounds))
|
||||
vRect.origin.y = NSMinY(_bounds);
|
||||
}
|
||||
else if (dragPoint.y >= NSMaxY(vRect) - DRAGGING_SCROLL_BORDER)
|
||||
{
|
||||
vRect.origin.y += DRAGGING_SCROLL_DIST;
|
||||
if (NSMaxY(vRect) > NSMaxY(_bounds))
|
||||
vRect.origin.y = NSMaxY(_bounds) - NSHeight(vRect);
|
||||
}
|
||||
[self scrollPoint: vRect.origin];
|
||||
#undef DRAGGING_SCROLL_BORDER
|
||||
#undef DRAGGING_SCROLL_DIST
|
||||
|
||||
if ([sender draggingSource] != self ||
|
||||
dragIndex <= [self selectedRange].location ||
|
||||
dragIndex >= NSMaxRange([self selectedRange]))
|
||||
[self _draggingHijackInsertionPoint: dragIndex];
|
||||
else
|
||||
{
|
||||
[self _draggingReleaseInsertionPoint];
|
||||
flags = NSDragOperationNone;
|
||||
}
|
||||
if (![type isEqual: NSColorPboardType])
|
||||
{
|
||||
[self _updateDragTargetLocation: sender operation: &flags];
|
||||
}
|
||||
else if (_dragTargetLocation != NSNotFound)
|
||||
[self _draggingReleaseInsertionPoint];
|
||||
return flags;
|
||||
}
|
||||
|
||||
- (void) draggingExited: (id <NSDraggingInfo>)sender
|
||||
{
|
||||
if (_dragTargetLocation != NSNotFound)
|
||||
{
|
||||
[self _draggingReleaseInsertionPoint];
|
||||
}
|
||||
unsigned int flags = NSDragOperationNone;
|
||||
[self _updateDragTargetLocation: sender operation: &flags];
|
||||
}
|
||||
|
||||
- (BOOL) prepareForDragOperation: (id <NSDraggingInfo>)sender
|
||||
|
@ -5073,7 +5057,7 @@ other than copy/paste or dragging. */
|
|||
if (_dragTargetLocation != NSNotFound)
|
||||
{
|
||||
changeRange = NSMakeRange(_dragTargetLocation, 0);
|
||||
[self _draggingReleaseInsertionPoint];
|
||||
_dragTargetLocation = NSNotFound;
|
||||
[self setSelectedRange: changeRange];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue