mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-06-01 16:01:54 +00:00
Multiple drawing fixes
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@4006 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
a0e8d526a3
commit
1ee7514981
6 changed files with 718 additions and 378 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
Wed Mar 31 21:06:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
|
* Source/NSCell.m: Make bezeled and bordered mutually exclusive
|
||||||
|
- bug report by Jonathan Gapen
|
||||||
|
* Headers/AppKit/NSStringDrawing.h: Add all the string drawing stuff
|
||||||
|
* Source/NSStringDrawing.m: Rewrite from scratch - preliminary work.
|
||||||
|
* Source/NSButton.m: Removed redundant lock/unlock in drawing ops.
|
||||||
|
* Source/NSControl.m: tidy.
|
||||||
|
* Source/NSSplitView.m: avoid compiler warning.
|
||||||
|
* Source/NSTextFieldCell.m: tidy up, set draws background color in
|
||||||
|
initialisation, fix border/bezel drawing.
|
||||||
|
|
||||||
Wed Mar 31 17:32:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
Wed Mar 31 17:32:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
* Source/NSView: ([-viewWithTag:]) complete rewrite to find nearest
|
* Source/NSView: ([-viewWithTag:]) complete rewrite to find nearest
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
Author: Felipe A. Rodriguez <far@ix.netcom.com>
|
Author: Felipe A. Rodriguez <far@ix.netcom.com>
|
||||||
Date: Aug 1998
|
Date: Aug 1998
|
||||||
|
Rewrite: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
Date: Mar 1999
|
||||||
|
|
||||||
This file is part of the GNUstep GUI Library.
|
This file is part of the GNUstep GUI Library.
|
||||||
|
|
||||||
|
@ -34,45 +36,42 @@
|
||||||
#include <Foundation/NSAttributedString.h>
|
#include <Foundation/NSAttributedString.h>
|
||||||
#include <Foundation/NSGeometry.h>
|
#include <Foundation/NSGeometry.h>
|
||||||
|
|
||||||
// global NSString attribute names used in ascessing
|
// global NSString attribute names used in accessing
|
||||||
// the respective property in a text attributes
|
// the respective property in a text attributes
|
||||||
// dictionary. if the key is not in the dictionary
|
// dictionary. if the key is not in the dictionary
|
||||||
// the default value is assumed
|
// the default value is assumed
|
||||||
extern NSString *NSFontAttributeName; // NSFont, Helvetica 12
|
extern NSString *NSFontAttributeName;
|
||||||
extern NSString *NSParagraphStyleAttributeName; // defaultParagraphStyle
|
extern NSString *NSParagraphStyleAttributeName;
|
||||||
extern NSString *NSForegroundColorAttributeName; // NSColor, blackColor
|
extern NSString *NSForegroundColorAttributeName;
|
||||||
extern NSString *NSUnderlineStyleAttributeName; // NSNumber int, 0 no line
|
extern NSString *NSUnderlineStyleAttributeName;
|
||||||
extern NSString *NSSuperscriptAttributeName; // NSNumber int, 0
|
extern NSString *NSSuperscriptAttributeName;
|
||||||
extern NSString *NSBackgroundColorAttributeName; // NSColor, nil
|
extern NSString *NSBackgroundColorAttributeName;
|
||||||
extern NSString *NSAttachmentAttributeName; // NSTextAttachment, nil
|
extern NSString *NSAttachmentAttributeName;
|
||||||
extern NSString *NSLigatureAttributeName; // NSNumber int, 1
|
extern NSString *NSLigatureAttributeName;
|
||||||
extern NSString *NSBaselineOffsetAttributeName; // NSNumber float, 0 points
|
extern NSString *NSBaselineOffsetAttributeName;
|
||||||
extern NSString *NSKernAttributeName; // NSNumber float, 0
|
extern NSString *NSKernAttributeName;
|
||||||
//
|
|
||||||
// Extended definitions:
|
|
||||||
//
|
|
||||||
// NSParagraphStyleAttributeName NSParagraphStyle, default is
|
|
||||||
// defaultParagraphStyle
|
|
||||||
//
|
|
||||||
// NSKernAttributeName NSNumber float, offset from
|
|
||||||
// baseline, amount to modify default
|
|
||||||
// kerning, if 0 kerning is off
|
|
||||||
|
|
||||||
|
// Currently supported values for NSUnderlineStyleAttributeName
|
||||||
enum
|
enum
|
||||||
{ // Currently supported values for
|
{
|
||||||
NSSingleUnderlineStyle = 1 // NSUnderlineStyleAttributeName
|
GSNoUnderlineStyle = 0,
|
||||||
|
NSSingleUnderlineStyle = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@interface NSString (NSStringDrawing)
|
@interface NSString (NSStringDrawing)
|
||||||
|
|
||||||
- (NSSize)sizeWithAttributes:(NSDictionary *)attrs;
|
- (void) drawAtPoint: (NSPoint)point withAttributes: (NSDictionary*)attrs;
|
||||||
|
- (void) drawInRect: (NSRect)rect withAttributes: (NSDictionary*)attrs;
|
||||||
|
- (NSSize) sizeWithAttributes: (NSDictionary*)attrs;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface NSAttributedString (NSStringDrawing)
|
@interface NSAttributedString (NSStringDrawing)
|
||||||
|
|
||||||
- (NSSize)size;
|
- (NSSize) size;
|
||||||
|
- (void) drawAtPoint: (NSPoint)point;
|
||||||
|
- (void) drawInRect: (NSRect)rect;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -508,11 +508,15 @@
|
||||||
- (void) setBezeled: (BOOL)flag
|
- (void) setBezeled: (BOOL)flag
|
||||||
{
|
{
|
||||||
cell_bezeled = flag;
|
cell_bezeled = flag;
|
||||||
|
if (cell_bezeled)
|
||||||
|
cell_bordered = NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setBordered: (BOOL)flag
|
- (void) setBordered: (BOOL)flag
|
||||||
{
|
{
|
||||||
cell_bordered = flag;
|
cell_bordered = flag;
|
||||||
|
if (cell_bordered)
|
||||||
|
cell_bezeled = NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -670,14 +674,11 @@ static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
|
||||||
// draw the border if needed
|
// draw the border if needed
|
||||||
if ([self isBordered])
|
if ([self isBordered])
|
||||||
{
|
{
|
||||||
if ([self isBezeled])
|
NSFrameRect(cellFrame);
|
||||||
{
|
}
|
||||||
NSDrawWhiteBezel(cellFrame, cellFrame);
|
else if ([self isBezeled])
|
||||||
}
|
{
|
||||||
else
|
NSDrawWhiteBezel(cellFrame, cellFrame);
|
||||||
{
|
|
||||||
NSFrameRect(cellFrame);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[self drawInteriorWithFrame: cellFrame inView: controlView];
|
[self drawInteriorWithFrame: cellFrame inView: controlView];
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
NSControl.m
|
NSControl.m
|
||||||
|
|
||||||
The abstract control class
|
The abstract control class
|
||||||
|
@ -9,14 +9,14 @@
|
||||||
Date: 1996
|
Date: 1996
|
||||||
Author: Felipe A. Rodriguez <far@ix.netcom.com>
|
Author: Felipe A. Rodriguez <far@ix.netcom.com>
|
||||||
Date: August 1998
|
Date: August 1998
|
||||||
|
|
||||||
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
|
||||||
modify it under the terms of the GNU Library General Public
|
modify it under the terms of the GNU Library General Public
|
||||||
License as published by the Free Software Foundation; either
|
License as published by the Free Software Foundation; either
|
||||||
version 2 of the License, or (at your option) any later version.
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
This library is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
@ -26,11 +26,13 @@
|
||||||
License along with this library; see the file COPYING.LIB.
|
License along with this library; see the file COPYING.LIB.
|
||||||
If not, write to the Free Software Foundation,
|
If not, write to the Free Software Foundation,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gnustep/gui/config.h>
|
#include <gnustep/gui/config.h>
|
||||||
|
|
||||||
|
#include <Foundation/NSException.h>
|
||||||
#include <AppKit/NSControl.h>
|
#include <AppKit/NSControl.h>
|
||||||
|
#include <AppKit/NSColor.h>
|
||||||
#include <AppKit/NSEvent.h>
|
#include <AppKit/NSEvent.h>
|
||||||
#include <AppKit/NSWindow.h>
|
#include <AppKit/NSWindow.h>
|
||||||
#include <AppKit/NSApplication.h>
|
#include <AppKit/NSApplication.h>
|
||||||
|
@ -48,39 +50,47 @@ static id _NSCONTROL_CELL_CLASS = nil;
|
||||||
//
|
//
|
||||||
// Class methods
|
// Class methods
|
||||||
//
|
//
|
||||||
+ (void)initialize
|
+ (void) initialize
|
||||||
{
|
{
|
||||||
if (self == [NSControl class])
|
if (self == [NSControl class])
|
||||||
{
|
{
|
||||||
NSDebugLog(@"Initialize NSControl class\n");
|
NSDebugLog(@"Initialize NSControl class\n");
|
||||||
[self setVersion:1]; // Initial version
|
[self setVersion: 1];
|
||||||
[self setCellClass:[NSCell class]]; // Set cell class
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setting the Control's Cell
|
// Setting the Control's Cell
|
||||||
//
|
//
|
||||||
+ (Class)cellClass { return _NSCONTROL_CELL_CLASS; }
|
+ (Class) cellClass
|
||||||
+ (void)setCellClass:(Class)factoryId { _NSCONTROL_CELL_CLASS = factoryId; }
|
{
|
||||||
|
return _NSCONTROL_CELL_CLASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void) setCellClass: (Class)factoryId
|
||||||
|
{
|
||||||
|
_NSCONTROL_CELL_CLASS = factoryId;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Instance methods
|
// Instance methods
|
||||||
//
|
//
|
||||||
- (id)initWithFrame:(NSRect)frameRect
|
- (id) initWithFrame: (NSRect)frameRect
|
||||||
{
|
{
|
||||||
[super initWithFrame:frameRect];
|
[super initWithFrame: frameRect];
|
||||||
// create our cell
|
if (_NSCONTROL_CELL_CLASS)
|
||||||
[self setCell:[[_NSCONTROL_CELL_CLASS new] autorelease]];
|
[self setCell: [[_NSCONTROL_CELL_CLASS new] autorelease]];
|
||||||
tag = 0;
|
else
|
||||||
|
[self setCell: [[NSCell new] autorelease]];
|
||||||
|
tag = 0;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
[cell release]; // release our cell
|
[cell release];
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -97,219 +107,259 @@ static id _NSCONTROL_CELL_CLASS = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setting the Control's Cell
|
// Setting the Control's Cell
|
||||||
//
|
//
|
||||||
- (id)cell { return cell; }
|
- (id) cell
|
||||||
|
|
||||||
- (void)setCell:(NSCell *)aCell
|
|
||||||
{
|
{
|
||||||
if (![aCell isKindOfClass:[NSCell class]]) // must be a cell
|
return cell;
|
||||||
return;
|
}
|
||||||
|
|
||||||
[cell setControlView:nil];
|
- (void) setCell: (NSCell *)aCell
|
||||||
[aCell setControlView:self];
|
{
|
||||||
|
if (![aCell isKindOfClass: [NSCell class]])
|
||||||
[aCell retain];
|
[NSException raise: NSInvalidArgumentException
|
||||||
[cell release];
|
format: @"attempt to set silly value for control cell"];
|
||||||
cell = aCell;
|
|
||||||
|
[cell setControlView: nil];
|
||||||
|
[aCell setControlView: self];
|
||||||
|
|
||||||
|
[aCell retain];
|
||||||
|
[cell release];
|
||||||
|
cell = aCell;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Enabling and Disabling the Control
|
// Enabling and Disabling the Control
|
||||||
//
|
//
|
||||||
- (BOOL)isEnabled { return [[self selectedCell] isEnabled]; }
|
- (BOOL) isEnabled
|
||||||
- (void)setEnabled:(BOOL)flag { [[self selectedCell] setEnabled:flag]; }
|
|
||||||
|
|
||||||
//
|
|
||||||
// Identifying the Selected Cell
|
|
||||||
//
|
|
||||||
- (id)selectedCell
|
|
||||||
{
|
{
|
||||||
if ([cell state])
|
return [[self selectedCell] isEnabled];
|
||||||
return cell;
|
|
||||||
else
|
|
||||||
return nil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int)selectedTag
|
- (void) setEnabled: (BOOL)flag
|
||||||
{
|
{
|
||||||
return [[self selectedCell] tag];
|
[[self selectedCell] setEnabled: flag];
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setting the Control's Value
|
// Identifying the Selected Cell
|
||||||
//
|
//
|
||||||
- (double)doubleValue
|
- (id) selectedCell
|
||||||
{
|
{
|
||||||
return [[self selectedCell] doubleValue];
|
if ([cell state])
|
||||||
|
return cell;
|
||||||
|
else
|
||||||
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (float)floatValue
|
- (int) selectedTag
|
||||||
{
|
{
|
||||||
return [[self selectedCell] floatValue];
|
return [[self selectedCell] tag];
|
||||||
}
|
|
||||||
|
|
||||||
- (int)intValue
|
|
||||||
{
|
|
||||||
return [[self selectedCell] intValue];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setDoubleValue:(double)aDouble
|
|
||||||
{
|
|
||||||
[[self selectedCell] setDoubleValue:aDouble];
|
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setFloatValue:(float)aFloat
|
|
||||||
{
|
|
||||||
[[self selectedCell] setFloatValue:aFloat];
|
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setIntValue:(int)anInt
|
|
||||||
{
|
|
||||||
[[self selectedCell] setIntValue:anInt];
|
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setNeedsDisplay { [super setNeedsDisplay:YES]; }
|
|
||||||
|
|
||||||
- (void)setStringValue:(NSString *)aString
|
|
||||||
{
|
|
||||||
[[self selectedCell] setStringValue:aString];
|
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)stringValue
|
|
||||||
{
|
|
||||||
return [[self selectedCell] stringValue];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Interacting with Other Controls
|
// Setting the Control's Value
|
||||||
//
|
//
|
||||||
- (void)takeDoubleValueFrom:(id)sender
|
- (double) doubleValue
|
||||||
{
|
{
|
||||||
[[self selectedCell] takeDoubleValueFrom:sender];
|
return [[self selectedCell] doubleValue];
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)takeFloatValueFrom:(id)sender
|
- (float) floatValue
|
||||||
{
|
{
|
||||||
[[self selectedCell] takeFloatValueFrom:sender];
|
return [[self selectedCell] floatValue];
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)takeIntValueFrom:(id)sender
|
- (int) intValue
|
||||||
{
|
{
|
||||||
[[self selectedCell] takeIntValueFrom:sender];
|
return [[self selectedCell] intValue];
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)takeStringValueFrom:(id)sender
|
- (void) setDoubleValue: (double)aDouble
|
||||||
{
|
{
|
||||||
[[self selectedCell] takeStringValueFrom:sender];
|
[[self selectedCell] setDoubleValue: aDouble];
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay: YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setFloatValue: (float)aFloat
|
||||||
|
{
|
||||||
|
[[self selectedCell] setFloatValue: aFloat];
|
||||||
|
[self setNeedsDisplay: YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setIntValue: (int)anInt
|
||||||
|
{
|
||||||
|
[[self selectedCell] setIntValue: anInt];
|
||||||
|
[self setNeedsDisplay: YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setNeedsDisplay
|
||||||
|
{
|
||||||
|
[super setNeedsDisplay: YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setStringValue: (NSString *)aString
|
||||||
|
{
|
||||||
|
[[self selectedCell] setStringValue: aString];
|
||||||
|
[self setNeedsDisplay: YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) stringValue
|
||||||
|
{
|
||||||
|
return [[self selectedCell] stringValue];
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Formatting Text
|
// Interacting with Other Controls
|
||||||
//
|
//
|
||||||
- (NSTextAlignment)alignment
|
- (void) takeDoubleValueFrom: (id)sender
|
||||||
{
|
{
|
||||||
if (cell)
|
[[self selectedCell] takeDoubleValueFrom: sender];
|
||||||
return [cell alignment];
|
[self setNeedsDisplay: YES];
|
||||||
else
|
|
||||||
return NSLeftTextAlignment;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSFont *)font
|
- (void) takeFloatValueFrom: (id)sender
|
||||||
{
|
{
|
||||||
if (cell)
|
[[self selectedCell] takeFloatValueFrom: sender];
|
||||||
return [cell font];
|
[self setNeedsDisplay: YES];
|
||||||
else
|
|
||||||
return nil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setAlignment:(NSTextAlignment)mode
|
- (void) takeIntValueFrom: (id)sender
|
||||||
{
|
{
|
||||||
if (cell)
|
[[self selectedCell] takeIntValueFrom: sender];
|
||||||
{
|
[self setNeedsDisplay: YES];
|
||||||
[cell setAlignment:mode];
|
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setFont:(NSFont *)fontObject
|
- (void) takeStringValueFrom: (id)sender
|
||||||
{
|
{
|
||||||
if (cell)
|
[[self selectedCell] takeStringValueFrom: sender];
|
||||||
[cell setFont:fontObject];
|
[self setNeedsDisplay: YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setFloatingPointFormat:(BOOL)autoRange
|
|
||||||
left:(unsigned)leftDigits
|
|
||||||
right:(unsigned)rightDigits
|
|
||||||
{}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Managing the Field Editor
|
// Formatting Text
|
||||||
//
|
//
|
||||||
- (BOOL)abortEditing { return NO; }
|
- (NSTextAlignment) alignment
|
||||||
- (NSText *)currentEditor { return nil; }
|
|
||||||
- (void)validateEditing {} // FIX ME
|
|
||||||
|
|
||||||
//
|
|
||||||
// Resizing the Control
|
|
||||||
//
|
|
||||||
- (void)calcSize {} // FIX ME
|
|
||||||
- (void)sizeToFit {}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Displaying the Control and Cell
|
|
||||||
//
|
|
||||||
- (void)drawCell:(NSCell *)aCell
|
|
||||||
{
|
{
|
||||||
if (cell == aCell)
|
if (cell)
|
||||||
{
|
return [cell alignment];
|
||||||
[self lockFocus];
|
else
|
||||||
[cell drawWithFrame:bounds inView:self];
|
return NSLeftTextAlignment;
|
||||||
[self unlockFocus];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)drawCellInside:(NSCell *)aCell
|
- (NSFont *) font
|
||||||
{
|
{
|
||||||
if (cell == aCell)
|
if (cell)
|
||||||
{
|
return [cell font];
|
||||||
[self lockFocus];
|
else
|
||||||
[cell drawInteriorWithFrame:bounds inView:self];
|
return nil;
|
||||||
[self unlockFocus];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)selectCell:(NSCell *)aCell
|
- (void) setAlignment: (NSTextAlignment)mode
|
||||||
{
|
{
|
||||||
if (cell == aCell)
|
if (cell)
|
||||||
[cell setState:1];
|
{
|
||||||
|
[cell setAlignment: mode];
|
||||||
|
[self setNeedsDisplay: YES];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateCell:(NSCell *)aCell { [self setNeedsDisplay:YES]; }
|
- (void) setFont: (NSFont *)fontObject
|
||||||
- (void)updateCellInside:(NSCell *)aCell { [self setNeedsDisplay:YES]; }
|
|
||||||
|
|
||||||
//
|
|
||||||
// Target and Action
|
|
||||||
//
|
|
||||||
- (SEL)action { return [cell action]; }
|
|
||||||
- (BOOL)isContinuous { return [cell isContinuous]; }
|
|
||||||
|
|
||||||
- (BOOL)sendAction:(SEL)theAction to:(id)theTarget
|
|
||||||
{
|
{
|
||||||
NSApplication *theApp = [NSApplication sharedApplication];
|
if (cell)
|
||||||
|
[cell setFont: fontObject];
|
||||||
|
}
|
||||||
|
|
||||||
if (theAction && theTarget)
|
- (void) setFloatingPointFormat: (BOOL)autoRange
|
||||||
return [theApp sendAction:theAction to:theTarget from:self];
|
left: (unsigned)leftDigits
|
||||||
else
|
right: (unsigned)rightDigits
|
||||||
return NO;
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Managing the Field Editor
|
||||||
|
//
|
||||||
|
- (BOOL) abortEditing
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSText *) currentEditor
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) validateEditing
|
||||||
|
{
|
||||||
|
} // FIX ME
|
||||||
|
|
||||||
|
//
|
||||||
|
// Resizing the Control
|
||||||
|
//
|
||||||
|
- (void) calcSize
|
||||||
|
{
|
||||||
|
} // FIX ME
|
||||||
|
|
||||||
|
- (void) sizeToFit
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Displaying the Control and Cell
|
||||||
|
//
|
||||||
|
- (void) drawCell: (NSCell *)aCell
|
||||||
|
{
|
||||||
|
if (cell == aCell)
|
||||||
|
{
|
||||||
|
[cell drawWithFrame: bounds inView: self];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) drawCellInside: (NSCell *)aCell
|
||||||
|
{
|
||||||
|
if (cell == aCell)
|
||||||
|
{
|
||||||
|
[cell drawInteriorWithFrame: bounds inView: self];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) selectCell: (NSCell *)aCell
|
||||||
|
{
|
||||||
|
if (cell == aCell)
|
||||||
|
[cell setState: 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) updateCell: (NSCell *)aCell
|
||||||
|
{
|
||||||
|
[self setNeedsDisplay: YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) updateCellInside: (NSCell *)aCell
|
||||||
|
{
|
||||||
|
[self setNeedsDisplay: YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Target and Action
|
||||||
|
//
|
||||||
|
- (SEL) action
|
||||||
|
{
|
||||||
|
return [cell action];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) isContinuous
|
||||||
|
{
|
||||||
|
return [cell isContinuous];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) sendAction: (SEL)theAction to: (id)theTarget
|
||||||
|
{
|
||||||
|
NSApplication *theApp = [NSApplication sharedApplication];
|
||||||
|
|
||||||
|
if (theAction && theTarget)
|
||||||
|
return [theApp sendAction: theAction to: theTarget from: self];
|
||||||
|
else
|
||||||
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int) sendActionOn: (int)mask
|
- (int) sendActionOn: (int)mask
|
||||||
|
@ -317,124 +367,154 @@ NSApplication *theApp = [NSApplication sharedApplication];
|
||||||
return [cell sendActionOn: mask];
|
return [cell sendActionOn: mask];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setAction:(SEL)aSelector { [cell setAction:aSelector]; }
|
- (void) setAction: (SEL)aSelector
|
||||||
- (void)setContinuous:(BOOL)flag { [cell setContinuous:flag]; }
|
|
||||||
- (void)setTarget:(id)anObject { [cell setTarget:anObject]; }
|
|
||||||
- (id)target { return [cell target]; }
|
|
||||||
|
|
||||||
//
|
|
||||||
// Assigning a Tag
|
|
||||||
//
|
|
||||||
- (void)setTag:(int)anInt { tag = anInt; }
|
|
||||||
- (int)tag { return tag; }
|
|
||||||
|
|
||||||
//
|
|
||||||
// Tracking the Mouse
|
|
||||||
//
|
|
||||||
- (void)mouseDown:(NSEvent *)theEvent
|
|
||||||
{
|
{
|
||||||
NSApplication *theApp = [NSApplication sharedApplication];
|
[cell setAction: aSelector];
|
||||||
BOOL mouseUp = NO, done = NO;
|
|
||||||
NSEvent *e;
|
|
||||||
int oldActionMask;
|
|
||||||
NSPoint location;
|
|
||||||
unsigned int event_mask = NSLeftMouseDownMask | NSLeftMouseUpMask |
|
|
||||||
NSMouseMovedMask | NSLeftMouseDraggedMask |
|
|
||||||
NSRightMouseDraggedMask;
|
|
||||||
|
|
||||||
NSDebugLog(@"NSControl mouseDown\n");
|
|
||||||
|
|
||||||
if (![self isEnabled]) // If we are not enabled
|
|
||||||
return; // then ignore the mouse
|
|
||||||
|
|
||||||
if ([cell isContinuous]) // Have NSCell send action
|
|
||||||
oldActionMask = [cell sendActionOn:0]; // only if we're continuous
|
|
||||||
else
|
|
||||||
oldActionMask = [cell sendActionOn: NSPeriodicMask];
|
|
||||||
|
|
||||||
[window _captureMouse: self]; // capture the mouse
|
|
||||||
|
|
||||||
[self lockFocus];
|
|
||||||
|
|
||||||
e = theEvent;
|
|
||||||
while (!done) // loop until mouse goes up
|
|
||||||
{
|
|
||||||
location = [e locationInWindow];
|
|
||||||
location = [self convertPoint:location fromView:nil];
|
|
||||||
// ask the cell to track the mouse only
|
|
||||||
// if the mouse is within the cell
|
|
||||||
if ((location.x >= 0) && (location.x < bounds.size.width) &&
|
|
||||||
(location.y >= 0 && location.y < bounds.size.height))
|
|
||||||
{ // highlight the cell
|
|
||||||
[cell highlight: YES withFrame: bounds inView: self];
|
|
||||||
[window flushWindow];
|
|
||||||
if([cell trackMouse:e inRect:bounds ofView:self untilMouseUp:YES])
|
|
||||||
done = mouseUp = YES; // YES if the mouse
|
|
||||||
else // goes up in the cell
|
|
||||||
{
|
|
||||||
[cell highlight: NO withFrame: bounds inView: self];
|
|
||||||
[window flushWindow];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (done) // if done break
|
|
||||||
break; // out of the loop
|
|
||||||
|
|
||||||
NSDebugLog(@"NSControl process another event\n");
|
|
||||||
e = [theApp nextEventMatchingMask:event_mask // get next event
|
|
||||||
untilDate:nil
|
|
||||||
inMode:NSEventTrackingRunLoopMode
|
|
||||||
dequeue:YES];
|
|
||||||
if ([e type] == NSLeftMouseUp) // If mouse went up
|
|
||||||
done = YES; // then we are done
|
|
||||||
}
|
|
||||||
|
|
||||||
[window _releaseMouse: self]; // Release mouse
|
|
||||||
|
|
||||||
if (mouseUp) // the mouse went up in the button
|
|
||||||
{
|
|
||||||
[self lockFocus]; // lockFocus gets released when button is
|
|
||||||
// drawn presseddown (NSView's displayRect)
|
|
||||||
// so we call it again, one of these needs
|
|
||||||
// to be optimized out FAR FIX ME
|
|
||||||
// [cell setState:![cell state]];
|
|
||||||
[cell highlight: NO withFrame: bounds inView: self]; // Unhighlight
|
|
||||||
[window flushWindow];
|
|
||||||
}
|
|
||||||
[self unlockFocus];
|
|
||||||
// Restore the old
|
|
||||||
[cell sendActionOn:oldActionMask]; // action mask
|
|
||||||
|
|
||||||
if (mouseUp) // Have the target
|
|
||||||
[self sendAction:[self action] to:[self target]]; // perform action
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)ignoresMultiClick { return NO; }
|
- (void) setContinuous: (BOOL)flag
|
||||||
- (void)setIgnoresMultiClick:(BOOL)flag {} // FIX ME
|
{
|
||||||
|
[cell setContinuous: flag];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setTarget: (id)anObject
|
||||||
|
{
|
||||||
|
[cell setTarget: anObject];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) target
|
||||||
|
{
|
||||||
|
return [cell target];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Assigning a Tag
|
||||||
|
//
|
||||||
|
- (void) setTag: (int)anInt
|
||||||
|
{
|
||||||
|
tag = anInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int) tag
|
||||||
|
{
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tracking the Mouse
|
||||||
|
//
|
||||||
|
- (void) mouseDown: (NSEvent *)theEvent
|
||||||
|
{
|
||||||
|
NSApplication *theApp = [NSApplication sharedApplication];
|
||||||
|
BOOL mouseUp = NO, done = NO;
|
||||||
|
NSEvent *e;
|
||||||
|
int oldActionMask;
|
||||||
|
NSPoint location;
|
||||||
|
unsigned int event_mask = NSLeftMouseDownMask | NSLeftMouseUpMask |
|
||||||
|
NSMouseMovedMask | NSLeftMouseDraggedMask |
|
||||||
|
NSRightMouseDraggedMask;
|
||||||
|
|
||||||
|
NSDebugLog(@"NSControl mouseDown\n");
|
||||||
|
|
||||||
|
if (![self isEnabled])
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ([cell isContinuous])
|
||||||
|
oldActionMask = [cell sendActionOn: 0];
|
||||||
|
else
|
||||||
|
oldActionMask = [cell sendActionOn: NSPeriodicMask];
|
||||||
|
|
||||||
|
[window _captureMouse: self];
|
||||||
|
|
||||||
|
[self lockFocus];
|
||||||
|
|
||||||
|
e = theEvent;
|
||||||
|
while (!done) // loop until mouse goes up
|
||||||
|
{
|
||||||
|
location = [e locationInWindow];
|
||||||
|
location = [self convertPoint: location fromView: nil];
|
||||||
|
// ask the cell to track the mouse only
|
||||||
|
// if the mouse is within the cell
|
||||||
|
if ((location.x >= 0) && (location.x < bounds.size.width) &&
|
||||||
|
(location.y >= 0 && location.y < bounds.size.height))
|
||||||
|
{
|
||||||
|
[cell highlight: YES withFrame: bounds inView: self];
|
||||||
|
[window flushWindow];
|
||||||
|
if ([cell trackMouse: e
|
||||||
|
inRect: bounds
|
||||||
|
ofView: self
|
||||||
|
untilMouseUp: YES])
|
||||||
|
done = mouseUp = YES;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[cell highlight: NO withFrame: bounds inView: self];
|
||||||
|
[window flushWindow];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (done)
|
||||||
|
break;
|
||||||
|
|
||||||
|
NSDebugLog(@"NSControl process another event\n");
|
||||||
|
e = [theApp nextEventMatchingMask: event_mask
|
||||||
|
untilDate: nil
|
||||||
|
inMode: NSEventTrackingRunLoopMode
|
||||||
|
dequeue: YES];
|
||||||
|
if ([e type] == NSLeftMouseUp)
|
||||||
|
done = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
[window _releaseMouse: self];
|
||||||
|
|
||||||
|
if (mouseUp)
|
||||||
|
{
|
||||||
|
[self lockFocus];
|
||||||
|
// [cell setState: ![cell state]];
|
||||||
|
[cell highlight: NO withFrame: bounds inView: self];
|
||||||
|
[window flushWindow];
|
||||||
|
}
|
||||||
|
[self unlockFocus];
|
||||||
|
[cell sendActionOn: oldActionMask];
|
||||||
|
|
||||||
|
if (mouseUp)
|
||||||
|
[self sendAction: [self action] to: [self target]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) ignoresMultiClick
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setIgnoresMultiClick: (BOOL)flag
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Methods Implemented by the Delegate
|
// Methods Implemented by the Delegate
|
||||||
//
|
//
|
||||||
- (BOOL)control:(NSControl *)control
|
- (BOOL) control: (NSControl *)control
|
||||||
textShouldBeginEditing:(NSText *)fieldEditor
|
textShouldBeginEditing: (NSText *)fieldEditor
|
||||||
{
|
{
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)control:(NSControl *)control
|
- (BOOL) control: (NSControl *)control
|
||||||
textShouldEndEditing:(NSText *)fieldEditor
|
textShouldEndEditing: (NSText *)fieldEditor
|
||||||
{
|
{
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)controlTextDidBeginEditing:(NSNotification *)aNotification
|
- (void) controlTextDidBeginEditing: (NSNotification *)aNotification
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
- (void)controlTextDidEndEditing:(NSNotification *)aNotification
|
- (void) controlTextDidEndEditing: (NSNotification *)aNotification
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
- (void)controlTextDidChange:(NSNotification *)aNotification
|
- (void) controlTextDidChange: (NSNotification *)aNotification
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// NSCoding protocol
|
// NSCoding protocol
|
||||||
|
@ -442,7 +522,7 @@ unsigned int event_mask = NSLeftMouseDownMask | NSLeftMouseUpMask |
|
||||||
- (void) encodeWithCoder: (NSCoder*)aCoder
|
- (void) encodeWithCoder: (NSCoder*)aCoder
|
||||||
{
|
{
|
||||||
[super encodeWithCoder: aCoder];
|
[super encodeWithCoder: aCoder];
|
||||||
|
|
||||||
[aCoder encodeValueOfObjCType: @encode(int) at: &tag];
|
[aCoder encodeValueOfObjCType: @encode(int) at: &tag];
|
||||||
[aCoder encodeObject: cell];
|
[aCoder encodeObject: cell];
|
||||||
}
|
}
|
||||||
|
@ -450,7 +530,7 @@ unsigned int event_mask = NSLeftMouseDownMask | NSLeftMouseUpMask |
|
||||||
- (id) initWithCoder: (NSCoder*)aDecoder
|
- (id) initWithCoder: (NSCoder*)aDecoder
|
||||||
{
|
{
|
||||||
[super initWithCoder: aDecoder];
|
[super initWithCoder: aDecoder];
|
||||||
|
|
||||||
[aDecoder decodeValueOfObjCType: @encode(int) at: &tag];
|
[aDecoder decodeValueOfObjCType: @encode(int) at: &tag];
|
||||||
[aDecoder decodeValueOfObjCType: @encode(id) at: &cell];
|
[aDecoder decodeValueOfObjCType: @encode(id) at: &cell];
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
NSPoint p;
|
NSPoint p;
|
||||||
NSEvent *e;
|
NSEvent *e;
|
||||||
NSRect r, r1, bigRect, vis;
|
NSRect r, r1, bigRect, vis;
|
||||||
id v, prev = nil;
|
id v = nil, prev = nil;
|
||||||
float minCoord, maxCoord;
|
float minCoord, maxCoord;
|
||||||
NSArray *subs = [self subviews];
|
NSArray *subs = [self subviews];
|
||||||
int offset = 0,i,count = [subs count];
|
int offset = 0,i,count = [subs count];
|
||||||
|
|
|
@ -1,21 +1,23 @@
|
||||||
/*
|
/*
|
||||||
NSStringDrawing.m
|
NSStringDrawing.m
|
||||||
|
|
||||||
Categories which add measure capabilities to NSAttributedString
|
Categories which add measure capabilities to NSAttributedString
|
||||||
and NSString.
|
and NSString.
|
||||||
|
|
||||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||||
|
|
||||||
Author: Felipe A. Rodriguez <far@ix.netcom.com>
|
Author: Felipe A. Rodriguez <far@ix.netcom.com>
|
||||||
Date: Aug 1998
|
Date: Aug 1998
|
||||||
|
Author: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
Date: Mar 1999 - rewrite from scratch
|
||||||
|
|
||||||
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
|
||||||
modify it under the terms of the GNU Library General Public
|
modify it under the terms of the GNU Library General Public
|
||||||
License as published by the Free Software Foundation; either
|
License as published by the Free Software Foundation; either
|
||||||
version 2 of the License, or (at your option) any later version.
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
This library is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
@ -25,79 +27,325 @@
|
||||||
License along with this library; see the file COPYING.LIB.
|
License along with this library; see the file COPYING.LIB.
|
||||||
If not, write to the Free Software Foundation,
|
If not, write to the Free Software Foundation,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <Foundation/Foundation.h>
|
||||||
#include <AppKit/NSStringDrawing.h>
|
#include <AppKit/NSStringDrawing.h>
|
||||||
#include <AppKit/AppKit.h>
|
#include <AppKit/AppKit.h>
|
||||||
// by default tabs are measured as one
|
|
||||||
#define TABWIDTH 3 // char so this value is set to one
|
|
||||||
// minus the default tab width of 4
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* I know it's severely sub-optimal, but the NSString methods just
|
||||||
|
* use NSAttributes string to do the job.
|
||||||
|
*/
|
||||||
@implementation NSString (NSStringDrawing)
|
@implementation NSString (NSStringDrawing)
|
||||||
|
|
||||||
- (NSSize)sizeWithAttributes:(NSDictionary *)attrs
|
- (void) drawAtPoint: (NSPoint)point withAttributes: (NSDictionary *)attrs
|
||||||
{
|
{
|
||||||
NSFont *font;
|
NSAttributedString *a;
|
||||||
const char *str = [self cString];
|
|
||||||
int i = 0, j = TABWIDTH;
|
|
||||||
static float tabSize;
|
|
||||||
float tabSumSize;
|
|
||||||
static float pointSize;
|
|
||||||
static NSFont *lastFont = nil;
|
|
||||||
|
|
||||||
while(*str != '\0') // calc the additional size
|
a = [NSAttributedString allocWithZone: NSDefaultMallocZone()];
|
||||||
{ // to be added for tabs.
|
[a initWithString: self attributes: attrs];
|
||||||
if(*str++ == '\t')
|
[a drawAtPoint: point];
|
||||||
{ // j is initialized to the
|
[a release];
|
||||||
i += j; // max number of spaces
|
|
||||||
j = TABWIDTH; // needed per tab. it then
|
|
||||||
} // varies in order to align
|
|
||||||
else // tabs to even multiples
|
|
||||||
j = j-- > 0 ? j : TABWIDTH; // of TABWIDTH + 1.
|
|
||||||
};
|
|
||||||
// if font is not
|
|
||||||
if(!(font = [attrs objectForKey:NSFontAttributeName])) // specified, use
|
|
||||||
font = [NSFont userFontOfSize:12]; // the default
|
|
||||||
|
|
||||||
if(font != lastFont) // update font info
|
|
||||||
{ // if font changes
|
|
||||||
tabSize = [font widthOfString:@"\t"];
|
|
||||||
lastFont = font;
|
|
||||||
pointSize = [font pointSize];
|
|
||||||
}
|
|
||||||
|
|
||||||
tabSumSize = (float)i * tabSize;
|
|
||||||
|
|
||||||
return NSMakeSize(([font widthOfString:self] + tabSumSize), pointSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) drawInRect: (NSRect)rect withAttributes: (NSDictionary *)attrs
|
||||||
|
{
|
||||||
|
NSAttributedString *a;
|
||||||
|
|
||||||
|
a = [NSAttributedString allocWithZone: NSDefaultMallocZone()];
|
||||||
|
[a initWithString: self attributes: attrs];
|
||||||
|
[a drawInRect: rect];
|
||||||
|
[a release];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSSize) sizeWithAttributes: (NSDictionary *)attrs
|
||||||
|
{
|
||||||
|
NSAttributedString *a;
|
||||||
|
NSSize s;
|
||||||
|
|
||||||
|
a = [NSAttributedString allocWithZone: NSDefaultMallocZone()];
|
||||||
|
[a initWithString: self attributes: attrs];
|
||||||
|
s = [a size];
|
||||||
|
[a release];
|
||||||
|
return s;
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@implementation NSAttributedString (NSStringDrawing)
|
@implementation NSAttributedString (NSStringDrawing)
|
||||||
|
|
||||||
- (NSSize)size // this method is
|
static NSCharacterSet *nlset = nil;
|
||||||
{ // untested FIX ME
|
|
||||||
NSFont *font;
|
|
||||||
unsigned int length;
|
|
||||||
NSRange effectiveRange;
|
|
||||||
NSString *subString;
|
|
||||||
float pointSize;
|
|
||||||
float sumOfCharacterRange = 0;
|
|
||||||
|
|
||||||
length = [self length];
|
/* FIXME completely ignores paragraph style attachments and other layout info */
|
||||||
effectiveRange = NSMakeRange(0, 0);
|
- (void) drawAtPoint: (NSPoint)point
|
||||||
|
{
|
||||||
|
NSGraphicsContext *ctxt = [NSGraphicsContext currentContext];
|
||||||
|
NSString *allText = [self string];
|
||||||
|
unsigned length = [allText length];
|
||||||
|
unsigned linePos = 0;
|
||||||
|
NSFont *defFont = [NSFont userFontOfSize: 12];
|
||||||
|
NSParagraphStyle *defStyle = [NSParagraphStyle defaultParagraphStyle];
|
||||||
|
NSColor *defFgCol = [NSColor textColor];
|
||||||
|
NSColor *defBgCol = nil;
|
||||||
|
BOOL isFlipped = [[ctxt focusView] isFlipped];
|
||||||
|
NSPoint start = point;
|
||||||
|
|
||||||
while (NSMaxRange(effectiveRange) < length)
|
/*
|
||||||
{
|
* Build a character set containing only newline characters if necessary.
|
||||||
font = (NSFont*)[self attribute:NSFontAttributeName
|
*/
|
||||||
atIndex:NSMaxRange(effectiveRange)
|
if (nlset == nil)
|
||||||
effectiveRange:&effectiveRange];
|
{
|
||||||
subString = [self attributedSubstringFromRange:effectiveRange];
|
NSCharacterSet *not_ws;
|
||||||
sumOfCharacterRange += [font widthOfString:subString];
|
NSMutableCharacterSet *new_set;
|
||||||
pointSize = MAX([font pointSize], pointSize);
|
|
||||||
}
|
not_ws = [[NSCharacterSet whitespaceCharacterSet] invertedSet];
|
||||||
|
new_set = [[NSCharacterSet whitespaceAndNewlineCharacterSet] mutableCopy];
|
||||||
return NSMakeSize(sumOfCharacterRange, pointSize);
|
[new_set formIntersectionWithCharacterSet: not_ws];
|
||||||
|
nlset = [new_set copy];
|
||||||
|
[new_set release];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now produce output on a per-line basis.
|
||||||
|
*/
|
||||||
|
while (linePos < length)
|
||||||
|
{
|
||||||
|
NSRange line; // Range of current line.
|
||||||
|
NSRange eol; // Rnage of newline character.
|
||||||
|
float lineHeight; // Height of text in this line.
|
||||||
|
unsigned position; // Position in NSString.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine the range of the next line of text (in 'line') and set
|
||||||
|
* 'linePos' to point after the terminating newline character (if any).
|
||||||
|
*/
|
||||||
|
line = NSMakeRange(linePos, length - linePos);
|
||||||
|
eol = [allText rangeOfCharacterFromSet: nlset
|
||||||
|
options: NSLiteralSearch
|
||||||
|
range: line];
|
||||||
|
|
||||||
|
if (eol.length == 0)
|
||||||
|
eol.location = length;
|
||||||
|
else
|
||||||
|
line.length = eol.location - line.location;
|
||||||
|
linePos = NSMaxRange(eol);
|
||||||
|
position = line.location;
|
||||||
|
|
||||||
|
while (position < eol.location)
|
||||||
|
{
|
||||||
|
NSAttributedString *subAttr;
|
||||||
|
NSString *subString;
|
||||||
|
NSSize size;
|
||||||
|
NSFont *font;
|
||||||
|
NSParagraphStyle *style;
|
||||||
|
NSColor *bg;
|
||||||
|
NSColor *fg;
|
||||||
|
int underline;
|
||||||
|
int superscript;
|
||||||
|
float base;
|
||||||
|
float kern;
|
||||||
|
float ypos;
|
||||||
|
int ligature;
|
||||||
|
NSNumber *num;
|
||||||
|
NSRange maxRange;
|
||||||
|
NSRange range;
|
||||||
|
|
||||||
|
// Maximum range is up to end of line.
|
||||||
|
maxRange = NSMakeRange(position, eol.location - position);
|
||||||
|
|
||||||
|
// Get font and range over which it applies.
|
||||||
|
font = (NSFont*)[self attribute: NSFontAttributeName
|
||||||
|
atIndex: position
|
||||||
|
effectiveRange: &range];
|
||||||
|
if (font == nil)
|
||||||
|
font = defFont;
|
||||||
|
maxRange = NSIntersectionRange(maxRange, range);
|
||||||
|
|
||||||
|
// Get style and range over which it applies.
|
||||||
|
style = (NSParagraphStyle*)[self attribute: NSParagraphStyleAttributeName
|
||||||
|
atIndex: position
|
||||||
|
effectiveRange: &range];
|
||||||
|
if (style == nil)
|
||||||
|
style = defStyle;
|
||||||
|
maxRange = NSIntersectionRange(maxRange, range);
|
||||||
|
|
||||||
|
// Get background color and range over which it applies.
|
||||||
|
bg = (NSColor*)[self attribute: NSBackgroundColorAttributeName
|
||||||
|
atIndex: position
|
||||||
|
effectiveRange: &range];
|
||||||
|
if (bg == nil)
|
||||||
|
bg = defBgCol;
|
||||||
|
maxRange = NSIntersectionRange(maxRange, range);
|
||||||
|
|
||||||
|
// Get foreground color and range over which it applies.
|
||||||
|
fg = (NSColor*)[self attribute: NSForegroundColorAttributeName
|
||||||
|
atIndex: position
|
||||||
|
effectiveRange: &range];
|
||||||
|
if (fg == nil)
|
||||||
|
fg = defFgCol;
|
||||||
|
maxRange = NSIntersectionRange(maxRange, range);
|
||||||
|
|
||||||
|
// Get underline style and range over which it applies.
|
||||||
|
num = (NSNumber*)[self attribute: NSUnderlineStyleAttributeName
|
||||||
|
atIndex: position
|
||||||
|
effectiveRange: &range];
|
||||||
|
if (num == nil)
|
||||||
|
underline = GSNoUnderlineStyle; // No underline
|
||||||
|
else
|
||||||
|
underline = [num intValue];
|
||||||
|
maxRange = NSIntersectionRange(maxRange, range);
|
||||||
|
|
||||||
|
// Get superscript and range over which it applies.
|
||||||
|
num = (NSNumber*)[self attribute: NSSuperscriptAttributeName
|
||||||
|
atIndex: position
|
||||||
|
effectiveRange: &range];
|
||||||
|
if (num == nil)
|
||||||
|
superscript = 0;
|
||||||
|
else
|
||||||
|
superscript = [num intValue];
|
||||||
|
maxRange = NSIntersectionRange(maxRange, range);
|
||||||
|
|
||||||
|
// Get baseline offset and range over which it applies.
|
||||||
|
num = (NSNumber*)[self attribute: NSBaselineOffsetAttributeName
|
||||||
|
atIndex: position
|
||||||
|
effectiveRange: &range];
|
||||||
|
if (num == nil)
|
||||||
|
base = 0.0;
|
||||||
|
else
|
||||||
|
base = [num floatValue];
|
||||||
|
maxRange = NSIntersectionRange(maxRange, range);
|
||||||
|
|
||||||
|
// Get kern attribute and range over which it applies.
|
||||||
|
num = (NSNumber*)[self attribute: NSKernAttributeName
|
||||||
|
atIndex: position
|
||||||
|
effectiveRange: &range];
|
||||||
|
if (num == nil)
|
||||||
|
kern = 0.0;
|
||||||
|
else
|
||||||
|
kern = [num floatValue];
|
||||||
|
maxRange = NSIntersectionRange(maxRange, range);
|
||||||
|
|
||||||
|
// Get ligature attribute and range over which it applies.
|
||||||
|
num = (NSNumber*)[self attribute: NSLigatureAttributeName
|
||||||
|
atIndex: position
|
||||||
|
effectiveRange: &range];
|
||||||
|
if (num == nil)
|
||||||
|
ligature = 1;
|
||||||
|
else
|
||||||
|
ligature = [num intValue];
|
||||||
|
maxRange = NSIntersectionRange(maxRange, range);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now, at last we have all the required text drawing attributes and
|
||||||
|
* we have a range over which ALL of them apply. We update our
|
||||||
|
* position to point past this range, then we grab the substring from
|
||||||
|
* the range, draw it, and update our drawing position.
|
||||||
|
*/
|
||||||
|
range = maxRange;
|
||||||
|
position = NSMaxRange(range); // Next position in string.
|
||||||
|
subAttr = [self attributedSubstringFromRange: range];
|
||||||
|
subString = [subAttr string];
|
||||||
|
size.width = [font widthOfString: subString];
|
||||||
|
size.height = [font pointSize];
|
||||||
|
|
||||||
|
lineHeight = size.height;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we have a background color set - we fill in the
|
||||||
|
* region occupied by this substring.
|
||||||
|
*/
|
||||||
|
if (bg)
|
||||||
|
{
|
||||||
|
NSRect rect;
|
||||||
|
|
||||||
|
rect.origin = point;
|
||||||
|
rect.size = size;
|
||||||
|
if (isFlipped == NO)
|
||||||
|
rect.origin.y -= size.height;
|
||||||
|
|
||||||
|
[bg set];
|
||||||
|
NSRectFill(rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set font and color, then draw the substring.
|
||||||
|
* NB. Our origin is top-left of the string so we need to
|
||||||
|
* calculate a vertical coordinate for the baseline of the
|
||||||
|
* text produced by psshow.
|
||||||
|
*/
|
||||||
|
if (isFlipped)
|
||||||
|
ypos = point.y + size.height - [font descender];
|
||||||
|
else
|
||||||
|
ypos = point.y - size.height + [font descender];
|
||||||
|
[fg set];
|
||||||
|
[font set];
|
||||||
|
DPSmoveto(ctxt, point.x, ypos);
|
||||||
|
DPSshow(ctxt, [subString cString]);
|
||||||
|
if (underline == NSSingleUnderlineStyle)
|
||||||
|
{
|
||||||
|
DPSmoveto(ctxt, point.x, ypos);
|
||||||
|
DPSlineto(ctxt, point.x + size.width - 1, ypos);
|
||||||
|
}
|
||||||
|
|
||||||
|
point.x += size.width; // Next point to draw from.
|
||||||
|
}
|
||||||
|
point.x = start.x;
|
||||||
|
if (isFlipped)
|
||||||
|
point.y += lineHeight;
|
||||||
|
else
|
||||||
|
point.y -= lineHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) drawInRect: (NSRect)rect
|
||||||
|
{
|
||||||
|
NSPoint point;
|
||||||
|
NSView *view = [NSView focusView];
|
||||||
|
|
||||||
|
NSRectClip(rect);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since [-drawAtPoint:] positions the top-left corner of the text at
|
||||||
|
* the point, we locate the top-left corner of the rectangle to do the
|
||||||
|
* drawing.
|
||||||
|
*/
|
||||||
|
point.x = rect.origin.x;
|
||||||
|
if ([view isFlipped])
|
||||||
|
point.y = rect.origin.y;
|
||||||
|
else
|
||||||
|
point.y = rect.origin.y + rect.size.height;
|
||||||
|
|
||||||
|
[self drawAtPoint: point];
|
||||||
|
NSRectClip([view bounds]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME completely ignores paragraph style attachments and other layout info */
|
||||||
|
- (NSSize) size
|
||||||
|
{
|
||||||
|
unsigned length = [self length];
|
||||||
|
unsigned position = 0;
|
||||||
|
float height = 0;
|
||||||
|
float width = 0;
|
||||||
|
|
||||||
|
while (position < length)
|
||||||
|
{
|
||||||
|
NSRange range;
|
||||||
|
NSFont *font;
|
||||||
|
NSString *subString;
|
||||||
|
|
||||||
|
font = (NSFont*)[self attribute: NSFontAttributeName
|
||||||
|
atIndex: position
|
||||||
|
effectiveRange: &range];
|
||||||
|
subString = [[self attributedSubstringFromRange: range] string];
|
||||||
|
width += [font widthOfString: subString];
|
||||||
|
height = MAX([font pointSize], height);
|
||||||
|
position = NSMaxRange(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NSMakeSize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue