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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [libgui/] [src/] [tkTableWin.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tkTableWin.c --
3
 *
4
 *      This module implements embedded windows for table widgets.
5
 *      Much of this code is adapted from tkGrid.c and tkTextWind.c.
6
 *
7
 * Copyright (c) 1998 Jeffrey Hobbs
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 "tkTable.h"
15
 
16
static int      StickyParseProc _ANSI_ARGS_((ClientData clientData,
17
                            Tcl_Interp *interp, Tk_Window tkwin, char *value,
18
                            char *widgRec, int offset));
19
static char *   StickyPrintProc _ANSI_ARGS_((ClientData clientData,
20
                            Tk_Window tkwin, char *widgRec, int offset,
21
                            Tcl_FreeProc **freeProcPtr));
22
 
23
static void     EmbWinLostSlaveProc _ANSI_ARGS_((ClientData clientData,
24
                                                Tk_Window tkwin));
25
static void     EmbWinRequestProc _ANSI_ARGS_((ClientData clientData,
26
                                               Tk_Window tkwin));
27
 
28
static void     EmbWinCleanup _ANSI_ARGS_((Table *tablePtr,
29
                                           TableEmbWindow *ewPtr));
30
static int      EmbWinConfigure _ANSI_ARGS_((Table *tablePtr,
31
                                             TableEmbWindow *ewPtr,
32
                                             int argc, char **argv));
33
static void     EmbWinStructureProc _ANSI_ARGS_((ClientData clientData,
34
                                                 XEvent *eventPtr));
35
static void     EmbWinUnmapNow _ANSI_ARGS_((Tk_Window ewTkwin,
36
                                            Tk_Window tkwin));
37
 
38
static Tk_GeomMgr tableGeomType = {
39
    "table",                    /* name */
40
    EmbWinRequestProc,          /* requestProc */
41
    EmbWinLostSlaveProc,        /* lostSlaveProc */
42
};
43
 
44
/* windows subcommands */
45
#define WIN_CGET        1       /* get config item of embedded window */
46
#define WIN_CONFIGURE   2       /* configure an embedded window */
47
#define WIN_DELETE      3       /* delete an embedded window */
48
#define WIN_MOVE        4       /* moves a window index */
49
#define WIN_NAMES       5       /* print the embedded window names */
50
static Cmd_Struct win_cmds[] = {
51
  {"configure", WIN_CONFIGURE},
52
  {"cget",      WIN_CGET},
53
  {"delete",    WIN_DELETE},
54
  {"move",      WIN_MOVE},
55
  {"names",     WIN_NAMES},
56
  {"", 0}
57
};
58
 
59
/* Flag values for "sticky"ness  The 16 combinations subsume the packer's
60
 * notion of anchor and fill.
61
 *
62
 * STICK_NORTH          This window sticks to the top of its cavity.
63
 * STICK_EAST           This window sticks to the right edge of its cavity.
64
 * STICK_SOUTH          This window sticks to the bottom of its cavity.
65
 * STICK_WEST           This window sticks to the left edge of its cavity.
66
 */
67
 
68
#define STICK_NORTH     (1<<0)
69
#define STICK_EAST      (1<<1)
70
#define STICK_SOUTH     (1<<2)
71
#define STICK_WEST      (1<<3)
72
 
73
/*
74
 * The default specification for configuring embedded windows
75
 * Done like this to make the command line parsing easy
76
 */
77
 
78
static Tk_CustomOption stickyOption = {StickyParseProc, StickyPrintProc,
79
                                       (ClientData) NULL};
80
 
81
static Tk_ConfigSpec winConfigSpecs[] = {
82
  {TK_CONFIG_BORDER, "-background", "background", "Background", NULL,
83
   Tk_Offset(TableEmbWindow, bg),
84
   TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK },
85
  {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
86
   (char *) NULL, 0, 0 },
87
  {TK_CONFIG_STRING, "-create", (char *) NULL, (char *) NULL, (char *) NULL,
88
   Tk_Offset(TableEmbWindow, create),
89
   TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK },
90
  {TK_CONFIG_PIXELS, "-padx", (char *) NULL, (char *) NULL, (char *) NULL,
91
   Tk_Offset(TableEmbWindow, padX), TK_CONFIG_DONT_SET_DEFAULT },
92
  {TK_CONFIG_PIXELS, "-pady", (char *) NULL, (char *) NULL, (char *) NULL,
93
   Tk_Offset(TableEmbWindow, padY), TK_CONFIG_DONT_SET_DEFAULT },
94
  {TK_CONFIG_CUSTOM, "-sticky", (char *) NULL, (char *) NULL, (char *) NULL,
95
   Tk_Offset(TableEmbWindow, sticky), TK_CONFIG_DONT_SET_DEFAULT,
96
   &stickyOption},
97
  {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", NULL,
98
   Tk_Offset(TableEmbWindow, relief), 0 },
99
  {TK_CONFIG_WINDOW, "-window", (char *) NULL, (char *) NULL, (char *) NULL,
100
   Tk_Offset(TableEmbWindow, tkwin),
101
   TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK },
102
  {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
103
   (char *) NULL, 0, 0 }
104
};
105
 
106
/*
107
 *----------------------------------------------------------------------
108
 *
109
 * StickyPrintProc --
110
 *      Converts the internal boolean combination of "sticky" bits onto
111
 *      a TCL string element containing zero or more of n, s, e, or w.
112
 *
113
 * Results:
114
 *      A string is placed into the "result" pointer.
115
 *
116
 * Side effects:
117
 *      none.
118
 *
119
 *----------------------------------------------------------------------
120
 */
121
static char *
122
StickyPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
123
    ClientData clientData;              /* Ignored. */
124
    Tk_Window tkwin;                    /* Window for text widget. */
125
    char *widgRec;                      /* Pointer to TkTextEmbWindow
126
                                         * structure. */
127
    int offset;                         /* Ignored. */
128
    Tcl_FreeProc **freeProcPtr;         /* Pointer to variable to fill in with
129
                                         * information about how to reclaim
130
                                         * storage for return string. */
131
{
132
  int flags = ((TableEmbWindow *) widgRec)->sticky;
133
  int count = 0;
134
  char *result = (char *) ckalloc(5*sizeof(char));
135
 
136
  if (flags&STICK_NORTH) result[count++] = 'n';
137
  if (flags&STICK_EAST)  result[count++] = 'e';
138
  if (flags&STICK_SOUTH) result[count++] = 's';
139
  if (flags&STICK_WEST)  result[count++] = 'w';
140
 
141
  *freeProcPtr = TCL_DYNAMIC;
142
  result[count] = '\0';
143
  return result;
144
}
145
 
146
/*
147
 *----------------------------------------------------------------------
148
 *
149
 * StringParseProc --
150
 *      Converts an ascii string representing a widgets stickyness
151
 *      into the boolean result.
152
 *
153
 * Results:
154
 *      The boolean combination of the "sticky" bits is retuned.  If an
155
 *      error occurs, such as an invalid character, -1 is returned instead.
156
 *
157
 * Side effects:
158
 *      none
159
 *
160
 *----------------------------------------------------------------------
161
 */
162
static int
163
StickyParseProc(clientData, interp, tkwin, value, widgRec, offset)
164
    ClientData clientData;              /* Not used.*/
165
    Tcl_Interp *interp;                 /* Used for reporting errors. */
166
    Tk_Window tkwin;                    /* Window for text widget. */
167
    char *value;                        /* Value of option. */
168
    char *widgRec;                      /* Pointer to TkTextEmbWindow
169
                                         * structure. */
170
    int offset;                         /* Offset into item (ignored). */
171
{
172
  register TableEmbWindow *ewPtr = (TableEmbWindow *) widgRec;
173
  int sticky = 0;
174
  char c;
175
 
176
  while ((c = *value++) != '\0') {
177
    switch (c) {
178
    case 'n': case 'N': sticky |= STICK_NORTH; break;
179
    case 'e': case 'E': sticky |= STICK_EAST;  break;
180
    case 's': case 'S': sticky |= STICK_SOUTH; break;
181
    case 'w': case 'W': sticky |= STICK_WEST;  break;
182
    case ' ': case ',': case '\t': case '\r': case '\n': break;
183
    default:
184
      Tcl_AppendResult(interp, "bad sticky value \"", --value,
185
                       "\": must contain n, s, e or w",
186
                       (char *) NULL);
187
      return TCL_ERROR;
188
    }
189
  }
190
  ewPtr->sticky = sticky;
191
  return TCL_OK;
192
}
193
 
194
/*
195
 * ckallocs space for a new embedded window structure and clears the structure
196
 * returns the pointer to the new structure
197
 */
198
static TableEmbWindow *
199
TableNewEmbWindow(Table *tablePtr)
200
{
201
  TableEmbWindow *ewPtr = (TableEmbWindow *) ckalloc(sizeof(TableEmbWindow));
202
  ewPtr->tablePtr       = tablePtr;
203
  ewPtr->tkwin          = NULL;
204
  ewPtr->hPtr           = NULL;
205
  ewPtr->bg             = NULL;
206
  ewPtr->create         = NULL;
207
  ewPtr->relief         = -1;
208
  ewPtr->sticky         = 0;
209
  ewPtr->padX           = 0;
210
  ewPtr->padY           = 0;
211
  ewPtr->displayed      = 0;
212
  return ewPtr;
213
}
214
 
215
/*
216
 *----------------------------------------------------------------------
217
 *
218
 * EmbWinCleanup --
219
 *      Releases resources used by an embedded window before it is freed up.
220
 *
221
 * Results:
222
 *      Window will no longer be valid.
223
 *
224
 * Side effects:
225
 *      None.
226
 *
227
 *----------------------------------------------------------------------
228
 */
229
static void
230
EmbWinCleanup(Table *tablePtr, TableEmbWindow *ewPtr)
231
{
232
  /* free the options in the widget */
233
  Tk_FreeOptions(winConfigSpecs, (char *) ewPtr, tablePtr->display, 0);
234
}
235
 
236
/*
237
 *--------------------------------------------------------------
238
 *
239
 * EmbWinDisplay --
240
 *
241
 *      This procedure is invoked by TableDisplay for
242
 *      mapping windows into cells.
243
 *
244
 * Results:
245
 *      Displays or moves window on table screen.
246
 *
247
 * Side effects:
248
 *      None.
249
 *
250
 *--------------------------------------------------------------
251
 */
252
void
253
EmbWinDisplay(Table *tablePtr, Drawable window, TableEmbWindow *ewPtr,
254
              TableTag *tagPtr, int x, int y, int width, int height)
255
{
256
  Tk_Window tkwin = tablePtr->tkwin;
257
  Tk_Window ewTkwin = ewPtr->tkwin;
258
  int diffx=0;   /* Cavity width - slave width. */
259
  int diffy=0;   /* Cavity hight - slave height. */
260
  int sticky = ewPtr->sticky;
261
 
262
 
263
  if (ewPtr->bg)
264
    tagPtr->bg = ewPtr->bg;
265
  if (ewPtr->relief != -1)
266
    tagPtr->relief = ewPtr->relief;
267
 
268
  x += ewPtr->padX/2;
269
  width -= ewPtr->padX;
270
  y += ewPtr->padY/2;
271
  height -= ewPtr->padY;
272
 
273
  if (width > Tk_ReqWidth(ewPtr->tkwin)) {
274
    diffx = width - Tk_ReqWidth(ewPtr->tkwin);
275
    width = Tk_ReqWidth(ewPtr->tkwin);
276
  }
277
  if (height > Tk_ReqHeight(ewPtr->tkwin)) {
278
    diffy = height - Tk_ReqHeight(ewPtr->tkwin);
279
    height = Tk_ReqHeight(ewPtr->tkwin);
280
  }
281
  if (sticky&STICK_EAST && sticky&STICK_WEST) {
282
    width += diffx;
283
  }
284
  if (sticky&STICK_NORTH && sticky&STICK_SOUTH) {
285
    height += diffy;
286
  }
287
  if (!(sticky&STICK_WEST)) {
288
    x += (sticky&STICK_EAST) ? diffx : diffx/2;
289
  }
290
  if (!(sticky&STICK_NORTH)) {
291
    y += (sticky&STICK_SOUTH) ? diffy : diffy/2;
292
  }
293
 
294
  /* If we fall below a specific minimum width/height requirement,
295
   * we just unmap the window */
296
  if (width < 4 || height < 4) {
297
    if (ewPtr->displayed) {
298
      EmbWinUnmapNow(ewTkwin, tkwin);
299
    }
300
    return;
301
  }
302
 
303
  if (tkwin == Tk_Parent(ewTkwin)) {
304
    if ((x != Tk_X(ewTkwin)) || (y != Tk_Y(ewTkwin))
305
        || (width != Tk_Width(ewTkwin)) || (height != Tk_Height(ewTkwin))) {
306
      Tk_MoveResizeWindow(ewTkwin, x, y, width, height);
307
    }
308
    Tk_MapWindow(ewTkwin);
309
  } else {
310
    Tk_MaintainGeometry(ewTkwin, tkwin, x, y, width, height);
311
  }
312
  ewPtr->displayed = 1;
313
}
314
 
315
/*
316
 *--------------------------------------------------------------
317
 *
318
 * EmbWinUnmapNow --
319
 *      Handles unmapping the window depending on parent.
320
 *      tkwin should be tablePtr->tkwin.
321
 *      ewTkwin should be ewPtr->tkwin.
322
 *
323
 * Results:
324
 *      Removes the window.
325
 *
326
 * Side effects:
327
 *      None.
328
 *
329
 *--------------------------------------------------------------
330
 */
331
static void
332
EmbWinUnmapNow(Tk_Window ewTkwin, Tk_Window tkwin)
333
{
334
  if (tkwin != Tk_Parent(ewTkwin)) {
335
    Tk_UnmaintainGeometry(ewTkwin, tkwin);
336
  } else {
337
    Tk_UnmapWindow(ewTkwin);
338
  }
339
}
340
 
341
/*
342
 *--------------------------------------------------------------
343
 *
344
 * EmbWinUnmap --
345
 *      This procedure is invoked by TableAdjustParams for
346
 *      unmapping windows managed moved offscreen.
347
 *      rlo, ... should be in real coords.
348
 *
349
 * Results:
350
 *      None.
351
 *
352
 * Side effects:
353
 *      Unmaps embedded windows.
354
 *
355
 *--------------------------------------------------------------
356
 */
357
void
358
EmbWinUnmap(Table *tablePtr, int rlo, int rhi, int clo, int chi)
359
{
360
  register TableEmbWindow *ewPtr;
361
  Tcl_HashEntry *entryPtr;
362
  int row, col;
363
  char buf[INDEX_BUFSIZE];
364
 
365
  /* we need to deal with things user coords */
366
  rlo += tablePtr->rowOffset;
367
  rhi += tablePtr->rowOffset;
368
  clo += tablePtr->colOffset;
369
  chi += tablePtr->colOffset;
370
  for (row = rlo; row <= rhi; row++) {
371
    for (col = clo; col <= chi; col++) {
372
      TableMakeArrayIndex(row, col, buf);
373
      if ((entryPtr = Tcl_FindHashEntry(tablePtr->winTable, buf)) != NULL) {
374
        ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr);
375
        if (ewPtr->displayed) {
376
          ewPtr->displayed = 0;
377
          if (ewPtr->tkwin != NULL && tablePtr->tkwin != NULL) {
378
            EmbWinUnmapNow(ewPtr->tkwin, tablePtr->tkwin);
379
          }
380
        }
381
      }
382
    }
383
  }
384
}
385
 
386
/*
387
 *--------------------------------------------------------------
388
 *
389
 * EmbWinRequestProc --
390
 *      This procedure is invoked by Tk_GeometryRequest for
391
 *      windows managed by the Table.
392
 *
393
 * Results:
394
 *      None.
395
 *
396
 * Side effects:
397
 *      Arranges for tkwin, and all its managed siblings, to
398
 *      be re-arranged at the next idle point.
399
 *
400
 *--------------------------------------------------------------
401
 */
402
static void
403
EmbWinRequestProc(clientData, tkwin)
404
    ClientData clientData;      /* Table's information about
405
                                 * window that got new preferred
406
                                 * geometry.  */
407
    Tk_Window tkwin;            /* Other Tk-related information
408
                                 * about the window. */
409
{
410
  register TableEmbWindow *ewPtr = (TableEmbWindow *) clientData;
411
 
412
  /* resize depends on the sticky */
413
  if (ewPtr->displayed && ewPtr->hPtr != NULL) {
414
    Table *tablePtr = ewPtr->tablePtr;
415
    int row, col, x, y, width, height;
416
 
417
    TableParseArrayIndex(&row, &col,
418
                         Tcl_GetHashKey(tablePtr->winTable, ewPtr->hPtr));
419
    if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset,
420
                     col-tablePtr->colOffset, &x, &y, &width, &height, 0)) {
421
      TableInvalidate(tablePtr, x, y, width, height, 0);
422
    }
423
  }
424
}
425
 
426
static void
427
EmbWinRemove(TableEmbWindow *ewPtr)
428
{
429
  Table *tablePtr = ewPtr->tablePtr;
430
 
431
  ewPtr->tkwin = NULL;
432
  ewPtr->displayed = 0;
433
  if (tablePtr->tkwin != NULL) {
434
    int row, col, x, y, width, height;
435
 
436
    TableParseArrayIndex(&row, &col,
437
                         Tcl_GetHashKey(tablePtr->winTable, ewPtr->hPtr));
438
    if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset,
439
                         col-tablePtr->colOffset, &x, &y, &width, &height, 0))
440
      TableInvalidate(tablePtr, x, y, width, height, 1);
441
  }
442
}
443
 
444
/*
445
 *--------------------------------------------------------------
446
 *
447
 * EmbWinLostSlaveProc --
448
 *      This procedure is invoked by Tk whenever some other geometry
449
 *      claims control over a slave that used to be managed by us.
450
 *
451
 * Results:
452
 *      None.
453
 *
454
 * Side effects:
455
 *      Forgets all table-related information about the slave.
456
 *
457
 *--------------------------------------------------------------
458
 */
459
 
460
static void
461
EmbWinLostSlaveProc(clientData, tkwin)
462
    ClientData clientData;      /* Table structure for slave window that
463
                                 * was stolen away. */
464
    Tk_Window tkwin;            /* Tk's handle for the slave window. */
465
{
466
    register TableEmbWindow *ewPtr = (TableEmbWindow *) clientData;
467
 
468
    Tk_DeleteEventHandler(ewPtr->tkwin, StructureNotifyMask,
469
                          EmbWinStructureProc, (ClientData) ewPtr);
470
#if 0
471
    Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) ewPtr);
472
#endif
473
    EmbWinUnmapNow(tkwin, ewPtr->tablePtr->tkwin);
474
    EmbWinRemove(ewPtr);
475
}
476
 
477
/*
478
 *--------------------------------------------------------------
479
 *
480
 * EmbWinStructureProc --
481
 *      This procedure is invoked by the Tk event loop whenever
482
 *      StructureNotify events occur for a window that's embedded
483
 *      in a table widget.  This procedure's only purpose is to
484
 *      clean up when windows are deleted.
485
 *
486
 * Results:
487
 *      None.
488
 *
489
 * Side effects:
490
 *      The window is disassociated from the window segment, and
491
 *      the portion of the table is redisplayed.
492
 *
493
 *--------------------------------------------------------------
494
 */
495
static void
496
EmbWinStructureProc(clientData, eventPtr)
497
    ClientData clientData;      /* Pointer to record describing window item. */
498
    XEvent *eventPtr;           /* Describes what just happened. */
499
{
500
  register TableEmbWindow *ewPtr = (TableEmbWindow *) clientData;
501
 
502
  if (eventPtr->type != DestroyNotify) {
503
    return;
504
  }
505
 
506
  EmbWinRemove(ewPtr);
507
}
508
 
509
/*
510
 *--------------------------------------------------------------
511
 *
512
 * EmbWinDelete --
513
 *      This procedure is invoked by ... whenever
514
 *      an embedded window is being deleted.
515
 *
516
 * Results:
517
 *      None.
518
 *
519
 * Side effects:
520
 *      The embedded window is deleted, if it exists, and any resources
521
 *      associated with it are released.
522
 *
523
 *--------------------------------------------------------------
524
 */
525
void
526
EmbWinDelete(register Table *tablePtr, TableEmbWindow *ewPtr)
527
{
528
  Tcl_HashEntry *entryPtr;
529
 
530
  if (ewPtr->tkwin != NULL) {
531
    int row, col, x, y, width, height;
532
    entryPtr = ewPtr->hPtr;
533
 
534
    /*
535
     * Delete the event handler for the window before destroying
536
     * the window, so that EmbWinStructureProc doesn't get called
537
     * (we'll already do everything that it would have done, and
538
     * it will just get confused).
539
     */
540
 
541
    Tk_DeleteEventHandler(ewPtr->tkwin, StructureNotifyMask,
542
                          EmbWinStructureProc, (ClientData) ewPtr);
543
    Tk_DestroyWindow(ewPtr->tkwin);
544
 
545
    if (tablePtr->tkwin != NULL && entryPtr != NULL) {
546
      TableParseArrayIndex(&row, &col,
547
                           Tcl_GetHashKey(tablePtr->winTable, entryPtr));
548
      Tcl_DeleteHashEntry(entryPtr);
549
 
550
      if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset,
551
                           col-tablePtr->colOffset,
552
                           &x, &y, &width, &height, 0))
553
        TableInvalidate(tablePtr, x, y, width, height, 0);
554
    }
555
  }
556
#if 0
557
  Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) ewPtr);
558
#endif
559
  EmbWinCleanup(tablePtr, ewPtr);
560
  ckfree((char *) ewPtr);
561
}
562
 
563
/*
564
 *--------------------------------------------------------------
565
 *
566
 * EmbWinConfigure --
567
 *      This procedure is called to handle configuration options
568
 *      for an embedded window, using an argc/argv list.
569
 *
570
 * Results:
571
 *      The return value is a standard Tcl result.  If TCL_ERROR is
572
 *      returned, then the interp's result contains an error message..
573
 *
574
 * Side effects:
575
 *      Configuration information for the embedded window changes,
576
 *      such as alignment, stretching, or name of the embedded
577
 *      window.
578
 *
579
 *--------------------------------------------------------------
580
 */
581
static int
582
EmbWinConfigure(tablePtr, ewPtr, argc, argv)
583
     Table *tablePtr;           /* Information about table widget that
584
                                 * contains embedded window. */
585
     TableEmbWindow *ewPtr;     /* Embedded window to be configured. */
586
     int argc;                  /* Number of strings in argv. */
587
     char **argv;               /* Array of strings describing configuration
588
                                 * options. */
589
{
590
  Tk_Window oldWindow;
591
 
592
  oldWindow = ewPtr->tkwin;
593
  if (Tk_ConfigureWidget(tablePtr->interp, tablePtr->tkwin, winConfigSpecs,
594
                         argc, argv, (char *) ewPtr, TK_CONFIG_ARGV_ONLY)
595
      != TCL_OK) {
596
    return TCL_ERROR;
597
  }
598
  if (oldWindow != ewPtr->tkwin) {
599
    ewPtr->displayed = 0;
600
    if (oldWindow != NULL) {
601
      Tk_DeleteEventHandler(oldWindow, StructureNotifyMask,
602
                            EmbWinStructureProc, (ClientData) ewPtr);
603
      Tk_ManageGeometry(oldWindow, (Tk_GeomMgr *) NULL,
604
                        (ClientData) NULL);
605
      EmbWinUnmapNow(oldWindow, tablePtr->tkwin);
606
    }
607
    if (ewPtr->tkwin != NULL) {
608
      Tk_Window ancestor, parent;
609
 
610
      /*
611
       * Make sure that the table is either the parent of the
612
       * embedded window or a descendant of that parent.  Also,
613
       * don't allow a top-level window to be managed inside
614
       * a table.
615
       */
616
 
617
      parent = Tk_Parent(ewPtr->tkwin);
618
      for (ancestor = tablePtr->tkwin; ;
619
           ancestor = Tk_Parent(ancestor)) {
620
        if (ancestor == parent) {
621
          break;
622
        }
623
        if (Tk_IsTopLevel(ancestor)) {
624
        badMaster:
625
          Tcl_AppendResult(tablePtr->interp, "can't embed ",
626
                           Tk_PathName(ewPtr->tkwin), " in ",
627
                           Tk_PathName(tablePtr->tkwin), (char *) NULL);
628
          ewPtr->tkwin = NULL;
629
          return TCL_ERROR;
630
        }
631
      }
632
      if (Tk_IsTopLevel(ewPtr->tkwin) || (ewPtr->tkwin == tablePtr->tkwin)) {
633
        goto badMaster;
634
      }
635
 
636
      /*
637
       * Take over geometry management for the window, plus create
638
       * an event handler to find out when it is deleted.
639
       */
640
 
641
      Tk_ManageGeometry(ewPtr->tkwin, &tableGeomType, (ClientData) ewPtr);
642
      Tk_CreateEventHandler(ewPtr->tkwin, StructureNotifyMask,
643
                            EmbWinStructureProc, (ClientData) ewPtr);
644
    }
645
  }
646
  return TCL_OK;
647
}
648
 
649
/*
650
 *--------------------------------------------------------------
651
 *
652
 * TableWindowCmd --
653
 *      This procedure is invoked to process the window method
654
 *      that corresponds to a widget managed by this module.
655
 *      See the user documentation for details on what it does.
656
 *
657
 * Results:
658
 *      A standard Tcl result.
659
 *
660
 * Side effects:
661
 *      See the user documentation.
662
 *
663
 *--------------------------------------------------------------
664
 */
665
int
666
TableWindowCmd(Table * tablePtr, register Tcl_Interp *interp,
667
               int argc, char *argv[])
668
{
669
  int result = TCL_OK, retval;
670
  int row, col, x, y, width, height, i, new;
671
  TableEmbWindow *ewPtr;
672
  Tcl_HashEntry *entryPtr;
673
  Tcl_HashSearch search;
674
  char buf[INDEX_BUFSIZE], *keybuf;
675
 
676
  /* parse the next argument */
677
  retval = Cmd_Parse(interp, win_cmds, argv[2]);
678
  switch (retval) {
679
    /* failed to parse the argument, error */
680
  case 0:
681
    return TCL_ERROR;
682
 
683
  case WIN_CGET:
684
    if (argc != 5) {
685
      Tcl_AppendResult(interp, "wrong # args: should be \"",
686
                       argv[0], " window cget index option\"", (char *) NULL);
687
      return TCL_ERROR;
688
    }
689
    if ((entryPtr=Tcl_FindHashEntry(tablePtr->winTable, argv[3])) == NULL) {
690
      Tcl_AppendResult(interp, "no window at index \"", argv[3],
691
                       "\"", (char *) NULL);
692
      return TCL_ERROR;
693
    } else {
694
      ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr);
695
      result = Tk_ConfigureValue(interp, tablePtr->tkwin, winConfigSpecs,
696
                                 (char *) ewPtr, argv[4], 0);
697
    }
698
    return result;      /* CGET */
699
 
700
  case WIN_CONFIGURE:
701
    if (argc < 4) {
702
      Tcl_AppendResult(interp, "wrong # args: should be \"",
703
                       argv[0], " window configure index ?arg arg  ...?\"",
704
                       (char *) NULL);
705
      return TCL_ERROR;
706
    }
707
    if (TableGetIndex(tablePtr, argv[3], &row, &col) == TCL_ERROR) {
708
      return TCL_ERROR;
709
    }
710
    TableMakeArrayIndex(row, col, buf);
711
    entryPtr = Tcl_CreateHashEntry(tablePtr->winTable, buf, &new);
712
    if (new) {
713
      /* create the structure */
714
      ewPtr = TableNewEmbWindow(tablePtr);
715
 
716
      /* insert it into the table */
717
      Tcl_SetHashValue(entryPtr, (ClientData) ewPtr);
718
      ewPtr->hPtr = entryPtr;
719
 
720
      /* configure the window structure */
721
      result = EmbWinConfigure(tablePtr, ewPtr, argc-4, argv+4);
722
      if (result == TCL_ERROR) {
723
        /* release the structure */
724
        EmbWinCleanup(tablePtr, ewPtr);
725
        ckfree((char *) ewPtr);
726
 
727
        /* and free the hash table entry */
728
        Tcl_DeleteHashEntry(entryPtr);
729
        return TCL_ERROR;
730
      }
731
 
732
      /* if a window was specified, make sure it exists */
733
    } else {
734
      /* pointer wasn't null, do a reconfig if we have enough arguments */
735
      /* get the window pointer from the table */
736
      ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr);
737
 
738
      /* 5 args means that there are values to replace */
739
      if (argc > 5) {
740
        /* and do a reconfigure */
741
        result = EmbWinConfigure(tablePtr, ewPtr, argc-4, argv+4);
742
        if (result == TCL_ERROR)
743
          return TCL_ERROR;
744
      }
745
    }
746
 
747
    /*
748
     * If there were less than 6 args, we need
749
     * to do a printout of the config, even for new windows
750
     */
751
    if (argc < 6) {
752
      result = Tk_ConfigureInfo(interp, tablePtr->tkwin, winConfigSpecs,
753
                                (char *) ewPtr, (argc == 5)?argv[4]:0, 0);
754
    } else {
755
      /* Otherwise we reconfigured so invalidate the table for a redraw */
756
      if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset,
757
                           col-tablePtr->colOffset,
758
                           &x, &y, &width, &height, 0)) {
759
        TableInvalidate(tablePtr, x, y, width, height, 1);
760
      }
761
    }
762
    return result;      /* CONFIGURE */
763
 
764
  case WIN_DELETE:
765
    if (argc < 4) {
766
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
767
                       " window delete index ?index ...?\"", (char *) NULL);
768
      return TCL_ERROR;
769
    }
770
    for (i = 3; i < argc; i++) {
771
      if ((entryPtr = Tcl_FindHashEntry(tablePtr->winTable, argv[i]))!=NULL) {
772
        /* get the window pointer */
773
        ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr);
774
 
775
        EmbWinDelete(tablePtr, ewPtr);
776
      }
777
    }
778
    /* clear up anything that might have been placed in the result string */
779
    Tcl_SetResult(interp, "", TCL_STATIC);
780
    return result;
781
 
782
  case WIN_MOVE:
783
    if (argc != 5) {
784
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
785
                       " window move oldIndex newIndex\"", (char *) NULL);
786
      return TCL_ERROR;
787
    }
788
    if (TableGetIndex(tablePtr, argv[3], &x, &y) == TCL_ERROR ||
789
        TableGetIndex(tablePtr, argv[4], &row, &col) == TCL_ERROR) {
790
      return TCL_ERROR;
791
    }
792
    TableMakeArrayIndex(x, y, buf);
793
    if ((entryPtr = Tcl_FindHashEntry(tablePtr->winTable, buf)) == NULL) {
794
      Tcl_AppendResult(interp, "no window at index \"", argv[3],
795
                       "\"", (char *) NULL);
796
      return TCL_ERROR;
797
    }
798
    /* avoid moving it to the same location */
799
    if (x == row && y == col) {
800
      return TCL_OK;
801
    }
802
    /* get the window pointer */
803
    ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr);
804
    /* and free the old hash table entry */
805
    Tcl_DeleteHashEntry(entryPtr);
806
 
807
    TableMakeArrayIndex(row, col, buf);
808
    entryPtr = Tcl_CreateHashEntry(tablePtr->winTable, buf, &new);
809
    if (!new) {
810
      /* window already there - just delete it */
811
      TableEmbWindow *ewPtrDel;
812
 
813
      ewPtrDel = (TableEmbWindow *) Tcl_GetHashValue(entryPtr);
814
      /* This prevents the deletion of it's own entry, since we need it */
815
      ewPtrDel->hPtr = NULL;
816
      EmbWinDelete(tablePtr, ewPtrDel);
817
    }
818
    /* set the new entry's value */
819
    Tcl_SetHashValue(entryPtr, (ClientData) ewPtr);
820
    ewPtr->hPtr = entryPtr;
821
 
822
    /* Invalidate old cell */
823
    if (TableCellVCoords(tablePtr, x-tablePtr->rowOffset,
824
                         y-tablePtr->colOffset,
825
                         &x, &y, &width, &height, 0)) {
826
      TableInvalidate(tablePtr, x, y, width, height, 0);
827
    }
828
    /* Invalidate new cell */
829
    if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset,
830
                         col-tablePtr->colOffset,
831
                         &x, &y, &width, &height, 0)) {
832
      TableInvalidate(tablePtr, x, y, width, height, 0);
833
    }
834
    break;
835
 
836
  case WIN_NAMES:
837
    /* just print out the image names */
838
    if (argc != 3 && argc != 4) {
839
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
840
                       " window names ?pattern?\"", (char *) NULL);
841
      return TCL_ERROR;
842
    }
843
    entryPtr = Tcl_FirstHashEntry(tablePtr->winTable, &search);
844
    while (entryPtr != NULL) {
845
      keybuf = Tcl_GetHashKey(tablePtr->winTable, entryPtr);
846
      if (argc == 3 || Tcl_StringMatch(keybuf, argv[3]))
847
        Tcl_AppendElement(interp, keybuf);
848
      entryPtr = Tcl_NextHashEntry(&search);
849
    }
850
    Tcl_SetResult(interp,
851
                  TableCellSort(tablePtr, Tcl_GetStringResult(interp)),
852
                  TCL_DYNAMIC);
853
    break;
854
  }
855
  return TCL_OK;
856
}

powered by: WebSVN 2.1.0

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