mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-06-01 21:31:56 +00:00
* Source/NSText.m ([NSText -initWithCoder:]):
Retain the decoded background color. * Source/NSTextView.m : multiple location: don't ignore textContainer's inset ([NSTextView -initWithCoder:]) ([NSTextView -encodeWithCoder:]) Encode caret color, textContainer's size and whether the textContainer has widthTracksTextView or heightTracksTextView set. ([NSTextView -sizeToFit]) Change width (height) only if is_horizontally_resizable (is_vertically_resizable). ([NSTextView -scrollRangeToVisible:]) scrolls to the first char of the range. ([NSTextView -invalidateTextContainerOrigin]): Don't ignore inset, set the origin so that the justification is preserved even if the textContainer's width is larger that the textview's width. ([NSTextView -updateInsertionPointStateAndRestartTimer:]): update and place the insertion point properly. ([NSTextView -moveDown:]) & ([NSTextView -moveUp:]): Don't ignore inset. Make insertion point visible. * Source/NSTextField.m ([NSTextField -acceptsFirstResponder:]): responds NO if the editing is still in progrss. * Source/NSLayoutManager.m ([NSLayoutManager -drawBackgroundForGlyphRange:atPoint:]): Don't ignore textContainer's inset. * Source/GSSimpleLayoutManager.m Replaced [-drawLinesInLineRange:] with [-drawLinesInLineRange:atPoint:]. Replaced [-drawSelectionAsRangeNoCaret:] with [-drawSelectionAsRangeNoCaret:atPoint:]. Those replacements make it easier to take inset into account. ([-lineFragmentUsedRectForGlyphAtIndex:effectiveRange:]) ([-locationForGlyphAtIndex:]) ([-boundingRectForGlyphRange:inTextContainer:]) ([-rectForCharacterIndex:]) ([-setNeedsDisplayForLineRange:inTextContainer:]): Various fixes. ([-textStorage:edited:range:changeInLength:invalidatedRange:]) Update insertion point if needed (useful when alignment changes). ([-rebuildForRange:delta:inTextContainer:]): Update layout mechanism. * Source/NSCell.m ([NSCell -highlight:withFrame:inView:]): Ask the control to draw the background if we are not opaque. ([NSCell -editWithFrame:inView:editor:delegate:event:]): ([NSCell -selectWithFrame:inView:editor:delegate:start:length:]): ([NSCell -endEditing:]): instantiate (and remove) the textview so that it can be scrolled. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@14429 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
80075ebc40
commit
9ae9ab48a3
7 changed files with 672 additions and 106 deletions
54
ChangeLog
54
ChangeLog
|
@ -1,3 +1,57 @@
|
||||||
|
2002-09-11 Pierre-Yves Rivaille <pyrivail@ens-lyon.fr>
|
||||||
|
|
||||||
|
* Source/NSText.m ([NSText -initWithCoder:]):
|
||||||
|
Retain the decoded background color.
|
||||||
|
|
||||||
|
* Source/NSTextView.m :
|
||||||
|
multiple location: don't ignore textContainer's inset
|
||||||
|
([NSTextView -initWithCoder:])
|
||||||
|
([NSTextView -encodeWithCoder:])
|
||||||
|
Encode caret color, textContainer's size and whether the
|
||||||
|
textContainer has widthTracksTextView or heightTracksTextView set.
|
||||||
|
([NSTextView -sizeToFit]) Change width (height) only if
|
||||||
|
is_horizontally_resizable (is_vertically_resizable).
|
||||||
|
([NSTextView -scrollRangeToVisible:]) scrolls to the first char of
|
||||||
|
the range.
|
||||||
|
([NSTextView -invalidateTextContainerOrigin]): Don't ignore inset,
|
||||||
|
set the origin so that the justification is preserved even if the
|
||||||
|
textContainer's width is larger that the textview's width.
|
||||||
|
([NSTextView -updateInsertionPointStateAndRestartTimer:]):
|
||||||
|
update and place the insertion point properly.
|
||||||
|
([NSTextView -moveDown:]) & ([NSTextView -moveUp:]):
|
||||||
|
Don't ignore inset. Make insertion point visible.
|
||||||
|
|
||||||
|
* Source/NSTextField.m ([NSTextField -acceptsFirstResponder:]):
|
||||||
|
responds NO if the editing is still in progrss.
|
||||||
|
|
||||||
|
* Source/NSLayoutManager.m
|
||||||
|
([NSLayoutManager -drawBackgroundForGlyphRange:atPoint:]):
|
||||||
|
Don't ignore textContainer's inset.
|
||||||
|
|
||||||
|
* Source/GSSimpleLayoutManager.m
|
||||||
|
Replaced [-drawLinesInLineRange:] with [-drawLinesInLineRange:atPoint:].
|
||||||
|
Replaced [-drawSelectionAsRangeNoCaret:] with
|
||||||
|
[-drawSelectionAsRangeNoCaret:atPoint:].
|
||||||
|
Those replacements make it easier to take inset into account.
|
||||||
|
([-lineFragmentUsedRectForGlyphAtIndex:effectiveRange:])
|
||||||
|
([-locationForGlyphAtIndex:])
|
||||||
|
([-boundingRectForGlyphRange:inTextContainer:])
|
||||||
|
([-rectForCharacterIndex:])
|
||||||
|
([-setNeedsDisplayForLineRange:inTextContainer:]):
|
||||||
|
Various fixes.
|
||||||
|
([-textStorage:edited:range:changeInLength:invalidatedRange:])
|
||||||
|
Update insertion point if needed (useful when alignment changes).
|
||||||
|
([-rebuildForRange:delta:inTextContainer:]):
|
||||||
|
Update layout mechanism.
|
||||||
|
|
||||||
|
* Source/NSCell.m
|
||||||
|
([NSCell -highlight:withFrame:inView:]):
|
||||||
|
Ask the control to draw the background if we are not opaque.
|
||||||
|
([NSCell -editWithFrame:inView:editor:delegate:event:]):
|
||||||
|
([NSCell -selectWithFrame:inView:editor:delegate:start:length:]):
|
||||||
|
([NSCell -endEditing:]):
|
||||||
|
instantiate (and remove) the textview so that it can be scrolled.
|
||||||
|
|
||||||
2002-09-09 Adam Fedor <fedor@gnu.org>
|
2002-09-09 Adam Fedor <fedor@gnu.org>
|
||||||
|
|
||||||
* configure.ac: Switch to disaple gsnd.
|
* configure.ac: Switch to disaple gsnd.
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
Date: September 2000
|
Date: September 2000
|
||||||
Extracted from NSText, reorganised to specification
|
Extracted from NSText, reorganised to specification
|
||||||
|
|
||||||
|
Author: Pierre-Yves Rivaille <pyrivail@ens-lyon.fr>
|
||||||
|
Date: September 2002
|
||||||
|
|
||||||
This file is part of the GNUstep GUI Library.
|
This file is part of the GNUstep GUI Library.
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
|
@ -47,6 +50,7 @@
|
||||||
#include <AppKit/NSTextStorage.h>
|
#include <AppKit/NSTextStorage.h>
|
||||||
#include <AppKit/NSTextContainer.h>
|
#include <AppKit/NSTextContainer.h>
|
||||||
#include <AppKit/NSStringDrawing.h>
|
#include <AppKit/NSStringDrawing.h>
|
||||||
|
#include <AppKit/NSParagraphStyle.h>
|
||||||
|
|
||||||
#include "GSSimpleLayoutManager.h"
|
#include "GSSimpleLayoutManager.h"
|
||||||
|
|
||||||
|
@ -309,6 +313,35 @@ static inline float defaultFontHeight ()
|
||||||
return currentInfo->lineFragmentRect;
|
return currentInfo->lineFragmentRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSRect)lineFragmentUsedRectForGlyphAtIndex: (unsigned)index
|
||||||
|
effectiveRange: (NSRange *)lineFragmentRange
|
||||||
|
{
|
||||||
|
_GNULineLayoutInfo *currentInfo;
|
||||||
|
|
||||||
|
if (![_textStorage length] || ![_lineLayoutInformation count])
|
||||||
|
{
|
||||||
|
// we return the line fragment from the virtual newline
|
||||||
|
// that we added at the end of the empty text
|
||||||
|
if (lineFragmentRange)
|
||||||
|
{
|
||||||
|
lineFragmentRange->location=0;
|
||||||
|
lineFragmentRange->length=0;
|
||||||
|
}
|
||||||
|
return ((_GNULineLayoutInfo *)[_lineLayoutInformation lastObject])->usedRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentInfo = [_lineLayoutInformation
|
||||||
|
objectAtIndex: [self lineLayoutIndexForGlyphIndex:
|
||||||
|
index]];
|
||||||
|
|
||||||
|
if (lineFragmentRange)
|
||||||
|
{
|
||||||
|
*lineFragmentRange = currentInfo->glyphRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentInfo->usedRect;
|
||||||
|
}
|
||||||
|
|
||||||
- (NSPoint)locationForGlyphAtIndex:(unsigned)index
|
- (NSPoint)locationForGlyphAtIndex:(unsigned)index
|
||||||
{
|
{
|
||||||
float x;
|
float x;
|
||||||
|
@ -325,7 +358,8 @@ static inline float defaultFontHeight ()
|
||||||
index]];
|
index]];
|
||||||
if (index >= NSMaxRange (currentInfo->glyphRange))
|
if (index >= NSMaxRange (currentInfo->glyphRange))
|
||||||
{
|
{
|
||||||
return NSMakePoint (NSMaxX (currentInfo->usedRect), 0);
|
x = [self _sizeOfRange: currentInfo->glyphRange].width;
|
||||||
|
return NSMakePoint (x, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
start = currentInfo->glyphRange.location;
|
start = currentInfo->glyphRange.location;
|
||||||
|
@ -341,7 +375,9 @@ static inline float defaultFontHeight ()
|
||||||
{
|
{
|
||||||
_GNULineLayoutInfo *currentInfo;
|
_GNULineLayoutInfo *currentInfo;
|
||||||
unsigned i1, i2;
|
unsigned i1, i2;
|
||||||
NSRect rect1;
|
NSRect rect1, rect2;
|
||||||
|
NSSize size;
|
||||||
|
NSRect rect;
|
||||||
|
|
||||||
if (![_textStorage length] || ![_lineLayoutInformation count])
|
if (![_textStorage length] || ![_lineLayoutInformation count])
|
||||||
{
|
{
|
||||||
|
@ -351,22 +387,72 @@ static inline float defaultFontHeight ()
|
||||||
i1 = [self lineLayoutIndexForGlyphIndex: aRange.location];
|
i1 = [self lineLayoutIndexForGlyphIndex: aRange.location];
|
||||||
i2 = [self lineLayoutIndexForGlyphIndex: NSMaxRange(aRange)];
|
i2 = [self lineLayoutIndexForGlyphIndex: NSMaxRange(aRange)];
|
||||||
|
|
||||||
// This is not exacty what we need, but should be correct enough
|
|
||||||
currentInfo = [_lineLayoutInformation objectAtIndex: i1];
|
|
||||||
rect1 = currentInfo->lineFragmentRect;
|
|
||||||
|
|
||||||
if (i1 != i2)
|
if (i1 == i2)
|
||||||
{
|
{
|
||||||
|
// the range is not multiline.
|
||||||
|
|
||||||
|
currentInfo = [_lineLayoutInformation objectAtIndex: i1];
|
||||||
|
rect1 = currentInfo->usedRect;
|
||||||
|
size = [self _sizeOfRange:
|
||||||
|
NSMakeRange
|
||||||
|
(currentInfo->glyphRange.location,
|
||||||
|
aRange.location -
|
||||||
|
currentInfo->glyphRange.location)];
|
||||||
|
rect1.origin.x += size.width;
|
||||||
|
rect1.size.width = [self _sizeOfRange:
|
||||||
|
NSMakeRange
|
||||||
|
(aRange.location -
|
||||||
|
currentInfo->glyphRange.location, 1)].width;
|
||||||
|
// rect1 is the rect for the first glyph in the range
|
||||||
|
|
||||||
currentInfo = [_lineLayoutInformation objectAtIndex: i2];
|
currentInfo = [_lineLayoutInformation objectAtIndex: i2];
|
||||||
rect1 = NSUnionRect(rect1, currentInfo->lineFragmentRect);
|
rect2 = currentInfo->usedRect;
|
||||||
|
size = [self _sizeOfRange:
|
||||||
|
NSMakeRange
|
||||||
|
(currentInfo->glyphRange.location,
|
||||||
|
NSMaxRange(aRange) -
|
||||||
|
currentInfo->glyphRange.location)];
|
||||||
|
rect2.origin.x += size.width;
|
||||||
|
rect2.size.width = [self _sizeOfRange:
|
||||||
|
NSMakeRange
|
||||||
|
(NSMaxRange(aRange) -
|
||||||
|
currentInfo->glyphRange.location, 1)].width;
|
||||||
|
// rect2 is the rect for the last glyph in the range
|
||||||
|
|
||||||
|
// TODO: it might not work if some glyph draw out of the usedRect.
|
||||||
|
// (is this really possible ?)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//float width = [aTextContainer containerSize].width;
|
// this is a multiline range, therefore the bounding rect goes
|
||||||
// FIXME: When we are on one line we may need only part of it
|
// from the beginning of a line till the end
|
||||||
|
// getting the lineFragmentRects will give the correct result
|
||||||
|
currentInfo = [_lineLayoutInformation objectAtIndex: i1];
|
||||||
|
rect1 = currentInfo->lineFragmentRect;
|
||||||
|
|
||||||
|
currentInfo = [_lineLayoutInformation objectAtIndex: i2];
|
||||||
|
rect2 = currentInfo->lineFragmentRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rect1;
|
|
||||||
|
|
||||||
|
|
||||||
|
// this does compute the smallest rect enclosing
|
||||||
|
// rect1 (or rect1.origin if rect1 is empty)
|
||||||
|
// and rect2 (or rect2.origin if rect1 is empty)
|
||||||
|
|
||||||
|
rect = NSMakeRect(MIN(NSMinX(rect1), NSMinX(rect2)),
|
||||||
|
MIN(NSMinY(rect1), NSMinY(rect2)), 0, 0);
|
||||||
|
|
||||||
|
rect = NSMakeRect(NSMinX(rect),
|
||||||
|
NSMinY(rect),
|
||||||
|
MAX(NSMaxX(rect1), NSMaxX(rect2)) - NSMinX(rect),
|
||||||
|
MAX(NSMaxY(rect1), NSMaxY(rect2)) - NSMinY(rect));
|
||||||
|
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSRange)glyphRangeForBoundingRect:(NSRect)aRect
|
- (NSRange)glyphRangeForBoundingRect:(NSRect)aRect
|
||||||
|
@ -492,9 +578,21 @@ static inline float defaultFontHeight ()
|
||||||
lineRange = [self rebuildForRange: aRange
|
lineRange = [self rebuildForRange: aRange
|
||||||
delta: delta
|
delta: delta
|
||||||
inTextContainer: aTextContainer];
|
inTextContainer: aTextContainer];
|
||||||
|
|
||||||
[[aTextContainer textView] sizeToFit];
|
[[aTextContainer textView] sizeToFit];
|
||||||
[[aTextContainer textView] invalidateTextContainerOrigin];
|
[[aTextContainer textView] invalidateTextContainerOrigin];
|
||||||
|
|
||||||
|
{
|
||||||
|
NSRange sr = [[aTextContainer textView] selectedRange];
|
||||||
|
if (sr.length == 0
|
||||||
|
&& aRange.location <= sr.location
|
||||||
|
&& aRange.location + aRange.length >= sr.location)
|
||||||
|
{
|
||||||
|
[[aTextContainer textView]
|
||||||
|
updateInsertionPointStateAndRestartTimer: YES];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME - it was reported that at this point lineRange is no longer
|
/* FIXME - it was reported that at this point lineRange is no longer
|
||||||
* correct ... looks like sizeToFit / invalidateTextContainerOrigin
|
* correct ... looks like sizeToFit / invalidateTextContainerOrigin
|
||||||
* migth cause additional relayout. */
|
* migth cause additional relayout. */
|
||||||
|
@ -511,7 +609,8 @@ static inline float defaultFontHeight ()
|
||||||
unsigned end = [self lineLayoutIndexForGlyphIndex: NSMaxRange(glyphRange)];
|
unsigned end = [self lineLayoutIndexForGlyphIndex: NSMaxRange(glyphRange)];
|
||||||
NSRange lineRange = NSMakeRange(start, end + 1 - start);
|
NSRange lineRange = NSMakeRange(start, end + 1 - start);
|
||||||
|
|
||||||
[self drawLinesInLineRange: lineRange];
|
[self drawLinesInLineRange: lineRange
|
||||||
|
atPoint: containerOrigin];
|
||||||
|
|
||||||
// We have to redraw the part of the selection that is inside
|
// We have to redraw the part of the selection that is inside
|
||||||
// the redrawn lines
|
// the redrawn lines
|
||||||
|
@ -520,7 +619,8 @@ static inline float defaultFontHeight ()
|
||||||
if ((selectedRange.length &&
|
if ((selectedRange.length &&
|
||||||
NSLocationInRange(newRange.location, selectedRange)))
|
NSLocationInRange(newRange.location, selectedRange)))
|
||||||
{
|
{
|
||||||
[self drawSelectionAsRangeNoCaret: newRange];
|
[self drawSelectionAsRangeNoCaret: newRange
|
||||||
|
atPoint: containerOrigin];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -705,7 +805,7 @@ forStartOfGlyphRange: (NSRange)glyphRange
|
||||||
currentInfo = [_lineLayoutInformation lastObject];
|
currentInfo = [_lineLayoutInformation lastObject];
|
||||||
if (index >= NSMaxRange(currentInfo->glyphRange))
|
if (index >= NSMaxRange(currentInfo->glyphRange))
|
||||||
{
|
{
|
||||||
NSRect rect = currentInfo->lineFragmentRect;
|
NSRect rect = currentInfo->usedRect;
|
||||||
|
|
||||||
return NSMakeRect(NSMaxX (rect), rect.origin.y,
|
return NSMakeRect(NSMaxX (rect), rect.origin.y,
|
||||||
width - NSMaxX (rect),
|
width - NSMaxX (rect),
|
||||||
|
@ -717,7 +817,7 @@ forStartOfGlyphRange: (NSRange)glyphRange
|
||||||
objectAtIndex: [self lineLayoutIndexForGlyphIndex:
|
objectAtIndex: [self lineLayoutIndexForGlyphIndex:
|
||||||
index]];
|
index]];
|
||||||
start = currentInfo->glyphRange.location;
|
start = currentInfo->glyphRange.location;
|
||||||
rect = currentInfo->lineFragmentRect;
|
rect = currentInfo->usedRect;
|
||||||
x = rect.origin.x + [self _sizeOfRange: NSMakeRange(start, index-start)].width;
|
x = rect.origin.x + [self _sizeOfRange: NSMakeRange(start, index-start)].width;
|
||||||
|
|
||||||
return NSMakeRect(x, rect.origin.y, NSMaxX (rect) - x,
|
return NSMakeRect(x, rect.origin.y, NSMaxX (rect) - x,
|
||||||
|
@ -725,6 +825,7 @@ forStartOfGlyphRange: (NSRange)glyphRange
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) drawSelectionAsRangeNoCaret: (NSRange)aRange
|
- (void) drawSelectionAsRangeNoCaret: (NSRange)aRange
|
||||||
|
atPoint: (NSPoint)containerOrigin
|
||||||
{
|
{
|
||||||
unsigned i, count;
|
unsigned i, count;
|
||||||
NSTextContainer *aTextContainer;
|
NSTextContainer *aTextContainer;
|
||||||
|
@ -739,6 +840,8 @@ forStartOfGlyphRange: (NSRange)glyphRange
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
|
rects[i].origin.x += containerOrigin.x;
|
||||||
|
rects[i].origin.y += containerOrigin.y;
|
||||||
NSHighlightRect (rects[i]);
|
NSHighlightRect (rects[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -758,7 +861,8 @@ forStartOfGlyphRange: (NSRange)glyphRange
|
||||||
}
|
}
|
||||||
|
|
||||||
// relies on _lineLayoutInformation
|
// relies on _lineLayoutInformation
|
||||||
- (void) drawLinesInLineRange: (NSRange)aRange;
|
- (void) drawLinesInLineRange: (NSRange)aRange
|
||||||
|
atPoint: (NSPoint)containerOrigin
|
||||||
{
|
{
|
||||||
NSArray *linesToDraw;
|
NSArray *linesToDraw;
|
||||||
NSEnumerator *lineEnum;
|
NSEnumerator *lineEnum;
|
||||||
|
@ -774,8 +878,12 @@ forStartOfGlyphRange: (NSRange)glyphRange
|
||||||
for ((lineEnum = [linesToDraw objectEnumerator]);
|
for ((lineEnum = [linesToDraw objectEnumerator]);
|
||||||
(currentInfo = [lineEnum nextObject]);)
|
(currentInfo = [lineEnum nextObject]);)
|
||||||
{
|
{
|
||||||
|
NSRect rect;
|
||||||
|
rect = currentInfo->lineFragmentRect;
|
||||||
|
rect.origin.x += containerOrigin.x;
|
||||||
|
rect.origin.y += containerOrigin.y;
|
||||||
[_textStorage drawRange: currentInfo->glyphRange
|
[_textStorage drawRange: currentInfo->glyphRange
|
||||||
inRect: currentInfo->lineFragmentRect];
|
inRect: rect];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -792,14 +900,17 @@ forStartOfGlyphRange: (NSRange)glyphRange
|
||||||
float width = 0;
|
float width = 0;
|
||||||
if (aTextContainer)
|
if (aTextContainer)
|
||||||
width = [aTextContainer containerSize].width;
|
width = [aTextContainer containerSize].width;
|
||||||
|
|
||||||
if (redrawLineRange.length > 1)
|
if (redrawLineRange.length > 1)
|
||||||
displayRect = NSUnionRect(displayRect,
|
displayRect = NSUnionRect(displayRect,
|
||||||
[[_lineLayoutInformation
|
[[_lineLayoutInformation
|
||||||
objectAtIndex:
|
objectAtIndex:
|
||||||
(int)NSMaxRange(redrawLineRange) - 1] lineFragmentRect]);
|
(int)NSMaxRange(redrawLineRange) - 1] lineFragmentRect]);
|
||||||
|
|
||||||
displayRect.size.width = width - displayRect.origin.x;
|
displayRect.size.width = width;
|
||||||
|
displayRect.origin.x +=
|
||||||
|
[[aTextContainer textView] textContainerInset].width;
|
||||||
|
displayRect.origin.y +=
|
||||||
|
[[aTextContainer textView] textContainerInset].height;
|
||||||
[[aTextContainer textView] setNeedsDisplayInRect: displayRect];
|
[[aTextContainer textView] setNeedsDisplayInRect: displayRect];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -908,10 +1019,11 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
|
||||||
{
|
{
|
||||||
_GNULineLayoutInfo *lastValidLineInfo = [_lineLayoutInformation
|
_GNULineLayoutInfo *lastValidLineInfo = [_lineLayoutInformation
|
||||||
objectAtIndex: aLine - 1];
|
objectAtIndex: aLine - 1];
|
||||||
NSRect aRect = lastValidLineInfo->lineFragmentRect;
|
NSRect aRect = lastValidLineInfo->usedRect;
|
||||||
|
|
||||||
startingIndex = NSMaxRange(lastValidLineInfo->glyphRange);
|
startingIndex = NSMaxRange(lastValidLineInfo->glyphRange);
|
||||||
drawingPoint = aRect.origin;
|
drawingPoint.x = 0;
|
||||||
|
drawingPoint.y = aRect.origin.y;
|
||||||
drawingPoint.y += aRect.size.height;
|
drawingPoint.y += aRect.size.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -927,11 +1039,39 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
|
||||||
|
|
||||||
// FIXME: This should be done via extra line fragment
|
// FIXME: This should be done via extra line fragment
|
||||||
// If there is no text add one empty box
|
// If there is no text add one empty box
|
||||||
[_lineLayoutInformation
|
{
|
||||||
addObject: [_GNULineLayoutInfo
|
NSParagraphStyle *style =
|
||||||
lineLayoutWithRange: NSMakeRange (0, 0)
|
(NSParagraphStyle*)[_textStorage
|
||||||
rect: NSMakeRect (0, 0, width, defaultFontHeight ())
|
attribute: NSParagraphStyleAttributeName
|
||||||
usedRect: NSMakeRect (0, 0, 1, defaultFontHeight ())]];
|
atIndex: 0
|
||||||
|
effectiveRange: NULL];
|
||||||
|
|
||||||
|
if ([style alignment] == NSRightTextAlignment)
|
||||||
|
{
|
||||||
|
[_lineLayoutInformation
|
||||||
|
addObject: [_GNULineLayoutInfo
|
||||||
|
lineLayoutWithRange: NSMakeRange (0, 0)
|
||||||
|
rect: NSMakeRect (0, 0, width, defaultFontHeight ())
|
||||||
|
usedRect: NSMakeRect (width-1, 0, 1, defaultFontHeight ())]];
|
||||||
|
}
|
||||||
|
else if ([style alignment] == NSCenterTextAlignment)
|
||||||
|
{
|
||||||
|
[_lineLayoutInformation
|
||||||
|
addObject: [_GNULineLayoutInfo
|
||||||
|
lineLayoutWithRange: NSMakeRange (0, 0)
|
||||||
|
rect: NSMakeRect (0, 0, width, defaultFontHeight ())
|
||||||
|
usedRect: NSMakeRect ((int) width/2, 0, 1, defaultFontHeight ())]];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[_lineLayoutInformation
|
||||||
|
addObject: [_GNULineLayoutInfo
|
||||||
|
lineLayoutWithRange: NSMakeRange (0, 0)
|
||||||
|
rect: NSMakeRect (0, 0, width, defaultFontHeight ())
|
||||||
|
usedRect: NSMakeRect (0, 0, 1, defaultFontHeight ())]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NSMakeRange(0,1);
|
return NSMakeRange(0,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1012,7 +1152,7 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
|
||||||
|
|
||||||
width = fragmentRect.size.width - 2 * padding;
|
width = fragmentRect.size.width - 2 * padding;
|
||||||
usedLineRect = fragmentRect;
|
usedLineRect = fragmentRect;
|
||||||
usedLineRect.origin.x += padding;
|
// usedLineRect.origin.x += padding;
|
||||||
usedLineRect.size = NSZeroSize;
|
usedLineRect.size = NSZeroSize;
|
||||||
|
|
||||||
// scan the individual words to the end of the line
|
// scan the individual words to the end of the line
|
||||||
|
@ -1129,6 +1269,29 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
|
||||||
// the to big
|
// the to big
|
||||||
fragmentRect.size.height = usedLineRect.size.height;
|
fragmentRect.size.height = usedLineRect.size.height;
|
||||||
|
|
||||||
|
// adjust the usedLineRect depending on the justification
|
||||||
|
{
|
||||||
|
NSParagraphStyle *style =
|
||||||
|
(NSParagraphStyle*)[_textStorage
|
||||||
|
attribute: NSParagraphStyleAttributeName
|
||||||
|
atIndex: startingLineCharIndex
|
||||||
|
effectiveRange: NULL];
|
||||||
|
|
||||||
|
if ([style alignment] == NSLeftTextAlignment)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if ([style alignment] == NSRightTextAlignment)
|
||||||
|
{
|
||||||
|
usedLineRect.origin.x +=
|
||||||
|
fragmentRect.size.width - usedLineRect.size.width - padding;
|
||||||
|
}
|
||||||
|
else if ([style alignment] == NSCenterTextAlignment)
|
||||||
|
{
|
||||||
|
usedLineRect.origin.x +=
|
||||||
|
(int) (fragmentRect.size.width - usedLineRect.size.width) / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This range is to small, as there are more lines that fit
|
// This range is to small, as there are more lines that fit
|
||||||
// into the container
|
// into the container
|
||||||
[self setTextContainer: aTextContainer
|
[self setTextContainer: aTextContainer
|
||||||
|
@ -1190,17 +1353,58 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
|
||||||
if (aTextContainer)
|
if (aTextContainer)
|
||||||
width = [aTextContainer containerSize].width;
|
width = [aTextContainer containerSize].width;
|
||||||
|
|
||||||
[_lineLayoutInformation
|
{
|
||||||
addObject: [_GNULineLayoutInfo
|
NSParagraphStyle *style =
|
||||||
lineLayoutWithRange: NSMakeRange (length, 0)
|
(NSParagraphStyle*)[_textStorage
|
||||||
rect: NSMakeRect (drawingPoint.x, drawingPoint.y,
|
attribute: NSParagraphStyleAttributeName
|
||||||
width, defaultFontHeight ())
|
atIndex: length - 1
|
||||||
usedRect: NSMakeRect (drawingPoint.x, drawingPoint.y,
|
effectiveRange: NULL];
|
||||||
1, defaultFontHeight ())]];
|
|
||||||
|
if ([style alignment] == NSRightTextAlignment)
|
||||||
|
{
|
||||||
|
[_lineLayoutInformation
|
||||||
|
addObject: [_GNULineLayoutInfo
|
||||||
|
lineLayoutWithRange: NSMakeRange (length, 0)
|
||||||
|
rect:
|
||||||
|
NSMakeRect (drawingPoint.x
|
||||||
|
+ (width - drawingPoint.x),
|
||||||
|
drawingPoint.y,
|
||||||
|
1, defaultFontHeight ())
|
||||||
|
usedRect:
|
||||||
|
NSMakeRect (drawingPoint.x
|
||||||
|
+ (width - drawingPoint.x),
|
||||||
|
drawingPoint.y,
|
||||||
|
1, defaultFontHeight ())]];
|
||||||
|
}
|
||||||
|
else if ([style alignment] == NSCenterTextAlignment)
|
||||||
|
{
|
||||||
|
[_lineLayoutInformation
|
||||||
|
addObject: [_GNULineLayoutInfo
|
||||||
|
lineLayoutWithRange: NSMakeRange (length, 0)
|
||||||
|
rect:
|
||||||
|
NSMakeRect (drawingPoint.x
|
||||||
|
+ (int)(width - drawingPoint.x) / 2,
|
||||||
|
drawingPoint.y,
|
||||||
|
1, defaultFontHeight ())
|
||||||
|
usedRect:
|
||||||
|
NSMakeRect (drawingPoint.x
|
||||||
|
+ (int)(width - drawingPoint.x) / 2,
|
||||||
|
drawingPoint.y,
|
||||||
|
1, defaultFontHeight ())]];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[_lineLayoutInformation
|
||||||
|
addObject: [_GNULineLayoutInfo
|
||||||
|
lineLayoutWithRange: NSMakeRange (length, 0)
|
||||||
|
rect: NSMakeRect (drawingPoint.x, drawingPoint.y,
|
||||||
|
width, defaultFontHeight ())
|
||||||
|
usedRect: NSMakeRect (drawingPoint.x, drawingPoint.y,
|
||||||
|
1, defaultFontHeight ())]];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// lines actually updated (optimized drawing)
|
// lines actually updated (optimized drawing)
|
||||||
return NSMakeRange(aLine, MAX(1, [_lineLayoutInformation count] - aLine));
|
return NSMakeRange(aLine, MAX(1, [_lineLayoutInformation count] - aLine));
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
#include <AppKit/PSOperators.h>
|
#include <AppKit/PSOperators.h>
|
||||||
#include <AppKit/NSAttributedString.h>
|
#include <AppKit/NSAttributedString.h>
|
||||||
|
|
||||||
|
#include <AppKit/NSClipView.h>
|
||||||
|
|
||||||
static Class colorClass;
|
static Class colorClass;
|
||||||
static Class cellClass;
|
static Class cellClass;
|
||||||
static Class fontClass;
|
static Class fontClass;
|
||||||
|
@ -1692,7 +1694,11 @@ static NSColor *shadowCol;
|
||||||
* NSCell simply draws border+text/image and makes no highlighting,
|
* NSCell simply draws border+text/image and makes no highlighting,
|
||||||
* for easier subclassing.
|
* for easier subclassing.
|
||||||
*/
|
*/
|
||||||
[self drawWithFrame: cellFrame inView: controlView];
|
if ([self isOpaque] == NO)
|
||||||
|
{
|
||||||
|
[controlView displayRect: cellFrame];
|
||||||
|
}
|
||||||
|
[self drawWithFrame: cellFrame inView: controlView];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1708,8 +1714,32 @@ static NSColor *shadowCol;
|
||||||
if (!controlView || !textObject || (_cell.type != NSTextCellType))
|
if (!controlView || !textObject || (_cell.type != NSTextCellType))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[textObject setFrame: [self titleRectForBounds: aRect]];
|
{
|
||||||
[controlView addSubview: textObject];
|
NSClipView *cv = [[NSClipView alloc]
|
||||||
|
initWithFrame:
|
||||||
|
[self titleRectForBounds: aRect]];
|
||||||
|
[controlView addSubview: cv];
|
||||||
|
RELEASE(cv);
|
||||||
|
[cv setAutoresizesSubviews: NO];
|
||||||
|
[cv setDocumentView: textObject];
|
||||||
|
[textObject setFrame: [cv bounds]];
|
||||||
|
[textObject setHorizontallyResizable: YES];
|
||||||
|
[textObject setVerticallyResizable: NO];
|
||||||
|
[textObject
|
||||||
|
setMaxSize:
|
||||||
|
NSMakeSize (3000,
|
||||||
|
[self titleRectForBounds: aRect].size.height)];
|
||||||
|
[textObject
|
||||||
|
setMinSize:
|
||||||
|
[self titleRectForBounds: aRect].size];
|
||||||
|
[[textObject textContainer]
|
||||||
|
setContainerSize:
|
||||||
|
NSMakeSize (3000,
|
||||||
|
[self titleRectForBounds: aRect].size.height)];
|
||||||
|
[[textObject textContainer] setHeightTracksTextView: NO];
|
||||||
|
[[textObject textContainer] setWidthTracksTextView: NO];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (_formatter != nil)
|
if (_formatter != nil)
|
||||||
{
|
{
|
||||||
|
@ -1734,6 +1764,7 @@ static NSColor *shadowCol;
|
||||||
[textObject setText: [(NSAttributedString *)_contents string]];
|
[textObject setText: [(NSAttributedString *)_contents string]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
[textObject sizeToFit];
|
||||||
|
|
||||||
[textObject setDelegate: anObject];
|
[textObject setDelegate: anObject];
|
||||||
[[controlView window] makeFirstResponder: textObject];
|
[[controlView window] makeFirstResponder: textObject];
|
||||||
|
@ -1748,8 +1779,11 @@ static NSColor *shadowCol;
|
||||||
|
|
||||||
- (void) endEditing: (NSText*)textObject
|
- (void) endEditing: (NSText*)textObject
|
||||||
{
|
{
|
||||||
|
NSClipView *cv;
|
||||||
[textObject setDelegate: nil];
|
[textObject setDelegate: nil];
|
||||||
|
cv = (NSClipView*)[textObject superview];
|
||||||
[textObject removeFromSuperview];
|
[textObject removeFromSuperview];
|
||||||
|
[cv removeFromSuperview];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) selectWithFrame: (NSRect)aRect
|
- (void) selectWithFrame: (NSRect)aRect
|
||||||
|
@ -1762,17 +1796,61 @@ static NSColor *shadowCol;
|
||||||
if (!controlView || !textObject || (_cell.type != NSTextCellType))
|
if (!controlView || !textObject || (_cell.type != NSTextCellType))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[textObject setFrame: [self titleRectForBounds: aRect]];
|
{
|
||||||
[controlView addSubview: textObject];
|
NSClipView *cv = [[NSClipView alloc]
|
||||||
if (_cell.contents_is_attributed_string == NO)
|
initWithFrame:
|
||||||
|
[self titleRectForBounds: aRect]];
|
||||||
|
[controlView addSubview: cv];
|
||||||
|
RELEASE(cv);
|
||||||
|
[cv setAutoresizesSubviews: NO];
|
||||||
|
[cv setDocumentView: textObject];
|
||||||
|
[textObject setFrame: [cv bounds]];
|
||||||
|
[textObject setHorizontallyResizable: YES];
|
||||||
|
[textObject setVerticallyResizable: NO];
|
||||||
|
[textObject
|
||||||
|
setMaxSize:
|
||||||
|
NSMakeSize (3000,
|
||||||
|
[self titleRectForBounds: aRect].size.height)];
|
||||||
|
[textObject
|
||||||
|
setMinSize:
|
||||||
|
[self titleRectForBounds: aRect].size];
|
||||||
|
[[textObject textContainer]
|
||||||
|
setContainerSize:
|
||||||
|
NSMakeSize (3000,
|
||||||
|
[self titleRectForBounds: aRect].size.height)];
|
||||||
|
[[textObject textContainer] setWidthTracksTextView: NO];
|
||||||
|
[[textObject textContainer] setWidthTracksTextView: NO];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_formatter != nil)
|
||||||
{
|
{
|
||||||
[textObject setText: _contents];
|
NSString *contents;
|
||||||
|
|
||||||
|
contents = [_formatter editingStringForObjectValue: _objectValue];
|
||||||
|
if (contents == nil)
|
||||||
|
{
|
||||||
|
contents = _contents;
|
||||||
|
}
|
||||||
|
[textObject setText: contents];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* FIXME/TODO make sure this is correct. */
|
if (_cell.contents_is_attributed_string == NO)
|
||||||
[textObject setText: [(NSAttributedString *)_contents string]];
|
{
|
||||||
|
[textObject setText: _contents];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* FIXME/TODO make sure this is correct. */
|
||||||
|
[textObject setText: [(NSAttributedString *)_contents string]];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
[textObject sizeToFit];
|
||||||
|
|
||||||
|
[textObject setDelegate: anObject];
|
||||||
|
[[controlView window] makeFirstResponder: textObject];
|
||||||
|
|
||||||
[textObject setSelectedRange: NSMakeRange (selStart, selLength)];
|
[textObject setSelectedRange: NSMakeRange (selStart, selLength)];
|
||||||
[textObject setDelegate: anObject];
|
[textObject setDelegate: anObject];
|
||||||
[[controlView window] makeFirstResponder: textObject];
|
[[controlView window] makeFirstResponder: textObject];
|
||||||
|
|
|
@ -2762,14 +2762,18 @@ forStartOfGlyphRange: (NSRange)glyphRange
|
||||||
atPoint: (NSPoint)containerOrigin
|
atPoint: (NSPoint)containerOrigin
|
||||||
{
|
{
|
||||||
NSTextContainer *aTextContainer;
|
NSTextContainer *aTextContainer;
|
||||||
|
NSRect rect;
|
||||||
|
|
||||||
aTextContainer = [self textContainerForGlyphAtIndex: glyphRange.location
|
aTextContainer = [self textContainerForGlyphAtIndex: glyphRange.location
|
||||||
effectiveRange: NULL];
|
effectiveRange: NULL];
|
||||||
|
|
||||||
[[[aTextContainer textView] backgroundColor] set];
|
[[[aTextContainer textView] backgroundColor] set];
|
||||||
|
|
||||||
NSRectFill ([self boundingRectForGlyphRange: glyphRange
|
rect = [self boundingRectForGlyphRange: glyphRange
|
||||||
inTextContainer: aTextContainer]);
|
inTextContainer: aTextContainer];
|
||||||
|
rect.origin.x += containerOrigin.x;
|
||||||
|
rect.origin.x += containerOrigin.y;
|
||||||
|
NSRectFill (rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) drawGlyphsForGlyphRange: (NSRange)glyphRange
|
- (void) drawGlyphsForGlyphRange: (NSRange)glyphRange
|
||||||
|
|
|
@ -715,7 +715,7 @@ static Class concrete;
|
||||||
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &flag];
|
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||||
_tf.is_ruler_visible = flag;
|
_tf.is_ruler_visible = flag;
|
||||||
|
|
||||||
_background_color = [aDecoder decodeObject];
|
_background_color = RETAIN([aDecoder decodeObject]);
|
||||||
[aDecoder decodeValueOfObjCType: @encode(NSSize) at: &_minSize];
|
[aDecoder decodeValueOfObjCType: @encode(NSSize) at: &_minSize];
|
||||||
[aDecoder decodeValueOfObjCType: @encode(NSSize) at: &_maxSize];
|
[aDecoder decodeValueOfObjCType: @encode(NSSize) at: &_maxSize];
|
||||||
|
|
||||||
|
|
|
@ -282,7 +282,9 @@ static Class textFieldCellClass;
|
||||||
|
|
||||||
/* This could happen if someone pressed the mouse on the borders. */
|
/* This could happen if someone pressed the mouse on the borders. */
|
||||||
if (_text_object)
|
if (_text_object)
|
||||||
return;
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
t = [_window fieldEditor: YES forObject: self];
|
t = [_window fieldEditor: YES forObject: self];
|
||||||
|
|
||||||
|
@ -297,7 +299,6 @@ static Class textFieldCellClass;
|
||||||
|
|
||||||
|
|
||||||
// [NSCursor hide];
|
// [NSCursor hide];
|
||||||
|
|
||||||
_text_object = [_cell setUpFieldEditorAttributes: t];
|
_text_object = [_cell setUpFieldEditorAttributes: t];
|
||||||
[_cell editWithFrame: _bounds
|
[_cell editWithFrame: _bounds
|
||||||
inView: self
|
inView: self
|
||||||
|
@ -313,7 +314,10 @@ static Class textFieldCellClass;
|
||||||
|
|
||||||
- (BOOL) acceptsFirstResponder
|
- (BOOL) acceptsFirstResponder
|
||||||
{
|
{
|
||||||
return [self isSelectable];
|
// we do not accept first responder if there is already a
|
||||||
|
// _text_object, else it would make the _text_object resign
|
||||||
|
// and end editing
|
||||||
|
return (_text_object == nil) && [self isSelectable];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) becomeFirstResponder
|
- (BOOL) becomeFirstResponder
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
Author: Nicola Pero <n.pero@mi.flashnet.it>
|
Author: Nicola Pero <n.pero@mi.flashnet.it>
|
||||||
Date: 2000, 2001, 2002
|
Date: 2000, 2001, 2002
|
||||||
|
|
||||||
|
Author: Pierre-Yves Rivaille <pyrivail@ens-lyon.fr>
|
||||||
|
Date: September 2002
|
||||||
|
|
||||||
This file is part of the GNUstep GUI Library.
|
This file is part of the GNUstep GUI Library.
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
|
@ -63,6 +66,8 @@
|
||||||
#include <AppKit/NSColorPanel.h>
|
#include <AppKit/NSColorPanel.h>
|
||||||
#include <AppKit/NSAttributedString.h>
|
#include <AppKit/NSAttributedString.h>
|
||||||
|
|
||||||
|
static const int currentVersion = 2;
|
||||||
|
|
||||||
#define HUGE 1e7
|
#define HUGE 1e7
|
||||||
|
|
||||||
/* not the same as NSMakeRange! */
|
/* not the same as NSMakeRange! */
|
||||||
|
@ -154,7 +159,7 @@ static NSNotificationCenter *nc;
|
||||||
{
|
{
|
||||||
if ([self class] == [NSTextView class])
|
if ([self class] == [NSTextView class])
|
||||||
{
|
{
|
||||||
[self setVersion: 1];
|
[self setVersion: currentVersion];
|
||||||
nc = [NSNotificationCenter defaultCenter];
|
nc = [NSNotificationCenter defaultCenter];
|
||||||
[self registerForServices];
|
[self registerForServices];
|
||||||
}
|
}
|
||||||
|
@ -266,7 +271,8 @@ static NSNotificationCenter *nc;
|
||||||
|
|
||||||
- (void) encodeWithCoder: (NSCoder *)aCoder
|
- (void) encodeWithCoder: (NSCoder *)aCoder
|
||||||
{
|
{
|
||||||
BOOL flag;
|
BOOL flag;
|
||||||
|
NSSize containerSize = [_textContainer containerSize];
|
||||||
|
|
||||||
[super encodeWithCoder: aCoder];
|
[super encodeWithCoder: aCoder];
|
||||||
|
|
||||||
|
@ -274,28 +280,71 @@ static NSNotificationCenter *nc;
|
||||||
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &flag];
|
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||||
flag = _tvf.allows_undo;
|
flag = _tvf.allows_undo;
|
||||||
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &flag];
|
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||||
|
[aCoder encodeObject: _caret_color];
|
||||||
|
[aCoder encodeValueOfObjCType: @encode(NSSize) at: &containerSize];
|
||||||
|
flag = [_textContainer widthTracksTextView];
|
||||||
|
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||||
|
flag = [_textContainer heightTracksTextView];
|
||||||
|
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithCoder: (NSCoder *)aDecoder
|
- (id) initWithCoder: (NSCoder *)aDecoder
|
||||||
{
|
{
|
||||||
NSTextContainer *aTextContainer;
|
int version = [aDecoder versionForClassName:
|
||||||
BOOL flag;
|
@"NSTextView"];
|
||||||
|
|
||||||
self = [super initWithCoder: aDecoder];
|
if (version == currentVersion)
|
||||||
|
{
|
||||||
|
NSTextContainer *aTextContainer;
|
||||||
|
BOOL flag;
|
||||||
|
NSSize containerSize;
|
||||||
|
|
||||||
|
self = [super initWithCoder: aDecoder];
|
||||||
|
|
||||||
|
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||||
|
_tvf.smart_insert_delete = flag;
|
||||||
|
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||||
|
_tvf.allows_undo = flag;
|
||||||
|
|
||||||
|
_caret_color = RETAIN([aDecoder decodeObject]);
|
||||||
|
[aDecoder decodeValueOfObjCType: @encode(NSSize) at: &containerSize];
|
||||||
|
/* build up the rest of the text system, which doesn't get stored
|
||||||
|
<doesn't even implement the Coding protocol>. */
|
||||||
|
aTextContainer = [self buildUpTextNetwork: _frame.size];
|
||||||
|
[aTextContainer setTextView: (NSTextView*)self];
|
||||||
|
[aTextContainer setContainerSize: containerSize];
|
||||||
|
|
||||||
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &flag];
|
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||||
_tvf.smart_insert_delete = flag;
|
[aTextContainer setWidthTracksTextView: flag];
|
||||||
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &flag];
|
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||||
_tvf.allows_undo = flag;
|
[aTextContainer setHeightTracksTextView: flag];
|
||||||
|
|
||||||
/* build up the rest of the text system, which doesn't get stored
|
|
||||||
<doesn't even implement the Coding protocol>. */
|
|
||||||
aTextContainer = [self buildUpTextNetwork: _frame.size];
|
|
||||||
[aTextContainer setTextView: (NSTextView*)self];
|
|
||||||
/* See initWithFrame: for comments on this RELEASE */
|
|
||||||
RELEASE (self);
|
|
||||||
|
|
||||||
[self setSelectedRange: NSMakeRange (0, 0)];
|
/* See initWithFrame: for comments on this RELEASE */
|
||||||
|
RELEASE (self);
|
||||||
|
|
||||||
|
[self setSelectedRange: NSMakeRange (0, 0)];
|
||||||
|
}
|
||||||
|
else if (version == 1)
|
||||||
|
{
|
||||||
|
NSTextContainer *aTextContainer;
|
||||||
|
BOOL flag;
|
||||||
|
|
||||||
|
self = [super initWithCoder: aDecoder];
|
||||||
|
|
||||||
|
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||||
|
_tvf.smart_insert_delete = flag;
|
||||||
|
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||||
|
_tvf.allows_undo = flag;
|
||||||
|
|
||||||
|
/* build up the rest of the text system, which doesn't get stored
|
||||||
|
<doesn't even implement the Coding protocol>. */
|
||||||
|
aTextContainer = [self buildUpTextNetwork: _frame.size];
|
||||||
|
[aTextContainer setTextView: (NSTextView*)self];
|
||||||
|
/* See initWithFrame: for comments on this RELEASE */
|
||||||
|
RELEASE (self);
|
||||||
|
|
||||||
|
[self setSelectedRange: NSMakeRange (0, 0)];
|
||||||
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -363,11 +412,50 @@ static NSNotificationCenter *nc;
|
||||||
this case. So we set the attributes manually. */
|
this case. So we set the attributes manually. */
|
||||||
NSAttributedString *as;
|
NSAttributedString *as;
|
||||||
|
|
||||||
as = AUTORELEASE ([[NSAttributedString alloc]
|
if ([aString length] == 0)
|
||||||
initWithString: aString
|
{
|
||||||
attributes: _typingAttributes]);
|
as = AUTORELEASE ([[NSAttributedString alloc]
|
||||||
[self replaceRange: aRange withAttributedString: as];
|
initWithString: @" "
|
||||||
|
attributes: _typingAttributes]);
|
||||||
|
[self replaceRange: aRange withAttributedString: as];
|
||||||
|
as = AUTORELEASE ([[NSAttributedString alloc]
|
||||||
|
initWithString: aString
|
||||||
|
attributes: _typingAttributes]);
|
||||||
|
[self replaceRange: NSMakeRange(0, 1) withAttributedString: as];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
as = AUTORELEASE ([[NSAttributedString alloc]
|
||||||
|
initWithString: aString
|
||||||
|
attributes: _typingAttributes]);
|
||||||
|
[self replaceRange: aRange withAttributedString: as];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// BEGIN: following code added by pyr
|
||||||
|
else if ([_textStorage length] == 0)
|
||||||
|
{
|
||||||
|
NSAttributedString *as;
|
||||||
|
if ([aString length] == 0)
|
||||||
|
{
|
||||||
|
as = AUTORELEASE ([[NSAttributedString alloc]
|
||||||
|
initWithString: @" "
|
||||||
|
attributes: _typingAttributes]);
|
||||||
|
[_textStorage replaceCharactersInRange: aRange withAttributedString: as];
|
||||||
|
as = AUTORELEASE ([[NSAttributedString alloc]
|
||||||
|
initWithString: aString
|
||||||
|
attributes: _typingAttributes]);
|
||||||
|
[_textStorage replaceCharactersInRange: NSMakeRange(0, 1) withAttributedString: as];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
as = AUTORELEASE ([[NSAttributedString alloc]
|
||||||
|
initWithString: aString
|
||||||
|
attributes: _typingAttributes]);
|
||||||
|
[_textStorage replaceCharactersInRange: aRange
|
||||||
|
withAttributedString: as];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// END
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
[_textStorage replaceCharactersInRange: aRange withString: aString];
|
[_textStorage replaceCharactersInRange: aRange withString: aString];
|
||||||
|
@ -837,18 +925,24 @@ static NSNotificationCenter *nc;
|
||||||
|
|
||||||
- (void) sizeToFit
|
- (void) sizeToFit
|
||||||
{
|
{
|
||||||
|
NSSize size;
|
||||||
if (_tf.is_horizontally_resizable || _tf.is_vertically_resizable)
|
if (_tf.is_horizontally_resizable || _tf.is_vertically_resizable)
|
||||||
{
|
size = [_layoutManager usedRectForTextContainer: _textContainer].size;
|
||||||
NSSize size;
|
|
||||||
|
if (!_tf.is_horizontally_resizable)
|
||||||
size = [_layoutManager usedRectForTextContainer: _textContainer].size;
|
size.width = _bounds.size.width;
|
||||||
size.width += 2 * _textContainerInset.width;
|
else
|
||||||
size.height += 2 * _textContainerInset.height;
|
size.width += 2 * _textContainerInset.width;
|
||||||
|
|
||||||
[self setConstrainedFrameSize: size];
|
if (!_tf.is_vertically_resizable)
|
||||||
}
|
size.height = _bounds.size.height;
|
||||||
|
else
|
||||||
|
size.height += 2 * _textContainerInset.height;
|
||||||
|
|
||||||
|
[self setConstrainedFrameSize: size];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* [NSText] Spelling
|
* [NSText] Spelling
|
||||||
*/
|
*/
|
||||||
|
@ -897,11 +991,42 @@ static NSNotificationCenter *nc;
|
||||||
*/
|
*/
|
||||||
- (void) scrollRangeToVisible: (NSRange)aRange
|
- (void) scrollRangeToVisible: (NSRange)aRange
|
||||||
{
|
{
|
||||||
// Don't try scrolling an ancestor clipview if we are field editor.
|
if (aRange.length > 0)
|
||||||
// This makes things so much simpler and stabler for now.
|
|
||||||
if (_tf.is_field_editor == NO)
|
|
||||||
{
|
{
|
||||||
[self scrollRectToVisible: [self rectForCharacterRange: aRange]];
|
aRange.length = 1;
|
||||||
|
[self scrollRectToVisible:
|
||||||
|
[self rectForCharacterRange: aRange]];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Update insertion point rect */
|
||||||
|
NSRange charRange;
|
||||||
|
NSRange glyphRange;
|
||||||
|
unsigned glyphIndex;
|
||||||
|
NSRect rect;
|
||||||
|
|
||||||
|
charRange = NSMakeRange (aRange.location, 0);
|
||||||
|
glyphRange = [_layoutManager glyphRangeForCharacterRange: charRange
|
||||||
|
actualCharacterRange: NULL];
|
||||||
|
glyphIndex = glyphRange.location;
|
||||||
|
|
||||||
|
rect = [_layoutManager lineFragmentUsedRectForGlyphAtIndex: glyphIndex
|
||||||
|
effectiveRange: NULL];
|
||||||
|
|
||||||
|
rect.origin.x += _textContainerOrigin.x;
|
||||||
|
rect.origin.y += _textContainerOrigin.y;
|
||||||
|
if ([self selectionAffinity] != NSSelectionAffinityUpstream)
|
||||||
|
{
|
||||||
|
/* Standard case - draw the insertion point just before the
|
||||||
|
associated glyph index */
|
||||||
|
NSPoint loc = [_layoutManager locationForGlyphAtIndex: glyphIndex];
|
||||||
|
|
||||||
|
rect.origin.x += loc.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.size.width = 1;
|
||||||
|
[self scrollRectToVisible: rect];
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1015,6 +1140,8 @@ static NSNotificationCenter *nc;
|
||||||
{
|
{
|
||||||
_textContainerInset = inset;
|
_textContainerInset = inset;
|
||||||
[self invalidateTextContainerOrigin];
|
[self invalidateTextContainerOrigin];
|
||||||
|
[nc postNotificationName: NSViewFrameDidChangeNotification
|
||||||
|
object: self];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSSize) textContainerInset
|
- (NSSize) textContainerInset
|
||||||
|
@ -1042,19 +1169,60 @@ static NSNotificationCenter *nc;
|
||||||
information is used when we ask the layout manager to draw - the
|
information is used when we ask the layout manager to draw - the
|
||||||
base point is precisely this `text container origin', which is
|
base point is precisely this `text container origin', which is
|
||||||
the origin of the used rect in our own coordinate system. */
|
the origin of the used rect in our own coordinate system. */
|
||||||
|
|
||||||
|
/* It seems like the `text container origin' is the origin
|
||||||
|
of the text container rect so that the used rect
|
||||||
|
is "well positionned" within the textview */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (usedRect.size.width - _bounds.size.width < 0.0001)
|
||||||
|
{
|
||||||
|
NSRect rect;
|
||||||
|
float diff;
|
||||||
|
float ratio;
|
||||||
|
rect.origin = NSMakePoint(0, 0);
|
||||||
|
rect.size = textContainerSize;
|
||||||
|
diff = rect.size.width - usedRect.size.width;
|
||||||
|
|
||||||
|
_textContainerOrigin.x = NSMinX(_bounds);
|
||||||
|
_textContainerOrigin.x += _textContainerInset.width;
|
||||||
|
|
||||||
|
if (diff)
|
||||||
|
{
|
||||||
|
ratio = (_bounds.size.width - usedRect.size.width)
|
||||||
|
/ diff;
|
||||||
|
|
||||||
|
if (NSMaxX(rect) == NSMaxX(usedRect))
|
||||||
|
{
|
||||||
|
_textContainerOrigin.x -= rect.size.width - _bounds.size.width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_textContainerOrigin.x -=
|
||||||
|
(int) (usedRect.origin.x * (1 - ratio ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* First get the pure text container origin */
|
||||||
|
_textContainerOrigin.x = NSMinX (_bounds);
|
||||||
|
_textContainerOrigin.x += _textContainerInset.width;
|
||||||
|
/* Then move to the used rect origin */
|
||||||
|
_textContainerOrigin.x -= usedRect.origin.x;
|
||||||
|
}
|
||||||
|
|
||||||
/* First get the pure text container origin */
|
/* First get the pure text container origin */
|
||||||
_textContainerOrigin.x = NSMinX (_bounds);
|
_textContainerOrigin.y = NSMinY (_bounds);
|
||||||
_textContainerOrigin.x += _textContainerInset.width;
|
_textContainerOrigin.y += _textContainerInset.height;
|
||||||
|
// _textContainerOrigin.y -= textContainerSize.height;
|
||||||
/* Then move to the used rect origin */
|
/* Then move to the used rect origin */
|
||||||
_textContainerOrigin.x += usedRect.origin.x;
|
_textContainerOrigin.y -= usedRect.origin.y;
|
||||||
|
|
||||||
/* First get the pure text container origin */
|
|
||||||
_textContainerOrigin.y = NSMaxY (_bounds);
|
|
||||||
_textContainerOrigin.y -= _textContainerInset.height;
|
|
||||||
_textContainerOrigin.y -= textContainerSize.height;
|
|
||||||
/* Then move to the used rect origin */
|
|
||||||
_textContainerOrigin.y += usedRect.origin.y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSLayoutManager*) layoutManager
|
- (NSLayoutManager*) layoutManager
|
||||||
|
@ -1427,8 +1595,13 @@ static NSNotificationCenter *nc;
|
||||||
|
|
||||||
if (flag == NO)
|
if (flag == NO)
|
||||||
{
|
{
|
||||||
/* Make the selected range visible */
|
// FIXME
|
||||||
[self scrollRangeToVisible: range];
|
// Make the selected range visible
|
||||||
|
// We do not always want to scroll to the beginning of the
|
||||||
|
// selection
|
||||||
|
// however we do for sure if the selection's length is 0
|
||||||
|
if (range.length == 0 && _tf.is_editable )
|
||||||
|
[self scrollRangeToVisible: range];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to optimize for overlapping ranges */
|
/* Try to optimize for overlapping ranges */
|
||||||
|
@ -1518,6 +1691,7 @@ static NSNotificationCenter *nc;
|
||||||
NSRange glyphRange;
|
NSRange glyphRange;
|
||||||
unsigned glyphIndex;
|
unsigned glyphIndex;
|
||||||
NSRect rect;
|
NSRect rect;
|
||||||
|
NSRect oldInsertionPointRect;
|
||||||
|
|
||||||
/* Simple case - no insertion point */
|
/* Simple case - no insertion point */
|
||||||
if ((_selected_range.length > 0) || _selected_range.location == NSNotFound)
|
if ((_selected_range.length > 0) || _selected_range.location == NSNotFound)
|
||||||
|
@ -1526,7 +1700,6 @@ static NSNotificationCenter *nc;
|
||||||
{
|
{
|
||||||
[_insertionPointTimer invalidate];
|
[_insertionPointTimer invalidate];
|
||||||
DESTROY (_insertionPointTimer);
|
DESTROY (_insertionPointTimer);
|
||||||
_drawInsertionPointNow = YES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: horizontal position of insertion point */
|
/* FIXME: horizontal position of insertion point */
|
||||||
|
@ -1539,9 +1712,11 @@ static NSNotificationCenter *nc;
|
||||||
actualCharacterRange: NULL];
|
actualCharacterRange: NULL];
|
||||||
glyphIndex = glyphRange.location;
|
glyphIndex = glyphRange.location;
|
||||||
|
|
||||||
rect = [_layoutManager lineFragmentRectForGlyphAtIndex: glyphIndex
|
rect = [_layoutManager lineFragmentUsedRectForGlyphAtIndex: glyphIndex
|
||||||
effectiveRange: NULL];
|
effectiveRange: NULL];
|
||||||
|
rect.origin.x += _textContainerOrigin.x;
|
||||||
|
rect.origin.y += _textContainerOrigin.y;
|
||||||
|
|
||||||
if ([self selectionAffinity] != NSSelectionAffinityUpstream)
|
if ([self selectionAffinity] != NSSelectionAffinityUpstream)
|
||||||
{
|
{
|
||||||
/* Standard case - draw the insertion point just before the
|
/* Standard case - draw the insertion point just before the
|
||||||
|
@ -1549,6 +1724,7 @@ static NSNotificationCenter *nc;
|
||||||
NSPoint loc = [_layoutManager locationForGlyphAtIndex: glyphIndex];
|
NSPoint loc = [_layoutManager locationForGlyphAtIndex: glyphIndex];
|
||||||
|
|
||||||
rect.origin.x += loc.x;
|
rect.origin.x += loc.x;
|
||||||
|
|
||||||
}
|
}
|
||||||
else /* _affinity == NSSelectionAffinityUpstream - non standard */
|
else /* _affinity == NSSelectionAffinityUpstream - non standard */
|
||||||
{
|
{
|
||||||
|
@ -1580,8 +1756,10 @@ static NSNotificationCenter *nc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
rect.size.width = 1;
|
rect.size.width = 1;
|
||||||
|
|
||||||
|
oldInsertionPointRect = _insertionPointRect;
|
||||||
_insertionPointRect = rect;
|
_insertionPointRect = rect;
|
||||||
|
|
||||||
/* Remember horizontal position of insertion point */
|
/* Remember horizontal position of insertion point */
|
||||||
|
@ -1592,6 +1770,22 @@ static NSNotificationCenter *nc;
|
||||||
/* Start blinking timer if not yet started */
|
/* Start blinking timer if not yet started */
|
||||||
if (_insertionPointTimer == nil && [self shouldDrawInsertionPoint])
|
if (_insertionPointTimer == nil && [self shouldDrawInsertionPoint])
|
||||||
{
|
{
|
||||||
|
_drawInsertionPointNow = NO;
|
||||||
|
[self _blink: nil];
|
||||||
|
_insertionPointTimer = [NSTimer scheduledTimerWithTimeInterval: 0.5
|
||||||
|
target: self
|
||||||
|
selector: @selector(_blink:)
|
||||||
|
userInfo: nil
|
||||||
|
repeats: YES];
|
||||||
|
RETAIN (_insertionPointTimer);
|
||||||
|
}
|
||||||
|
else if (_insertionPointTimer != nil)
|
||||||
|
{
|
||||||
|
[_insertionPointTimer invalidate];
|
||||||
|
DESTROY (_insertionPointTimer);
|
||||||
|
[self setNeedsDisplayInRect: oldInsertionPointRect];
|
||||||
|
_drawInsertionPointNow = NO;
|
||||||
|
[self _blink: nil];
|
||||||
_insertionPointTimer = [NSTimer scheduledTimerWithTimeInterval: 0.5
|
_insertionPointTimer = [NSTimer scheduledTimerWithTimeInterval: 0.5
|
||||||
target: self
|
target: self
|
||||||
selector: @selector(_blink:)
|
selector: @selector(_blink:)
|
||||||
|
@ -1610,8 +1804,10 @@ static NSNotificationCenter *nc;
|
||||||
{
|
{
|
||||||
if (_insertionPointTimer != nil)
|
if (_insertionPointTimer != nil)
|
||||||
{
|
{
|
||||||
|
[self setNeedsDisplayInRect: oldInsertionPointRect];
|
||||||
[_insertionPointTimer invalidate];
|
[_insertionPointTimer invalidate];
|
||||||
DESTROY (_insertionPointTimer);
|
DESTROY (_insertionPointTimer);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2067,6 +2263,7 @@ replacing the selection.
|
||||||
|
|
||||||
- (void) didChangeText
|
- (void) didChangeText
|
||||||
{
|
{
|
||||||
|
[self sizeToFit];
|
||||||
[nc postNotificationName: NSTextDidChangeNotification
|
[nc postNotificationName: NSTextDidChangeNotification
|
||||||
object: _notifObject];
|
object: _notifObject];
|
||||||
}
|
}
|
||||||
|
@ -2467,6 +2664,7 @@ afterString in order over charRange. */
|
||||||
- (void) moveUp: (id)sender
|
- (void) moveUp: (id)sender
|
||||||
{
|
{
|
||||||
float originalInsertionPoint;
|
float originalInsertionPoint;
|
||||||
|
float savedOriginalInsertionPoint;
|
||||||
float startingY;
|
float startingY;
|
||||||
unsigned newLocation;
|
unsigned newLocation;
|
||||||
|
|
||||||
|
@ -2481,10 +2679,16 @@ afterString in order over charRange. */
|
||||||
|
|
||||||
/* Read from memory the horizontal position we aim to move the cursor
|
/* Read from memory the horizontal position we aim to move the cursor
|
||||||
at on the next line */
|
at on the next line */
|
||||||
|
savedOriginalInsertionPoint = _originalInsertPoint;
|
||||||
originalInsertionPoint = _originalInsertPoint;
|
originalInsertionPoint = _originalInsertPoint;
|
||||||
|
|
||||||
/* Ask the layout manager to compute where to go */
|
/* Ask the layout manager to compute where to go */
|
||||||
startingY = NSMidY (_insertionPointRect);
|
startingY = NSMidY (_insertionPointRect);
|
||||||
|
|
||||||
|
/* consider textContainerInset */
|
||||||
|
startingY -= _textContainerInset.height;
|
||||||
|
originalInsertionPoint -= _textContainerInset.width;
|
||||||
|
|
||||||
newLocation = [_layoutManager
|
newLocation = [_layoutManager
|
||||||
_charIndexForInsertionPointMovingFromY: startingY
|
_charIndexForInsertionPointMovingFromY: startingY
|
||||||
bestX: originalInsertionPoint
|
bestX: originalInsertionPoint
|
||||||
|
@ -2497,12 +2701,13 @@ afterString in order over charRange. */
|
||||||
/* Restore the _originalInsertPoint (which was changed
|
/* Restore the _originalInsertPoint (which was changed
|
||||||
by setSelectedRange:) because we don't want it to change between
|
by setSelectedRange:) because we don't want it to change between
|
||||||
moveUp:/moveDown: operations. */
|
moveUp:/moveDown: operations. */
|
||||||
_originalInsertPoint = originalInsertionPoint;
|
_originalInsertPoint = savedOriginalInsertionPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) moveDown: (id)sender
|
- (void) moveDown: (id)sender
|
||||||
{
|
{
|
||||||
float originalInsertionPoint;
|
float originalInsertionPoint;
|
||||||
|
float savedOriginalInsertionPoint;
|
||||||
float startingY;
|
float startingY;
|
||||||
unsigned newLocation;
|
unsigned newLocation;
|
||||||
|
|
||||||
|
@ -2517,10 +2722,16 @@ afterString in order over charRange. */
|
||||||
|
|
||||||
/* Read from memory the horizontal position we aim to move the cursor
|
/* Read from memory the horizontal position we aim to move the cursor
|
||||||
at on the next line */
|
at on the next line */
|
||||||
|
savedOriginalInsertionPoint = _originalInsertPoint;
|
||||||
originalInsertionPoint = _originalInsertPoint;
|
originalInsertionPoint = _originalInsertPoint;
|
||||||
|
|
||||||
/* Ask the layout manager to compute where to go */
|
/* Ask the layout manager to compute where to go */
|
||||||
startingY = NSMidY (_insertionPointRect);
|
startingY = NSMidY (_insertionPointRect);
|
||||||
|
|
||||||
|
/* consider textContainerInset */
|
||||||
|
startingY -= _textContainerInset.height;
|
||||||
|
originalInsertionPoint -= _textContainerInset.width;
|
||||||
|
|
||||||
newLocation = [_layoutManager
|
newLocation = [_layoutManager
|
||||||
_charIndexForInsertionPointMovingFromY: startingY
|
_charIndexForInsertionPointMovingFromY: startingY
|
||||||
bestX: originalInsertionPoint
|
bestX: originalInsertionPoint
|
||||||
|
@ -2533,7 +2744,7 @@ afterString in order over charRange. */
|
||||||
/* Restore the _originalInsertPoint (which was changed
|
/* Restore the _originalInsertPoint (which was changed
|
||||||
by setSelectedRange:) because we don't want it to change between
|
by setSelectedRange:) because we don't want it to change between
|
||||||
moveUp:/moveDown: operations. */
|
moveUp:/moveDown: operations. */
|
||||||
_originalInsertPoint = originalInsertionPoint;
|
_originalInsertPoint = savedOriginalInsertionPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) moveLeft: (id)sender
|
- (void) moveLeft: (id)sender
|
||||||
|
@ -3027,8 +3238,12 @@ afterString in order over charRange. */
|
||||||
- (void) drawRect: (NSRect)rect
|
- (void) drawRect: (NSRect)rect
|
||||||
{
|
{
|
||||||
/* TODO: Only do relayout if needed */
|
/* TODO: Only do relayout if needed */
|
||||||
NSRange drawnRange = [_layoutManager glyphRangeForBoundingRect: rect
|
NSRange drawnRange;
|
||||||
inTextContainer: _textContainer];
|
NSRect containerRect = rect;
|
||||||
|
containerRect.origin.x -= _textContainerOrigin.x;
|
||||||
|
containerRect.origin.y -= _textContainerOrigin.y;
|
||||||
|
drawnRange = [_layoutManager glyphRangeForBoundingRect: containerRect
|
||||||
|
inTextContainer: _textContainer];
|
||||||
if (_tf.draws_background)
|
if (_tf.draws_background)
|
||||||
{
|
{
|
||||||
/* First paint the background with the color. This is necessary
|
/* First paint the background with the color. This is necessary
|
||||||
|
@ -3043,6 +3258,7 @@ afterString in order over charRange. */
|
||||||
/* Then draw the special background of the new glyphs. */
|
/* Then draw the special background of the new glyphs. */
|
||||||
[_layoutManager drawBackgroundForGlyphRange: drawnRange
|
[_layoutManager drawBackgroundForGlyphRange: drawnRange
|
||||||
atPoint: _textContainerOrigin];
|
atPoint: _textContainerOrigin];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[_layoutManager drawGlyphsForGlyphRange: drawnRange
|
[_layoutManager drawGlyphsForGlyphRange: drawnRange
|
||||||
|
@ -3934,6 +4150,9 @@ other than copy/paste or dragging. */
|
||||||
unsigned index;
|
unsigned index;
|
||||||
float fraction;
|
float fraction;
|
||||||
|
|
||||||
|
point.x -= _textContainerOrigin.x;
|
||||||
|
point.y -= _textContainerOrigin.y;
|
||||||
|
|
||||||
index = [_layoutManager glyphIndexForPoint: point
|
index = [_layoutManager glyphIndexForPoint: point
|
||||||
inTextContainer: _textContainer
|
inTextContainer: _textContainer
|
||||||
fractionOfDistanceThroughGlyph: &fraction];
|
fractionOfDistanceThroughGlyph: &fraction];
|
||||||
|
@ -4122,12 +4341,15 @@ other than copy/paste or dragging. */
|
||||||
- (NSRect) rectForCharacterRange: (NSRange)aRange
|
- (NSRect) rectForCharacterRange: (NSRange)aRange
|
||||||
{
|
{
|
||||||
NSRange glyphRange;
|
NSRange glyphRange;
|
||||||
|
NSRect rect;
|
||||||
|
|
||||||
glyphRange = [_layoutManager glyphRangeForCharacterRange: aRange
|
glyphRange = [_layoutManager glyphRangeForCharacterRange: aRange
|
||||||
actualCharacterRange: NULL];
|
actualCharacterRange: NULL];
|
||||||
|
rect = [_layoutManager boundingRectForGlyphRange: glyphRange
|
||||||
return [_layoutManager boundingRectForGlyphRange: glyphRange
|
|
||||||
inTextContainer: _textContainer];
|
inTextContainer: _textContainer];
|
||||||
|
rect.origin.x += _textContainerOrigin.x;
|
||||||
|
rect.origin.y += _textContainerOrigin.y;
|
||||||
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Extension method that copies the current selected text to the
|
/** Extension method that copies the current selected text to the
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue