OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tix/] [generic/] [tixHLHdr.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 *  tixHLHdr.c ---
3
 *
4
 *
5
 *      Implements headers for tixHList widgets
6
 *
7
 * Copyright (c) 1996, Expert Interface Technologies
8
 *
9
 * See the file "license.terms" for information on usage and redistribution
10
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11
 *
12
 */
13
 
14
#include <tixPort.h>
15
#include <tixInt.h>
16
#include <tixHList.h>
17
#include <tixDef.h>
18
 
19
static TIX_DECLARE_SUBCMD(Tix_HLHdrCreate);
20
static TIX_DECLARE_SUBCMD(Tix_HLHdrConfig);
21
static TIX_DECLARE_SUBCMD(Tix_HLHdrCGet);
22
static TIX_DECLARE_SUBCMD(Tix_HLHdrDelete);
23
static TIX_DECLARE_SUBCMD(Tix_HLHdrExist);
24
static TIX_DECLARE_SUBCMD(Tix_HLHdrSize);
25
 
26
static void             FreeWindowItem _ANSI_ARGS_((Tcl_Interp  *interp,
27
                            WidgetPtr wPtr, HListHeader *hPtr));
28
static void             FreeHeader _ANSI_ARGS_((Tcl_Interp  *interp,
29
                            WidgetPtr wPtr, HListHeader *hPtr));
30
static HListHeader*     AllocHeader _ANSI_ARGS_((Tcl_Interp *interp,
31
                            WidgetPtr wPtr));
32
static HListHeader*     Tix_HLGetHeader _ANSI_ARGS_((Tcl_Interp * interp,
33
                            WidgetPtr wPtr, char * string,
34
                            int requireIPtr));
35
 
36
static Tk_ConfigSpec headerConfigSpecs[] = {
37
    {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL,
38
       (char *) NULL, 0, 0},
39
 
40
    {TK_CONFIG_PIXELS, "-borderwidth", "headerBorderWidth", "BorderWidth",
41
       DEF_HLISTHEADER_BORDER_WIDTH, Tk_Offset(HListHeader, borderWidth), 0},
42
 
43
    {TK_CONFIG_BORDER, "-headerbackground", "headerBackground", "Background",
44
       DEF_HLISTHEADER_BG_COLOR, Tk_Offset(HListHeader, background),
45
       TK_CONFIG_COLOR_ONLY},
46
 
47
    {TK_CONFIG_BORDER, "-headerbackground", "headerBackground", "Background",
48
       DEF_HLISTHEADER_BG_MONO, Tk_Offset(HListHeader, background),
49
       TK_CONFIG_MONO_ONLY},
50
 
51
    {TK_CONFIG_RELIEF, "-relief", "headerRelief", "Relief",
52
       DEF_HLISTHEADER_RELIEF, Tk_Offset(HListHeader, relief), 0},
53
 
54
    {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
55
       (char *) NULL, 0, 0}
56
};
57
 
58
/*----------------------------------------------------------------------
59
 *
60
 *              Local functions
61
 *
62
 *----------------------------------------------------------------------
63
 */
64
 
65
static HListHeader*
66
AllocHeader(interp, wPtr)
67
    Tcl_Interp *interp;
68
    WidgetPtr wPtr;
69
{
70
    HListHeader * hPtr = (HListHeader*)ckalloc(sizeof(HListHeader));
71
    hPtr->type          = HLTYPE_HEADER;
72
    hPtr->self          = (char*)hPtr;
73
    hPtr->wPtr          = wPtr;
74
    hPtr->iPtr          = NULL;
75
    hPtr->width         = 0;
76
    hPtr->background    = NULL;
77
    hPtr->relief        = TK_RELIEF_RAISED;
78
    hPtr->borderWidth   = 2;
79
 
80
    if (Tk_ConfigureWidget(interp, wPtr->dispData.tkwin, headerConfigSpecs,
81
            0, 0, (char *)hPtr, 0) != TCL_OK) {
82
        /* some unrecoverable errors */
83
        return NULL;
84
    }
85
    return hPtr;
86
}
87
 
88
static void
89
FreeWindowItem(interp, wPtr, hPtr)
90
    Tcl_Interp  *interp;
91
    WidgetPtr    wPtr;
92
    HListHeader *hPtr;
93
{
94
    Tix_WindowItemListRemove(&wPtr->mappedWindows,
95
        hPtr->iPtr);
96
}
97
 
98
static void
99
FreeHeader(interp, wPtr, hPtr)
100
    Tcl_Interp  *interp;
101
    WidgetPtr    wPtr;
102
    HListHeader *hPtr;
103
{
104
    if (hPtr->iPtr) {
105
        if (Tix_DItemType(hPtr->iPtr) == TIX_DITEM_WINDOW) {
106
            FreeWindowItem(interp, wPtr, hPtr);
107
        }
108
        Tix_DItemFree(hPtr->iPtr);
109
    }
110
 
111
    Tk_FreeOptions(headerConfigSpecs, (char *)hPtr, wPtr->dispData.display, 0);
112
    ckfree((char*) hPtr);
113
}
114
 
115
static HListHeader*
116
Tix_HLGetHeader(interp, wPtr, string, requireIPtr)
117
    Tcl_Interp * interp;
118
    WidgetPtr wPtr;
119
    char * string;
120
    int requireIPtr;
121
{
122
    int column;
123
 
124
    if (Tcl_GetInt(interp, string, &column) != TCL_OK) {
125
        return NULL;
126
    }
127
    if (column >= wPtr->numColumns || column < 0) {
128
        Tcl_AppendResult(interp, "Column \"", string,
129
            "\" does not exist", (char*)NULL);
130
        return NULL;
131
    }
132
    if (requireIPtr && wPtr->headers[column]->iPtr == NULL) {
133
        Tcl_AppendResult(interp, "Column \"", string,
134
            "\" does not have a header", (char*)NULL);
135
        return NULL;
136
    }
137
 
138
    return wPtr->headers[column];
139
}
140
 
141
int
142
Tix_HLCreateHeaders(interp, wPtr)
143
    Tcl_Interp *interp;
144
    WidgetPtr wPtr;
145
{
146
    int i;
147
 
148
    wPtr->headers = (HListHeader**)
149
      ckalloc(sizeof(HListHeader*) * wPtr->numColumns);
150
 
151
    for (i=0; i<wPtr->numColumns; i++) {
152
        wPtr->headers[i] = NULL;
153
    }
154
 
155
    for (i=0; i<wPtr->numColumns; i++) {
156
        if ((wPtr->headers[i] = AllocHeader(interp, wPtr)) == NULL) {
157
            return TCL_ERROR;
158
        }
159
    }
160
 
161
    wPtr->headerDirty = 1;
162
    return TCL_OK;
163
}
164
 
165
void Tix_HLFreeHeaders(interp, wPtr)
166
    Tcl_Interp *interp;
167
    WidgetPtr wPtr;
168
{
169
    int i;
170
 
171
    if (wPtr->headers == NULL) {
172
        return;
173
    }
174
 
175
    for (i=0; i<wPtr->numColumns; i++) {
176
        if (wPtr->headers[i] != NULL) {
177
            FreeHeader(interp, wPtr, wPtr->headers[i]);
178
        }
179
    }
180
 
181
    ckfree((char*)wPtr->headers);
182
}
183
 
184
void
185
Tix_HLDrawHeader(wPtr, pixmap, gc, hdrX, hdrY, hdrW, hdrH, xOffset)
186
    WidgetPtr wPtr;
187
    Pixmap pixmap;
188
    GC gc;
189
    int hdrX;
190
    int hdrY;
191
    int hdrW;
192
    int hdrH;
193
    int xOffset;
194
{
195
    int i, x, y;
196
    int drawnWidth;             /* how much of the header have I drawn? */
197
    int width;                  /* width of the current header item */
198
    int winItemExtra;           /* window items need a bit extra offset
199
                                 * because they must be places relative to
200
                                 * the main window, not the header subwindow
201
                                 */
202
    x = hdrX - xOffset;
203
    y = hdrY;
204
    drawnWidth = 0;
205
 
206
    winItemExtra = wPtr->borderWidth + wPtr->highlightWidth;
207
 
208
    if (wPtr->needToRaise) {
209
        /* the needToRaise flag is set every time a new window item is
210
         * created inside the header of the HList.
211
         *
212
         * We need to make sure that the windows items in the list
213
         * body are clipped by the header subwindow. However, the window
214
         * items inside the header should be over the header subwindow.
215
         *
216
         * The two XRaiseWindow calls in this function make sure that
217
         * the stacking relationship as described above always hold
218
         */
219
        XRaiseWindow(Tk_Display(wPtr->headerWin),
220
            Tk_WindowId(wPtr->headerWin));
221
    }
222
 
223
    for (i=0; i<wPtr->numColumns; i++) {
224
        HListHeader * hPtr = wPtr->headers[i];
225
        width = wPtr->actualSize[i].width;
226
 
227
        if (i == wPtr->numColumns-1) {
228
            /* If the widget is wider than required,
229
             * We need to extend the last item to the end of the list,
230
             * or otherwise we'll see a curtailed header
231
             */
232
            if (drawnWidth + width <hdrW) {
233
                width = hdrW - drawnWidth;
234
            }
235
        }
236
 
237
        Tk_Fill3DRectangle(wPtr->dispData.tkwin, pixmap, hPtr->background,
238
            x, y, width, wPtr->headerHeight, hPtr->borderWidth,
239
            hPtr->relief);
240
 
241
        /* Note when we draw the item, we use the
242
         * wPtr->actualSize[i].width instead of the (possibly extended) width
243
         * so that the header is well-aligned with the element columns.
244
         */
245
        if (hPtr->iPtr) {
246
            int itemX, itemY;
247
            itemX = x+hPtr->borderWidth;
248
            itemY = y+hPtr->borderWidth;
249
 
250
            if (Tix_DItemType(hPtr->iPtr) == TIX_DITEM_WINDOW) {
251
                itemX += winItemExtra;
252
                itemY += winItemExtra;
253
            }
254
 
255
            Tix_DItemDisplay(pixmap, gc, hPtr->iPtr,
256
                itemX, itemY,
257
                wPtr->actualSize[i].width - 2*hPtr->borderWidth,
258
                wPtr->headerHeight        - 2*hPtr->borderWidth,
259
                TIX_DITEM_NORMAL_FG);
260
 
261
            if (wPtr->needToRaise &&
262
                Tix_DItemType(hPtr->iPtr) == TIX_DITEM_WINDOW) {
263
                TixWindowItem * wiPtr;
264
 
265
                wiPtr = (TixWindowItem *)hPtr->iPtr;
266
                if (Tk_WindowId(wiPtr->tkwin) == None) {
267
                    Tk_MakeWindowExist(wiPtr->tkwin);
268
                }
269
 
270
                XRaiseWindow(Tk_Display(wiPtr->tkwin),
271
                    Tk_WindowId(wiPtr->tkwin));
272
            }
273
        }
274
 
275
        x += width;
276
        drawnWidth += width;
277
 
278
#if 0
279
        /* %% funny, doesn't work */
280
        if (drawnWidth >= hdrW) {
281
            /* The rest is invisible. Don't bother to draw */
282
            break;
283
        }
284
#endif
285
    }
286
 
287
    wPtr->needToRaise = 0;
288
}
289
 
290
void Tix_HLComputeHeaderGeometry(wPtr)
291
    WidgetPtr wPtr;
292
{
293
    int i;
294
 
295
    wPtr->headerHeight = 0;
296
 
297
    for (i=0; i<wPtr->numColumns; i++) {
298
        int height;
299
        int width;
300
 
301
        if (wPtr->headers[i]->iPtr) {
302
            width  = Tix_DItemWidth (wPtr->headers[i]->iPtr);
303
            height = Tix_DItemHeight(wPtr->headers[i]->iPtr);
304
        } else {
305
            width  = 0;
306
            height = 0;
307
        }
308
 
309
        width  += wPtr->headers[i]->borderWidth * 2;
310
        height += wPtr->headers[i]->borderWidth * 2;
311
 
312
        wPtr->headers[i]->width = width;
313
 
314
        if (height > wPtr->headerHeight) {
315
            wPtr->headerHeight = height;
316
        }
317
    }
318
 
319
    wPtr->headerDirty = 0;
320
}
321
 
322
/*----------------------------------------------------------------------
323
 * "header" sub command
324
 *----------------------------------------------------------------------
325
 */
326
int
327
Tix_HLHeader(clientData, interp, argc, argv)
328
    ClientData clientData;
329
    Tcl_Interp *interp;         /* Current interpreter. */
330
    int argc;                   /* Number of arguments. */
331
    char **argv;                /* Argument strings. */
332
{
333
    static Tix_SubCmdInfo subCmdInfo[] = {
334
        {TIX_DEFAULT_LEN, "cget", 2, 2, Tix_HLHdrCGet,
335
           "column option"},
336
        {TIX_DEFAULT_LEN, "configure", 1, TIX_VAR_ARGS, Tix_HLHdrConfig,
337
           "column ?option? ?value ...?"},
338
        {TIX_DEFAULT_LEN, "create", 1, TIX_VAR_ARGS, Tix_HLHdrCreate,
339
           "column ?option value ...?"},
340
        {TIX_DEFAULT_LEN, "delete", 1, 1, Tix_HLHdrDelete,
341
           "column"},
342
        {TIX_DEFAULT_LEN, "exist", 1, 1, Tix_HLHdrExist,
343
           "column"},
344
        {TIX_DEFAULT_LEN, "size", 1, 1, Tix_HLHdrSize,
345
           "column"},
346
    };
347
    static Tix_CmdInfo cmdInfo = {
348
        Tix_ArraySize(subCmdInfo), 1, TIX_VAR_ARGS, "?option? ?arg ...?",
349
    };
350
 
351
    return Tix_HandleSubCmds(&cmdInfo, subCmdInfo, clientData,
352
        interp, argc+1, argv-1);
353
}
354
 
355
/*----------------------------------------------------------------------
356
 * "header cget" sub command
357
 *----------------------------------------------------------------------
358
 */
359
static int
360
Tix_HLHdrCGet(clientData, interp, argc, argv)
361
    ClientData clientData;
362
    Tcl_Interp *interp;         /* Current interpreter. */
363
    int argc;                   /* Number of arguments. */
364
    char **argv;                /* Argument strings. */
365
{
366
    WidgetPtr wPtr = (WidgetPtr) clientData;
367
    HListHeader * hPtr;
368
 
369
    if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 1)) == NULL) {
370
        return TCL_ERROR;
371
    }
372
 
373
    return Tix_ConfigureValue2(interp, wPtr->dispData.tkwin,
374
        (char*)hPtr, headerConfigSpecs, hPtr->iPtr, argv[1], 0);
375
}
376
 
377
/*----------------------------------------------------------------------
378
 * "header configure" sub command
379
 *----------------------------------------------------------------------
380
 */
381
static int
382
Tix_HLHdrConfig(clientData, interp, argc, argv)
383
    ClientData clientData;
384
    Tcl_Interp *interp;         /* Current interpreter. */
385
    int argc;                   /* Number of arguments. */
386
    char **argv;                /* Argument strings. */
387
{
388
    WidgetPtr wPtr = (WidgetPtr) clientData;
389
    HListHeader * hPtr;
390
 
391
    if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 1)) == NULL) {
392
        return TCL_ERROR;
393
    }
394
 
395
    if (argc == 1) {
396
        return Tix_ConfigureInfo2(interp, wPtr->dispData.tkwin,
397
            (char*)hPtr, headerConfigSpecs, hPtr->iPtr,
398
            (char *) NULL, 0);
399
    } else if (argc == 2) {
400
        return Tix_ConfigureInfo2(interp, wPtr->dispData.tkwin,
401
            (char*)hPtr, headerConfigSpecs, hPtr->iPtr,
402
            (char *) argv[1], 0);
403
    } else {
404
        int sizeChanged = 0;
405
 
406
        if (Tix_WidgetConfigure2(interp, wPtr->dispData.tkwin,
407
            (char*)hPtr, headerConfigSpecs, hPtr->iPtr,
408
            argc-1, argv+1, TK_CONFIG_ARGV_ONLY, 0, &sizeChanged) != TCL_OK) {
409
            return TCL_ERROR;
410
        }
411
        if (sizeChanged) {
412
            wPtr->headerDirty = 1;
413
            Tix_HLResizeWhenIdle(wPtr);
414
        }
415
        return TCL_OK;
416
    }
417
}
418
 
419
 
420
/*----------------------------------------------------------------------
421
 * "header create" sub command
422
 *----------------------------------------------------------------------
423
 */
424
static int
425
Tix_HLHdrCreate(clientData, interp, argc, argv)
426
    ClientData clientData;
427
    Tcl_Interp *interp;         /* Current interpreter. */
428
    int argc;                   /* Number of arguments. */
429
    char **argv;                /* Argument strings. */
430
{
431
    WidgetPtr wPtr = (WidgetPtr) clientData;
432
    HListHeader * hPtr;
433
    int i;
434
    Tix_DItem * iPtr;
435
    char * ditemType = NULL;
436
 
437
    if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 0)) == NULL) {
438
        return TCL_ERROR;
439
    }
440
 
441
    if ((argc %2) == 0) {
442
        Tcl_AppendResult(interp, "value for \"", argv[argc-1],
443
            "\" missing", NULL);
444
        return TCL_ERROR;
445
    }
446
    for (i=1; i<argc; i+=2) {
447
        if (strncmp(argv[i], "-itemtype", strlen(argv[i])) == 0) {
448
            ditemType = argv[i+1];
449
        }
450
    }
451
    if (ditemType == NULL) {
452
        ditemType = wPtr->diTypePtr->name;
453
    }
454
 
455
    iPtr = Tix_DItemCreate(&wPtr->dispData, ditemType);
456
    if (iPtr == NULL) {
457
        return TCL_ERROR;
458
    }
459
    if (Tix_DItemType(iPtr) == TIX_DITEM_WINDOW) {
460
        wPtr->needToRaise = 1;
461
    }
462
 
463
    /*
464
     * mark clientData to NULL. This will tell DItemSizeChanged()
465
     * that ths item belongs to the header
466
     */
467
    iPtr->base.clientData = (ClientData)hPtr;
468
 
469
    if (hPtr->iPtr != NULL) {
470
        if (Tix_DItemType(hPtr->iPtr) == TIX_DITEM_WINDOW) {
471
            FreeWindowItem(interp, wPtr, hPtr);
472
        }
473
        Tix_DItemFree(hPtr->iPtr);
474
    }
475
    hPtr->iPtr = iPtr;
476
 
477
    if (Tix_WidgetConfigure2(wPtr->dispData.interp, wPtr->dispData.tkwin,
478
        (char*)hPtr, headerConfigSpecs, hPtr->iPtr, argc-1, argv+1, 0,
479
        1, NULL) != TCL_OK) {
480
        return TCL_ERROR;
481
    }
482
 
483
 
484
    wPtr->headerDirty = 1;
485
    Tix_HLResizeWhenIdle(wPtr);
486
 
487
    return TCL_OK;
488
}
489
/*----------------------------------------------------------------------
490
 * "header delete" sub command
491
 *----------------------------------------------------------------------
492
 */
493
static int
494
Tix_HLHdrDelete(clientData, interp, argc, argv)
495
    ClientData clientData;
496
    Tcl_Interp *interp;         /* Current interpreter. */
497
    int argc;                   /* Number of arguments. */
498
    char **argv;                /* Argument strings. */
499
{
500
    WidgetPtr wPtr = (WidgetPtr) clientData;
501
    HListHeader * hPtr;
502
 
503
    if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 1)) == NULL) {
504
        return TCL_ERROR;
505
    }
506
 
507
    if (Tix_DItemType(hPtr->iPtr) == TIX_DITEM_WINDOW) {
508
        FreeWindowItem(interp, wPtr, hPtr);
509
    }
510
 
511
    /* Free the item and leave a blank! */
512
    Tix_DItemFree(hPtr->iPtr);
513
    hPtr->iPtr = NULL;
514
 
515
    wPtr->headerDirty = 1;
516
    Tix_HLResizeWhenIdle(wPtr);
517
 
518
    return TCL_OK;
519
}
520
/*----------------------------------------------------------------------
521
 * "header exist" sub command
522
 *----------------------------------------------------------------------
523
 */
524
static int
525
Tix_HLHdrExist(clientData, interp, argc, argv)
526
    ClientData clientData;
527
    Tcl_Interp *interp;         /* Current interpreter. */
528
    int argc;                   /* Number of arguments. */
529
    char **argv;                /* Argument strings. */
530
{
531
    WidgetPtr wPtr = (WidgetPtr) clientData;
532
    HListHeader * hPtr;
533
 
534
    if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 0)) == NULL) {
535
        return TCL_ERROR;
536
    }
537
 
538
    if (hPtr->iPtr == NULL) {
539
        Tcl_AppendResult(interp, "0", NULL);
540
    } else {
541
        Tcl_AppendResult(interp, "1", NULL);
542
    }
543
 
544
    return TCL_OK;
545
}
546
 
547
/*----------------------------------------------------------------------
548
 * "header size" sub command
549
 *----------------------------------------------------------------------
550
 */
551
static int
552
Tix_HLHdrSize(clientData, interp, argc, argv)
553
    ClientData clientData;
554
    Tcl_Interp *interp;         /* Current interpreter. */
555
    int argc;                   /* Number of arguments. */
556
    char **argv;                /* Argument strings. */
557
{
558
    WidgetPtr wPtr = (WidgetPtr) clientData;
559
    HListHeader * hPtr;
560
    char buff[128];
561
 
562
    if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 1)) == NULL) {
563
        return TCL_ERROR;
564
    }
565
 
566
    if (hPtr->iPtr == NULL) {
567
        Tcl_AppendResult(interp, "entry \"", argv[0],
568
            "\" does not have a header", (char*)NULL);
569
        return TCL_ERROR;
570
    }
571
    sprintf(buff, "%d %d",
572
        Tix_DItemWidth(hPtr->iPtr),
573
        Tix_DItemHeight(hPtr->iPtr));
574
    Tcl_AppendResult(interp, buff, NULL);
575
    return TCL_OK;
576
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.