NSTextContainer update.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@4421 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 1999-06-17 15:08:05 +00:00
parent f794f819cf
commit 8ab2a93c25
4 changed files with 290 additions and 81 deletions

View file

@ -1,3 +1,10 @@
Thu Jun 17 16:20:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Source/NSTextContainer.m: New by jagapen@whitewater.chem.wisc.edu
* Headers/AppKit/NSTextContainer.h: rewrite by jagapen
* Source/GNUmakefile: Modified to build NSTextContainer and
NSTextStorage.
1999-06-16 Adam Fedor <fedor@gnu.org>
* Headers/gnustep/gui/DPSOperators.h: New functions

View file

@ -1,118 +1,112 @@
/*
NSTextContainer.h
An NSTextContainer defines a region in which to lay out text. It's main
responsibility is to calculate line fragments which fall within the region
it represents. Containers have a line fragment padding which is used by
the typesetter to inset text from the edges of line fragments along the
sweep direction.
Text container for text system
The container can enforce any other geometric constraints as well. When
drawing the text that has been laid in a container, a NSTextView will clip
to the interior of the container (it clips to the container's rectagular
area only, however, not to the arbitrary shape the container may define
for text flow).
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1996 Free Software Foundation, Inc.
Author: Jonathan Gapen <jagapen@smithlab.chem.wisc.edu>
Date: 1999
Author: Daniel Bðhringer <boehring@biomed.ruhr-uni-bochum.de>
Date: August 1998
Source by Daniel Bðhringer integrated into GNUstep gui
by Felipe A. Rodriguez <far@ix.netcom.com>
This file is part of the GNUstep GUI Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
License along with this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _GNUstep_H_NSTextContainer
#define _GNUstep_H_NSTextContainer
#ifdef STRICT_OPENSTEP
#error "The OpenStep specification does not define an NSTextContainer class."
#endif
#import <Foundation/Foundation.h>
@class NSLayoutManager;
@class NSTextView;
typedef enum {
NSLineSweepLeft = 0,
NSLineSweepRight = 1,
NSLineSweepDown = 2,
NSLineSweepUp = 3,
NSLineSweepLeft,
NSLineSweepRight,
NSLineSweepDown,
NSLineSweepUp
} NSLineSweepDirection;
typedef enum {
NSLineDoesntMove = 0,
NSLineMovesLeft = 1,
NSLineMovesRight = 2,
NSLineMovesDown = 3,
NSLineMovesUp = 4,
NSLineMoveLeft,
NSLineMoveRight,
NSLineMoveDown,
NSLineMoveUp,
NSLineDoesntMove
} NSLineMovementDirection;
@interface NSTextContainer : NSObject
{ NSLayoutManager *layoutManager;
NSTextView *textView;
NSSize size;
float lineFragmentPadding;
BOOL widthTracksTextView;
BOOL heightTracksTextView;
BOOL observingFrameChanges;
{
id _layoutManager;
id _textView;
NSRect _containerRect;
float _lineFragmentPadding;
BOOL _observingFrameChanges;
BOOL _widthTracksTextView;
BOOL _heightTracksTextView;
}
/**************************** Initialization ****************************/
/*
* Creating an instance
*/
- (id) initWithContainerSize: (NSSize)aSize;
- (id)initWithContainerSize:(NSSize)size;
/*
* Managing text components
*/
- (void) setLayoutManager: (NSLayoutManager *)aLayoutManager;
- (NSLayoutManager *) layoutManager;
- (void) replaceLayoutManager: (NSLayoutManager *)aLayoutManager;
- (void) setTextView: (NSTextView *)aTextView;
- (NSTextView *) textView;
/**************************** Layout and View ****************************/
/*
* Controlling size
*/
- (void) setContainerSize: (NSSize)aSize;
- (NSSize) containerSize;
- (void) setWidthTracksTextView: (BOOL)flag;
- (BOOL) widthTracksTextView;
- (void) setHeightTracksTextView: (BOOL)flag;
- (BOOL) heightTracksTextView;
- (NSLayoutManager *)layoutManager;
- (void)setLayoutManager:(NSLayoutManager *)layoutManager;
// The set method generally should not be called directly, but you may want to override it. Adding a container to a NSLayoutManager through the provided NSLayoutManager methods will cause the set method to be called appropriately.
/*
* Setting line fragment padding
*/
- (void) setLineFragmentPadding: (float)aFloat;
- (float) lineFragmentPadding;
- (void)replaceLayoutManager:(NSLayoutManager *)newLayoutManager;
// This method should be used instead of the primitive -setLayoutManager: if you need to replace a container's layoutManager with a new one leaving the rest of the web intact. All the NSTextContainers on the old NSLayoutManager get transferred to the new one. This method deals with all the work of making sure the containers don't get deallocated and removing the old layoutManager from the text storage and replacing it with the new one.
/*
* Calculating text layout
*/
- (NSRect) lineFragmentRectForProposedRect: (NSRect)proposedRect
sweepDirection: (NSLineSweepDirection)sweepDir
movementDirection: (NSLineMovementDirection)moveDir
remainingRect: (NSRect *)remainingRect;
- (BOOL) isSimpleRectangularTextContainer;
- (NSTextView *)textView;
- (void)setTextView:(NSTextView *)textView;
// Set/get the view which the container is drawn in. Having a view is optional.
- (void)setWidthTracksTextView:(BOOL)flag;
- (BOOL)widthTracksTextView;
- (void)setHeightTracksTextView:(BOOL)flag;
- (BOOL)heightTracksTextView;
// If a container tracks the size of it's view in one or both of these dimensions then those dimensions will be kept in synch with with the view's frame (taking into account the views textContainerInset).
/************************* Container size and padding *************************/
- (void)setContainerSize:(NSSize)size;
- (NSSize)containerSize;
// Sets/Returns the current size of the container. This size has nothing to do with how much text is in the container and how much space it takes up (which the container is not in a position to know). It is basically the maximum flowable area of the container. The NSTextView's size will not generally have much connection to this size. The NSTextView will generally want to be big enough to display all the text which has been laid in the container at the moment and no bigger. The NSLayoutManager will generally be in charge of telling the view what size it should be.
- (void)setLineFragmentPadding:(float)pad;
- (float)lineFragmentPadding;
// This value is used by the typesetter to inset the line fragment rects it gets along the sweep direction to give a little default pad to each fragment.
/**************************** Line fragments ****************************/
- (NSRect)lineFragmentRectForProposedRect:(NSRect)proposedRect sweepDirection:(NSLineSweepDirection)sweepDirection movementDirection:(NSLineMovementDirection)movementDirection remainingRect:(NSRect *)remainingRect;
// Returns the first and largest subrect of proposedRect which falls within the container's region. All rects are given in the container's coordinate system. sweepDirection determines what edge of the proposedRect to start from. movementDirection determines in which direction (if any) the proposedRect can be translated if it is necessary to move the rect to find a non-empty fragment. remainingRect is set to hold whatever portion of of the proposedRect (after any line movement translation) which is left after subtracting the returned fragment. The proposed rect should fall within the frame area of the container. remainingRect will only be non-empty if there are parts of the proposedRect left within the container's frame area ("after" the returned fragment rect in the sweep direction) that are not included in the returned rect.
- (BOOL)isSimpleRectangularTextContainer;
// Subclasses should override this method to return NO if the containers area is not truly rectangular with no holes or concavities. NSLayoutManager uses this method to determine whether it can make certain optimizations when relaying text in the container. NSTextContainer's implementation returns YES.
/**************************** Hit testing ****************************/
- (BOOL)containsPoint:(NSPoint)point;
// Returns YES if the point (given in the coordinate system of the container) falls within the region of the container.
/*
* Mouse hit testing
*/
- (BOOL) containsPoint: (NSPoint)aPoint;
@end
#endif /* _GNUstep_H_NSTextContainer */

View file

@ -102,8 +102,10 @@ NSSpellServer.m \
NSSplitView.m \
NSStringDrawing.m \
NSText.m \
NSTextContainer.m \
NSTextField.m \
NSTextFieldCell.m \
NSTextStorage.m \
NSTextView.m \
NSView.m \
NSWindow.m \
@ -194,7 +196,6 @@ AppKit/NSSpellChecker.h \
AppKit/NSSpellProtocol.h \
AppKit/NSSpellServer.h \
AppKit/NSSplitView.h \
AppKit/NSTextStorage.h \
AppKit/NSStringDrawing.h \
AppKit/NSText.h \
AppKit/NSTextAttachment.h \

207
Source/NSTextContainer.m Normal file
View file

@ -0,0 +1,207 @@
/*
NSTextContainer.m
Copyright (C) 1999 Free Software Foundation, Inc.
Author: Jonathan Gapen <jagapen@smithlab.chem.wisc.edu>
Date: 1999
This file is part of the GNUstep GUI Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <AppKit/NSLayoutManager.h>
#import <AppKit/NSTextContainer.h>
#import <AppKit/NSTextStorage.h>
#import <AppKit/NSTextView.h>
#import <Foundation/NSGeometry.h>
#import <Foundation/NSNotification.h>
@interface NSTextContainer (TextViewObserver)
- (void) _textViewFrameChanged: (NSNotification *)aNotification;
@end
@implementation NSTextContainer (TextViewObserver)
- (void) _textViewFrameChanged: (NSNotification *)aNotification
{
id textView;
NSSize newSize;
NSSize inset;
if ( _observingFrameChanges )
{
textView = [aNotification object];
newSize = [textView frame].size;
inset = [textView textContainerInset];
if ( _widthTracksTextView )
newSize.width = MAX(newSize.width - (inset.width * 2.0), 0.0);
if ( _heightTracksTextView )
newSize.height = MAX(newSize.height - (inset.height * 2.0), 0.0);
[self setContainerSize: newSize];
}
}
@end /* NSTextContainer (TextViewObserver) */
@implementation NSTextContainer
+ (void) initialize
{
if ( self == [NSTextContainer class] )
[self setVersion: 1];
}
- (id) initWithContainerSize: (NSSize)aSize
{
NSLog(@"NSTextContainer initWithContainerSize");
_layoutManager = nil;
_textView = nil;
_containerRect.size = aSize;
_lineFragmentPadding = 0.0;
_observingFrameChanges = NO;
_widthTracksTextView = NO;
_heightTracksTextView = NO;
return self;
}
- (void) setLayoutManager: (NSLayoutManager *)aLayoutManager
{
ASSIGN(_layoutManager, aLayoutManager);
}
- (NSLayoutManager *) layoutManager
{
return _layoutManager;
}
- (void) replaceLayoutManager: (NSLayoutManager *)newLayoutManager
{
id textStorage = [_layoutManager textStorage];
NSArray *textContainers = [_layoutManager textContainers];
unsigned i, count = [textContainers count];
[textStorage removeLayoutManager: _layoutManager];
[textStorage addLayoutManager: newLayoutManager];
[_layoutManager setTextStorage: nil];
for ( i = 0; i < count; i++ )
{
[newLayoutManager addTextContainer: [textContainers objectAtIndex: i]];
[_layoutManager removeTextContainerAtIndex: i];
}
}
- (void) setTextView: (NSTextView *)aTextView
{
if ( _textView )
{
[_textView setTextContainer: nil];
[[NSNotificationCenter defaultCenter] removeObserver: self];
}
ASSIGN(_textView, aTextView);
if ( aTextView )
{
[_textView setTextContainer: self];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(_textViewFrameChanged: )
name: NSViewFrameDidChangeNotification
object: _textView];
}
}
- (NSTextView *) textView
{
return _textView;
}
- (void) setContainerSize: (NSSize)aSize
{
_containerRect = NSMakeRect(0, 0, aSize.width, aSize.height);
if ( _layoutManager )
[_layoutManager textContainerChangedGeometry: self];
}
- (NSSize) containerSize
{
return _containerRect.size;
}
- (void) setWidthTracksTextView: (BOOL)flag
{
_widthTracksTextView = flag;
_observingFrameChanges = _widthTracksTextView | _heightTracksTextView;
}
- (BOOL) widthTracksTextView
{
return _widthTracksTextView;
}
- (void) setHeightTracksTextView: (BOOL)flag
{
_heightTracksTextView = flag;
_observingFrameChanges = _widthTracksTextView | _heightTracksTextView;
}
- (BOOL) heightTracksTextView
{
return _heightTracksTextView;
}
- (void) setLineFragmentPadding: (float)aFloat
{
_lineFragmentPadding = aFloat;
if ( _layoutManager )
[_layoutManager textContainerChangedGeometry: self];
}
- (float) lineFragmentPadding
{
return _lineFragmentPadding;
}
- (NSRect) lineFragmentRectForProposedRect: (NSRect)proposedRect
sweepDirection: (NSLineSweepDirection)sweepDir
movementDirection: (NSLineMovementDirection)moveDir
remainingRect: (NSRect *)remainingRect;
{
// line fragment rectangle simply must fit within the container rectangle
*remainingRect = NSZeroRect;
return NSIntersectionRect(proposedRect, _containerRect);
}
- (BOOL) isSimpleRectangularTextContainer
{
// sub-classes may say no; this class always says yes
return YES;
}
- (BOOL) containsPoint: (NSPoint)aPoint
{
return NSPointInRect(aPoint, _containerRect);
}
@end /* NSTextContainer */