1
2 /* $Id: tixHLCol.c,v 1.2 2004/03/28 02:44:56 hobbs Exp $ */
3
4 /*
5 * tixHLCol.c ---
6 *
7 *
8 * Implements columns inside tixHList widgets
9 *
10 * Copyright (c) 1996, Expert Interface Technologies
11 *
12 * See the file "license.terms" for information on usage and redistribution
13 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14 *
15 */
16
17 #include <tixPort.h>
18 #include <tixInt.h>
19 #include <tixHList.h>
20
21 static TIX_DECLARE_SUBCMD(Tix_HLItemCreate);
22 static TIX_DECLARE_SUBCMD(Tix_HLItemConfig);
23 static TIX_DECLARE_SUBCMD(Tix_HLItemCGet);
24 static TIX_DECLARE_SUBCMD(Tix_HLItemDelete);
25 static TIX_DECLARE_SUBCMD(Tix_HLItemExists);
26
27 static TIX_DECLARE_SUBCMD(Tix_HLColWidth);
28
29 static HListElement * Tix_HLGetColumn(Tcl_Interp *interp, WidgetPtr wPtr,
30 CONST84 char ** argv, int * column_ret, int mustExist);
31
32 HListColumn *
Tix_HLAllocColumn(wPtr,chPtr)33 Tix_HLAllocColumn(wPtr, chPtr)
34 WidgetPtr wPtr;
35 HListElement * chPtr;
36 {
37 HListColumn * column;
38 int i;
39
40 column =
41 (HListColumn*)ckalloc(sizeof(HListColumn)*wPtr->numColumns);
42 for (i=0; i<wPtr->numColumns; i++) {
43 column[i].type = HLTYPE_COLUMN;
44 column[i].self = (char*)&column[i];
45 column[i].chPtr = chPtr;
46 column[i].iPtr = NULL;
47 column[i].iPtr = NULL;
48 column[i].width = UNINITIALIZED;
49 }
50 return column;
51 }
52
53 static HListElement *
Tix_HLGetColumn(interp,wPtr,argv,column_ret,mustExist)54 Tix_HLGetColumn(interp, wPtr, argv, column_ret, mustExist)
55 Tcl_Interp *interp;
56 WidgetPtr wPtr;
57 CONST84 char ** argv;
58 int * column_ret;
59 int mustExist;
60 {
61 HListElement * chPtr;
62 int column;
63
64 if ((chPtr = Tix_HLFindElement(interp, wPtr, argv[0])) == NULL) {
65 return NULL;
66 }
67 if (Tcl_GetInt(interp, argv[1], &column) != TCL_OK) {
68 return NULL;
69 }
70 if (column >= wPtr->numColumns || column < 0) {
71 Tcl_AppendResult(interp, "Column \"", argv[1],
72 "\" does not exist", (char*)NULL);
73 return NULL;
74 }
75 if (mustExist && chPtr->col[column].iPtr == NULL) {
76 Tcl_AppendResult(interp, "entry \"", argv[0],
77 "\" does not have an item at column ", argv[1], NULL);
78 return NULL;
79 }
80
81 * column_ret = column;
82 return chPtr;
83 }
84
85 /*----------------------------------------------------------------------
86 * "item" sub command
87 *----------------------------------------------------------------------
88 */
89 int
Tix_HLItem(clientData,interp,argc,argv)90 Tix_HLItem(clientData, interp, argc, argv)
91 ClientData clientData;
92 Tcl_Interp *interp; /* Current interpreter. */
93 int argc; /* Number of arguments. */
94 CONST84 char **argv; /* Argument strings. */
95 {
96 static Tix_SubCmdInfo subCmdInfo[] = {
97 {TIX_DEFAULT_LEN, "cget", 3, 3, Tix_HLItemCGet,
98 "entryPath column option"},
99 {TIX_DEFAULT_LEN, "configure", 2, TIX_VAR_ARGS, Tix_HLItemConfig,
100 "entryPath column ?option? ?value ...?"},
101 {TIX_DEFAULT_LEN, "create", 2, TIX_VAR_ARGS, Tix_HLItemCreate,
102 "entryPath column ?option value ...?"},
103 {TIX_DEFAULT_LEN, "delete", 2, 2, Tix_HLItemDelete,
104 "entryPath column"},
105 {TIX_DEFAULT_LEN, "exists", 2, 2, Tix_HLItemExists,
106 "entryPath column"},
107 };
108 static Tix_CmdInfo cmdInfo = {
109 Tix_ArraySize(subCmdInfo), 1, TIX_VAR_ARGS, "?option? ?arg ...?",
110 };
111
112 return Tix_HandleSubCmds(&cmdInfo, subCmdInfo, clientData,
113 interp, argc+1, argv-1);
114 }
115
116 /*----------------------------------------------------------------------
117 * "item cget" sub command
118 *----------------------------------------------------------------------
119 */
120 static int
Tix_HLItemCGet(clientData,interp,argc,argv)121 Tix_HLItemCGet(clientData, interp, argc, argv)
122 ClientData clientData;
123 Tcl_Interp *interp; /* Current interpreter. */
124 int argc; /* Number of arguments. */
125 CONST84 char **argv; /* Argument strings. */
126 {
127 WidgetPtr wPtr = (WidgetPtr) clientData;
128 HListElement * chPtr;
129 int column;
130
131 if ((chPtr=Tix_HLGetColumn(interp, wPtr, argv, &column, 1)) == NULL) {
132 return TCL_ERROR;
133 }
134
135 return Tk_ConfigureValue(interp, wPtr->dispData.tkwin,
136 chPtr->col[column].iPtr->base.diTypePtr->itemConfigSpecs,
137 (char *)chPtr->col[column].iPtr, argv[2], 0);
138 }
139
140 /*----------------------------------------------------------------------
141 * "item configure" sub command
142 *----------------------------------------------------------------------
143 */
144 static int
Tix_HLItemConfig(clientData,interp,argc,argv)145 Tix_HLItemConfig(clientData, interp, argc, argv)
146 ClientData clientData;
147 Tcl_Interp *interp; /* Current interpreter. */
148 int argc; /* Number of arguments. */
149 CONST84 char **argv; /* Argument strings. */
150 {
151 WidgetPtr wPtr = (WidgetPtr) clientData;
152 HListElement * chPtr;
153 int column;
154
155 if ((chPtr=Tix_HLGetColumn(interp, wPtr, argv, &column, 1)) == NULL) {
156 return TCL_ERROR;
157 }
158
159 if (argc == 2) {
160 return Tk_ConfigureInfo(interp, wPtr->dispData.tkwin,
161 chPtr->col[column].iPtr->base.diTypePtr->itemConfigSpecs,
162 (char *)chPtr->col[column].iPtr, NULL, 0);
163 } else if (argc == 3) {
164 return Tk_ConfigureInfo(interp, wPtr->dispData.tkwin,
165 chPtr->col[column].iPtr->base.diTypePtr->itemConfigSpecs,
166 (char *)chPtr->col[column].iPtr, argv[2], 0);
167 } else {
168 Tix_HLMarkElementDirty(wPtr, chPtr);
169 Tix_HLResizeWhenIdle(wPtr);
170
171 return Tix_DItemConfigure(chPtr->col[column].iPtr,
172 argc-2, argv+2, TK_CONFIG_ARGV_ONLY);
173 }
174 }
175
176 /*----------------------------------------------------------------------
177 * "item create" sub command
178 *----------------------------------------------------------------------
179 */
180 static int
Tix_HLItemCreate(clientData,interp,argc,argv)181 Tix_HLItemCreate(clientData, interp, argc, argv)
182 ClientData clientData;
183 Tcl_Interp *interp; /* Current interpreter. */
184 int argc; /* Number of arguments. */
185 CONST84 char **argv; /* Argument strings. */
186 {
187 WidgetPtr wPtr = (WidgetPtr) clientData;
188 HListElement * chPtr;
189 int column, i;
190 size_t len;
191 Tix_DItem * iPtr;
192 CONST84 char * ditemType = NULL;
193
194 if ((chPtr=Tix_HLGetColumn(interp, wPtr, argv, &column, 0)) == NULL) {
195 return TCL_ERROR;
196 }
197
198 if (argc %2) {
199 Tcl_AppendResult(interp, "value for \"", argv[argc-1],
200 "\" missing", NULL);
201 return TCL_ERROR;
202 }
203 for (i=2; i<argc; i+=2) {
204 len = strlen(argv[i]);
205 if (strncmp(argv[i], "-itemtype", len) == 0) {
206 ditemType = argv[i+1];
207 }
208 }
209 if (ditemType == NULL) {
210 ditemType = wPtr->diTypePtr->name;
211 }
212
213 iPtr = Tix_DItemCreate(&wPtr->dispData, ditemType);
214 if (iPtr == NULL) {
215 return TCL_ERROR;
216 }
217
218 iPtr->base.clientData = (ClientData)&chPtr->col[column];
219 if (Tix_DItemConfigure(iPtr, argc-2, argv+2, 0) != TCL_OK) {
220 return TCL_ERROR;
221 }
222
223 if (chPtr->col[column].iPtr != NULL) {
224 if (Tix_DItemType(chPtr->col[column].iPtr) == TIX_DITEM_WINDOW) {
225 Tix_WindowItemListRemove(&wPtr->mappedWindows,
226 chPtr->col[column].iPtr);
227 }
228 Tix_DItemFree(chPtr->col[column].iPtr);
229 }
230 chPtr->col[column].iPtr = iPtr;
231 Tix_HLMarkElementDirty(wPtr, chPtr);
232 Tix_HLResizeWhenIdle(wPtr);
233
234 return TCL_OK;
235 }
236 /*----------------------------------------------------------------------
237 * "item delete" sub command
238 *----------------------------------------------------------------------
239 */
240 static int
Tix_HLItemDelete(clientData,interp,argc,argv)241 Tix_HLItemDelete(clientData, interp, argc, argv)
242 ClientData clientData;
243 Tcl_Interp *interp; /* Current interpreter. */
244 int argc; /* Number of arguments. */
245 CONST84 char **argv; /* Argument strings. */
246 {
247 WidgetPtr wPtr = (WidgetPtr) clientData;
248 HListElement * chPtr;
249 int column;
250
251 if ((chPtr=Tix_HLGetColumn(interp, wPtr, argv, &column, 1)) == NULL) {
252 return TCL_ERROR;
253 }
254
255 if (column == 0) {
256 Tcl_AppendResult(interp,"Cannot delete item at column 0",(char*)NULL);
257 return TCL_ERROR;
258 }
259
260 if (Tix_DItemType(chPtr->col[column].iPtr) == TIX_DITEM_WINDOW) {
261 Tix_WindowItemListRemove(&wPtr->mappedWindows,
262 chPtr->col[column].iPtr);
263 }
264
265 /* Free the item and leave a blank */
266 Tix_DItemFree(chPtr->col[column].iPtr);
267 chPtr->col[column].iPtr = NULL;
268
269 Tix_HLMarkElementDirty(wPtr, chPtr);
270 Tix_HLResizeWhenIdle(wPtr);
271
272 return TCL_OK;
273 }
274
275 /*----------------------------------------------------------------------
276 * "item exists" sub command
277 *----------------------------------------------------------------------
278 */
279 static int
Tix_HLItemExists(clientData,interp,argc,argv)280 Tix_HLItemExists(clientData, interp, argc, argv)
281 ClientData clientData;
282 Tcl_Interp *interp; /* Current interpreter. */
283 int argc; /* Number of arguments. */
284 CONST84 char **argv; /* Argument strings. */
285 {
286 WidgetPtr wPtr = (WidgetPtr) clientData;
287 HListElement * chPtr;
288 int column;
289
290 if ((chPtr=Tix_HLGetColumn(interp, wPtr, argv, &column, 0)) == NULL) {
291 return TCL_ERROR;
292 }
293
294 if (chPtr->col[column].iPtr == NULL) {
295 Tcl_AppendResult(interp, "0", NULL);
296 } else {
297 Tcl_AppendResult(interp, "1", NULL);
298 }
299
300 return TCL_OK;
301 }
302 /*----------------------------------------------------------------------
303 * "column" sub command
304 *----------------------------------------------------------------------
305 */
306 int
Tix_HLColumn(clientData,interp,argc,argv)307 Tix_HLColumn(clientData, interp, argc, argv)
308 ClientData clientData;
309 Tcl_Interp *interp; /* Current interpreter. */
310 int argc; /* Number of arguments. */
311 CONST84 char **argv; /* Argument strings. */
312 {
313 static Tix_SubCmdInfo subCmdInfo[] = {
314 {TIX_DEFAULT_LEN, "width", 1, 3, Tix_HLColWidth,
315 "column ?-char? ?size?"},
316 };
317 static Tix_CmdInfo cmdInfo = {
318 Tix_ArraySize(subCmdInfo), 1, TIX_VAR_ARGS, "?option? ?arg ...?",
319 };
320
321 return Tix_HandleSubCmds(&cmdInfo, subCmdInfo, clientData,
322 interp, argc+1, argv-1);
323 }
324
325 /*----------------------------------------------------------------------
326 * "column width" sub command
327 *----------------------------------------------------------------------
328 */
329 static int
Tix_HLColWidth(clientData,interp,argc,argv)330 Tix_HLColWidth(clientData, interp, argc, argv)
331 ClientData clientData;
332 Tcl_Interp *interp; /* Current interpreter. */
333 int argc; /* Number of arguments. */
334 CONST84 char **argv; /* Argument strings. */
335 {
336 WidgetPtr wPtr = (WidgetPtr) clientData;
337 int column;
338 char buff[128];
339 int newWidth;
340
341 if (Tcl_GetInt(interp, argv[0], &column) != TCL_OK) {
342 return TCL_ERROR;
343 }
344 if (column >= wPtr->numColumns || column < 0) {
345 Tcl_AppendResult(interp, "Column \"", argv[0],
346 "\" does not exist", (char*)NULL);
347 return TCL_ERROR;
348 }
349 if (argc == 1) { /* Query */
350 if (wPtr->root->dirty || wPtr->allDirty) {
351 /* We must update the geometry NOW otherwise we will get a wrong
352 * width
353 */
354 Tix_HLCancelResizeWhenIdle(wPtr);
355 Tix_HLComputeGeometry((ClientData)wPtr);
356 }
357 sprintf(buff, "%d", wPtr->actualSize[column].width);
358 Tcl_AppendResult(interp, buff, NULL);
359 return TCL_OK;
360 }
361 else if (argc == 2) {
362 if (argv[1][0] == '\0') {
363 newWidth = UNINITIALIZED;
364 goto setwidth;
365 }
366 if (Tk_GetPixels(interp, wPtr->dispData.tkwin, argv[1],
367 &newWidth) != TCL_OK) {
368 return TCL_ERROR;
369 }
370 if (newWidth < 0) {
371 newWidth = 0;
372 }
373 }
374 else if (argc == 3 && strcmp(argv[1], "-char")==0) {
375 if (argv[2][0] == '\0') {
376 newWidth = UNINITIALIZED;
377 goto setwidth;
378 }
379 if (Tcl_GetInt(interp, argv[2], &newWidth) != TCL_OK) {
380 return TCL_ERROR;
381 }
382 if (newWidth < 0) {
383 newWidth = 0;
384 }
385 newWidth *= wPtr->scrollUnit[0];
386 }
387 else {
388 return Tix_ArgcError(interp, argc+3, argv-3, 3,
389 "column ?-char? ?size?");
390 }
391
392 setwidth:
393
394 if (wPtr->reqSize[column].width == newWidth) {
395 return TCL_OK;
396 } else {
397 wPtr->reqSize[column].width = newWidth;
398 }
399
400 if (wPtr->actualSize[column].width == newWidth) {
401 return TCL_OK;
402 } else {
403 wPtr->allDirty = 1;
404 Tix_HLResizeWhenIdle(wPtr);
405 return TCL_OK;
406 }
407 }
408