1 /*
2  * bltTable.h --
3  *
4  *	This module implements a table-based geometry manager
5  *	for the BLT toolkit.
6  *
7  * Copyright 1993-1998 Lucent Technologies, Inc.
8  *
9  * Permission to use, copy, modify, and distribute this software and
10  * its documentation for any purpose and without fee is hereby
11  * granted, provided that the above copyright notice appear in all
12  * copies and that both that the copyright notice and warranty
13  * disclaimer appear in supporting documentation, and that the names
14  * of Lucent Technologies any of their entities not be used in
15  * advertising or publicity pertaining to distribution of the software
16  * without specific, written prior permission.
17  *
18  * Lucent Technologies disclaims all warranties with regard to this
19  * software, including all implied warranties of merchantability and
20  * fitness.  In no event shall Lucent Technologies be liable for any
21  * special, indirect or consequential damages or any damages
22  * whatsoever resulting from loss of use, data or profits, whether in
23  * an action of contract, negligence or other tortuous action, arising
24  * out of or in connection with the use or performance of this
25  * software.
26  *
27  *	The table geometry manager was created by George Howlett.
28  */
29 
30 #ifndef _BLT_TABLE_H
31 #define _BLT_TABLE_H
32 
33 #include "bltChain.h"
34 #include "bltHash.h"
35 #include "bltList.h"
36 
37 typedef struct {
38     Blt_HashTable tableTable;	/* Hash table of table structures keyed by
39 				 * the address of the reference Tk window */
40 } TableInterpData;
41 
42 
43 typedef struct EditorStruct Editor;
44 typedef void (EditorDrawProc) _ANSI_ARGS_((Editor *editor));
45 typedef void (EditorDestroyProc) _ANSI_ARGS_((DestroyData destroyData));
46 
47 struct EditorStruct {
48     int gridLineWidth;
49     int buttonHeight;
50     int entryPad;
51     int minSize;		/* Minimum size to allow any partition */
52 
53     EditorDrawProc *drawProc;
54     EditorDestroyProc *destroyProc;
55 };
56 
57 #define nRows		rowInfo.chainPtr->nLinks
58 #define nColumns	columnInfo.chainPtr->nLinks
59 
60 /*
61  * Limits --
62  *
63  * 	Defines the bounding of a size (width or height) in the table.
64  * 	It may be related to the partition, entry, or table size.  The
65  * 	widget pointers are used to associate sizes with the requested
66  * 	size of other widgets.
67  */
68 
69 typedef struct {
70     int flags;			/* Flags indicate whether using default
71 				 * values for limits or not. See flags
72 				 * below. */
73     int max, min;		/* Values for respective limits. */
74     int nom;			/* Nominal starting value. */
75     Tk_Window wMax, wMin;	/* If non-NULL, represents widgets whose
76 				 * requested sizes will be set as limits. */
77     Tk_Window wNom;		/* If non-NULL represents widget whose
78 				 * requested size will be the nominal
79 				 * size. */
80 } Limits;
81 
82 #define LIMITS_SET_BIT	1
83 #define LIMITS_SET_MIN  (LIMITS_SET_BIT<<0)
84 #define LIMITS_SET_MAX  (LIMITS_SET_BIT<<1)
85 #define LIMITS_SET_NOM  (LIMITS_SET_BIT<<2)
86 
87 #define LIMITS_MIN	0	/* Default minimum limit  */
88 #define LIMITS_MAX	SHRT_MAX/* Default maximum limit */
89 #define LIMITS_NOM	-1000	/* Default nomimal value.  Indicates if a
90 				 * partition has received any space yet */
91 
92 typedef int (LimitsProc) _ANSI_ARGS_((int value, Limits *limitsPtr));
93 
94 /*
95  * Resize --
96  *
97  *	These flags indicate in what ways each partition in a table
98  *	can be resized from its default dimensions.  The normal size of
99  *	a row/column is the minimum amount of space needed to hold the
100  *	widgets that span it.  The table may then be stretched or
101  *	shrunk depending if the container is larger or smaller than
102  *	the table. This can occur if 1) the user resizes the toplevel
103  *	widget, or 2) the container is in turn packed into a larger
104  *	widget and the "fill" option is set.
105  *
106  * 	  RESIZE_NONE 	  - No resizing from normal size.
107  *	  RESIZE_EXPAND   - Do not allow the size to decrease.
108  *			    The size may increase however.
109  *        RESIZE_SHRINK   - Do not allow the size to increase.
110  *			    The size may decrease however.
111  *	  RESIZE_BOTH     - Allow the size to increase or
112  *			    decrease from the normal size.
113  *	  RESIZE_VIRGIN   - Special case of the resize flag.  Used to
114  *			    indicate the initial state of the flag.
115  *			    Empty rows/columns are treated differently
116  *			    if this row/column is set.
117  */
118 
119 #define RESIZE_NONE	0
120 #define RESIZE_EXPAND	(1<<0)
121 #define RESIZE_SHRINK	(1<<1)
122 #define RESIZE_BOTH	(RESIZE_EXPAND | RESIZE_SHRINK)
123 #define RESIZE_VIRGIN	(1<<2)
124 
125 /*
126  * Control --
127  */
128 #define CONTROL_NORMAL	1.0	/* Consider the widget when
129 				 * calculating the row heights and
130 				 * column widths.  */
131 #define CONTROL_NONE	0.0	/* Ignore the widget.  The height and
132 				 * width of the rows/columns spanned
133 				 * by this widget will not affected by
134 				 * the size of the widget.
135 				 */
136 #define CONTROL_FULL	-1.0	/* Consider only this widget when
137 				 * determining the column widths
138 				 * and row heights of the partitions
139 				 * it spans. */
140 #define EXCL_PAD 	0
141 #define INCL_PAD	1
142 
143 typedef struct TableStruct Table;
144 typedef struct RowColumnStruct RowColumn;
145 
146 /*
147  * Entry --
148  *
149  *	An entry holds a widget and describes how the widget should
150  *	appear in a range of cells.
151  *	 1. padding.
152  *	 2. how many rows/columns the entry spans.
153  *	 3. size bounds for the widget.
154  *
155  *	Several entries may start at the same cell in
156  *	the table, but a entry can hold only one widget.
157  */
158 
159 typedef struct  {
160     Tk_Window tkwin;		/* Widget to be managed. */
161 
162     Table *tablePtr;		/* Table managing this widget */
163 
164     int borderWidth;		/* The external border width of
165 				 * the widget. This is needed to check if
166 				 * Tk_Changes(tkwin)->border_width changes.
167 				 */
168 
169     int manageWhenNeeded;	/* If non-zero, allow joint custody of
170 				 * the widget.  This is for cases
171 				 * where the same widget may be shared
172 				 * between two different tables
173 				 * (e.g. same graph on two different
174 				 * notebook pages).  Claim the widget
175 				 * only when the table is
176 				 * mapped. Don't destroy the entry if
177 				 * the table loses custody of the
178 				 * widget. */
179 
180     Limits reqWidth, reqHeight;	/* Bounds for width and height requests
181 				 * made by the widget. */
182     struct PositionInfo {
183 	RowColumn *rcPtr;	/* Row or column where this entry starts. */
184 
185 	int span;		/* Number of rows or columns spanned. */
186 	double control;		/* Weight of widget in the row or column. */
187 
188 	Blt_ChainLink *linkPtr;	/* Link to widget in the chain of spans */
189 
190 	Blt_Chain *chainPtr;	/* Pointer to the chain of spans. */
191     } row, column;
192 
193     Tk_Anchor anchor;		/* Anchor type: indicates how the
194 				 * widget is positioned if extra space
195 				 * is available in the entry */
196 
197     Blt_Pad padX;		/* Extra padding placed left and right of the
198 				 * widget. */
199     Blt_Pad padY;		/* Extra padding placed above and below the
200 				 * widget */
201 
202     int ipadX, ipadY;		/* Extra padding added to the interior of
203 				 * the widget (i.e. adds to the requested
204 				 * size of the widget) */
205 
206     int fill;			/* Indicates how the widget should
207 				 * fill the span of cells it occupies. */
208 
209     int x, y;			/* Origin of widget wrt container. */
210 
211     Blt_ChainLink *linkPtr;	/* Pointer into list of entries. */
212 
213     Blt_HashEntry *hashPtr;	/* Pointer into table of entries. */
214 
215 } Entry;
216 
217 /*
218  * RowColumn --
219  *
220  * 	Creates a definable space (row or column) in the table. It may
221  * 	have both requested minimum or maximum values which constrain
222  * 	the size of it.
223  */
224 
225 struct RowColumnStruct {
226     int index;			/* Index of row or column */
227 
228     int size;			/* Current size of the partition. This size
229 				 * is bounded by minSize and maxSize. */
230 
231     /*
232      * nomSize and size perform similar duties.  I need to keep track
233      * of the amount of space allocated to the partition (using size).
234      * But at the same time, I need to indicate that space can be
235      * parcelled out to this partition.  If a nominal size was set for
236      * this partition, I don't want to add space.
237      */
238 
239     int nomSize;		/* The nominal size (neither expanded
240 				 * nor shrunk) of the partition based
241 				 * upon the requested sizes of the
242 				 * widgets spanning this partition. */
243 
244     int minSize, maxSize;	/* Size constraints on the partition */
245 
246     int offset;			/* Offset of the partition (in pixels)
247 				 * from the origin of the container. */
248 
249     int minSpan;		/* Minimum spanning widget in
250 				 * partition. Used for bookkeeping
251 				 * when growing a span of partitions
252 				 * */
253 
254     double weight;		/* Weight of row or column */
255 
256     Entry *control;		/* Pointer to the entry that is
257 				 * determining the size of this
258 				 * partition.  This is used to know
259 				 * when a partition is occupied. */
260 
261     int resize;			/* Indicates if the partition should
262 				 * shrink or expand from its nominal
263 				 * size. */
264 
265     Blt_Pad pad;		/* Pads the partition beyond its nominal
266 				 * size */
267 
268     Limits reqSize;		/* Requested bounds for the size of
269 				 * the partition. The partition will
270 				 * not expand or shrink beyond these
271 				 * limits, regardless of how it was
272 				 * specified (max widget size).  This
273 				 * includes any extra padding which
274 				 * may be specified. */
275 
276     int maxSpan;		/* Maximum spanning widget to consider
277 				 * when growing a span of partitions.
278 				 * A value of zero indicates that all
279 				 * spans should be considered. */
280 
281     int count;
282 
283     Blt_ChainLink *linkPtr;
284 
285 };
286 
287 #define DEF_TBL_RESIZE	"both"
288 #define DEF_TBL_PAD	"0"
289 #define DEF_TBL_MAXSPAN	"0"
290 
291 
292 /*
293  * This is the default number of elements in the statically
294  * pre-allocated column and row arrays.  This number should reflect a
295  * useful number of row and columns, which fit most applications.
296  */
297 #define DEF_ARRAY_SIZE	32
298 
299 typedef Entry *(EntrySearchProc) _ANSI_ARGS_((Table *tablePtr,
300 	Tk_Window tkwin));
301 
302 /*
303  * PartitionInfo --
304  *
305  * 	Manages the rows or columns of the table.  Contains
306  *	a chain of partitions (representing the individiual
307  *	rows or columns).
308  *
309  */
310 typedef struct PartitionInfo {
311     char *type;			/* String identifying the type of
312 				 * partition: "row" or "column". */
313     Blt_Chain *chainPtr;
314     Blt_List list;		/* Linked list of bins of widgets
315 				 * keyed by increasing span. */
316     Tk_ConfigSpec *configSpecs;
317     int reqLength;
318     int ePad;			/* Extra padding for row/column
319 				 * needed to display editor marks */
320 } PartitionInfo;
321 
322 /*
323  * Table structure
324  */
325 struct TableStruct {
326     int flags;			/* See the flags definitions below. */
327     Tk_Window tkwin;		/* The container widget into which
328 				 * other widgets are arranged. */
329     Tcl_Interp *interp;		/* Interpreter associated with all
330 				 * widgets */
331 
332     Blt_Chain *chainPtr;	/* Chain of entries in the table. */
333 
334     Blt_HashTable entryTable;	/* Table of entries.  Serves as a
335 				 * directory to look up entries from
336 				 * widget their names. */
337     Blt_Pad padX, padY;
338 
339     int propagate;		/* If non-zero, the table will make a
340 				 * geometry request on behalf of the
341 				 * container widget. */
342 
343     int eTablePad, eEntryPad;
344 
345     PartitionInfo columnInfo;
346     PartitionInfo rowInfo;	/* Manages row and column partitions */
347 
348     Dim2D container;		/* Last known dimenion of the container. */
349     Dim2D normal;		/* Normal dimensions of the table */
350     Limits reqWidth, reqHeight;	/* Constraints on the table's normal
351 				 * width and height */
352     Editor *editPtr;		/* If non-NULL, indicates that the
353 				 * table is currently being edited */
354     Tcl_IdleProc *arrangeProc;
355     EntrySearchProc *findEntryProc;
356     Blt_HashEntry *hashPtr;	/* Used to delete the table from its
357 				 * hashtable. */
358     Blt_HashTable *tablePtr;
359 };
360 
361 /*
362  * Table flags definitions
363  */
364 #define ARRANGE_PENDING (1<<0)	/* A call to ArrangeTable is
365 				 * pending. This flag allows multiple
366 				 * layout changes to be requested
367 				 * before the table is actually
368 				 * reconfigured. */
369 #define REQUEST_LAYOUT 	(1<<1)	/* Get the requested sizes of the
370 				 * widgets before expanding/shrinking
371 				 * the size of the container.  It's
372 				 * necessary to recompute the layout
373 				 * every time a partition or entry is
374 				 * added, reconfigured, or deleted,
375 				 * but not when the container is
376 				 * resized. */
377 #define NON_PARENT	(1<<2)	/* The table is managing widgets that
378 				 * arern't children of the container.
379 				 * This requires that they are
380 				 * manually moved when the container
381 				 * is moved (a definite performance
382 				 * hit). */
383 /*
384  * Forward declarations
385  */
386 
387 extern int Blt_GetTable _ANSI_ARGS_((TableInterpData *dataPtr,
388 	Tcl_Interp *interp, char *pathName, Table **tablePtrPtr));
389 
390 #endif /* _BLT_TABLE_H */
391