diff --git a/ChangeLog b/ChangeLog index 4c9674e3d..c21c96769 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-04-28 18:35 Alexander Malmberg + + * Headers/gnustep/gui/NSTextContainer.h: Documented. + * Source/NSTextContainer.m: Cleanups. + Mon Apr 28 13:14:15 2003 Nicola Pero * Source/NSApplication.m ([NSApplication -targetForAction:]): If this diff --git a/Headers/gnustep/gui/NSTextContainer.h b/Headers/gnustep/gui/NSTextContainer.h index ab5028982..8b5778653 100644 --- a/Headers/gnustep/gui/NSTextContainer.h +++ b/Headers/gnustep/gui/NSTextContainer.h @@ -5,6 +5,9 @@ Copyright (C) 1999 Free Software Foundation, Inc. + Author: Alexander Malmberg + Date: April 2003 + Author: Jonathan Gapen Date: 1999 @@ -17,7 +20,7 @@ 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 @@ -26,6 +29,38 @@ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/** +A text container defines a region in the plane. It is used by the +text system to lay out text: text is laid out inside this region. A layout +manager has a list of text containers that it lays out text in. A text +container may have one NSTextView attached to it that displays the text laid +out in the text container. + +Note that the coordinate system used by NSTextContainer is the +same as in the rest of the text system classes, ie. positive y is down. + +NSTextContainer itself defines a simple rectangular region as large as the +container size. In most cases, only a single, simple text container is used +with a layout manager and a text view. Examples of cases where you might want +to use several text containers, or subclasses that define more complex +regions, are: + + + + Multi-page layout; one text container for each page. + + Multi-column layout; one text container for each column. + + Layout flowing around pictures; the text container would define a region + that does not include the space used by the picture. + + + +If the region defined by a text container can change dynamically, the text +container should call [GSLayoutManager-textContainerChangedGeometry:] +whenever this happens. +*/ + #ifndef _GNUstep_H_NSTextContainer #define _GNUstep_H_NSTextContainer @@ -66,50 +101,165 @@ typedef enum { BOOL _heightTracksTextView; } -/* - * Creating an instance - */ +/** +Initializes a new instance and sets the container size to aSize. +*/ - (id) initWithContainerSize: (NSSize)aSize; -/* - * Managing text components - */ -- (void) setLayoutManager: (GSLayoutManager *)aLayoutManager; -- (GSLayoutManager *) layoutManager; + +/** +Querying the region +*/ + +/** +Returns YES if the region for this container is a rectangle +as large as the container size, otherwise NO. For simple rectangular regions, +the text system can apply certain optimizations. + +NSTextContainer always returns YES. Subclasses that define more complex +regions must return NO. +*/ +- (BOOL) isSimpleRectangularTextContainer; + +/** +This is the main method used by the text system for querying the region +and flowing text in it. It takes a proposed line fragment rectangle and, +if possible, splits it into a valid line fragment rectangle, and a remaining +rectangle that can be used in subsequent calls to this method. + +sweepDir is the direction that text moves inside the lines, and moveDir is +the direction lines move in, or NSLineDoesntMove if the line may not move. +The line sweep and line movement may not both be in the same dimension, ie. +both be vertical, or both be horizontal. + +The method returns the first (according to the sweep direction) valid line +fragment rectangle in the proposed rectangle. This line fragment rectangle +is a sub-rectangle of the proposed rectangle in the sweep direction, and has +the same size in the other direction. (Ie. if the sweep direction is left, +the line fragment rectangle must have the same height as the proposed +rectangle.) If there is no valid line fragment rectangle in the proposed +rectangle, the proposed rectangle may be moved in the line movement direction +until there is one. If no valid line fragment rectangle can be returned, +the method returns NSZeroRect. + +The remaining rectangle should be set to the potentially valid part of the +proposed rectangle, after moving in the line movement direction, that remains +after the first line fragment rectangle. + +The proposed rectangle may be any rectangle; in particular, it may extend +outside the container size. The remaining rectangle does not have to be or +contain a valid line fragment rectangle. + +Subclasses define regions by overriding this method. + +Note: The TextContainerExample in the text system example collection +(TODO: link) contains an example implementation of an NSTextContainer subclass +that defiens a non-trivial region, as well as an interactive demonstration of +this method. It can also be used as a simple test of custom subclasses. + +Note: Although a correct NSTextContainer implementation must handle all line +sweep and movement directions, the current standard typesetter will only call +this method with sweep right, and no movement or movement down. Relying on +this makes writing a subclass easier, but it is not safe. +*/ +- (NSRect) lineFragmentRectForProposedRect: (NSRect)proposedRect + sweepDirection: (NSLineSweepDirection)sweepDir + movementDirection: (NSLineMovementDirection)moveDir + remainingRect: (NSRect *)remainingRect; + +/** +Returns YES if aPoint is inside the region. + +Subclasses define regions by overriding this method. +*/ +- (BOOL) containsPoint: (NSPoint)aPoint; + + +/** +Managing the text network + +A text container may be attached to one layout manager and one text view. +The text container is retained by the layout manager, and retains the text +view. +*/ + +/** +Replaces the layout manager of this text container with aLayoutManager. +This is done without changing the rest of the text network, so +aLayoutManager will be connected to the text storage and text containers +that the current layout manager is connected to. +*/ - (void) replaceLayoutManager: (GSLayoutManager *)aLayoutManager; + +/** +Returns the layout manager of this text container. +*/ +- (GSLayoutManager *) layoutManager; + +/** +This method should not be called directly. It is called by the layout manager +when the layout manager of a text container changes. +*/ +- (void) setLayoutManager: (GSLayoutManager *)aLayoutManager; + + +/** +Sets the NSTextView for this text container. Note that a text view +should be attached to a text container only if the text container is attached +to a layout manager that can handle text views (eg. NSLayoutManager). + +The text view is retained by the text container. +*/ - (void) setTextView: (NSTextView *)aTextView; + +/** +Returns the NSTextView attached to this text container, or nil if there is +none. +*/ - (NSTextView *) textView; -/* - * Controlling size - */ + +/** +The container size + +A text container has a container size. The region defined by the text +container must be a subset of the rectangle of this size with it's top-left +corner in the origin. + +Subclasses do not have to support arbitrary sizes, and may choose to ignore +-setContainerSize: completely. However, the size returned by -containerSize +must be valid. +*/ - (void) setContainerSize: (NSSize)aSize; - (NSSize) containerSize; + + +/** +Automatic resizing + +A text container can be set to automatically track the width and/or height +of its NSTextView (TODO: frame? bounds?). For more information, see the +documentation on automatic resizing in NSTextView. (TODO: link) + +When enabled, the automatic resizing is done by calling +[NSTextContainer-setContainerSize:] with the new size whenever the text view +is resized. +*/ - (void) setWidthTracksTextView: (BOOL)flag; - (BOOL) widthTracksTextView; - (void) setHeightTracksTextView: (BOOL)flag; - (BOOL) heightTracksTextView; -/* - * Setting line fragment padding - */ + +/** +Line fragment padding + +The line fragment padding is an amount of space left empty at each end of +a line fragment rectangle by the standard typesetter. The default is 0.0. +*/ - (void) setLineFragmentPadding: (float)aFloat; - (float) lineFragmentPadding; -/* - * Calculating text layout - */ -- (NSRect) lineFragmentRectForProposedRect: (NSRect)proposedRect - sweepDirection: (NSLineSweepDirection)sweepDir - movementDirection: (NSLineMovementDirection)moveDir - remainingRect: (NSRect *)remainingRect; -- (BOOL) isSimpleRectangularTextContainer; - -/* - * Mouse hit testing - */ -- (BOOL) containsPoint: (NSPoint)aPoint; - @end #endif /* _GNUstep_H_NSTextContainer */ diff --git a/Source/NSTextContainer.m b/Source/NSTextContainer.m index 1b9ace06f..ff48d118e 100644 --- a/Source/NSTextContainer.m +++ b/Source/NSTextContainer.m @@ -56,7 +56,7 @@ use bounds rectangle instead of frame? */ textView = [aNotification object]; if (textView != _textView) { - NSDebugLog (@"NSTextContainer got notification for wrong View %@", + NSDebugLog(@"NSTextContainer got notification for wrong View %@", textView); return; } @@ -66,12 +66,12 @@ use bounds rectangle instead of frame? */ if (_widthTracksTextView) { - size.width = MAX (newTextViewSize.width - (inset.width * 2.0), 0.0); + size.width = MAX(newTextViewSize.width - (inset.width * 2.0), 0.0); } if (_heightTracksTextView) { - size.height = MAX (newTextViewSize.height - (inset.height * 2.0), - 0.0); + size.height = MAX(newTextViewSize.height - (inset.height * 2.0), + 0.0); } [self setContainerSize: size]; @@ -92,7 +92,7 @@ use bounds rectangle instead of frame? */ - (id) initWithContainerSize: (NSSize)aSize { - NSDebugLLog (@"NSText", @"NSTextContainer initWithContainerSize"); + NSDebugLLog(@"NSText", @"NSTextContainer initWithContainerSize"); _layoutManager = nil; _textView = nil; _containerRect.size = aSize; @@ -113,7 +113,7 @@ use bounds rectangle instead of frame? */ name: NSViewFrameDidChangeNotification object: _textView]; - RELEASE (_textView); + RELEASE(_textView); } [super dealloc]; } @@ -135,10 +135,10 @@ See [NSTextView -setTextContainer:] for more information about these calls. return _layoutManager; } -/** - * Replaces the layout manager while maintaining the text object - * framework intact. - */ +/* +Replaces the layout manager while maintaining the text object +framework intact. +*/ - (void) replaceLayoutManager: (GSLayoutManager*)aLayoutManager { if (aLayoutManager != _layoutManager) @@ -189,7 +189,7 @@ See [NSTextView -setTextContainer:] for more information about these calls. the frame change notifications. */ } - ASSIGN (_textView, aTextView); + ASSIGN(_textView, aTextView); if (aTextView != nil) { @@ -216,12 +216,12 @@ See [NSTextView -setTextContainer:] for more information about these calls. - (void) setContainerSize: (NSSize)aSize { - if (NSEqualSizes (_containerRect.size, aSize)) + if (NSEqualSizes(_containerRect.size, aSize)) { return; } - _containerRect = NSMakeRect (0, 0, aSize.width, aSize.height); + _containerRect = NSMakeRect(0, 0, aSize.width, aSize.height); if (_layoutManager) { @@ -426,7 +426,7 @@ See [NSTextView -setTextContainer:] for more information about these calls. - (BOOL) containsPoint: (NSPoint)aPoint { - return NSPointInRect (aPoint, _containerRect); + return NSPointInRect(aPoint, _containerRect); } @end /* NSTextContainer */