mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 03:11:18 +00:00
Clarify comments about user attribute changing now that I've figured out a way for it to work. Rewrite the actions to match.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@15852 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
5d36c3e89a
commit
94ecd621eb
3 changed files with 227 additions and 163 deletions
|
@ -1,3 +1,9 @@
|
|||
2003-02-02 02:31 Alexander Malmberg <alexander@malmberg.org>
|
||||
|
||||
* Source/NSTextView.m, Source/NSTextView_actions.m: Clarify
|
||||
comments about user attribute changing now that I've figured out
|
||||
a way for it to work. Rewrite the actions to match.
|
||||
|
||||
2003-02-02 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/NSTextView.m
|
||||
|
@ -9,7 +15,7 @@
|
|||
[setFrame:display:]. Use [NSScreen visibleFrame] here and in
|
||||
[stringWithSavedFrame]. Implemented [cascadeTopLeftFromPoint:].
|
||||
Removed unused and empty methods [performHide:] and [performUnhide:].
|
||||
|
||||
|
||||
2003-02-01 15:09 Alexander Malmberg <alexander@malmberg.org>
|
||||
|
||||
* Source/NSTextView.m (-shouldChangeTextInRange:replacementString:):
|
||||
|
|
|
@ -87,16 +87,6 @@ TODOs:
|
|||
think hard about insertion point management
|
||||
|
||||
|
||||
When should the typing attributes be changed? Docs imply that normally
|
||||
you don't touch them at all, you just change the attributes of the
|
||||
selection and the typing attributes will update automagically, but if
|
||||
the selection is empty, you should change the typing attributes instead.
|
||||
|
||||
In a non-rich-text text view, I assume that the typing attributes always
|
||||
hold the attributes of the text. Will need to look over methods that deal
|
||||
with attributes to make sure this holds.
|
||||
|
||||
|
||||
How should resizing work? If the text view is set to track the used part
|
||||
of the text container, when does it actually update its size? Might need
|
||||
a new internal method called from NSLayoutManager when text has changed.
|
||||
|
@ -1983,7 +1973,9 @@ replacementString should be the string that will replace the affected range
|
|||
(disregarding attributes), or nil if only attributes are changed.
|
||||
|
||||
If the affected range or replacement string can't be determined, pass in
|
||||
NSNotFound for the range's location and nil for the string
|
||||
NSNotFound for the range's location and nil for the string. (Ie. even if
|
||||
you know the range, you should pass in NSNotFound so the delegate can tell
|
||||
the difference between a pure attribute change and an unknown change.)
|
||||
|
||||
|
||||
TODO: What if the view isn't first responder? It should be impossible for
|
||||
|
|
|
@ -66,6 +66,23 @@ All actions from NSResponder that make sense for a text view should be
|
|||
implemented here, but this is _not_ the place to add new actions.
|
||||
|
||||
|
||||
When changing attributes, the range returned by
|
||||
rangeForUserCharacterAttributeChange or rangeForUserParagraphAttributeChange
|
||||
should be used. If the location is NSNotFound, nothing should be done (in
|
||||
particular, the typing attributes should _not_ be changed). Otherwise,
|
||||
-shouldChangeTextInRange:replacementString: should be called, and if it
|
||||
returns YES, the attributes of the range and the typing attributes should be
|
||||
changed, and -didChangeText should be called.
|
||||
|
||||
In a non-rich-text text view, the typing attributes _must_always_ hold the
|
||||
attributes of the text. Thus, the typing attributes muse always be changed
|
||||
in the same way that the attributes of the text are changed.
|
||||
|
||||
(TODO: Will need to look over methods that deal with attributes to make
|
||||
sure this holds.)
|
||||
|
||||
|
||||
|
||||
Not all user actions are here. Exceptions:
|
||||
|
||||
-toggleRuler:
|
||||
|
@ -109,6 +126,10 @@ send -shouldChangeTextInRange:replacementString: or -didChangeText.
|
|||
|
||||
-(void) _illegalMovement: (int)textMovement;
|
||||
|
||||
-(void) _changeAttribute: (NSString *)name
|
||||
inRange: (NSRange)r
|
||||
using: (id (*)(id))func;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -146,69 +167,177 @@ send -shouldChangeTextInRange:replacementString: or -didChangeText.
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
-(void) _changeAttribute: (NSString *)name
|
||||
inRange: (NSRange)r
|
||||
using: (id (*)(id))func
|
||||
{
|
||||
unsigned int i;
|
||||
NSRange e, r2;
|
||||
id current, new;
|
||||
|
||||
if (![self shouldChangeTextInRange: r replacementString: nil])
|
||||
return;
|
||||
|
||||
[_textStorage beginEditing];
|
||||
for (i = r.location; i < NSMaxRange(r); )
|
||||
{
|
||||
current = [_textStorage attribute: name
|
||||
atIndex: i
|
||||
effectiveRange: &e];
|
||||
|
||||
r2 = NSMakeRange(i, NSMaxRange(e) - i);
|
||||
r2 = NSIntersectionRange(r2, r);
|
||||
i = NSMaxRange(e);
|
||||
|
||||
new = func(current);
|
||||
if (new != current)
|
||||
{
|
||||
if (!new)
|
||||
{
|
||||
[_textStorage removeAttribute: name
|
||||
range: r2];
|
||||
}
|
||||
else
|
||||
{
|
||||
[_textStorage addAttribute: name
|
||||
value: new
|
||||
range: r2];
|
||||
}
|
||||
}
|
||||
}
|
||||
[_textStorage endEditing];
|
||||
|
||||
current = [_layoutManager->_typingAttributes objectForKey: name];
|
||||
new = func(current);
|
||||
if (new != current)
|
||||
{
|
||||
if (!new)
|
||||
{
|
||||
[_layoutManager->_typingAttributes removeObjectForKey: name];
|
||||
}
|
||||
else
|
||||
{
|
||||
[_layoutManager->_typingAttributes setObject: new forKey: name];
|
||||
}
|
||||
}
|
||||
|
||||
[self didChangeText];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSTextView (user_actions)
|
||||
|
||||
/* Helpers used with _changeAttribute:inRange:using:. */
|
||||
static NSNumber *int_minus_one(NSNumber *cur)
|
||||
{
|
||||
int value;
|
||||
|
||||
if (cur)
|
||||
value = [cur intValue] - 1;
|
||||
else
|
||||
value = -1;
|
||||
|
||||
if (value)
|
||||
return [NSNumber numberWithInt: value];
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
||||
static NSNumber *int_plus_one(NSNumber *cur)
|
||||
{
|
||||
int value;
|
||||
|
||||
if (cur)
|
||||
value = [cur intValue] + 1;
|
||||
else
|
||||
value = 1;
|
||||
|
||||
if (value)
|
||||
return [NSNumber numberWithInt: value];
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
||||
static NSNumber *float_minus_one(NSNumber *cur)
|
||||
{
|
||||
float value;
|
||||
|
||||
if (cur)
|
||||
value = [cur floatValue] - 1;
|
||||
else
|
||||
value = -1;
|
||||
|
||||
if (value)
|
||||
return [NSNumber numberWithFloat: value];
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
||||
static NSNumber *float_plus_one(NSNumber *cur)
|
||||
{
|
||||
int value;
|
||||
|
||||
if (cur)
|
||||
value = [cur floatValue] + 1;
|
||||
else
|
||||
value = 1;
|
||||
|
||||
if (value)
|
||||
return [NSNumber numberWithFloat: value];
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
-(void) subscript: (id)sender
|
||||
{
|
||||
NSNumber *value = [_layoutManager->_typingAttributes
|
||||
objectForKey: NSSuperscriptAttributeName];
|
||||
int sValue;
|
||||
NSRange aRange = [self rangeForUserCharacterAttributeChange];
|
||||
NSRange r = [self rangeForUserCharacterAttributeChange];
|
||||
|
||||
if (aRange.location == NSNotFound)
|
||||
if (r.location == NSNotFound)
|
||||
return;
|
||||
|
||||
if (aRange.length)
|
||||
{
|
||||
if (![self shouldChangeTextInRange: aRange
|
||||
replacementString: nil])
|
||||
return;
|
||||
[_textStorage beginEditing];
|
||||
[_textStorage subscriptRange: aRange];
|
||||
[_textStorage endEditing];
|
||||
[self didChangeText];
|
||||
}
|
||||
|
||||
// Set the typing attributes
|
||||
if (value != nil)
|
||||
sValue = [value intValue] - 1;
|
||||
else
|
||||
sValue = -1;
|
||||
[_layoutManager->_typingAttributes setObject: [NSNumber numberWithInt: sValue]
|
||||
forKey: NSSuperscriptAttributeName];
|
||||
[self _changeAttribute: NSSuperscriptAttributeName
|
||||
inRange: r
|
||||
using: int_minus_one];
|
||||
}
|
||||
|
||||
-(void) superscript: (id)sender
|
||||
{
|
||||
NSNumber *value = [_layoutManager->_typingAttributes
|
||||
objectForKey: NSSuperscriptAttributeName];
|
||||
int sValue;
|
||||
NSRange aRange = [self rangeForUserCharacterAttributeChange];
|
||||
NSRange r = [self rangeForUserCharacterAttributeChange];
|
||||
|
||||
if (aRange.location == NSNotFound)
|
||||
if (r.location == NSNotFound)
|
||||
return;
|
||||
|
||||
if (aRange.length)
|
||||
{
|
||||
if (![self shouldChangeTextInRange: aRange
|
||||
replacementString: nil])
|
||||
return;
|
||||
[_textStorage beginEditing];
|
||||
[_textStorage superscriptRange: aRange];
|
||||
[_textStorage endEditing];
|
||||
[self didChangeText];
|
||||
}
|
||||
[self _changeAttribute: NSSuperscriptAttributeName
|
||||
inRange: r
|
||||
using: int_plus_one];
|
||||
}
|
||||
|
||||
// Set the typing attributes
|
||||
if (value != nil)
|
||||
sValue = [value intValue] + 1;
|
||||
else
|
||||
sValue = 1;
|
||||
[_layoutManager->_typingAttributes setObject: [NSNumber numberWithInt: sValue]
|
||||
forKey: NSSuperscriptAttributeName];
|
||||
-(void) lowerBaseline: (id)sender
|
||||
{
|
||||
NSRange r = [self rangeForUserCharacterAttributeChange];
|
||||
|
||||
if (r.location == NSNotFound)
|
||||
return;
|
||||
|
||||
[self _changeAttribute: NSSuperscriptAttributeName
|
||||
inRange: r
|
||||
using: float_plus_one];
|
||||
}
|
||||
|
||||
-(void) raiseBaseline: (id)sender
|
||||
{
|
||||
NSRange r = [self rangeForUserCharacterAttributeChange];
|
||||
|
||||
if (r.location == NSNotFound)
|
||||
return;
|
||||
|
||||
[self _changeAttribute: NSBaselineOffsetAttributeName
|
||||
inRange: r
|
||||
using: float_minus_one];
|
||||
}
|
||||
|
||||
-(void) unscript: (id)sender
|
||||
|
@ -218,21 +347,27 @@ send -shouldChangeTextInRange:replacementString: or -didChangeText.
|
|||
if (aRange.location == NSNotFound)
|
||||
return;
|
||||
|
||||
if (![self shouldChangeTextInRange: aRange
|
||||
replacementString: nil])
|
||||
return;
|
||||
|
||||
if (aRange.length)
|
||||
{
|
||||
if (![self shouldChangeTextInRange: aRange
|
||||
replacementString: nil])
|
||||
return;
|
||||
[_textStorage beginEditing];
|
||||
[_textStorage unscriptRange: aRange];
|
||||
[_textStorage removeAttribute: NSSuperscriptAttributeName
|
||||
range: aRange];
|
||||
[_textStorage removeAttribute: NSBaselineOffsetAttributeName
|
||||
range: aRange];
|
||||
[_textStorage endEditing];
|
||||
[self didChangeText];
|
||||
}
|
||||
|
||||
// Set the typing attributes
|
||||
[_layoutManager->_typingAttributes removeObjectForKey: NSSuperscriptAttributeName];
|
||||
[_layoutManager->_typingAttributes removeObjectForKey: NSBaselineOffsetAttributeName];
|
||||
|
||||
[self didChangeText];
|
||||
}
|
||||
|
||||
|
||||
-(void) underline: (id)sender
|
||||
{
|
||||
BOOL doUnderline = YES;
|
||||
|
@ -264,81 +399,20 @@ send -shouldChangeTextInRange:replacementString: or -didChangeText.
|
|||
forKey: NSUnderlineStyleAttributeName];
|
||||
}
|
||||
|
||||
|
||||
-(void) useStandardKerning: (id)sender
|
||||
{
|
||||
// rekern for selected range if rich text, else rekern entire document.
|
||||
NSRange aRange = [self rangeForUserCharacterAttributeChange];
|
||||
|
||||
if (aRange.location == NSNotFound)
|
||||
return;
|
||||
|
||||
if (![self shouldChangeTextInRange: aRange
|
||||
replacementString: nil])
|
||||
return;
|
||||
[_textStorage beginEditing];
|
||||
|
||||
[_textStorage removeAttribute: NSKernAttributeName
|
||||
range: aRange];
|
||||
[_textStorage endEditing];
|
||||
[self didChangeText];
|
||||
}
|
||||
|
||||
-(void) lowerBaseline: (id)sender
|
||||
{
|
||||
id value;
|
||||
float sValue;
|
||||
NSRange effRange;
|
||||
NSRange aRange = [self rangeForUserCharacterAttributeChange];
|
||||
|
||||
if (aRange.location == NSNotFound)
|
||||
return;
|
||||
|
||||
if (![self shouldChangeTextInRange: aRange
|
||||
replacementString: nil])
|
||||
return;
|
||||
[_textStorage beginEditing];
|
||||
// We take the value form the first character and use it for the whole range
|
||||
value = [_textStorage attribute: NSBaselineOffsetAttributeName
|
||||
atIndex: aRange.location
|
||||
effectiveRange: &effRange];
|
||||
|
||||
if (value != nil)
|
||||
sValue = [value floatValue] + 1.0;
|
||||
else
|
||||
sValue = 1.0;
|
||||
|
||||
[_textStorage addAttribute: NSBaselineOffsetAttributeName
|
||||
value: [NSNumber numberWithFloat: sValue]
|
||||
range: aRange];
|
||||
}
|
||||
|
||||
-(void) raiseBaseline: (id)sender
|
||||
{
|
||||
id value;
|
||||
float sValue;
|
||||
NSRange effRange;
|
||||
NSRange aRange = [self rangeForUserCharacterAttributeChange];
|
||||
|
||||
if (aRange.location == NSNotFound)
|
||||
return;
|
||||
|
||||
if (![self shouldChangeTextInRange: aRange
|
||||
replacementString: nil])
|
||||
return;
|
||||
[_textStorage beginEditing];
|
||||
// We take the value form the first character and use it for the whole range
|
||||
value = [_textStorage attribute: NSBaselineOffsetAttributeName
|
||||
atIndex: aRange.location
|
||||
effectiveRange: &effRange];
|
||||
|
||||
if (value != nil)
|
||||
sValue = [value floatValue] - 1.0;
|
||||
else
|
||||
sValue = -1.0;
|
||||
|
||||
[_textStorage addAttribute: NSBaselineOffsetAttributeName
|
||||
value: [NSNumber numberWithFloat: sValue]
|
||||
range: aRange];
|
||||
[_textStorage endEditing];
|
||||
[_layoutManager->_typingAttributes removeObjectForKey: NSKernAttributeName];
|
||||
[self didChangeText];
|
||||
}
|
||||
|
||||
|
@ -348,54 +422,40 @@ send -shouldChangeTextInRange:replacementString: or -didChangeText.
|
|||
|
||||
if (aRange.location == NSNotFound)
|
||||
return;
|
||||
|
||||
if (![self shouldChangeTextInRange: aRange
|
||||
replacementString: nil])
|
||||
return;
|
||||
[_textStorage beginEditing];
|
||||
|
||||
[_textStorage addAttribute: NSKernAttributeName
|
||||
value: [NSNumber numberWithFloat: 0.0]
|
||||
range: aRange];
|
||||
[_textStorage endEditing];
|
||||
[_layoutManager->_typingAttributes setObject: [NSNumber numberWithFloat: 0.0]
|
||||
forKey: NSKernAttributeName];
|
||||
[self didChangeText];
|
||||
}
|
||||
|
||||
-(void) loosenKerning: (id)sender
|
||||
{
|
||||
NSRange aRange = [self rangeForUserCharacterAttributeChange];
|
||||
NSRange r = [self rangeForUserCharacterAttributeChange];
|
||||
|
||||
if (aRange.location == NSNotFound)
|
||||
if (r.location == NSNotFound)
|
||||
return;
|
||||
|
||||
if (![self shouldChangeTextInRange: aRange
|
||||
replacementString: nil])
|
||||
return;
|
||||
[_textStorage beginEditing];
|
||||
// FIXME: Should use the current kerning and work relative to point size
|
||||
[_textStorage addAttribute: NSKernAttributeName
|
||||
value: [NSNumber numberWithFloat: 1.0]
|
||||
range: aRange];
|
||||
[_textStorage endEditing];
|
||||
[self didChangeText];
|
||||
[self _changeAttribute: NSKernAttributeName
|
||||
inRange: r
|
||||
using: float_plus_one];
|
||||
}
|
||||
|
||||
-(void) tightenKerning: (id)sender
|
||||
{
|
||||
NSRange aRange = [self rangeForUserCharacterAttributeChange];
|
||||
NSRange r = [self rangeForUserCharacterAttributeChange];
|
||||
|
||||
if (aRange.location == NSNotFound)
|
||||
if (r.location == NSNotFound)
|
||||
return;
|
||||
|
||||
if (![self shouldChangeTextInRange: aRange
|
||||
replacementString: nil])
|
||||
return;
|
||||
[_textStorage beginEditing];
|
||||
// FIXME: Should use the current kerning and work relative to point size
|
||||
[_textStorage addAttribute: NSKernAttributeName
|
||||
value: [NSNumber numberWithFloat: -1.0]
|
||||
range: aRange];
|
||||
[_textStorage endEditing];
|
||||
[self didChangeText];
|
||||
[self _changeAttribute: NSKernAttributeName
|
||||
inRange: r
|
||||
using: float_minus_one];
|
||||
}
|
||||
|
||||
-(void) useStandardLigatures: (id)sender
|
||||
|
@ -408,11 +468,11 @@ send -shouldChangeTextInRange:replacementString: or -didChangeText.
|
|||
if (![self shouldChangeTextInRange: aRange
|
||||
replacementString: nil])
|
||||
return;
|
||||
[_textStorage beginEditing];
|
||||
[_textStorage addAttribute: NSLigatureAttributeName
|
||||
value: [NSNumber numberWithInt: 1]
|
||||
range: aRange];
|
||||
[_textStorage endEditing];
|
||||
[_layoutManager->_typingAttributes setObject: [NSNumber numberWithInt: 1]
|
||||
forKey: NSLigatureAttributeName];
|
||||
[self didChangeText];
|
||||
}
|
||||
|
||||
|
@ -426,11 +486,10 @@ send -shouldChangeTextInRange:replacementString: or -didChangeText.
|
|||
if (![self shouldChangeTextInRange: aRange
|
||||
replacementString: nil])
|
||||
return;
|
||||
[_textStorage beginEditing];
|
||||
[_textStorage addAttribute: NSLigatureAttributeName
|
||||
value: [NSNumber numberWithInt: 0]
|
||||
|
||||
[_textStorage removeAttribute: NSLigatureAttributeName
|
||||
range: aRange];
|
||||
[_textStorage endEditing];
|
||||
[_layoutManager->_typingAttributes removeObjectForKey: NSLigatureAttributeName];
|
||||
[self didChangeText];
|
||||
}
|
||||
|
||||
|
@ -444,11 +503,11 @@ send -shouldChangeTextInRange:replacementString: or -didChangeText.
|
|||
if (![self shouldChangeTextInRange: aRange
|
||||
replacementString: nil])
|
||||
return;
|
||||
[_textStorage beginEditing];
|
||||
[_textStorage addAttribute: NSLigatureAttributeName
|
||||
value: [NSNumber numberWithInt: 2]
|
||||
range: aRange];
|
||||
[_textStorage endEditing];
|
||||
[_layoutManager->_typingAttributes setObject: [NSNumber numberWithInt: 2]
|
||||
forKey: NSLigatureAttributeName];
|
||||
[self didChangeText];
|
||||
}
|
||||
|
||||
|
@ -459,6 +518,7 @@ send -shouldChangeTextInRange:replacementString: or -didChangeText.
|
|||
"toggleTraditionalCharacterShape:", "NSTextView");
|
||||
}
|
||||
|
||||
|
||||
-(void) insertNewline: (id)sender
|
||||
{
|
||||
if (_tf.is_field_editor)
|
||||
|
@ -492,6 +552,7 @@ send -shouldChangeTextInRange:replacementString: or -didChangeText.
|
|||
//[self insertText: @"\t"];
|
||||
}
|
||||
|
||||
|
||||
-(void) deleteForward: (id)sender
|
||||
{
|
||||
NSRange range = [self rangeForUserTextChange];
|
||||
|
@ -577,6 +638,7 @@ send -shouldChangeTextInRange:replacementString: or -didChangeText.
|
|||
[self setSelectedRange: NSMakeRange (range.location, 0)];
|
||||
}
|
||||
|
||||
|
||||
-(void) moveUp: (id)sender
|
||||
{
|
||||
/* float originalInsertionPoint;
|
||||
|
@ -1109,6 +1171,7 @@ send -shouldChangeTextInRange:replacementString: or -didChangeText.
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
-(void) scrollLineDown: (id)sender
|
||||
{
|
||||
// TODO
|
||||
|
@ -1146,7 +1209,8 @@ send -shouldChangeTextInRange:replacementString: or -didChangeText.
|
|||
{
|
||||
NSRange aRange;
|
||||
NSRect ignored;
|
||||
|
||||
|
||||
/* TODO: broken. assumes glyph==character */
|
||||
ignored = [_layoutManager lineFragmentRectForGlyphAtIndex:
|
||||
_layoutManager->_selected_range.location
|
||||
effectiveRange: &aRange];
|
||||
|
@ -1155,6 +1219,7 @@ send -shouldChangeTextInRange:replacementString: or -didChangeText.
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* The following method is bound to 'Control-t', and must work like
|
||||
* pressing 'Control-t' inside Emacs. For example, say that I type
|
||||
* 'Nicoal' in a NSTextView. Then, I press 'Control-t'. This should
|
||||
|
@ -1202,6 +1267,7 @@ insertion point. (see also: miswart)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
-(void) delete: (id)sender
|
||||
{
|
||||
[self deleteForward: sender];
|
||||
|
|
Loading…
Reference in a new issue