home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / wcl / part03 < prev    next >
Encoding:
Internet Message Format  |  1990-07-06  |  71.6 KB

  1. Path: uunet!aplcen!uakari.primate.wisc.edu!zaphod.mps.ohio-state.edu!wuarchive!cs.utexas.edu!sun-barr!newstop!sun!devvax.Jpl.Nasa.Gov
  2. From: david@devvax.Jpl.Nasa.Gov (David E. Smyth)
  3. Newsgroups: comp.sources.x
  4. Subject: v08i033: wcl - Widget Creation Library, Part03/06
  5. Message-ID: <138459@sun.Eng.Sun.COM>
  6. Date: 6 Jul 90 07:40:47 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 2321
  9. Approved: argv@sun.com
  10.  
  11. Submitted-by: david@devvax.Jpl.Nasa.Gov (David E. Smyth)
  12. Posting-number: Volume 8, Issue 33
  13. Archive-name: wcl/part03
  14.  
  15. # to unbundle, "sh" this file -- DO NOT use csh
  16. #  SHAR archive format.  Archive created Tue Jul 3 16:49:00 PDT 1990
  17. echo x - Table.c
  18. sed 's/^X//' > Table.c <<'+FUNKY+STUFF+'
  19. X/*LINTLIBRARY*/
  20. X/*
  21. X * Table - Forms-based composite widget/geometry manager for the X Toolkit
  22. X *
  23. X * David Harrison
  24. X * University of California, Berkeley
  25. X * 1989
  26. X *
  27. X * This file contains the implementation for the Table widget.
  28. X */
  29. X
  30. X#include "X11/IntrinsicP.h"
  31. X#include "X11/StringDefs.h"
  32. X
  33. X#ifdef X11R4
  34. X#include "X11/Xmu/Xmu.h"
  35. X#else
  36. X#include "X11/Xmu.h"
  37. X#endif
  38. X
  39. X#include "TableP.h"
  40. X
  41. X#define INIT_TBL_SIZE    10
  42. X#define TBL_CLASS_NAME    "Table"
  43. X
  44. Xstatic caddr_t def = (caddr_t) 0;
  45. X
  46. Xstatic XtResource resources[] = {
  47. X    { XtNlayout, XtCLayout, XtRPointer, sizeof(caddr_t),
  48. X    XtOffset(TableWidget, table.init_layout), XtRPointer, (caddr_t) &def },
  49. X    { XtNinternalHeight, XtCHeight, XtRDimension, sizeof(Dimension),
  50. X    XtOffset(TableWidget, table.int_height), XtRImmediate, (caddr_t) 0 },
  51. X    { XtNinternalWidth, XtCWidth, XtRDimension, sizeof(Dimension),
  52. X    XtOffset(TableWidget, table.int_width), XtRImmediate, (caddr_t) 0 },
  53. X    { XtNcolumnSpacing, XtCSpacing, XtRDimension, sizeof(Dimension),
  54. X    XtOffset(TableWidget, table.col_spacing), XtRImmediate, (caddr_t) 0 },
  55. X    { XtNrowSpacing, XtCSpacing, XtRDimension, sizeof(Dimension),
  56. X    XtOffset(TableWidget, table.row_spacing), XtRImmediate, (caddr_t) 0 },
  57. X    { XtNdefaultOptions, XtCOptions, XtROptions, sizeof(XtTblMask),
  58. X    XtOffset(TableWidget, table.def_options), XtRImmediate, (caddr_t) 0 }
  59. X};
  60. X
  61. X/* Forward declarations */
  62. Xstatic void TblClassInitialize();
  63. Xstatic void TblInitialize();
  64. Xstatic void TblResize();
  65. Xstatic XtGeometryResult TblQueryGeometry();
  66. Xstatic void TblPositionChild();
  67. Xstatic Boolean TblSetValues();
  68. Xstatic XtGeometryResult TblGeometryManager();
  69. Xstatic void TblChangeManaged();
  70. Xstatic Boolean TblFindChild();
  71. Xstatic void TblDestroy();
  72. Xstatic XtTblMask ParseOpts();
  73. X
  74. X
  75. X
  76. X/*
  77. X * Local structures
  78. X */
  79. X
  80. Xtypedef struct _TableLoc {
  81. X    Position ax, ay;        /* Position in array       */
  82. X    Dimension h_span, v_span;    /* Span size in array      */
  83. X    XtTblMask options;        /* Widget position options */
  84. X} TableLoc, *TableLocPtr;
  85. X
  86. Xtypedef struct _TableLocEntry {
  87. X    Widget w;
  88. X    TableLoc loc;
  89. X} TableLocEntry, *TableLocEntryPtr;
  90. X
  91. Xstruct _TableLocTbl {
  92. X    Cardinal n_layout;        /* Number of layout widgets */
  93. X    Cardinal a_layout;        /* Allocated space          */
  94. X    TableLocEntryPtr locs;    /* Widget locations         */
  95. X};
  96. X
  97. Xstruct _TableDefLoc {
  98. X    String w_name;        /* Widget name        */
  99. X    TableLoc loc;        /* Widget information */
  100. X};
  101. X
  102. Xtypedef unsigned long TableVecMask;
  103. X#define    VEC_MINIMIZE    0x01
  104. X
  105. Xstruct _TableVector {
  106. X    TableVecMask mask;        /* Option mask  */
  107. X    Cardinal value;        /* Size of item */
  108. X};
  109. X
  110. X
  111. X
  112. XTableClassRec tableClassRec = {
  113. X  { /* core_class fields */
  114. X    /* superclass         */    (WidgetClass) &compositeClassRec,
  115. X    /* class_name         */    TBL_CLASS_NAME,
  116. X    /* widget_size        */    sizeof(TableRec),
  117. X    /* class_initialize   */    TblClassInitialize,
  118. X    /* class_part_init    */    NULL,
  119. X    /* class_inited       */    FALSE,
  120. X    /* initialize         */    TblInitialize,
  121. X    /* initialize_hook    */    NULL,
  122. X    /* realize            */    XtInheritRealize,
  123. X    /* actions            */    NULL,
  124. X    /* num_actions        */    0,
  125. X    /* resources          */    resources,
  126. X    /* num_resources      */    XtNumber(resources),
  127. X    /* xrm_class          */    NULLQUARK,
  128. X    /* compress_motion    */    TRUE,
  129. X    /* compress_exposure  */    TRUE,
  130. X    /* compress_enterleave*/    TRUE,
  131. X    /* visible_interest   */    FALSE,
  132. X    /* destroy            */    TblDestroy,
  133. X    /* resize             */    TblResize,
  134. X    /* expose             */    XtInheritExpose,
  135. X    /* set_values         */    TblSetValues,
  136. X    /* set_values_hook    */    NULL,
  137. X    /* set_values_almost  */    XtInheritSetValuesAlmost,
  138. X    /* get_values_hook    */    NULL,
  139. X    /* accept_focus       */    NULL,
  140. X    /* version            */    XtVersion,
  141. X    /* callback_private   */    NULL,
  142. X    /* tm_table           */    NULL,
  143. X    /* query_geometry     */    TblQueryGeometry,
  144. X    /* display_accelerator*/    XtInheritDisplayAccelerator,
  145. X    /* extension          */    NULL
  146. X  },
  147. X  { /* composite_class fields */
  148. X    /* geometry_manager   */   TblGeometryManager,
  149. X    /* change_managed     */   TblChangeManaged,
  150. X    /* insert_child       */   XtInheritInsertChild,
  151. X    /* delete_child       */   XtInheritDeleteChild,
  152. X    /* extension          */   NULL
  153. X  },
  154. X  { /* table_class fields */
  155. X    /* position_child      */    TblPositionChild,
  156. X    /* find_child      */    TblFindChild,
  157. X  }
  158. X};
  159. X
  160. XWidgetClass tableWidgetClass = (WidgetClass) &tableClassRec;
  161. X
  162. X
  163. X
  164. X/*ARGSUSED*/
  165. Xstatic void cvtStrToDefLoc(args, num_args, from, to)
  166. XXrmValue *args;            /* Arguments to converter */
  167. XCardinal *num_args;        /* Number of arguments    */
  168. XXrmValue *from;            /* From type              */
  169. XXrmValue *to;            /* To type                */
  170. X/*
  171. X * Converts a string representation into an array of TableDefLoc
  172. X * structures.
  173. X */
  174. X{
  175. X    static caddr_t ptr;
  176. X    String layout_spec;
  177. X
  178. X    if (*num_args != 0) {
  179. X    XtErrorMsg("cvtStrToDefLoc", "wrongParameters", "XtToolkitError",
  180. X           "String to layout takes no additional arguments",
  181. X           (String *) NULL, (Cardinal *) NULL);
  182. X    }
  183. X
  184. X    layout_spec = (String) from->addr;
  185. X    to->size = sizeof(caddr_t);
  186. X    ptr = XtTblParseLayout(layout_spec);
  187. X    to->addr = (caddr_t) &ptr;
  188. X}
  189. X
  190. X/*ARGSUSED*/
  191. Xstatic void cvtStrToOpts(args, num_args, from, to)
  192. XXrmValue *args;            /* Arguments to converter */
  193. XCardinal *num_args;        /* Number of arguments    */
  194. XXrmValue *from;            /* From type              */
  195. XXrmValue *to;            /* To type                */
  196. X/*
  197. X * Converts a string representation into a default options
  198. X * mask (XtTblMask).
  199. X */
  200. X{
  201. X    static XtTblMask mask;
  202. X    String opt_spec;
  203. X
  204. X    if (*num_args != 0) {
  205. X    XtErrorMsg("cvtStrToOpts", "wrongParameters", "XtToolkitError",
  206. X           "String to options takes no additional arguments",
  207. X           (String *) NULL, (Cardinal *) NULL);
  208. X    }
  209. X
  210. X    opt_spec = (String) from->addr;
  211. X    to->size = sizeof(int);
  212. X    mask = ParseOpts(opt_spec);
  213. X    to->addr = (caddr_t) &mask;
  214. X}
  215. X
  216. X
  217. Xstatic void TblClassInitialize()
  218. X/*
  219. X * Adds an appropriate string-to-default widget location table
  220. X * converter.
  221. X */
  222. X{
  223. X    XtAddConverter(XtRString, XtRPointer, cvtStrToDefLoc, NULL, 0);
  224. X    XtAddConverter(XtRString, XtROptions, cvtStrToOpts, NULL, 0);
  225. X}
  226. X
  227. X
  228. X
  229. X/* 
  230. X * Table Management Functions
  231. X *
  232. X * Default table is a linear null terminated array,  the location
  233. X * array is a linear dynamic array.  Both should be replaced
  234. X * with hash tables.
  235. X */
  236. X
  237. Xstatic Cardinal LenDefLoc(ptr)
  238. XTableDefLocPtr ptr;
  239. X/*
  240. X * Returns the length of a DefLoc list.
  241. X */
  242. X{
  243. X    Cardinal i;
  244. X
  245. X    for (i = 0;  ptr && ptr[i].w_name;  i++) {
  246. X    /* Null body */
  247. X    }
  248. X    return i;
  249. X}
  250. X
  251. Xstatic TableDefLocPtr CopyDefLoc(ptr)
  252. XTableDefLocPtr ptr;
  253. X/*
  254. X * Makes a dynamically allocated copy of `ptr'.
  255. X */
  256. X{
  257. X    TableDefLocPtr copy;
  258. X    Cardinal i, len;
  259. X
  260. X    len = LenDefLoc(ptr);
  261. X    if (len) {
  262. X    copy = (TableDefLocPtr) XtCalloc(len+1, sizeof(struct _TableDefLoc));
  263. X    for (i = 0;  i < len;  i++) {
  264. X        copy[i] = ptr[i];
  265. X    }
  266. X    copy[i].w_name = (String) 0;
  267. X    } else {
  268. X    copy = (TableDefLocPtr) 0;
  269. X    }
  270. X    return copy;
  271. X}
  272. X
  273. Xstatic TableDefLocPtr FindDefLoc(tbl, name)
  274. XTableDefLocPtr tbl;        /* Table to examine */
  275. XString name;            /* Widget name      */
  276. X/*
  277. X * Scans through `tbl' looking for the name `name'.  Returns
  278. X * a pointer to the found value or NULL if not found.
  279. X */
  280. X{
  281. X    TableDefLocPtr idx;
  282. X
  283. X    for (idx = tbl;  idx && idx->w_name;  idx++) {
  284. X    if (strcmp(idx->w_name, name) == 0) return idx;
  285. X    }
  286. X    return (TableDefLocPtr) 0;
  287. X}
  288. X
  289. Xstatic TableDefLocPtr MergeDefLoc(source, dest)
  290. XTableDefLocPtr source;        /* Original table     */
  291. XTableDefLocPtr dest;        /* Additional entries */
  292. X/*
  293. X * Returns a table where the entries in `dest' have been
  294. X * merged with those in `source'.  Similar entries in
  295. X * `dest' override those in `source'.  The returned
  296. X * table is allocated.
  297. X */
  298. X{
  299. X    TableDefLocPtr result, update;
  300. X    Cardinal s_len, d_len;
  301. X    Cardinal i, j;
  302. X
  303. X    s_len = LenDefLoc(source);
  304. X    d_len = LenDefLoc(dest);
  305. X    result = (TableDefLocPtr)
  306. X      XtCalloc(s_len + d_len + 1, sizeof(struct _TableDefLoc));
  307. X    for (i = 0;  i < s_len;  i++) {
  308. X    result[i] = source[i];
  309. X    }
  310. X    /* Add null termination */
  311. X    result[i].w_name = (String) 0;
  312. X    /* Now merge the results */
  313. X    for (j = 0;  j < d_len;  j++) {
  314. X    if (update = FindDefLoc(result, dest[j].w_name)) {
  315. X        update->loc = dest[j].loc;
  316. X    } else {
  317. X        /* Add to end */
  318. X        result[i].w_name = dest[j].w_name;
  319. X        result[i].loc = dest[j].loc;
  320. X        i += 1;
  321. X        result[i].w_name = (String) 0;
  322. X    }
  323. X    }
  324. X    return result;
  325. X}
  326. X
  327. X
  328. X
  329. Xstatic TableLocTblPtr TblInitLocTbl()
  330. X/*
  331. X * Returns a newly allocated location table.  This is implemented
  332. X * at the moment as dynamic array.  Eventually,  a hash table
  333. X * will be used.
  334. X */
  335. X{
  336. X    TableLocTblPtr rtn;
  337. X
  338. X    rtn = (TableLocTblPtr) XtMalloc(sizeof(struct _TableLocTbl));
  339. X    rtn->n_layout = 0;
  340. X    rtn->a_layout = INIT_TBL_SIZE;
  341. X    rtn->locs = (TableLocEntryPtr)
  342. X      XtCalloc(INIT_TBL_SIZE, sizeof(TableLocEntry));
  343. X    return rtn;
  344. X}
  345. X
  346. Xstatic void TblInsertLoc(tbl, w, locp)
  347. XTableLocTblPtr tbl;        /* Table for insertion             */
  348. XWidget w;            /* Subwidget to place              */
  349. XTableLocPtr locp;        /* Widget location information     */
  350. X/*
  351. X * Inserts an item into the location table.  If there is already
  352. X * an entry for the widget,  it is replaced by this one.  If there
  353. X * is no room,  additional room is allocated.
  354. X */
  355. X{
  356. X    int i;
  357. X
  358. X    for (i = 0;  i < tbl->n_layout;  i++) {
  359. X    if (tbl->locs[i].w == w) {
  360. X        tbl->locs[i].loc = *locp;
  361. X        return;
  362. X    }
  363. X    }
  364. X    /* Not in the table */
  365. X    if (tbl->n_layout >= tbl->a_layout) {
  366. X    /* Make more space */
  367. X    tbl->a_layout += tbl->a_layout;
  368. X    tbl->locs = (TableLocEntryPtr)
  369. X      XtRealloc(tbl->locs, tbl->a_layout * sizeof(TableLocEntry));
  370. X    }
  371. X    tbl->locs[tbl->n_layout].w = w;
  372. X    tbl->locs[tbl->n_layout].loc = *locp;
  373. X    tbl->n_layout += 1;
  374. X}
  375. X
  376. Xstatic TableLocPtr TblLocLookup(tbl, w)
  377. XTableLocTblPtr tbl;        /* Table for lookup      */
  378. XWidget w;            /* What widget to lookup */
  379. X/*
  380. X * Looks up widget `w' in the hard widget position table.
  381. X * Returns NULL if it can't find the widget.
  382. X */
  383. X{
  384. X    int i;
  385. X
  386. X    for (i = 0;  i < tbl->n_layout;  i++) {
  387. X    if (tbl->locs[i].w == w) {
  388. X        return &(tbl->locs[i].loc);
  389. X    }
  390. X    }
  391. X    return (TableLocPtr) 0;
  392. X}
  393. X
  394. Xstatic void TblFreeLocTbl(tbl)
  395. XTableLocTblPtr tbl;        /* Table to free */
  396. X/*
  397. X * Frees memory resources of `tbl'.
  398. X */
  399. X{
  400. X    XtFree((char *) (tbl->locs));
  401. X    XtFree((char *) tbl);
  402. X}
  403. X
  404. X
  405. X
  406. Xstatic void TblInitialize(request, new)
  407. XWidget request;            /* Values from resources */
  408. XWidget new;            /* Actual widget         */
  409. X/*
  410. X * Intializes appropriate fields in instance record.
  411. X */
  412. X{
  413. X    TableWidget old = (TableWidget) request;
  414. X    TableWidget tw = (TableWidget) new;
  415. X
  416. X    tw->table.init_layout = CopyDefLoc(old->table.init_layout);
  417. X    tw->table.layout_db = (TableDefLocPtr) 0;
  418. X    tw->table.real_layout = TblInitLocTbl();
  419. X    tw->table.vec_state = INVALID;
  420. X    tw->table.num_rows = tw->table.num_cols = 0;
  421. X    tw->table.rows = (TableVecPtr) 0;
  422. X    tw->table.cols = (TableVecPtr) 0;
  423. X    tw->table.vec_height = 0;
  424. X    tw->table.vec_width = 0;
  425. X}
  426. X
  427. X
  428. X
  429. Xstatic TableLocTblPtr GetManaged(nw, wl)
  430. XCardinal nw;            /* Number of widgets */
  431. XWidgetList wl;            /* Widget list       */
  432. X/*
  433. X * Returns those widgets in `wl' that are managed and looks
  434. X * up their table postions.  If no table position is found,
  435. X * the widget is placed at 0,0 with a span of 1 with no options.
  436. X */
  437. X{
  438. X    TableLocTblPtr result;
  439. X    Cardinal i;
  440. X
  441. X    result = TblInitLocTbl();
  442. X    for (i = 0;  i < nw;  i++) {
  443. X    if (XtIsManaged(wl[i])) {
  444. X        if (result->n_layout >= result->a_layout) {
  445. X        /* Make more space */
  446. X        result->a_layout += result->a_layout;
  447. X        result->locs = (TableLocEntryPtr)
  448. X          XtRealloc(result->locs,
  449. X                result->a_layout * sizeof(TableLocEntry));
  450. X        }
  451. X        result->locs[result->n_layout].w = wl[i];
  452. X        if (!TblFindChild(wl[i],
  453. X                  &(result->locs[result->n_layout].loc.ax),
  454. X                  &(result->locs[result->n_layout].loc.ay),
  455. X                  &(result->locs[result->n_layout].loc.h_span),
  456. X                  &(result->locs[result->n_layout].loc.v_span),
  457. X                  &(result->locs[result->n_layout].loc.options))) {
  458. X        /* Can't find location -- make one up */
  459. X        result->locs[result->n_layout].loc.ax = 0;
  460. X        result->locs[result->n_layout].loc.ay = 0;
  461. X        result->locs[result->n_layout].loc.h_span = 1;
  462. X        result->locs[result->n_layout].loc.v_span = 1;
  463. X        result->locs[result->n_layout].loc.options = 0;
  464. X        }
  465. X        result->n_layout += 1;
  466. X    }
  467. X    }
  468. X    return result;
  469. X}
  470. X
  471. X
  472. Xstatic Cardinal VecSize(mw, val_func)
  473. XTableLocTblPtr mw;        /* List of managed widgets           */
  474. Xvoid (*val_func)();        /* Returns either row or column info */
  475. X/*
  476. X * Determines the vector size by examining locations of all
  477. X * widgets in `mw'.  Basically determines the maximum of loc+span.
  478. X */
  479. X{
  480. X    Cardinal i, loc, span;
  481. X    Cardinal result = 0;
  482. X    Boolean small_flag;
  483. X
  484. X    for (i = 0;  i < mw->n_layout;  i++) {
  485. X    (*val_func)(&(mw->locs[i]), &loc, &span, &small_flag);
  486. X    if (result < loc+span) {
  487. X        result = loc+span;
  488. X    }
  489. X    }
  490. X    return result;
  491. X}
  492. X
  493. X
  494. X
  495. Xstatic void SetVecOptions(mw, val_func, vec)
  496. XTableLocTblPtr mw;        /* Managed widget list */
  497. Xvoid (*val_func)();        /* Row or col info     */
  498. XTableVecPtr vec;        /* Spacing vector      */
  499. X/*
  500. X * Steps through the list of widgets.  If the widget is marked
  501. X * as having the small flag set,  it sets all corresponding
  502. X * options in `vec'.
  503. X */
  504. X{
  505. X    Cardinal i, j;
  506. X    Cardinal loc, span;
  507. X    Boolean small_flag;
  508. X
  509. X    for (i = 0;  i < mw->n_layout;  i++) {
  510. X    (*val_func)(&(mw->locs[i]), &loc, &span, &small_flag);
  511. X    if (small_flag) {
  512. X        for (j = loc;  j < loc+span;  j++) {
  513. X        vec[j].mask = VEC_MINIMIZE;
  514. X        }
  515. X    }
  516. X    }
  517. X}
  518. X
  519. X
  520. X/* Must be set before span_cmp works */
  521. Xstatic void (*span_cmp_val_func)();
  522. X
  523. Xstatic int span_cmp(a, b)
  524. Xchar *a, *b;
  525. X/*
  526. X * Compares items based on span.
  527. X */
  528. X{
  529. X    Cardinal loc_a, loc_b;
  530. X    Cardinal span_a, span_b;
  531. X    Boolean small_flag;
  532. X
  533. X    (*span_cmp_val_func)((TableLocEntryPtr) a, &loc_a, &span_a, &small_flag);
  534. X    (*span_cmp_val_func)((TableLocEntryPtr) b, &loc_b, &span_b, &small_flag);
  535. X    return span_a - span_b;
  536. X}
  537. X
  538. X
  539. Xstatic Cardinal FindDistrib(loc, span, vec, result)
  540. XCardinal loc, span;        /* Widget loc and span */
  541. XTableVecPtr vec;        /* Spacing vector     */
  542. XCardinal *result;        /* Result array       */
  543. X/*
  544. X * This routine fills in `result' with a list of indices
  545. X * into the spacing vector suitable for distributing required
  546. X * space.  Normally,  it skips those items marked as
  547. X * VEC_MINIMIZE.  However,  if there aren't any non-VEC_MINIMIZE
  548. X * spaces,  all of them become candidates.
  549. X */
  550. X{
  551. X    Cardinal i, count;
  552. X
  553. X    count = 0;
  554. X    for (i = loc;  i < loc+span;  i++) {
  555. X    if (vec[i].mask & VEC_MINIMIZE) continue;
  556. X    result[count++] = i;
  557. X    }
  558. X    if (count == 0) {
  559. X    /* Add them all back in */
  560. X    for (i = loc;  i < loc+span;  i++) {
  561. X        result[count++] = i;
  562. X    }
  563. X    }
  564. X    return count;
  565. X}
  566. X
  567. X
  568. Xstatic void DoDistrib(n_dist, distrib, loc, span, vec, size, inter)
  569. XCardinal n_dist;        /* Number of distribution points */
  570. XCardinal *distrib;        /* Indicies into `vec'           */
  571. XCardinal loc, span;        /* Widget location and span      */
  572. XTableVecPtr vec;        /* Spacing vector                */
  573. XDimension size;            /* Size of widget                */
  574. XDimension inter;        /* inter {col,row} spacing     */
  575. X/*
  576. X * If `size' is larger than the current sum of space in `vec'
  577. X * specified by `loc' and `span',  the difference in space
  578. X * is evenly added to each vector entry given by `distrib'.
  579. X */
  580. X{
  581. X    Cardinal sum = 0;
  582. X    Cardinal i;
  583. X    int diff, amt;
  584. X
  585. X    for (i = loc;  i < loc+span;  i++) {
  586. X    sum += vec[i].value;
  587. X    }
  588. X    if (span > 1)
  589. X    sum += (span-1) * inter;
  590. X    diff = size - sum;
  591. X    if (diff > 0) {
  592. X    /* Distribution required */
  593. X    amt = diff / n_dist;
  594. X    for (i = 0;  i < n_dist-1;  i++) {
  595. X        vec[distrib[i]].value += amt;
  596. X        diff -= amt;
  597. X    }
  598. X    /* Last one deincremented by remaining space */
  599. X    vec[distrib[i]].value += diff;
  600. X    }
  601. X}
  602. X
  603. X
  604. X
  605. X
  606. Xstatic Cardinal CompVector(mw, val_func, size_func, inter, result)
  607. XTableLocTblPtr mw;        /* List of managed widgets with locs */
  608. Xvoid (*val_func)();        /* Returns either row or column info */
  609. XDimension (*size_func)();    /* Returns desired size of subwidget */
  610. XDimension inter;        /* inter {row,col} spacing         */
  611. XTableVecPtr *result;        /* Result vector                     */
  612. X/*
  613. X * This routine computes the values for either the row or column
  614. X * spacing vector.  The strategy is as follows:
  615. X *   1. Scan mw and determine number of entrys in result and allocate
  616. X *   2. Scan list and set appropriate vector flags.
  617. X *   3. Sort the managed widgets in span order (low to high)
  618. X *   4. For each item in sorted list:
  619. X *      A. Determine distribution locations.
  620. X *      B. Distribute any needed space to locations.
  621. X * There are some inefficiencies here that could be overcome.
  622. X */
  623. X{
  624. X    Cardinal res_num, i;
  625. X    Cardinal n_dist, *distrib;
  626. X    Cardinal loc, span;
  627. X    Boolean small_flag;
  628. X
  629. X    res_num = VecSize(mw, val_func);
  630. X    if (res_num) {
  631. X    *result = (TableVecPtr) XtCalloc(res_num, sizeof(struct _TableVector));
  632. X    for (i = 0;  i < res_num;  i++) {
  633. X        (*result)[i].mask = 0;
  634. X        (*result)[i].value = 0;
  635. X    }
  636. X    SetVecOptions(mw, val_func, *result);
  637. X
  638. X    span_cmp_val_func = val_func;
  639. X    qsort((char *) mw->locs, (int) mw->n_layout,
  640. X          sizeof(TableLocEntry), span_cmp);
  641. X
  642. X    distrib = (Cardinal *) XtCalloc(res_num, sizeof(Cardinal));
  643. X    for (i = 0;  i < mw->n_layout;  i++) {
  644. X        (*val_func)(&(mw->locs[i]), &loc, &span, &small_flag);
  645. X        n_dist = FindDistrib(loc, span, *result, distrib);
  646. X        DoDistrib(n_dist, distrib, loc, span, *result,
  647. X              (*size_func)(mw->locs[i].w), inter);
  648. X    }
  649. X    return res_num;
  650. X    } else {
  651. X    *result = (TableVecPtr) 0;
  652. X    return 0;
  653. X    }
  654. X    /*NOTREACHED*/
  655. X}
  656. X
  657. X
  658. Xstatic void ColValues(oneloc, loc, span, small_flag)
  659. XTableLocEntryPtr oneloc;    /* Widget data       */
  660. XCardinal *loc;            /* Location in array */
  661. XCardinal *span;            /* Spanning distance */
  662. XBoolean *small_flag;        /* Whether locked    */
  663. X/*
  664. X * This routine returns column data from `oneloc'.  It is
  665. X * passed to CompVector when computing the column spacing vector.
  666. X */
  667. X{
  668. X    *loc = oneloc->loc.ax;
  669. X    *span = oneloc->loc.h_span;
  670. X    *small_flag = oneloc->loc.options & TBL_SM_WIDTH;
  671. X}
  672. X
  673. Xstatic void RowValues(oneloc, loc, span, small_flag)
  674. XTableLocEntryPtr oneloc;    /* Widget data       */
  675. XCardinal *loc;            /* Location in array */
  676. XCardinal *span;            /* Spanning distance */
  677. XBoolean *small_flag;        /* Whether locked    */
  678. X/*
  679. X * This routine returns row data from `oneloc'.  It is
  680. X * passed to CompVector when computing the row spacing vector.
  681. X */
  682. X{
  683. X    *loc = oneloc->loc.ay;
  684. X    *span = oneloc->loc.v_span;
  685. X    *small_flag = oneloc->loc.options & TBL_SM_HEIGHT;
  686. X}
  687. X
  688. Xstatic Dimension ColSize(w)
  689. XWidget w;            /* Child widget */
  690. X/*
  691. X * This routine returns the desired width of the widget `w'.
  692. X * It is used by CompVector when computing the column vector.
  693. X */
  694. X{
  695. X    Dimension r_size, r_border;
  696. X    XtWidgetGeometry child;
  697. X
  698. X    r_size = w->core.width;
  699. X    r_border = w->core.border_width;
  700. X    (void) XtQueryGeometry(w, (XtWidgetGeometry *) 0, &child);
  701. X    if (child.request_mode & CWWidth) r_size = child.width;
  702. X    if (child.request_mode & CWBorderWidth) r_border = child.border_width;
  703. X    return r_size + r_border + r_border;
  704. X}
  705. X
  706. Xstatic Dimension RowSize(w)
  707. XWidget w;            /* Child widget */
  708. X/*
  709. X * This routine returns the desired width of the widget `w'.
  710. X * It is used by CompVector when computing the column vector.
  711. X */
  712. X{
  713. X    Dimension r_size, r_border;
  714. X    XtWidgetGeometry child;
  715. X
  716. X    r_size = w->core.height;
  717. X    r_border = w->core.border_width;
  718. X    (void) XtQueryGeometry(w, (XtWidgetGeometry *) 0, &child);
  719. X    if (child.request_mode & CWHeight) r_size = child.height;
  720. X    if (child.request_mode & CWBorderWidth) r_border = child.border_width;
  721. X    return r_size + r_border + r_border;
  722. X}
  723. X
  724. X
  725. X
  726. X/*ARGSUSED*/
  727. Xstatic void TblRecompVectors(tw)
  728. XTableWidget tw;            /* Table widget */
  729. X/*
  730. X * Recomputes the size vectors in the table widget by
  731. X * examining the preferred sizes of subwidgets.  The
  732. X * following fields are modified: num_rows, num_cols,
  733. X * rows, cols, vec_height, and vec_width.
  734. X */
  735. X{
  736. X    TableLocTblPtr managed;
  737. X    Cardinal i;
  738. X
  739. X    /* Free existing vectors */
  740. X    if (tw->table.cols) XtFree((char *) (tw->table.cols));
  741. X    tw->table.num_cols = 0;
  742. X    if (tw->table.rows) XtFree((char *) (tw->table.rows));
  743. X    tw->table.num_rows = 0;
  744. X    tw->table.vec_width = tw->table.vec_height = 0;
  745. X
  746. X    /* Generate list of managed widgets with locations */
  747. X    managed = GetManaged(tw->composite.num_children, tw->composite.children);
  748. X    
  749. X    /* Handle columns */
  750. X    tw->table.num_cols = CompVector(managed, ColValues, ColSize,
  751. X                    tw->table.col_spacing, &(tw->table.cols));
  752. X    for (i = 0;  i < tw->table.num_cols;  i++) {
  753. X    tw->table.vec_width += tw->table.cols[i].value;
  754. X    }
  755. X      
  756. X
  757. X    /* Handle rows */
  758. X    tw->table.num_rows = CompVector(managed, RowValues, RowSize,
  759. X                    tw->table.row_spacing, &(tw->table.rows));
  760. X    for (i = 0;  i < tw->table.num_rows;  i++) {
  761. X    tw->table.vec_height += tw->table.rows[i].value;
  762. X    }
  763. X
  764. X    TblFreeLocTbl(managed);
  765. X}
  766. X
  767. X
  768. Xstatic void TblRequestResize(tw)
  769. XTableWidget tw;            /* Table widget */
  770. X/*
  771. X * Asks the parent to become the size given by the row and
  772. X * column vectors.  Precondition: vec_state must be MINIMUM.
  773. X */
  774. X{
  775. X    XtGeometryResult rtn;
  776. X    Dimension act_width, act_height;
  777. X    Dimension r_width, r_height;
  778. X
  779. X    act_width = tw->table.vec_width + 2*tw->table.int_width +
  780. X      (tw->table.num_cols-1)*tw->table.col_spacing;
  781. X    act_height = tw->table.vec_height + 2*tw->table.int_height +
  782. X      (tw->table.num_rows-1)*tw->table.row_spacing;
  783. X    rtn = XtMakeResizeRequest((Widget) tw, act_width, act_height,
  784. X                  &r_width, &r_height);
  785. X    switch (rtn) {
  786. X    case XtGeometryYes:
  787. X    case XtGeometryNo:
  788. X    /* Either case -- no action required */
  789. X    break;
  790. X    case XtGeometryAlmost:
  791. X    if ((r_width >= act_width) &&
  792. X        (r_height >= act_height)) {
  793. X        (void) XtMakeResizeRequest((Widget) tw, r_width, r_height,
  794. X                       (Dimension *) 0, (Dimension *) 0);
  795. X    }
  796. X    break;
  797. X    }
  798. X}
  799. X
  800. X
  801. X
  802. Xstatic void ExtraSpace(num, vec, size)
  803. XCardinal num;            /* Length of `vec' */
  804. XTableVecPtr vec;        /* Spacing vector  */
  805. XDimension size;            /* Overall size    */
  806. X/*
  807. X * If `size' is larger than the sum of all widths in `vec',
  808. X * the extra space is distributed evenly among appropriate
  809. X * candidates of `vec'.
  810. X */
  811. X{
  812. X    Cardinal i, ndist, sum = 0;
  813. X    Cardinal *dist;
  814. X    int diff, amt;
  815. X
  816. X    for (i = 0;  i < num;  i++) sum += vec[i].value;
  817. X    diff = size - sum;
  818. X    if (diff > 0) {
  819. X    /* Have to distribute space */
  820. X    dist = (Cardinal *) XtCalloc(num, sizeof(Cardinal));
  821. X    ndist = FindDistrib(0, num, vec, dist);
  822. X    amt = diff/ndist;
  823. X    for (i = 0;  i < ndist-1;  i++) {
  824. X        vec[dist[i]].value += amt;
  825. X        diff -= amt;
  826. X    }
  827. X    vec[dist[i]].value += diff;
  828. X    XtFree((char *) dist);
  829. X    }
  830. X}
  831. X
  832. X
  833. Xstatic Dimension SumVec(loc, span, vec, start, inter, end)
  834. XPosition loc, span;        /* Start and length      */
  835. XTableVecPtr vec;        /* Spacing vector        */
  836. XDimension start;        /* Added before sum      */
  837. XDimension inter;        /* Added between items   */
  838. XDimension end;            /* Added after sum       */
  839. X/*
  840. X * Returns the sum of the space in `vec' from `loc' for length `span'.
  841. X * Adds in the appropriate padding given by `start', `inter' and `end'.
  842. X */
  843. X{
  844. X    Position i;
  845. X    Dimension sum = 0;
  846. X
  847. X    for (i = loc;  i < loc+span;  i++) sum += vec[i].value;
  848. X    return sum + start + end + ((span >= 0) ? span*inter : 0);
  849. X}
  850. X
  851. Xstatic void PlaceWidget(w, x, y, width, height, rw, rh, opt)
  852. XWidget w;            /* What widget to place  */
  853. XPosition x, y;            /* Location of space     */
  854. XDimension width, height;    /* Size of space         */
  855. XDimension rw, rh;        /* Actual size           */
  856. XXtTblMask opt;            /* Justification options */
  857. X/*
  858. X * This routine moves the widget `w' inside the space given
  859. X * by x, y, width, height.  Its location in this space
  860. X * is determined by looking at the justification options of 
  861. X * `opt'.
  862. X */
  863. X{
  864. X    Position rx, ry;
  865. X
  866. X    if (opt & TBL_LEFT) rx = x;
  867. X    else if (opt & TBL_RIGHT) rx = x + width - rw;
  868. X    else rx = x + (width-rw)/2;
  869. X    if (opt & TBL_TOP) ry = y;
  870. X    else if (opt & TBL_BOTTOM) ry = y + height - rh;
  871. X    else ry = y + (height-rh)/2;
  872. X#ifdef NOTDEF
  873. X    rx += w->core.border_width;
  874. X    ry += w->core.border_width;
  875. X#endif
  876. X    
  877. X    XtMoveWidget(w, rx, ry);
  878. X}
  879. X
  880. X
  881. Xstatic void DoPlace(managed, cvec, rvec, vp, hp, rs, cs)
  882. XTableLocTblPtr managed;        /* List of managed widgets with locs */
  883. XTableVecPtr cvec, rvec;        /* Column and row spacing vector     */
  884. XDimension vp, hp;        /* Vertical and horizontal padding   */
  885. XDimension rs, cs;        /* Row and column interspace         */
  886. X/*
  887. X * This routine places each widget in `managed' according to the
  888. X * spacing vectors `cvec' and `rvec' and the widget placement
  889. X * options (justification and resizing).  First,  if allowed,
  890. X * the routine will resize the widget to fit its allocated
  891. X * space.  Then it will place the widget paying attention
  892. X * to the justification.
  893. X */
  894. X{
  895. X    Cardinal i;
  896. X    Position ax, ay;
  897. X    Dimension aw, ah;
  898. X    Dimension nw, nh;
  899. X
  900. X    for (i = 0;  i < managed->n_layout;  i++) {
  901. X    ax = SumVec(0, managed->locs[i].loc.ax, cvec, hp, cs, 0);
  902. X    ay = SumVec(0, managed->locs[i].loc.ay, rvec, vp, rs, 0);
  903. X    aw = SumVec(managed->locs[i].loc.ax,
  904. X            (Position) managed->locs[i].loc.h_span, cvec, 0, cs, -cs);
  905. X    ah = SumVec(managed->locs[i].loc.ay,
  906. X            (Position) managed->locs[i].loc.v_span, rvec, 0, rs, -rs);
  907. X    nw = aw - 2*managed->locs[i].w->core.border_width;
  908. X    nh = ah - 2*managed->locs[i].w->core.border_width;
  909. X    if (managed->locs[i].loc.options & TBL_LK_WIDTH) {
  910. X        nw = managed->locs[i].w->core.width;
  911. X    }
  912. X    if (managed->locs[i].loc.options & TBL_LK_HEIGHT) {
  913. X        nh = managed->locs[i].w->core.height;
  914. X    }
  915. X    if (((nw != managed->locs[i].w->core.width) ||
  916. X         (nh != managed->locs[i].w->core.height)) &&
  917. X        (nw > 0) && (nh > 0)) {
  918. X        /* Resize widget */
  919. X        XtResizeWidget(managed->locs[i].w, nw, nh,
  920. X               managed->locs[i].w->core.border_width);
  921. X    }
  922. X    /* Now place */
  923. X    nw = managed->locs[i].w->core.width +
  924. X      2*managed->locs[i].w->core.border_width;;
  925. X    nh = managed->locs[i].w->core.height +
  926. X      2*managed->locs[i].w->core.border_width;;
  927. X    PlaceWidget(managed->locs[i].w, ax, ay, aw, ah, nw, nh,
  928. X            managed->locs[i].loc.options);
  929. X    }
  930. X}
  931. X
  932. X
  933. X
  934. X/*ARGSUSED*/
  935. Xstatic void TblPlacement(tw)
  936. XTableWidget tw;            /* Table widget */
  937. X/*
  938. X * Places the children of the table widget.  There are several steps:
  939. X *   1.  Distribute any extra space into local copies of spacing vectors.
  940. X *   2.  If the option is set,  any extra space is offered to each widget.
  941. X *   3.  The final placement is done according to the actual size of
  942. X *       each widget and the space allocated for it.
  943. X */
  944. X{
  945. X    Cardinal i;
  946. X    TableVecPtr lrows, lcols;
  947. X    TableLocTblPtr managed;
  948. X    Dimension real_width, real_height;
  949. X
  950. X    if (tw->table.num_rows && tw->table.num_cols) {
  951. X    /* Make local copies of vectors */
  952. X    lrows = (TableVecPtr)
  953. X      XtCalloc(tw->table.num_rows, sizeof(struct _TableVector));
  954. X    for (i = 0;  i < tw->table.num_rows;  i++) {
  955. X        lrows[i] = tw->table.rows[i];
  956. X    }
  957. X    lcols = (TableVecPtr)
  958. X      XtCalloc(tw->table.num_cols, sizeof(struct _TableVector));
  959. X    for (i = 0;  i < tw->table.num_cols;  i++) {
  960. X        lcols[i] = tw->table.cols[i];
  961. X    }
  962. X
  963. X    /* Add extra space to vector */
  964. X    real_width = tw->core.width - 2*tw->table.int_width -
  965. X      (tw->table.num_cols-1)*tw->table.col_spacing;
  966. X    real_height = tw->core.height - 2*tw->table.int_height -
  967. X      (tw->table.num_rows-1)*tw->table.row_spacing;
  968. X    ExtraSpace(tw->table.num_cols, lcols, real_width);
  969. X    ExtraSpace(tw->table.num_rows, lrows, real_height);
  970. X
  971. X    /* Get list of managed widgets with locations */
  972. X    managed = GetManaged(tw->composite.num_children, tw->composite.children);
  973. X    DoPlace(managed, lcols, lrows, tw->table.int_height, tw->table.int_width,
  974. X        tw->table.row_spacing, tw->table.col_spacing);
  975. X
  976. X    /* Free up resources */
  977. X    XtFree((char *) lcols);
  978. X    XtFree((char *) lrows);
  979. X    TblFreeLocTbl(managed);
  980. X    }
  981. X}
  982. X
  983. X
  984. X
  985. X
  986. Xstatic void TblResize(w)
  987. XWidget w;            /* Table widget */
  988. X/*
  989. X * This routine is called when the table widget itself is
  990. X * resized.  If needed,  the vectors are recomputed and
  991. X * placement is done.
  992. X */
  993. X{
  994. X    TableWidget tw = (TableWidget) w;
  995. X
  996. X    if ((tw->core.width < tw->table.vec_width) ||
  997. X    (tw->core.height < tw->table.vec_height)) {
  998. X    TblRequestResize(tw);
  999. X    }
  1000. X    if (tw->table.vec_state == INVALID) {
  1001. X    TblRecompVectors(tw);
  1002. X    tw->table.vec_state = MINIMUM;
  1003. X    }
  1004. X    TblPlacement(tw);
  1005. X}
  1006. X
  1007. X
  1008. X
  1009. Xstatic XtGeometryResult ExamineRequest(request)
  1010. XXtWidgetGeometry *request;
  1011. X/*
  1012. X * Examines the bits set in `request' and returns an appropriate
  1013. X * geometry manager result.  Pure size changes are accepted
  1014. X * (XtGeometryYes),  pure position changes are rejected
  1015. X * (XtGeometryNo),  and combinations are conditionally
  1016. X * accepted (XtGeometryAlmost).
  1017. X */
  1018. X{
  1019. X    if (request->request_mode & (CWWidth|CWHeight|CWBorderWidth)) {
  1020. X    if (request->request_mode & (CWX|CWY|CWSibling|CWStackMode)) {
  1021. X        return XtGeometryAlmost;
  1022. X    } else {
  1023. X        return XtGeometryYes;
  1024. X    }
  1025. X    } else {
  1026. X    return XtGeometryNo;
  1027. X    }
  1028. X}
  1029. X
  1030. X
  1031. X
  1032. Xstatic XtGeometryResult TblGeometryManager(w, request, reply)
  1033. XWidget w;            /* Widget                    */
  1034. XXtWidgetGeometry *request;    /* Requested geometry change */
  1035. XXtWidgetGeometry *reply;    /* Actual reply to request   */
  1036. X/*
  1037. X * This routine handles geometry requests from children.  Width
  1038. X * and height changes are always accepted.  Position changes
  1039. X * are always rejected.  Combinations result in XtGeometryAlmost
  1040. X * with the requested widths filled in.  Accepted changes cause
  1041. X * an immediate XtResizeWidget followed by a new placement.
  1042. X */
  1043. X{
  1044. X    Widget parent;
  1045. X    TableWidget tw = (TableWidget) w->core.parent;
  1046. X    XtGeometryResult result;
  1047. X    Dimension width, height, bdr;
  1048. X    Dimension ow, oh;
  1049. X
  1050. X    parent = w->core.parent;
  1051. X    if (parent &&
  1052. X    (strcmp(parent->core.widget_class->core_class.class_name,
  1053. X        TBL_CLASS_NAME) == 0)) {
  1054. X    tw = (TableWidget) parent;
  1055. X    result = ExamineRequest(request);
  1056. X    switch (result) {
  1057. X    case XtGeometryYes:
  1058. X        if (request->request_mode & XtCWQueryOnly) {
  1059. X        return XtGeometryYes;
  1060. X        }
  1061. X        if (request->request_mode & CWWidth) {
  1062. X        width = request->width;
  1063. X        } else {
  1064. X        width = w->core.width;
  1065. X        }
  1066. X        if (request->request_mode & CWHeight) {
  1067. X        height = request->height;
  1068. X        } else {
  1069. X        height = w->core.height;
  1070. X        }
  1071. X        bdr = w->core.border_width;
  1072. X        if ((width > 0) && (height > 0)) {
  1073. X        XtResizeWidget(w, width, height, bdr);
  1074. X        }
  1075. X        ow = tw->table.vec_width;
  1076. X        oh = tw->table.vec_height;
  1077. X        TblRecompVectors(tw);
  1078. X        tw->table.vec_state = MINIMUM;
  1079. X        if ((ow != tw->table.vec_width) || (oh != tw->table.vec_height)) {
  1080. X        TblRequestResize(tw);
  1081. X        }
  1082. X        TblPlacement(tw);
  1083. X        return XtGeometryDone;
  1084. X        /*NOTREACHED*/
  1085. X    case XtGeometryNo:
  1086. X        return result;
  1087. X    case XtGeometryAlmost:
  1088. X        *reply = *request;
  1089. X        /* Turn off all but the size changes */
  1090. X        reply->request_mode &= (CWWidth|CWHeight|CWBorderWidth);
  1091. X        return XtGeometryAlmost;
  1092. X    }
  1093. X    /*NOTREACHED*/
  1094. X    } else {
  1095. X    XtErrorMsg("TblGeometryManager", "badParent", "XtToolkitError",
  1096. X           "Parent of widget is not a tableClassWidget",
  1097. X           (String *) NULL, (Cardinal *) NULL);
  1098. X    }
  1099. X    /*NOTREACHED*/
  1100. X}
  1101. X
  1102. X
  1103. X
  1104. X/*ARGSUSED*/
  1105. Xstatic Boolean TblSetValues(current, request, new)
  1106. XWidget current;            /* Before call to XtSetValues */
  1107. XWidget request;            /* After call to XtSetValues  */
  1108. XWidget new;            /* Final version of widget    */
  1109. X/*
  1110. X * Checks for changes to `init_table'.  If so,  a recomputation
  1111. X * and replacement occurs.  Always returns false.
  1112. X */
  1113. X{
  1114. X    TableWidget old = (TableWidget) current;
  1115. X    TableWidget tw = (TableWidget) new;
  1116. X    Boolean recomp = False;
  1117. X
  1118. X    if ((tw->table.init_layout) ||
  1119. X    (old->table.int_width != tw->table.int_width) ||
  1120. X    (old->table.int_height != tw->table.int_height) ||
  1121. X    (old->table.row_spacing != tw->table.row_spacing) ||
  1122. X    (old->table.col_spacing != tw->table.col_spacing)) {
  1123. X    recomp = True;
  1124. X    }
  1125. X    if (recomp) {
  1126. X    /* Causes complete recomputation and placement */
  1127. X    TblRecompVectors(tw);
  1128. X    tw->table.vec_state = MINIMUM;
  1129. X    TblRequestResize(tw);
  1130. X    TblPlacement(tw);
  1131. X    }
  1132. X    return FALSE;
  1133. X}
  1134. X
  1135. X
  1136. X
  1137. X
  1138. Xstatic void TblChangeManaged(w)
  1139. XWidget w;            /* Table widget */
  1140. X/*
  1141. X * This routine is called when a change to the managed set of
  1142. X * children occurs.  The current implementation simply refigures
  1143. X * the widget and repositions all widgets.  Better implementations
  1144. X * may be able to examine the change and react accordingly.
  1145. X */
  1146. X{
  1147. X    TableWidget tw = (TableWidget) w;
  1148. X
  1149. X    TblRecompVectors(tw);
  1150. X    tw->table.vec_state = MINIMUM;
  1151. X    TblRequestResize(tw);
  1152. X    TblPlacement(tw);
  1153. X}
  1154. X
  1155. X
  1156. X
  1157. Xstatic XtGeometryResult TblQueryGeometry(w, request, geo_return)
  1158. XWidget w;            /* Table widget         */
  1159. XXtWidgetGeometry *request;    /* Parent intended size */
  1160. XXtWidgetGeometry *geo_return;   /* This widget's size   */
  1161. X/*
  1162. X * This routine is called by a parent that wants a preferred
  1163. X * size for the widget.  The `request' is the size (and/or position) 
  1164. X * the parent intends to make the widget.  The `geo_return' is the
  1165. X * preferred size of the widget.  The preferred size of the
  1166. X * table widget is its vector size.
  1167. X */
  1168. X{
  1169. X    TableWidget tw = (TableWidget) w;
  1170. X
  1171. X    if (tw->table.vec_state == INVALID) {
  1172. X    TblRecompVectors(tw);
  1173. X    tw->table.vec_state = MINIMUM;
  1174. X    }
  1175. X    geo_return->request_mode = CWWidth|CWHeight;
  1176. X    geo_return->width = tw->table.vec_width + 2*tw->table.int_width +
  1177. X      (tw->table.num_cols-1)*tw->table.col_spacing;
  1178. X    geo_return->height = tw->table.vec_height + 2*tw->table.int_height +
  1179. X      (tw->table.num_rows-1)*tw->table.row_spacing;
  1180. X
  1181. X    /* Now determine return code */
  1182. X    if (((geo_return->request_mode & request->request_mode) !=
  1183. X     geo_return->request_mode) ||
  1184. X    (request->width < geo_return->width) ||
  1185. X    (request->height < geo_return->height)) {
  1186. X    return XtGeometryAlmost;
  1187. X    } else if ((request->width == geo_return->width) &&
  1188. X           (request->height == geo_return->height)) {
  1189. X    return XtGeometryNo;
  1190. X    } else {
  1191. X    return XtGeometryYes;
  1192. X    }
  1193. X    /*NOTREACHED*/
  1194. X}
  1195. X
  1196. X
  1197. X
  1198. Xstatic void TblPositionChild(w, c, r, hspan, vspan, options)
  1199. XWidget w;            /* Subwidget to place              */
  1200. XPosition c, r;            /* Position in array (column, row) */
  1201. XDimension hspan, vspan;        /* Horizontal and vertical span    */
  1202. XXtTblMask options;        /* Widget placement options        */
  1203. X/*
  1204. X * This routine registers the position of Widget w.  The widget
  1205. X * must be a sub-widget of a Table class widget.  The row and
  1206. X * column must be non-negative.  The horizontal and vertical
  1207. X * span must be positive.  The options are as follows:
  1208. X *   TBL_LEFT        Horizontally left justified.
  1209. X *   TBL_RIGHT        Horizontally right justified.
  1210. X *   TBL_TOP        Vertically top justified.
  1211. X *   TBL_BOTTOM     Vertically bottom justified.
  1212. X *   TBL_SM_WIDTH    Force the width to be as small as possible.
  1213. X *   TBL_SM_HEIGHT    Force the height to be as small as possible.
  1214. X *   TBL_LK_WIDTH    Don't try to expand the widget horizontally.
  1215. X *   TBL_LK_HEIGHT    Don't try to expand the widget vertically.
  1216. X * If `options' is equal to TBL_DEF_OPT,  it is filled with 
  1217. X * the default value for the table widget. The routine adds the 
  1218. X * information into a table and recomputes position information.
  1219. X */
  1220. X{
  1221. X    Widget parent;
  1222. X    TableWidget tw;
  1223. X    TableLoc loc;
  1224. X
  1225. X    if ((c < 0) || (r < 0) || (hspan == 0) || (vspan == 0)) {
  1226. X    /* Bad arguments */
  1227. X    XtErrorMsg("TblPositionChild", "wrongParameters", "XtToolkitError",
  1228. X           "Bad value for row, column, hspan, or vspan",
  1229. X           (String *) NULL, (Cardinal *) NULL);
  1230. X    }
  1231. X    parent = w->core.parent;
  1232. X    if (parent &&
  1233. X    (strcmp(parent->core.widget_class->core_class.class_name,
  1234. X        TBL_CLASS_NAME)==0)){
  1235. X    /* The parent exists and is a TableWidget */
  1236. X    tw = (TableWidget) parent;
  1237. X    loc.ax = c;
  1238. X    loc.ay = r;
  1239. X    loc.h_span = hspan;
  1240. X    loc.v_span = vspan;
  1241. X    if (options == TBL_DEF_OPT) {
  1242. X        loc.options = tw->table.def_options;
  1243. X    } else {
  1244. X        loc.options = options;
  1245. X    }
  1246. X    TblInsertLoc(tw->table.real_layout, w, &loc);
  1247. X    tw->table.vec_state = INVALID;
  1248. X    /* Full recomputation if realized */
  1249. X    if (XtIsRealized(parent)) TblResize(parent);
  1250. X    } else {
  1251. X    XtErrorMsg("TblPositionChild", "badParent", "XtToolkitError",
  1252. X           "Parent of widget is not a tableClassWidget",
  1253. X           (String *) NULL, (Cardinal *) NULL);
  1254. X    }
  1255. X}
  1256. X
  1257. X
  1258. X
  1259. Xstatic Boolean TblFindChild(w, c_r, r_r, hspan_r, vspan_r, opt_r)
  1260. XWidget w;            /* Widget to locate  */
  1261. XPosition *c_r, *r_r;        /* Returned position */
  1262. XDimension *hspan_r, *vspan_r;    /* Returned span     */
  1263. XXtTblMask *opt_r;        /* Returned options  */
  1264. X/*
  1265. X * This routine looks up a child widget's location and span.  The
  1266. X * parent must be a table widget.  Only non-zero fields are filled
  1267. X * in.  If the widget cannot be found,  the routine returns False
  1268. X * and does not modify any of the passed in pointers.  The routine
  1269. X * first looks in a table of widget positions defined by the
  1270. X * `position_child' class procedure.  If not found there,  it
  1271. X * searches the default table using the widget name.  These
  1272. X * defaults are set by resources or XtSetValues().
  1273. X */
  1274. X{
  1275. X    Widget parent;
  1276. X    TableWidget tw;
  1277. X    TableLocPtr locp;
  1278. X    TableDefLocPtr temp;
  1279. X
  1280. X    parent = w->core.parent;
  1281. X    if (parent &&
  1282. X    (strcmp(parent->core.widget_class->core_class.class_name,
  1283. X        TBL_CLASS_NAME)==0)) {
  1284. X    tw = (TableWidget) parent;
  1285. X    if (locp = TblLocLookup(tw->table.real_layout, w)) {
  1286. X        if (c_r) *c_r = locp->ax;
  1287. X        if (r_r) *r_r = locp->ay;
  1288. X        if (hspan_r) *hspan_r = locp->h_span;
  1289. X        if (vspan_r) *vspan_r = locp->v_span;
  1290. X        if (opt_r) *opt_r = locp->options;
  1291. X        return True;
  1292. X    } else {
  1293. X        if (tw->table.init_layout) {
  1294. X        temp = MergeDefLoc(tw->table.layout_db, tw->table.init_layout);
  1295. X        XtFree((char *) (tw->table.init_layout));
  1296. X        tw->table.init_layout = (TableDefLocPtr) 0;
  1297. X        XtFree((char *) (tw->table.layout_db));
  1298. X        tw->table.layout_db = temp;
  1299. X        }
  1300. X        /* Attempt to look it up */
  1301. X        if (temp = FindDefLoc(tw->table.layout_db, w->core.name)) {
  1302. X        if (c_r) *c_r = temp->loc.ax;
  1303. X        if (r_r) *r_r = temp->loc.ay;
  1304. X        if (hspan_r) *hspan_r = temp->loc.h_span;
  1305. X        if (vspan_r) *vspan_r = temp->loc.v_span;
  1306. X        if (opt_r) *opt_r = temp->loc.options;
  1307. X        return True;
  1308. X        } else {
  1309. X        return False;
  1310. X        }
  1311. X    }
  1312. X    } else {
  1313. X    XtErrorMsg("TblFindChild", "badParent", "XtToolkitError",
  1314. X           "Parent of widget is not a tableClassWidget",
  1315. X           (String *) NULL, (Cardinal *) NULL);
  1316. X    }
  1317. X    /*NOTREACHED*/
  1318. X}
  1319. X
  1320. X
  1321. X
  1322. Xstatic void TblDestroy(w)
  1323. XWidget w;            /* Widget to destroy */
  1324. X/*
  1325. X * Called to free resources consumed by the widget.
  1326. X */
  1327. X{
  1328. X    TableWidget tw = (TableWidget) w;
  1329. X
  1330. X    XtFree((char *) (tw->table.init_layout));
  1331. X    XtFree((char *) (tw->table.layout_db));
  1332. X    TblFreeLocTbl(tw->table.real_layout);
  1333. X    if (tw->table.rows) XtFree((char *) (tw->table.rows));
  1334. X    if (tw->table.cols) XtFree((char *) (tw->table.cols));
  1335. X}
  1336. X
  1337. X
  1338. Xstatic Cardinal DefSpecLen(layout)
  1339. XString layout;            /* Full layout specification string */
  1340. X/*
  1341. X * Examines `layout' and determines how many statements there are.
  1342. X * Basically counts semi-colons and adds one.
  1343. X */
  1344. X{
  1345. X    extern String strchr();
  1346. X    String idx = layout;
  1347. X    Cardinal result = 0;
  1348. X
  1349. X    while (idx && *idx) {
  1350. X    idx = strchr(idx, ';');
  1351. X    if (idx) {
  1352. X        result++;
  1353. X        idx++;
  1354. X    }
  1355. X    }
  1356. X    return result+1;
  1357. X}
  1358. X
  1359. X#define MAX_FIELD    128
  1360. X#define NUM_FIELDS    6
  1361. X#define MAX_CHARS    255
  1362. X
  1363. Xstatic XtTblMask ParseOpts(spec)
  1364. XString spec;            /* Option letters */
  1365. X/*
  1366. X * Parses the null-terminated string of option characters in `spec'.
  1367. X * Returns a mask that is the `or' of all options selected.
  1368. X */
  1369. X{
  1370. X    static Boolean init = 0;
  1371. X    static XtTblMask all_chars[MAX_CHARS];
  1372. X    XtTblMask result = 0;
  1373. X    String idx;
  1374. X
  1375. X    if (!init) {
  1376. X    Cardinal i;
  1377. X
  1378. X    for (i = 0;  i < MAX_CHARS;  i++) all_chars[i] = 0;
  1379. X    all_chars['l'] = TBL_LEFT;
  1380. X    all_chars['r'] = TBL_RIGHT;
  1381. X    all_chars['t'] = TBL_TOP;
  1382. X    all_chars['b'] = TBL_BOTTOM;
  1383. X    all_chars['w'] = TBL_LK_WIDTH;
  1384. X    all_chars['h'] = TBL_LK_HEIGHT;
  1385. X    all_chars['W'] = TBL_SM_WIDTH;
  1386. X    all_chars['H'] = TBL_SM_HEIGHT;
  1387. X    }
  1388. X    for (idx = spec;  *idx;  idx++) {
  1389. X    result |= all_chars[*idx];
  1390. X    }
  1391. X    return result;
  1392. X}
  1393. X
  1394. Xstatic void DefParse(spec, loc_spec)
  1395. XString spec;            /* One specification statement */
  1396. XTableDefLocPtr loc_spec;    /* Result location spec        */
  1397. X/*
  1398. X * Parses a text specification statement into an internal
  1399. X * form given  by `loc_spec'.
  1400. X */
  1401. X{
  1402. X    static String def_name = "No Name";
  1403. X    char fields[NUM_FIELDS][MAX_FIELD];
  1404. X    Cardinal num;
  1405. X
  1406. X    /* First, set up defaults */
  1407. X    loc_spec->w_name = def_name;
  1408. X    loc_spec->loc.ax = loc_spec->loc.ay = 0;
  1409. X    loc_spec->loc.h_span = loc_spec->loc.v_span = 1;
  1410. X    loc_spec->loc.options = 0;
  1411. X
  1412. X    /* Now attempt to parse the string */
  1413. X    num = sscanf(spec, "%s %s %s %s %s %s",
  1414. X         fields[0], fields[1], fields[2], fields[3], fields[4], fields[5]);
  1415. X    if (num >= 1) {
  1416. X    loc_spec->w_name = XtNewString(fields[0]);
  1417. X    }
  1418. X    if (num >= 2) {
  1419. X    loc_spec->loc.ax = atoi(fields[1]);
  1420. X    }
  1421. X    if (num >= 3) {
  1422. X    loc_spec->loc.ay = atoi(fields[2]);
  1423. X    }
  1424. X    if (num >= 4) {
  1425. X    loc_spec->loc.h_span = atoi(fields[3]);
  1426. X    }
  1427. X    if (num >= 5) {
  1428. X    loc_spec->loc.v_span = atoi(fields[4]);
  1429. X    }
  1430. X    if (num >= 6) {
  1431. X    loc_spec->loc.options = ParseOpts(fields[5]);
  1432. X    }
  1433. X}
  1434. X
  1435. Xstatic String GetSpec(spec_ptr)
  1436. XString *spec_ptr;        /* Specification pointer */
  1437. X/*
  1438. X * This routine gets the next specification from the string
  1439. X * `spec_ptr' and updates the pointer appropriately.
  1440. X */
  1441. X{
  1442. X    extern String strchr();
  1443. X    String result;
  1444. X    String semi;
  1445. X
  1446. X    if (*spec_ptr && **spec_ptr) {
  1447. X    semi = strchr(*spec_ptr, ';');
  1448. X    if (semi) {
  1449. X        *semi = '\0';
  1450. X        result = *spec_ptr;
  1451. X        *spec_ptr = semi+1;
  1452. X        return result;
  1453. X    } else {
  1454. X        result = *spec_ptr;
  1455. X        *spec_ptr += strlen(*spec_ptr);
  1456. X        return result;
  1457. X    }
  1458. X    } else {
  1459. X    return (String) 0;
  1460. X    }
  1461. X}
  1462. X
  1463. X
  1464. X
  1465. X/**********************************************************************
  1466. X *
  1467. X * Public routines
  1468. X *
  1469. X **********************************************************************/
  1470. X
  1471. X
  1472. X/*ARGSUSED*/
  1473. Xcaddr_t XtTblParseLayout(layout)
  1474. XString layout;            /* String layout specification */
  1475. X/*
  1476. X * Parses a string layout specification into an internal form
  1477. X * suitable for use in a call to XtSetValues().  The form is
  1478. X * a list of statements separated by semicolons.  Each statement
  1479. X * has the form:
  1480. X *   widget_name column row horizontal_span vertical_span opt_list
  1481. X * where the meaning of each field is:
  1482. X *   widget_name    Name of the widget as given to XtCreateWidget().
  1483. X *   column        Integer >= 0 descibing column in array
  1484. X *   row        Row >= 0 describing row in array
  1485. X *   horizontal_span    Integer >= 1 describing horizontal widget span
  1486. X *   vertical_span    Integer >= 1 describing vertical widget span
  1487. X *   opt_list        Series of characters each representing an option:
  1488. X *    l:  TBL_LEFT
  1489. X *    r:  TBL_RIGHT
  1490. X *      t:  TBL_TOP
  1491. X *      b:  TBL_BOTTOM
  1492. X *      w:  TBL_LK_WIDTH
  1493. X *      h:  TBL_LK_HEIGHT
  1494. X *      W:  TBL_SM_WIDTH
  1495. X *      H:  TBL_SM_HEIGHT
  1496. X * The options are as described in TblPostionChild().  The horizontal_span,
  1497. X * vertical_span, and opt_list are optional and will default to reasonable
  1498. X * values.
  1499. X */
  1500. X{
  1501. X    TableDefLocPtr result, idx;
  1502. X    Cardinal len;
  1503. X    String spec;
  1504. X
  1505. X    /* Make a copy for safety */
  1506. X    if (layout && ((len = DefSpecLen(layout)) > 0)) {
  1507. X    layout = XtNewString(layout);
  1508. X    result = (TableDefLocPtr) XtCalloc(len+1, sizeof(struct _TableDefLoc));
  1509. X    idx = result;
  1510. X    while (spec = GetSpec(&layout)) {
  1511. X        DefParse(spec, idx);
  1512. X        idx++;
  1513. X    }
  1514. X    /* null terminate */
  1515. X    idx->w_name = (String) 0;
  1516. X    XtFree(layout);
  1517. X    return (caddr_t) result;
  1518. X    } else {
  1519. X    return (caddr_t) 0;
  1520. X    }
  1521. X    /*NOTREACHED*/
  1522. X}
  1523. X
  1524. Xvoid XtTblPosition(w, col, row)
  1525. XWidget w;            /* Widget to position */
  1526. XPosition col, row;        /* Position in array  */
  1527. X/*
  1528. X * This routine positions a widget that has been created
  1529. X * under a widget of class tableWidgetClass.  The widget
  1530. X * will be placed at column `col' and row `row'.  If
  1531. X * the widget has never been placed before,  it will
  1532. X * span only one space in each direction and its
  1533. X * options will be the defaults for the table widget.
  1534. X */
  1535. X{
  1536. X    Position old_row, old_col;
  1537. X    Dimension old_hspan, old_vspan;
  1538. X    XtTblMask old_opts;
  1539. X
  1540. X    if (TblFindChild(w, &old_col, &old_row, &old_hspan, &old_vspan, &old_opts)) {
  1541. X    TblPositionChild(w, col, row, old_hspan, old_vspan, old_opts);
  1542. X    } else {
  1543. X    TblPositionChild(w, col, row, 1, 1, TBL_DEF_OPT);
  1544. X    }
  1545. X}
  1546. X
  1547. Xvoid XtTblResize(w, h_span, v_span)
  1548. XWidget w;            /* Widget to resize            */
  1549. XDimension h_span, v_span;    /* New widget span             */
  1550. X/*
  1551. X * This routine changes the span of widget `w' to (`h_span', `v_span').
  1552. X * If the widget has never been placed before,  it will be located
  1553. X * at (0,0) and its options will be the defaults for its
  1554. X * parent table widget.
  1555. X */
  1556. X{
  1557. X    Position old_row, old_col;
  1558. X    Dimension old_hspan, old_vspan;
  1559. X    XtTblMask old_opts;
  1560. X
  1561. X    if (TblFindChild(w, &old_col, &old_row, &old_hspan, &old_vspan, &old_opts)) {
  1562. X    TblPositionChild(w, old_col, old_row, h_span, v_span, old_opts);
  1563. X    } else {
  1564. X    TblPositionChild(w, 0, 0, h_span, v_span, TBL_DEF_OPT);
  1565. X    }
  1566. X}
  1567. X
  1568. Xvoid XtTblOptions(w, opt)
  1569. XWidget w;            /* Widget to change */
  1570. XXtTblMask opt;            /* New option mask  */
  1571. X/*
  1572. X * This routine changes the options of widget `w' to `opt'.  If
  1573. X * the widget has never been placed before,  it will be located
  1574. X * and (0,0) with a span of (1,1) and its options will be the
  1575. X * default options for its parent table widget.  The option
  1576. X * mask is as described for TblPositionChild.
  1577. X */
  1578. X{
  1579. X    Position old_row, old_col;
  1580. X    Dimension old_hspan, old_vspan;
  1581. X    XtTblMask old_opts;
  1582. X
  1583. X    if (TblFindChild(w, &old_col, &old_row, &old_hspan, &old_vspan, &old_opts)) {
  1584. X    TblPositionChild(w, old_col, old_row, old_hspan, old_vspan, opt);
  1585. X    } else {
  1586. X    TblPositionChild(w, 0, 0, 1, 1, opt);
  1587. X    }
  1588. X}
  1589. X
  1590. Xvoid XtTblConfig(w, col, row, h_span, v_span, opt)
  1591. XWidget w;            /* Widget to position          */
  1592. XPosition col, row;        /* Position in array           */
  1593. XDimension h_span, v_span;    /* Horizonal and vertical span */
  1594. XXtTblMask opt;            /* Widget placement options    */
  1595. X/*
  1596. X * This routine positions a widget that has been created
  1597. X * under a widget of class tableWidgetClass.  The widget
  1598. X * will be placed at column `col' and row `row'.  The
  1599. X * widget will span the distances given by `h_span' and `v_span'.
  1600. X * The options argument is as described for TblPositionChild.
  1601. X */
  1602. X{
  1603. X    TblPositionChild(w, col, row, h_span, v_span, opt);
  1604. X}
  1605. X
  1606. +FUNKY+STUFF+
  1607. echo '-rw-r--r--  1 david       45961 Jul  3 13:48 Table.c    (as sent)'
  1608. chmod u=rw,g=r,o=r Table.c
  1609. ls -l Table.c
  1610. echo x - Table.doc
  1611. sed 's/^X//' > Table.doc <<'+FUNKY+STUFF+'
  1612. X
  1613. XTable - Geometry Management Widget for the X Toolkit
  1614. X
  1615. XDavid Harrison
  1616. XUC Berkeley Electronics Research Lab
  1617. X(davidh@ic.Berkeley.EDU, ...!ucbvax!ucbcad!davidh)
  1618. X
  1619. XTable is a composite widget designed to manage the size and location
  1620. Xof its children.  The widget uses an array model to simplify the
  1621. Xarrangement of child widgets.  The widget is directly derived from the
  1622. Xcore and composite widgets provided by the X Toolkit and can be used
  1623. Xwith any widget set.  It has been tested using the Athena widget set.
  1624. XBelow is a short summary on the operation and use of the Table widget.
  1625. XIt assumes a working knowledge of the X Toolkit Intrinsics.
  1626. X
  1627. XThe Table widget addresses formatting for dialog boxes.  Dialog boxes
  1628. Xare rectangular windows that contain a wide variety of widgets.  Most
  1629. Xdialog boxes are arranged with widgets aligned in a way similar to the
  1630. Xlayout found in business forms.  The Table widget is designed to make
  1631. Xsuch layouts easy to specify.
  1632. X
  1633. XWhen designing dialog boxes that resemble business forms, the primary
  1634. Xproblem is specifying the alignment between widgets.  The Table widget
  1635. Xaddresses this problem by adopting an array model.  Under this model,
  1636. Xwidgets are placed at row and column locations in a variable sized
  1637. Xarray.  Widgets may span more than one row or column.  The array can
  1638. Xexpand or contract in size as needed.  There are options to control
  1639. Xjustification and place size restrictions on rows and columns of
  1640. Xwidgets.
  1641. X
  1642. XThe Table widget can contain any number and type of sub-widgets
  1643. X(including other Table widgets).  XtCreateWidget() is used to create
  1644. Xnew Table widgets using the class variable tableWidgetClass.  The
  1645. Xresources listed below are retrieved from the argument list or from
  1646. Xthe resource database:
  1647. X
  1648. X            tableWidgetClass
  1649. X
  1650. XName        Type        Default            Description
  1651. X--------------------------------------------------------------------------------
  1652. XXtNbackground    Pixel        XtDefaultBackground    Window background
  1653. XXtNborder    Pixel        XtDefaultForeground    Window border
  1654. XXtNborderWidth    Dimension    0            Width of border
  1655. XXtNx        Position    0            X position of table
  1656. XXtNy        Position    0            Y position of table
  1657. XXtNwidth    Dimension    (computed at realize)    Width of form
  1658. XXtNheight    Dimension    (computed at realize)    Height of form
  1659. XXtNmappedWhenManaged Boolean    True            XtMapWidget is automatic
  1660. XXtNsensitive    Boolean        True            Widget receives input
  1661. XXtNlayout    Layout        None            See text
  1662. XXtNinternalHeight Dimension    0            Int. horizontal padding
  1663. XXtNinternalWidth Dimension    0            Int. vertical padding
  1664. XXtNcolumnSpacing Dimension    0            Inter-column padding
  1665. XXtNrowSpacing    Dimension    0            Inter-row padding
  1666. XXtNdefaultOptions Options    None            See text
  1667. X
  1668. X
  1669. XWidgets are added to a Table by specifying a Table widget as the
  1670. Xparent widget when the widget is created.  Once a widget is added to a
  1671. Xtable, it can be assigned a row and column position, a horizontal
  1672. Xand vertical span, and justification options.  This information can be
  1673. Xspecified in two ways: using public access functions or using the
  1674. Xresource database.
  1675. X
  1676. XPublic access functions allow the programmer to dynamically alter the
  1677. Xformatting of children of a Table widget.  One can alter the position,
  1678. Xspan, or options of a widget using XtTblConfig:
  1679. X
  1680. Xvoid XtTblConfig(
  1681. X     Widget w,        /* Subwidget to modify          */
  1682. X     Position col,    /* Column position (horizontal) */
  1683. X     Position row,    /* Row position (vertical)      */
  1684. X     Dimension h_span,    /* How many columns to span     */
  1685. X     Dimension v_span,    /* How many rows to span        */
  1686. X     XtTblMask opt    /* Justification options        */
  1687. X);
  1688. X
  1689. XThe specified widget (which must be a child of a Table widget) will be
  1690. Xplaced at column `col' and row `row'.  The widget will span `h_span'
  1691. Xcolumns to the right of `col' and `v_span' rows below `row'.  The
  1692. Xarray for the table will expand as necessary.  Options are specified
  1693. Xby `or'ing together the following option bits: 
  1694. X
  1695. X   TBL_LEFT        Horizontally left justified.
  1696. X   TBL_RIGHT        Horizontally right justified.
  1697. X   TBL_TOP        Vertically top justified.
  1698. X   TBL_BOTTOM         Vertically bottom justified.
  1699. X   TBL_LK_WIDTH        Don't try to expand the widget horizontally.
  1700. X   TBL_LK_HEIGHT    Don't try to expand the widget vertically.
  1701. X   TBL_SM_WIDTH        Force the width to be as small as possible.
  1702. X   TBL_SM_HEIGHT    Force the height to be as small as possible.
  1703. X
  1704. XAlternatively,  if `options' is equal to TBL_DEF_OPT,  the options are
  1705. Xset to the default options for the Table widget.  The default options
  1706. Xfor the Table widget are set using the XtNdefaultOptions resource (see
  1707. Xresource specifications below).  The routine changes the formatting
  1708. Xinformation in its internal table.  If the Table widget is realized,
  1709. Xthe positions of all child widgets are recomputed and the change on
  1710. Xthe screen will be immediate.
  1711. X
  1712. X
  1713. XThe Table widget computes the size of a widget based on the minimum
  1714. Xsize required for the row(s) and column(s) it occupies.  However, some
  1715. Xwidgets may require less space than that computed by the Table widget.
  1716. XIn this case, the widget is aligned in the larger space according to
  1717. Xthe bits TBL_LEFT, TBL_RIGHT, TBL_TOP, and TBL_BOTTOM.  These bits may
  1718. Xbe combined (i.e. TBL_RIGHT|TBL_TOP specifies upper right hand corner
  1719. Xjustification). If no justification bits are specified, the widget is
  1720. Xcentered.
  1721. X
  1722. XSome widgets may be amenable to growing to any size specified by the
  1723. XTable widget.  Often, it may be desirable to force these widgets to
  1724. Xremain at their optimal size for asthetic or operational convenience.
  1725. XIf the TBL_LK_WIDTH bit is specified, the Table widget will not make
  1726. Xthe widget any wider than it's original desired size.  Similarly, if
  1727. Xthe TBL_LK_HEIGHT bit is specified, the Table widget will not make the
  1728. Xwidget any taller than it's original size.  Note this may bring widget
  1729. Xjustification into play.
  1730. X
  1731. XWhen a Table widget is resized, it automatically recomputes the sizes
  1732. Xof the rows and columns of an array and distributes extra space evenly
  1733. Xamong the rows and columns.  Often, it may be useful to control this
  1734. Xdistribution of space so that some rows or columns are not resized
  1735. Xwhen extra space becomes available.  If the TBL_SM_WIDTH bit is
  1736. Xspecified, the entire column(s) containing the widget are excluded
  1737. Xfrom the excess space distribution algorithm.  Thus, the column(s) are
  1738. Xforced to remain as small as possible.  The TBL_SM_HEIGHT bit works
  1739. Xthe same way with respect to the row(s) containing the widget. A title
  1740. Xbar is a good example of this concept. When a dialog is resized, any
  1741. Xexcess vertical space should be given to the body of the dialog not to
  1742. Xthe title bar.  Thus, TBL_SM_HEIGHT would be specified for a title bar
  1743. Xwidget.
  1744. X
  1745. X
  1746. XIn most applications, the programmer will not set all of the above
  1747. Xinformation for all widgets.  The following convenience functions have
  1748. Xbeen defined for use in these cases:
  1749. X
  1750. Xvoid XtTblPosition(
  1751. X     Widget w,        /* Child of table widget        */
  1752. X     Position col,    /* Column position (horizontal) */
  1753. X     Position row    /* Row position (vertical)      */
  1754. X);
  1755. X
  1756. XThe specified widget (which must be a child of a Table widget) will be
  1757. Xplaced at column `col' and row `row'.  The vertical and horizontal
  1758. Xspan of the widget will remain unchanged.  If the span of the widget
  1759. Xwas not set, it will default to one row and one column.  The
  1760. Xjustification options of the widget will remain unchanged.  If the
  1761. Xjustification options of the widget were not set, it will default to
  1762. XTBL_DEF_OPT (see XtTblConfig).
  1763. X
  1764. Xvoid XtTblResize(
  1765. X     Widget w,        /* Child of table widget        */
  1766. X     Dimension h_span,    /* How many columns to span     */
  1767. X     Dimention v_span    /* How many rows to span        */
  1768. X);
  1769. X
  1770. XThis routine changes the span of widget `w' (which must be a child of
  1771. Xa Table widget) to span `h_span' columns and `v_span' rows.  Any
  1772. Xprevious position or options assigned to the widget will be preserved.
  1773. XIf no position is associated with the widget,  it will be placed at
  1774. X(0,0).  If no options are associated with the widget, its options will
  1775. Xbe the defaults for the parent table widget.
  1776. X
  1777. Xvoid XtTblOptions(
  1778. X     Widget w,        /* Child of table widget */
  1779. X     XtTblMask opt    /* Option mask           */
  1780. X);
  1781. X
  1782. XThis routine changes the option bits of widget `w' (which must be a
  1783. Xchild of a Table widget) to `opt'.  The options are as described for
  1784. XXtTblConfig().  Any associated position and span of the widget remains
  1785. Xunchanged.  If the widget hasn't been placed, it will be located at
  1786. X(0,0) and given a span of (1,1).
  1787. X
  1788. X
  1789. XLayout information may also be specified using XtSetValues() or using
  1790. Xthe resource database.  The resources XtNlayout and XtNdefaultOptions
  1791. Xmay both be set in this fashion.
  1792. X
  1793. XThe XtNlayout resource allows the user to specify the row, column,
  1794. Xvertical span, horizontal span, and options for a set of widgets
  1795. Xstatically through the resource database or dynamically using
  1796. XXtSetValues().  The type of this resource is private to the Table
  1797. Xwidget.  However, the widget automatically registers a type converter
  1798. Xthat converts between a string layout format and the internal form
  1799. Xused by the Table widget.  This form is a list of statements separated
  1800. Xby semicolons.  Each statement has the form:
  1801. X
  1802. X    widget_name column row horizontal_span vertical_span opt_list
  1803. X
  1804. Xwidget_name    Name of the widget as given to XtCreateWidget().
  1805. Xcolumn        Integer >= 0 giving column in array
  1806. Xrow        Integer >= 0 giving row in array
  1807. Xhorizontal_span    Integer >= 1 giving number of columns to span
  1808. Xvertical_span    Integer >= 1 giving number of rows to span
  1809. Xopt_list    Series of characters each representing an option:
  1810. X    l:    TBL_LEFT
  1811. X    r:    TBL_RIGHT
  1812. X    t:    TBL_TOP
  1813. X    b:    TBL_BOTTOM
  1814. X    w:    TBL_LK_WIDTH
  1815. X    h:    TBL_LK_HEIGHT
  1816. X    W:    TBL_SM_WIDTH
  1817. X    H:    TBL_SM_HEIGHT
  1818. X
  1819. XThe options are as described for XtTblConfig().  The horizontal_span,
  1820. Xvertical_span, and opt_list are optional and may be omitted.  The
  1821. Xhorizontal and vertical spans will default to 1.  The option list will
  1822. Xdefault to the default options for the Table widget.  A sample layout
  1823. Xdescription is given below:
  1824. X
  1825. X    "Title 0 0 2 1 H; First 0 1; Second 1 1"
  1826. X
  1827. XWhen using XtSetValues to specify the XtNlayout resource, the caller
  1828. Xshould use the following function to parse a textual form into the
  1829. Xinternal form used by the Table widget:
  1830. X
  1831. Xcaddr_t XtTblParseLayout(
  1832. X    String layout        /* String layout specification */
  1833. X);
  1834. X
  1835. XThis function parses `layout' into an internal form that can be passed
  1836. Xto a Table widget as the XtNlayout resource.  The form of the layout
  1837. Xis described above.
  1838. X
  1839. XUnless otherwise specified, all options for widgets created under a
  1840. XTable widget are set based on the default options for the Table
  1841. Xwidget.  These default options are set using the XtNdefaultOptions
  1842. Xresource.  This resource can be specified in the resource database as
  1843. Xa string of option characters.  This string has the same form as the
  1844. Xopt_list described above for XtTblParseLayout().
  1845. X
  1846. X/*
  1847. X * Table Widget Example - Using resources
  1848. X *
  1849. X * Place the following entries in your resources file:
  1850. X *   TableExample.table.Layout: title 0 0 2 1 H; bt1 0 1; bt2 1 1
  1851. X *   TableExample*title.label: Title Bar
  1852. X *   TableExample*bt1.label: Button One
  1853. X *   TableExample*bt2.label: Button Two
  1854. X */
  1855. X
  1856. X#include <X11/StringDefs.h>
  1857. X#include <X11/Intrinsic.h>
  1858. X#include <X11/Shell.h>
  1859. X#include <X11/Label.h>
  1860. X#include <X11/Command.h>
  1861. X
  1862. X#include "Table.h"
  1863. X
  1864. X#define MAX_ARGS    10
  1865. X#define APP_NAME    "TableExample"
  1866. X
  1867. Xmain(argc, argv)
  1868. Xint argc;
  1869. Xchar *argv[];
  1870. X{
  1871. X    Widget initialize(), top, table, title, bt1, bt2;
  1872. X    Arg arg_list[MAX_ARGS];
  1873. X    int arg_len;
  1874. X
  1875. X    top = initialize(&argc, argv);
  1876. X    arg_len = 0;
  1877. X    table = XtCreateManagedWidget("table", tableWidgetClass,
  1878. X                  top, arg_list, arg_len);
  1879. X    title = XtCreateManagedWidget("title", labelWidgetClass,
  1880. X                  table, arg_list, arg_len);
  1881. X    bt1 = XtCreateManagedWidget("bt1", commandWidgetClass,
  1882. X                table, arg_list, arg_len);
  1883. X    bt2 = XtCreateManagedWidget("bt2", commandWidgetClass,
  1884. X                table, arg_list, arg_len);
  1885. X    XtRealizeWidget(top);
  1886. X    XtMainLoop();
  1887. X}
  1888. X
  1889. XWidget initialize(argc_p, argv)
  1890. Xint *argc_p;
  1891. Xchar *argv[];
  1892. X{
  1893. X    Widget top;
  1894. X    Display *disp;
  1895. X    Arg arg_list[MAX_ARGS];
  1896. X    int arg_len;
  1897. X
  1898. X    XtToolkitInitialize();
  1899. X    disp = XtOpenDisplay((XtAppContext) 0, "", argv[0], APP_NAME,
  1900. X             (XrmOptionDescRec *) 0, 0, argc_p, argv);
  1901. X    arg_len = 0;
  1902. X    XtSetArg(arg_list[arg_len], XtNallowShellResize, True); arg_len++;
  1903. X    top = XtAppCreateShell(argv[0], APP_NAME, applicationShellWidgetClass,
  1904. X               disp, arg_list, arg_len);
  1905. X    return top;
  1906. X}
  1907. X
  1908. X/*
  1909. X * Table Widget Example - Direct specification
  1910. X *
  1911. X * This program creates one button for each string on the command
  1912. X * line.  Try "ex2 *" to see all the files in the directory.
  1913. X */
  1914. X
  1915. X#include <X11/StringDefs.h>
  1916. X#include <X11/Intrinsic.h>
  1917. X#include <X11/Shell.h>
  1918. X#include <X11/Label.h>
  1919. X#include <X11/Command.h>
  1920. X
  1921. X#include "Table.h"
  1922. X
  1923. X#define MAX_ARGS    10
  1924. X#define APP_NAME    "TableExample"
  1925. X#define NUM_ROWS    3
  1926. X
  1927. Xmain(argc, argv)
  1928. Xint argc;
  1929. Xchar *argv[];
  1930. X{
  1931. X    Widget initialize(), top, table, title, button;
  1932. X    Arg arg_list[MAX_ARGS];
  1933. X    int arg_len, i, cols;
  1934. X
  1935. X    top = initialize(&argc, argv);
  1936. X    arg_len = 0;
  1937. X    table = XtCreateManagedWidget("table", tableWidgetClass,
  1938. X                  top, arg_list, arg_len);
  1939. X    XtSetArg(arg_list[arg_len], XtNlabel, "Title Bar");  arg_len++;
  1940. X    title = XtCreateManagedWidget("title", labelWidgetClass,
  1941. X                  table, arg_list, arg_len);
  1942. X    /* Each column will have three rows */
  1943. X    cols = (argc-1)/NUM_ROWS + 1;
  1944. X    XtTblConfig(title, 0, 0, cols, 1, TBL_SM_HEIGHT);
  1945. X    for (i = 1;  i < argc;  i++) {
  1946. X    arg_len = 0;
  1947. X    XtSetArg(arg_list[arg_len], XtNlabel, argv[i]);  arg_len++;
  1948. X    button = XtCreateManagedWidget("button", commandWidgetClass,
  1949. X                       table, arg_list, arg_len);
  1950. X    if (i < argc-1) {
  1951. X        XtTblPosition(button, (i-1)/NUM_ROWS, (i-1)%NUM_ROWS + 1);
  1952. X    } else {
  1953. X        /* Last one spans to bottom */
  1954. X        XtTblConfig(button, (i-1)/NUM_ROWS, (i-1)%NUM_ROWS + 1,
  1955. X            1, 3 - ((i-1)%NUM_ROWS), TBL_DEF_OPT);
  1956. X    }
  1957. X    }
  1958. X    XtRealizeWidget(top);
  1959. X    XtMainLoop();
  1960. X}
  1961. X
  1962. XWidget initialize(argc_p, argv)
  1963. Xint *argc_p;
  1964. Xchar *argv[];
  1965. X{
  1966. X    Widget top;
  1967. X    Display *disp;
  1968. X    Arg arg_list[MAX_ARGS];
  1969. X    int arg_len;
  1970. X
  1971. X    XtToolkitInitialize();
  1972. X    disp = XtOpenDisplay((XtAppContext) 0, "", argv[0], APP_NAME,
  1973. X             (XrmOptionDescRec *) 0, 0, argc_p, argv);
  1974. X    arg_len = 0;
  1975. X    XtSetArg(arg_list[arg_len], XtNallowShellResize, True); arg_len++;
  1976. X    top = XtAppCreateShell(argv[0], APP_NAME, applicationShellWidgetClass,
  1977. X               disp, arg_list, arg_len);
  1978. X    return top;
  1979. X}
  1980. +FUNKY+STUFF+
  1981. echo '-rw-r--r--  1 david       14285 Jun 28 09:13 Table.doc    (as sent)'
  1982. chmod u=rw,g=r,o=r Table.doc
  1983. ls -l Table.doc
  1984. echo x - Table.h
  1985. sed 's/^X//' > Table.h <<'+FUNKY+STUFF+'
  1986. X/*
  1987. X * Table - Forms-based composite widget/geometry manager for the X Toolkit
  1988. X *
  1989. X * David Harrison
  1990. X * University of California, Berkeley
  1991. X * 1989
  1992. X *
  1993. X * This file contains the Table public declarations.
  1994. X */
  1995. X#ifndef _Table_h
  1996. X#define _Table_h
  1997. X
  1998. X/*
  1999. X * Table Widget Parameters
  2000. X *
  2001. X * Name            Class        RepType        Default Value
  2002. X *
  2003. X * background        Background    Pixel        XtDefaultBackground
  2004. X * border        BorderColor    Pixel        XtDefaultForeground
  2005. X * borderWidth        BorderWidth    Dimension    0
  2006. X * x            Position    Position    0
  2007. X * y            Position    Position    0
  2008. X * width        Width        Dimension    (computed)
  2009. X * height        Height        Dimension    (computed)
  2010. X * mappedWhenManaged    MappedWhenManaged Boolean    True
  2011. X * sensitive        Sensitive    Boolean        True
  2012. X * layout        Layout        String        NULL
  2013. X * internalHeight    Height        Dimension    0
  2014. X * internalWidth    Width        Dimension    0
  2015. X * columnSpacing    Spacing        Dimension    0
  2016. X * rowSpacing        Spacing        Dimension    0
  2017. X */
  2018. X
  2019. X#define XtNlayout        "layout"
  2020. X#define XtNcolumnSpacing        "columnSpacing"
  2021. X#define XtNrowSpacing           "rowSpacing"
  2022. X#define XtNdefaultOptions    "defaultOptions"
  2023. X
  2024. X#define XtCLayout        "Layout"
  2025. X#ifndef XtCSpacing
  2026. X#define XtCSpacing        "Spacing"
  2027. X#endif
  2028. X#define XtCOptions        "Options"
  2029. X
  2030. X#define XtROptions        "Options"
  2031. X
  2032. X/*
  2033. X * Option masks
  2034. X */
  2035. X#define TBL_LEFT    (1<<0)
  2036. X#define TBL_RIGHT    (1<<1)
  2037. X#define TBL_TOP        (1<<2)
  2038. X#define TBL_BOTTOM    (1<<3)
  2039. X#define TBL_SM_WIDTH    (1<<4)
  2040. X#define TBL_SM_HEIGHT    (1<<5)    
  2041. X#define TBL_LK_WIDTH    (1<<6)
  2042. X#define TBL_LK_HEIGHT    (1<<7)
  2043. X
  2044. X#define TBL_DEF_OPT    -1
  2045. X
  2046. Xtypedef int XtTblMask;
  2047. X
  2048. X/*
  2049. X * Opaque class and instance records
  2050. X */
  2051. X
  2052. Xtypedef struct _TableClassRec    *TableWidgetClass;
  2053. Xtypedef struct _TableRec    *TableWidget;
  2054. X
  2055. Xextern WidgetClass tableWidgetClass;
  2056. X
  2057. X/*
  2058. X * Public access routines
  2059. X */
  2060. X
  2061. Xextern caddr_t XtTblParseLayout();
  2062. X  /* String layout; */
  2063. X
  2064. Xextern void XtTblPosition();
  2065. X  /* 
  2066. X   * Widget w;
  2067. X   * Position col, row;
  2068. X   */
  2069. X
  2070. Xextern void XtTblResize();
  2071. X  /*
  2072. X   * Widget w;
  2073. X   * Dimension h_span, v_span;
  2074. X   */
  2075. X
  2076. Xextern void XtTblOptions();
  2077. X  /*
  2078. X   * Widget w;
  2079. X   * XtTblMask opt;
  2080. X   */
  2081. X
  2082. Xextern void XtTblConfig();
  2083. X  /* 
  2084. X   * Widget w;
  2085. X   * Position col, row;
  2086. X   * Dimension h_span, v_span;
  2087. X   * XtTblMask opt;
  2088. X   */
  2089. X#endif /* _Table_h */
  2090. X
  2091. +FUNKY+STUFF+
  2092. echo '-rw-r--r--  1 david        2125 Jun 28 09:13 Table.h    (as sent)'
  2093. chmod u=rw,g=r,o=r Table.h
  2094. ls -l Table.h
  2095. echo x - TableP.h
  2096. sed 's/^X//' > TableP.h <<'+FUNKY+STUFF+'
  2097. X/*
  2098. X * Table - Forms-based composite widget/geometry manager for the X Toolkit
  2099. X *
  2100. X * David Harrison
  2101. X * University of California, Berkeley
  2102. X * 1989
  2103. X *
  2104. X * This file contains the Table private declarations.
  2105. X */
  2106. X
  2107. X#ifndef _TableP_h
  2108. X#define _TableP_h
  2109. X
  2110. X#include "Table.h"
  2111. X
  2112. X/*
  2113. X * Local definitions
  2114. X */
  2115. X
  2116. Xtypedef void (*XtTblRProc)();
  2117. X  /*
  2118. X   * Widget table;
  2119. X   * Widget subwidget;
  2120. X   * Position r, c;
  2121. X   * Dimension hspan, vspan;
  2122. X   * XtTblMask options;
  2123. X   */
  2124. X
  2125. Xtypedef Boolean (*XtTblLProc)();
  2126. X   /*
  2127. X    * Widget w;
  2128. X    * Position *r, *c;
  2129. X    * Dimension *hspan, *vspan;
  2130. X    * XtTblMask *options;
  2131. X    */
  2132. X
  2133. Xtypedef struct _TableLocTbl *TableLocTblPtr;
  2134. X   /*
  2135. X    * Opaque reference to actual widget location table
  2136. X    * defined in Table.c
  2137. X    */
  2138. X
  2139. Xtypedef struct _TableDefLoc *TableDefLocPtr;
  2140. X   /*
  2141. X    * Opaque reference to default widget location table defined
  2142. X    * in Table.c.
  2143. X    */    
  2144. X
  2145. Xtypedef struct _TableVector *TableVecPtr;
  2146. X   /*
  2147. X    * Opaque reference to vectors used for giving size of
  2148. X    * each row and column.
  2149. X    */
  2150. X
  2151. Xtypedef enum _TableVecState { INVALID, MINIMUM } TableVecState;
  2152. X
  2153. X/*
  2154. X * Information kept in class record
  2155. X */
  2156. X
  2157. Xtypedef struct {
  2158. X    XtTblRProc position_child;    /* Register location of some child widget  */
  2159. X    XtTblLProc find_child;    /* Return information about a child widget */
  2160. X} TableClassPart;
  2161. X
  2162. X/*
  2163. X * Class hierarchy
  2164. X */
  2165. X
  2166. Xtypedef struct _TableClassRec {
  2167. X    CoreClassPart    core_class;
  2168. X    CompositeClassPart    composite_class;
  2169. X    TableClassPart    table_class;
  2170. X} TableClassRec;
  2171. X
  2172. Xextern TableClassRec tableClassRec;
  2173. X
  2174. X/*
  2175. X * Information in instance record
  2176. X */
  2177. X
  2178. Xtypedef struct _TablePart {
  2179. X    Dimension        int_width;   /* Inner horizontal padding          */
  2180. X    Dimension        int_height;  /* Inner vertical padding            */
  2181. X    Dimension        row_spacing; /* Space between rows                */
  2182. X    Dimension        col_spacing; /* Space between columns             */
  2183. X    XtTblMask        def_options; /* Default layout options            */
  2184. X    TableDefLocPtr    init_layout; /* Initial layout spec from resource */
  2185. X    TableDefLocPtr    layout_db;   /* Merged table                      */
  2186. X    TableLocTblPtr    real_layout; /* Actual current layout information */
  2187. X    TableVecState    vec_state;   /* Current state of vectors          */
  2188. X    Cardinal        num_rows;    /* Number of rows                    */
  2189. X    TableVecPtr        rows;         /* Heights of each row               */
  2190. X    Cardinal        num_cols;    /* Number of columns                 */
  2191. X    TableVecPtr        cols;         /* Widths of each column             */
  2192. X    Cardinal        vec_height;  /* Sum of current rows               */
  2193. X    Cardinal        vec_width;   /* Sum of current columns            */
  2194. X} TablePart;
  2195. X
  2196. X/*
  2197. X * Instance hierarchy
  2198. X */
  2199. X
  2200. Xtypedef struct _TableRec {
  2201. X    CorePart        core;
  2202. X    CompositePart    composite;
  2203. X    TablePart        table;
  2204. X} TableRec;
  2205. X
  2206. X#endif /* _TableP_h */
  2207. +FUNKY+STUFF+
  2208. echo '-rw-r--r--  1 david        2809 Jun 28 09:13 TableP.h    (as sent)'
  2209. chmod u=rw,g=r,o=r TableP.h
  2210. ls -l TableP.h
  2211. echo x - TableREADME.ANNOUNCE
  2212. sed 's/^X//' > TableREADME.ANNOUNCE <<'+FUNKY+STUFF+'
  2213. X
  2214. XRecently, some notes were posted to this newsgroup about the lack of
  2215. Xalternate geometry managers for the Athena Widget set.  I have written
  2216. Xa row/column based geometry management widget that I have used
  2217. Xextensively in my toolkit applications.  A short description is given
  2218. Xbelow:
  2219. X
  2220. XTable - Geometry Management Widget for the X Toolkit
  2221. X
  2222. XTable is a composite widget designed to manage the size and location
  2223. Xof its children.  The widget uses an array model to simplify the
  2224. Xarrangement of child widgets.  Widgets are placed at row and column
  2225. Xlocations in a variable sized array.  Widgets may span more than one
  2226. Xrow or column.  The array automatically expands or contracts as
  2227. Xneeded.  There are options to control justification and place size
  2228. Xrestrictions on rows or columns in the array.  The widget is directly
  2229. Xderived from the core and composite widgets provided by the X Toolkit
  2230. Xand can be used with any widget set.  It has been tested using the
  2231. XAthena widget set.
  2232. X
  2233. XSource for the Table widget is available through anonymous ftp to
  2234. Xshambhala.Berkeley.EDU (128.32.132.54).  Instructions are given below:
  2235. X
  2236. X    % ftp shambhala.Berkeley.EDU
  2237. X    Name: anonymous
  2238. X    Password: <anything non-null>
  2239. X    ftp> cd pub
  2240. X    ftp> binary
  2241. X    ftp> get Table.tar.Z
  2242. X    ftp> quit
  2243. X    % uncompress Table.tar.Z
  2244. X    % tar xf Table.tar
  2245. X
  2246. XThose without ftp access can obtain the source for the Table widget
  2247. Xusing a mail archive system I have installed on dent.Berkeley.EDU
  2248. X(courtesy of Brian Reid at Digital).  An example is given below:
  2249. X
  2250. X    To: ucbvax!dent!archive-server
  2251. X    Subject: send programs Table.shar.01 Table.shar.02
  2252. X
  2253. XThe archive server will send you these files as time and load
  2254. Xpermits.  They are standard shell archives that can be unpacked
  2255. Xby running them through /bin/sh (in order).  If you would like
  2256. Xto know more about the mail server, send a message with a subject
  2257. Xof "help".
  2258. X
  2259. XAfter unpacking the files, you will find a README file in the directory
  2260. Xthat contains installation instructions.
  2261. X
  2262. X            David Harrison
  2263. X            UC Berkeley Electronics Research Lab
  2264. X            (davidh@ic.Berkeley.EDU, ...!ucbvax!ucbcad!davidh)
  2265. X
  2266. X
  2267. X
  2268. +FUNKY+STUFF+
  2269. echo '-rw-r--r--  1 david        2068 Jun 28 09:13 TableREADME.ANNOUNCE    (as sent)'
  2270. chmod u=rw,g=r,o=r TableREADME.ANNOUNCE
  2271. ls -l TableREADME.ANNOUNCE
  2272. echo x - TableREADME.FIRST
  2273. sed 's/^X//' > TableREADME.FIRST <<'+FUNKY+STUFF+'
  2274. X
  2275. XTable - Geometry Management Widget for the X Toolkit
  2276. X
  2277. XTable is a composite widget designed to manage the size and location
  2278. Xof its children.  The widget uses an array model to simplify the
  2279. Xarrangement of child widgets.  The widget is directly derived from the
  2280. Xcore and composite widgets provided by the X Toolkit and can be used
  2281. Xwith any widget set.  It has been tested using the Athena widget set.
  2282. X
  2283. XInstallation instructions are found in the file INSTALL.  Programming 
  2284. Xdocumentation can be found in Table.doc.  Two example programs
  2285. Xare provided: ex1, and ex2.  These can all be made using the
  2286. Xprovided Makefile.  Comments and suggestions should be sent the
  2287. Xaddress below:
  2288. X
  2289. X            David Harrison
  2290. X            UC Berkeley Electronics Research Lab
  2291. X            (davidh@ic.Berkeley.EDU, ...!ucbvax!ucbcad!davidh)
  2292. X
  2293. +FUNKY+STUFF+
  2294. echo '-rw-r--r--  1 david         788 Jun 28 09:13 TableREADME.FIRST    (as sent)'
  2295. chmod u=rw,g=r,o=r TableREADME.FIRST
  2296. ls -l TableREADME.FIRST
  2297. echo x - TableREADME.INSTALL
  2298. sed 's/^X//' > TableREADME.INSTALL <<'+FUNKY+STUFF+'
  2299. X
  2300. XThis file contains instructions for building the Table widget.
  2301. XIf you have X11R4 libraries installed on your machine, you should
  2302. Xbe able to type "make" and libTable.a will be built for you.  If
  2303. Xyou are running an earlier version of X11, use the old Makefile
  2304. Xby typing "make -f Makefile.old" instead of just make.
  2305. X
  2306. XOnce the library is made, you can make the example programs by
  2307. Xtyping:
  2308. X
  2309. X    % make ex1
  2310. X    % make ex2
  2311. X
  2312. XAgain, if you are using an older version of X, replace make with
  2313. X"make -f Makefile.old".  See the comment at the top of the corresponding 
  2314. X.c files for instructions on how to run these programs.
  2315. X
  2316. X            David Harrison
  2317. X            UC Berkeley Electronics Research Lab
  2318. X            (davidh@ic.Berkeley.EDU, ...!ucbvax!ucbcad!davidh)
  2319. X
  2320. +FUNKY+STUFF+
  2321. echo '-rw-r--r--  1 david         721 Jun 28 09:13 TableREADME.INSTALL    (as sent)'
  2322. chmod u=rw,g=r,o=r TableREADME.INSTALL
  2323. ls -l TableREADME.INSTALL
  2324. exit 0
  2325.  
  2326. dan
  2327. ----------------------------------------------------
  2328. O'Reilly && Associates   argv@sun.com / argv@ora.com
  2329. Opinions expressed reflect those of the author only.
  2330.