* Source/NSLayoutManager.m

(-characterIndexMoving:fromCharacterIndex:originalCharacterIndex:distance:):
Rework this method to suport moving the insertion point between text
containers, for both left/right and up/down movements. However, it will
only have this behaviour when distance == 0.

This is part of what is needed to support moving the insertion point
between text views in, e.g., TextEdit when using the multi-page view.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@32964 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
ericwa 2011-05-01 22:06:45 +00:00
parent 13d635f673
commit 32bab79ad4
2 changed files with 78 additions and 17 deletions

View file

@ -1,3 +1,14 @@
2011-05-01 Eric Wasylishen <ewasylishen@gmail.com>
* Source/NSLayoutManager.m
(-characterIndexMoving:fromCharacterIndex:originalCharacterIndex:distance:):
Rework this method to suport moving the insertion point between text
containers, for both left/right and up/down movements. However, it will
only have this behaviour when distance == 0.
This is part of what is needed to support moving the insertion point
between text views in, e.g., TextEdit when using the multi-page view.
2011-04-30 Eric Wasylishen <ewasylishen@gmail.com> 2011-04-30 Eric Wasylishen <ewasylishen@gmail.com>
* Source/NSView.m (-updateBoundsMatrix): * Source/NSView.m (-updateBoundsMatrix):

View file

@ -963,7 +963,6 @@ has the same y origin and height as the line frag rect it is in.
{ {
NSRect from_rect, new_rect; NSRect from_rect, new_rect;
int from_tc, new_tc; int from_tc, new_tc;
int i;
unsigned int new; unsigned int new;
unsigned int length = [_textStorage length]; unsigned int length = [_textStorage length];
@ -973,33 +972,84 @@ has the same y origin and height as the line frag rect it is in.
textContainer: &from_tc]; textContainer: &from_tc];
if (from_tc == -1) if (from_tc == -1)
{ {
NSLog(@"%s: character index not in any text container", /* The from character index is not in a text container, so move the
__PRETTY_FUNCTION__); cursor to the start of the text. */
return from; return 0;
} }
if (direction == GSInsertionPointMoveLeft || /* Simple case which moves one character left/right or one line up/down,
direction == GSInsertionPointMoveRight) but supports moving between text containers. */
if (distance == 0.0)
{ {
float target; if (direction == GSInsertionPointMoveLeft ||
direction == GSInsertionPointMoveRight)
if (distance == 0.0)
{ {
new = from; new = from;
if (direction == GSInsertionPointMoveLeft && new > 0) if (direction == GSInsertionPointMoveLeft && new > 0)
new--; new--;
if (direction == GSInsertionPointMoveRight && new < length) if (direction == GSInsertionPointMoveRight && new < length)
new++; new++;
[self _insertionPointRectForCharacterIndex: new
textContainer: &i];
/* Don't leave the text container. */
if (i == from_tc)
return new; return new;
else
return from;
} }
else if (direction == GSInsertionPointMoveUp ||
direction == GSInsertionPointMoveDown)
{
int orig_tc;
const float target = [self _insertionPointRectForCharacterIndex: original
textContainer: &orig_tc].origin.x;
const int delta = (direction == GSInsertionPointMoveUp) ? -1 : 1;
/* First scan forward or backwards until we end up on a new line */
for (new = from; (direction == GSInsertionPointMoveUp) ? (new >= 0) : (new <= length); new += delta)
{
new_rect = [self _insertionPointRectForCharacterIndex: new
textContainer: &new_tc];
if (new_rect.origin.y != from_rect.origin.y || new_tc != from_tc)
break;
}
/* We found the start of the line, now find the target character on that line. */
new_rect = [self _insertionPointRectForCharacterIndex: new
textContainer: &new_tc];
while ((direction == GSInsertionPointMoveUp) ? (new > 0) : (new < length))
{
int prev_tc = new_tc;
NSRect prev_rect = new_rect;
new_rect = [self _insertionPointRectForCharacterIndex: new + delta
textContainer: &new_tc];
/* 'new+delta' is on a different line than the target line, so the
target character must be 'new'.*/
if (new_rect.origin.y != prev_rect.origin.y || new_tc != prev_tc)
return new;
/* If we pass the target point, the character we want is either
'new' or 'new+delta' */
if ((direction == GSInsertionPointMoveDown && NSMinX(new_rect) >= target)
|| (direction == GSInsertionPointMoveUp && NSMinX(new_rect) <= target))
{
if (fabs(NSMinX(new_rect) - target) > fabs(NSMinX(prev_rect) - target))
return new;
return new + delta;
}
new += delta;
}
return new;
}
}
/* The following more complex cases are for when a minimum distance is specified.
However, they will not move out of from's text container.
*/
if (direction == GSInsertionPointMoveLeft ||
direction == GSInsertionPointMoveRight)
{
float target;
/* /*
This is probably very inefficient, but it shouldn't be a bottleneck, This is probably very inefficient, but it shouldn't be a bottleneck,