mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-31 20:40:47 +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
23553a5404
commit
c91aef6c08
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>
|
2010-12-29 Wolfgang Lux <wolfgang.lux@gmail.com>
|
||||||
|
|
||||||
* configure.ac:
|
* configure.ac:
|
||||||
|
|
|
@ -4913,12 +4913,11 @@ other than copy/paste or dragging. */
|
||||||
/**** Drag and drop handling ****/
|
/**** Drag and drop handling ****/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: Dragging should use a transient insertion point distinct from the
|
* Note: Dragging uses a transient insertion point distinct from the text
|
||||||
* text view's current selection. This allows subclasses of NSTextView to
|
* view's current selection. This allows subclasses of NSTextView to determine
|
||||||
* determine the origin of the dragged selection during a drag operation and
|
* the origin of the dragged selection during a drag operation and provides
|
||||||
* provides better visual feedback for users, since the origin of the dragged
|
* better visual feedback for users, since the origin of the dragged selection
|
||||||
* selection remains visible. Note that -rangeForUserTextChange will have to
|
* remains visible.
|
||||||
* be changed to take this transient insertion point into account.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// dragging of text, colors and files
|
// dragging of text, colors and files
|
||||||
|
@ -4927,16 +4926,35 @@ other than copy/paste or dragging. */
|
||||||
return (NSDragOperationGeneric | NSDragOperationCopy);
|
return (NSDragOperationGeneric | NSDragOperationCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_draggingHijackInsertionPoint: (unsigned int)dragIndex
|
- (void) _updateDragTargetLocation: (id <NSDraggingInfo>)sender
|
||||||
|
operation: (unsigned int *)flags
|
||||||
{
|
{
|
||||||
_dragTargetLocation = dragIndex;
|
if (*flags != NSDragOperationNone)
|
||||||
[self updateInsertionPointStateAndRestartTimer: NO];
|
{
|
||||||
[self displayIfNeeded];
|
NSPoint dragPoint;
|
||||||
}
|
unsigned dragIndex;
|
||||||
|
|
||||||
- (void)_draggingReleaseInsertionPoint
|
dragPoint = [sender draggingLocation];
|
||||||
{
|
dragPoint = [self convertPoint: dragPoint fromView: nil];
|
||||||
_dragTargetLocation = NSNotFound;
|
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 updateInsertionPointStateAndRestartTimer: NO];
|
||||||
[self displayIfNeeded];
|
[self displayIfNeeded];
|
||||||
}
|
}
|
||||||
|
@ -4949,29 +4967,10 @@ other than copy/paste or dragging. */
|
||||||
restrictedToTypesFromArray: types];
|
restrictedToTypesFromArray: types];
|
||||||
unsigned int flags = [self dragOperationForDraggingInfo: sender type: type];
|
unsigned int flags = [self dragOperationForDraggingInfo: sender type: type];
|
||||||
|
|
||||||
if (flags != NSDragOperationNone
|
if (![type isEqual: NSColorPboardType])
|
||||||
&& ![type isEqual:NSColorPboardType])
|
|
||||||
{
|
{
|
||||||
NSPoint dragPoint;
|
[self _updateDragTargetLocation: sender operation: &flags];
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (_dragTargetLocation != NSNotFound)
|
|
||||||
[self _draggingReleaseInsertionPoint];
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4983,74 +4982,59 @@ other than copy/paste or dragging. */
|
||||||
restrictedToTypesFromArray: types];
|
restrictedToTypesFromArray: types];
|
||||||
unsigned int flags = [self dragOperationForDraggingInfo: sender type: type];
|
unsigned int flags = [self dragOperationForDraggingInfo: sender type: type];
|
||||||
|
|
||||||
if (flags != NSDragOperationNone && ![type isEqual: NSColorPboardType])
|
NSPoint dragPoint;
|
||||||
{
|
NSRect vRect;
|
||||||
NSPoint dragPoint;
|
|
||||||
unsigned dragIndex;
|
|
||||||
NSRect vRect;
|
|
||||||
|
|
||||||
dragPoint = [sender draggingLocation];
|
dragPoint = [sender draggingLocation];
|
||||||
dragPoint = [self convertPoint: dragPoint fromView: nil];
|
dragPoint = [self convertPoint: dragPoint fromView: nil];
|
||||||
dragIndex = [self _characterIndexForPoint: dragPoint
|
|
||||||
respectFraction: YES];
|
|
||||||
|
|
||||||
/* Note: Keep DRAGGING_SCROLL_BORDER in sync with a similar value used
|
/* Note: Keep DRAGGING_SCROLL_BORDER in sync with a similar value used
|
||||||
* in -draggingUpdated: of NSOutlineView and NSTableView.
|
* in -draggingUpdated: of NSOutlineView and NSTableView.
|
||||||
* FIXME: Is the value of DRAGGING_SCROLL_DIST reasonable?
|
* FIXME: Is the value of DRAGGING_SCROLL_DIST reasonable?
|
||||||
*/
|
*/
|
||||||
#define DRAGGING_SCROLL_BORDER 3
|
#define DRAGGING_SCROLL_BORDER 3
|
||||||
#define DRAGGING_SCROLL_DIST 10
|
#define DRAGGING_SCROLL_DIST 10
|
||||||
vRect = [self visibleRect];
|
vRect = [self visibleRect];
|
||||||
if (dragPoint.x <= NSMinX(vRect) + DRAGGING_SCROLL_BORDER)
|
if (dragPoint.x <= NSMinX(vRect) + DRAGGING_SCROLL_BORDER)
|
||||||
{
|
{
|
||||||
vRect.origin.x -= DRAGGING_SCROLL_DIST;
|
vRect.origin.x -= DRAGGING_SCROLL_DIST;
|
||||||
if (NSMinX(vRect) < NSMinX(_bounds))
|
if (NSMinX(vRect) < NSMinX(_bounds))
|
||||||
vRect.origin.x = NSMinX(_bounds);
|
vRect.origin.x = NSMinX(_bounds);
|
||||||
}
|
}
|
||||||
else if (dragPoint.x >= NSMaxX(vRect) - DRAGGING_SCROLL_BORDER)
|
else if (dragPoint.x >= NSMaxX(vRect) - DRAGGING_SCROLL_BORDER)
|
||||||
{
|
{
|
||||||
vRect.origin.x += DRAGGING_SCROLL_DIST;
|
vRect.origin.x += DRAGGING_SCROLL_DIST;
|
||||||
if (NSMaxX(vRect) > NSMaxX(_bounds))
|
if (NSMaxX(vRect) > NSMaxX(_bounds))
|
||||||
vRect.origin.x = NSMaxX(_bounds) - NSWidth(vRect);
|
vRect.origin.x = NSMaxX(_bounds) - NSWidth(vRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dragPoint.y <= NSMinY(vRect) + DRAGGING_SCROLL_BORDER)
|
if (dragPoint.y <= NSMinY(vRect) + DRAGGING_SCROLL_BORDER)
|
||||||
{
|
{
|
||||||
vRect.origin.y -= DRAGGING_SCROLL_DIST;
|
vRect.origin.y -= DRAGGING_SCROLL_DIST;
|
||||||
if (NSMinY(vRect) < NSMinY(_bounds))
|
if (NSMinY(vRect) < NSMinY(_bounds))
|
||||||
vRect.origin.y = NSMinY(_bounds);
|
vRect.origin.y = NSMinY(_bounds);
|
||||||
}
|
}
|
||||||
else if (dragPoint.y >= NSMaxY(vRect) - DRAGGING_SCROLL_BORDER)
|
else if (dragPoint.y >= NSMaxY(vRect) - DRAGGING_SCROLL_BORDER)
|
||||||
{
|
{
|
||||||
vRect.origin.y += DRAGGING_SCROLL_DIST;
|
vRect.origin.y += DRAGGING_SCROLL_DIST;
|
||||||
if (NSMaxY(vRect) > NSMaxY(_bounds))
|
if (NSMaxY(vRect) > NSMaxY(_bounds))
|
||||||
vRect.origin.y = NSMaxY(_bounds) - NSHeight(vRect);
|
vRect.origin.y = NSMaxY(_bounds) - NSHeight(vRect);
|
||||||
}
|
}
|
||||||
[self scrollPoint: vRect.origin];
|
[self scrollPoint: vRect.origin];
|
||||||
#undef DRAGGING_SCROLL_BORDER
|
#undef DRAGGING_SCROLL_BORDER
|
||||||
#undef DRAGGING_SCROLL_DIST
|
#undef DRAGGING_SCROLL_DIST
|
||||||
|
|
||||||
if ([sender draggingSource] != self ||
|
if (![type isEqual: NSColorPboardType])
|
||||||
dragIndex <= [self selectedRange].location ||
|
{
|
||||||
dragIndex >= NSMaxRange([self selectedRange]))
|
[self _updateDragTargetLocation: sender operation: &flags];
|
||||||
[self _draggingHijackInsertionPoint: dragIndex];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
[self _draggingReleaseInsertionPoint];
|
|
||||||
flags = NSDragOperationNone;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (_dragTargetLocation != NSNotFound)
|
|
||||||
[self _draggingReleaseInsertionPoint];
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) draggingExited: (id <NSDraggingInfo>)sender
|
- (void) draggingExited: (id <NSDraggingInfo>)sender
|
||||||
{
|
{
|
||||||
if (_dragTargetLocation != NSNotFound)
|
unsigned int flags = NSDragOperationNone;
|
||||||
{
|
[self _updateDragTargetLocation: sender operation: &flags];
|
||||||
[self _draggingReleaseInsertionPoint];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) prepareForDragOperation: (id <NSDraggingInfo>)sender
|
- (BOOL) prepareForDragOperation: (id <NSDraggingInfo>)sender
|
||||||
|
@ -5073,7 +5057,7 @@ other than copy/paste or dragging. */
|
||||||
if (_dragTargetLocation != NSNotFound)
|
if (_dragTargetLocation != NSNotFound)
|
||||||
{
|
{
|
||||||
changeRange = NSMakeRange(_dragTargetLocation, 0);
|
changeRange = NSMakeRange(_dragTargetLocation, 0);
|
||||||
[self _draggingReleaseInsertionPoint];
|
_dragTargetLocation = NSNotFound;
|
||||||
[self setSelectedRange: changeRange];
|
[self setSelectedRange: changeRange];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue