1 /*
2    NSTextContainer.h
3 
4    Text container for text system
5 
6    Copyright (C) 1999, 2003 Free Software Foundation, Inc.
7 
8    Author: Alexander Malmberg <alexander@malmberg.org>
9    Date: April 2003
10 
11    Author: Jonathan Gapen <jagapen@smithlab.chem.wisc.edu>
12    Date: 1999
13 
14    This file is part of the GNUstep GUI Library.
15 
16    This library is free software; you can redistribute it and/or
17    modify it under the terms of the GNU Lesser General Public
18    License as published by the Free Software Foundation; either
19    version 2 of the License, or (at your option) any later version.
20 
21    This library is distributed in the hope that it will be useful,
22    but WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
24    Lesser General Public License for more details.
25 
26    You should have received a copy of the GNU Lesser General Public
27    License along with this library; see the file COPYING.LIB.
28    If not, see <http://www.gnu.org/licenses/> or write to the
29    Free Software Foundation, 51 Franklin Street, Fifth Floor,
30    Boston, MA 02110-1301, USA.
31 */
32 
33 /**
34 A text container defines a region in the plane. It is used by the
35 text system to lay out text: text is laid out inside this region. A layout
36 manager has a list of text containers that it lays out text in. A text
37 container may have one NSTextView attached to it that displays the text laid
38 out in the text container.
39 
40 Note that the coordinate system used by NSTextContainer is the
41 same as in the rest of the text system classes, ie. positive y is down.
42 
43 NSTextContainer itself defines a simple rectangular region as large as the
44 container size. In most cases, only a single, simple text container is used
45 with a layout manager and a text view. Examples of cases where you might want
46 to use several text containers, or subclasses that define more complex
47 regions, are:
48 
49 <list>
50   <item>
51     Multi-page layout; one text container for each page.
52   </item><item>
53     Multi-column layout; one text container for each column.
54   </item><item>
55     Layout flowing around pictures; the text container would define a region
56     that does not include the space used by the picture.
57   </item>
58 </list>
59 
60 If the region defined by a text container can change dynamically, the text
61 container should call [GSLayoutManager-textContainerChangedGeometry:]
62 whenever this happens.
63 */
64 
65 #ifndef _GNUstep_H_NSTextContainer
66 #define _GNUstep_H_NSTextContainer
67 #import <GNUstepBase/GSVersionMacros.h>
68 
69 #if GS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
70 
71 #import <Foundation/NSGeometry.h>
72 #import <Foundation/NSObject.h>
73 
74 @class GSLayoutManager;
75 @class NSTextView;
76 
77 enum {
78   NSLineSweepLeft,
79   NSLineSweepRight,
80   NSLineSweepDown,
81   NSLineSweepUp
82 };
83 typedef NSUInteger NSLineSweepDirection;
84 
85 enum {
86   NSLineDoesntMove,
87   NSLineMovesLeft,
88   NSLineMovesRight,
89   NSLineMovesDown,
90   NSLineMovesUp
91 };
92 typedef NSUInteger NSLineMovementDirection;
93 
94 @interface NSTextContainer : NSObject
95 {
96   id _layoutManager;
97   id _textView;
98 
99   NSRect _containerRect;
100   CGFloat _lineFragmentPadding;
101 
102   BOOL _observingFrameChanges;
103   BOOL _widthTracksTextView;
104   BOOL _heightTracksTextView;
105 }
106 
107 /**
108 Initializes a new instance and sets the container size to aSize.
109 */
110 - (id) initWithContainerSize: (NSSize)aSize;
111 
112 
113 /**
114 Querying the region
115 */
116 
117 /**
118 Returns YES if the region for this container is a rectangle
119 as large as the container size, otherwise NO. For simple rectangular regions,
120 the text system can apply certain optimizations.
121 
122 NSTextContainer always returns YES. Subclasses that define more complex
123 regions must return NO.
124 */
125 - (BOOL) isSimpleRectangularTextContainer;
126 
127 /**
128 This is the main method used by the text system for querying the region
129 and flowing text in it. It takes a proposed line fragment rectangle and,
130 if possible, splits it into a valid line fragment rectangle, and a remaining
131 rectangle that can be used in subsequent calls to this method.
132 
133 sweepDir is the direction that text moves inside the lines, and moveDir is
134 the direction lines move in, or NSLineDoesntMove if the line may not move.
135 The line sweep and line movement may not both be in the same dimension, ie.
136 both be vertical, or both be horizontal.
137 
138 The method returns the first (according to the sweep direction) valid line
139 fragment rectangle in the proposed rectangle. This line fragment rectangle
140 is a sub-rectangle of the proposed rectangle in the sweep direction, and has
141 the same size in the other direction. (Ie. if the sweep direction is left,
142 the line fragment rectangle must have the same height as the proposed
143 rectangle.) If there is no valid line fragment rectangle in the proposed
144 rectangle, the proposed rectangle may be moved in the line movement direction
145 until there is one. If no valid line fragment rectangle can be returned,
146 the method returns NSZeroRect.
147 
148 The remaining rectangle should be set to the potentially valid part of the
149 proposed rectangle, after moving in the line movement direction, that remains
150 after the first line fragment rectangle.
151 
152 The proposed rectangle may be any rectangle; in particular, it may extend
153 outside the container size. The remaining rectangle does not have to be or
154 contain a valid line fragment rectangle.
155 
156 Subclasses define regions by overriding this method.
157 
158 Note: The TextContainerExample in the text system example collection
159 (TODO: link) contains an example implementation of an NSTextContainer subclass
160 that defiens a non-trivial region, as well as an interactive demonstration of
161 this method. It can also be used as a simple test of custom subclasses.
162 
163 Note: Although a correct NSTextContainer implementation must handle all line
164 sweep and movement directions, the current standard typesetter will only call
165 this method with sweep right, and no movement or movement down. Relying on
166 this makes writing a subclass easier, but it is <em>not</em> safe.
167 */
168 - (NSRect) lineFragmentRectForProposedRect: (NSRect)proposedRect
169 			    sweepDirection: (NSLineSweepDirection)sweepDir
170 			 movementDirection: (NSLineMovementDirection)moveDir
171 			     remainingRect: (NSRect *)remainingRect;
172 
173 /**
174 Returns YES if aPoint is inside the region.
175 
176 Subclasses define regions by overriding this method.
177 */
178 - (BOOL) containsPoint: (NSPoint)aPoint;
179 
180 
181 /**
182 Managing the text network<br />
183 
184 A text container may be attached to one layout manager and one text view.
185 The text container is retained by the layout manager, and retains the text
186 view.
187 */
188 
189 /**
190 Replaces the layout manager of this text container with aLayoutManager.
191 This is done without changing the rest of the text network, so
192 aLayoutManager will be connected to the text storage and text containers
193 that the current layout manager is connected to.
194 */
195 - (void) replaceLayoutManager: (GSLayoutManager *)aLayoutManager;
196 
197 /**
198 Returns the layout manager of this text container.
199 */
200 - (GSLayoutManager *) layoutManager;
201 
202 /**
203 This method should not be called directly. It is called by the layout manager
204 when the layout manager of a text container changes.
205 */
206 - (void) setLayoutManager: (GSLayoutManager *)aLayoutManager;
207 
208 
209 /**
210 Sets the NSTextView for this text container. Note that a text view
211 should be attached to a text container only if the text container is attached
212 to a layout manager that can handle text views (eg. NSLayoutManager).
213 
214 The text view is retained by the text container.
215 */
216 - (void) setTextView: (NSTextView *)aTextView;
217 
218 /**
219 Returns the NSTextView attached to this text container, or nil if there is
220 none.
221 */
222 - (NSTextView *) textView;
223 
224 
225 /**
226 The container size<br />
227 
228 A text container has a container size. The region defined by the text
229 container must be a subset of the rectangle of this size with it's top-left
230 corner in the origin.
231 
232 Subclasses do not have to support arbitrary sizes, and may choose to ignore
233 -setContainerSize: completely. However, the size returned by -containerSize
234 must be valid.
235 */
236 - (void) setContainerSize: (NSSize)aSize;
237 - (NSSize) containerSize;
238 
239 
240 /**
241 Automatic resizing<br />
242 
243 A text container can be set to automatically track the width and/or height
244 of its NSTextView (TODO: frame? bounds?). For more information, see the
245 documentation on automatic resizing in NSTextView. (TODO: link)
246 
247 When enabled, the automatic resizing is done by calling
248 [NSTextContainer-setContainerSize:] with the new size whenever the text view
249 is resized.
250 */
251 - (void) setWidthTracksTextView: (BOOL)flag;
252 - (BOOL) widthTracksTextView;
253 - (void) setHeightTracksTextView: (BOOL)flag;
254 - (BOOL) heightTracksTextView;
255 
256 
257 /**
258 Line fragment padding<br />
259 
260 The line fragment padding is an amount of space left empty at each end of
261 a line fragment rectangle by the standard typesetter. The default is 0.0.
262 */
263 - (void) setLineFragmentPadding: (CGFloat)aFloat;
264 - (CGFloat) lineFragmentPadding;
265 
266 @end
267 
268 #else
269 #error "The OpenStep specification does not define an NSTextContainer class."
270 #endif
271 
272 #endif /* _GNUstep_H_NSTextContainer */
273