summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/g_text.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/g_text.c')
-rw-r--r--apps/plugins/pdbox/PDa/src/g_text.c1317
1 files changed, 0 insertions, 1317 deletions
diff --git a/apps/plugins/pdbox/PDa/src/g_text.c b/apps/plugins/pdbox/PDa/src/g_text.c
index 8cf1fe2834..f1fbb7f719 100644
--- a/apps/plugins/pdbox/PDa/src/g_text.c
+++ b/apps/plugins/pdbox/PDa/src/g_text.c
@@ -1313,1320 +1313,3 @@ void g_text_setup(void)
1313 class_setpropertiesfn(gatom_class, gatom_properties); 1313 class_setpropertiesfn(gatom_class, gatom_properties);
1314} 1314}
1315 1315
1316
1317/* Copyright (c) 1997-1999 Miller Puckette.
1318* For information on usage and redistribution, and for a DISCLAIMER OF ALL
1319* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
1320
1321/* changes by Thomas Musil IEM KUG Graz Austria 2001 */
1322/* the methods for calling the gui-objects from menu are implemented */
1323/* all changes are labeled with iemlib */
1324
1325#include <stdlib.h>
1326#include "m_pd.h"
1327#include "m_imp.h"
1328#include "s_stuff.h"
1329#include "t_tk.h"
1330#include "g_canvas.h"
1331#include <stdio.h>
1332#include <string.h>
1333#include <math.h>
1334
1335static t_class *text_class;
1336static t_class *message_class;
1337static t_class *gatom_class;
1338static void text_vis(t_gobj *z, t_glist *glist, int vis);
1339static void text_displace(t_gobj *z, t_glist *glist,
1340 int dx, int dy);
1341static void text_getrect(t_gobj *z, t_glist *glist,
1342 int *xp1, int *yp1, int *xp2, int *yp2);
1343
1344void canvas_startmotion(t_canvas *x);
1345t_widgetbehavior text_widgetbehavior;
1346
1347/* ----------------- the "text" object. ------------------ */
1348
1349 /* add a "text" object (comment) to a glist. While this one goes for any glist,
1350 the other 3 below are for canvases only. (why?) This is called
1351 without args if invoked from the GUI; otherwise at least x and y
1352 are provided. */
1353
1354void glist_text(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
1355{
1356 t_text *x = (t_text *)pd_new(text_class);
1357 t_atom at;
1358 x->te_width = 0; /* don't know it yet. */
1359 x->te_type = T_TEXT;
1360 x->te_binbuf = binbuf_new();
1361 if (argc > 1)
1362 {
1363 x->te_xpix = atom_getfloatarg(0, argc, argv);
1364 x->te_ypix = atom_getfloatarg(1, argc, argv);
1365 if (argc > 2) binbuf_restore(x->te_binbuf, argc-2, argv+2);
1366 else
1367 {
1368 SETSYMBOL(&at, gensym("comment"));
1369 binbuf_restore(x->te_binbuf, 1, &at);
1370 }
1371 glist_add(gl, &x->te_g);
1372 }
1373 else
1374 {
1375 int xpix, ypix;
1376 pd_vmess((t_pd *)glist_getcanvas(gl), gensym("editmode"), "i", 1);
1377 SETSYMBOL(&at, gensym("comment"));
1378 glist_noselect(gl);
1379 glist_getnextxy(gl, &xpix, &ypix);
1380 x->te_xpix = glist_pixelstox(gl, xpix-3);
1381 x->te_ypix = glist_pixelstoy(gl, ypix-3);
1382 binbuf_restore(x->te_binbuf, 1, &at);
1383 glist_add(gl, &x->te_g);
1384 glist_noselect(gl);
1385 glist_select(gl, &x->te_g);
1386 /* it would be nice to "activate" here, but then the second,
1387 "put-me-down" click changes the text selection, which is quite
1388 irritating, so I took this back out. It's OK in messages
1389 and objects though since there's no text in them at menu
1390 creation. */
1391 /* gobj_activate(&x->te_g, gl, 1); */
1392 canvas_startmotion(glist_getcanvas(gl));
1393 }
1394}
1395
1396/* ----------------- the "object" object. ------------------ */
1397
1398extern t_pd *newest;
1399void canvas_getargs(int *argcp, t_atom **argvp);
1400
1401static void canvas_objtext(t_glist *gl, int xpix, int ypix, int selected,
1402 t_binbuf *b)
1403{
1404 t_text *x;
1405 int argc;
1406 t_atom *argv;
1407 newest = 0;
1408 canvas_setcurrent((t_canvas *)gl);
1409 canvas_getargs(&argc, &argv);
1410 binbuf_eval(b, &pd_objectmaker, argc, argv);
1411 if (binbuf_getnatom(b))
1412 {
1413 if (!newest)
1414 {
1415 binbuf_print(b);
1416 post("... couldn't create");
1417 x = 0;
1418 }
1419 else if (!(x = pd_checkobject(newest)))
1420 {
1421 binbuf_print(b);
1422 post("... didn't return a patchable object");
1423 }
1424 }
1425 else x = 0;
1426 if (!x)
1427 {
1428
1429 /* LATER make the color reflect this */
1430 x = (t_text *)pd_new(text_class);
1431 }
1432 x->te_binbuf = b;
1433 x->te_xpix = xpix;
1434 x->te_ypix = ypix;
1435 x->te_width = 0;
1436 x->te_type = T_OBJECT;
1437 glist_add(gl, &x->te_g);
1438 if (selected)
1439 {
1440 /* this is called if we've been created from the menu. */
1441 glist_select(gl, &x->te_g);
1442 gobj_activate(&x->te_g, gl, 1);
1443 }
1444 if (pd_class(&x->ob_pd) == vinlet_class)
1445 canvas_resortinlets(glist_getcanvas(gl));
1446 if (pd_class(&x->ob_pd) == voutlet_class)
1447 canvas_resortoutlets(glist_getcanvas(gl));
1448 canvas_unsetcurrent((t_canvas *)gl);
1449}
1450
1451 /* object creation routine. These are called without any arguments if
1452 they're invoked from the
1453 gui; when pasting or restoring from a file, we get at least x and y. */
1454
1455void canvas_obj(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
1456{
1457 t_text *x;
1458 if (argc >= 2)
1459 {
1460 t_binbuf *b = binbuf_new();
1461 binbuf_restore(b, argc-2, argv+2);
1462 canvas_objtext(gl, atom_getintarg(0, argc, argv),
1463 atom_getintarg(1, argc, argv), 0, b);
1464 }
1465 else
1466 {
1467 t_binbuf *b = binbuf_new();
1468 int xpix, ypix;
1469 pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1);
1470 glist_noselect(gl);
1471 glist_getnextxy(gl, &xpix, &ypix);
1472 canvas_objtext(gl, xpix, ypix, 1, b);
1473 canvas_startmotion(glist_getcanvas(gl));
1474 }
1475}
1476
1477/* make an object box for an object that's already there. */
1478
1479/* iemlib */
1480void canvas_iemguis(t_glist *gl, t_symbol *guiobjname)
1481{
1482 t_atom at;
1483 t_binbuf *b = binbuf_new();
1484 int xpix, ypix;
1485
1486 pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1);
1487 glist_noselect(gl);
1488 SETSYMBOL(&at, guiobjname);
1489 binbuf_restore(b, 1, &at);
1490 glist_getnextxy(gl, &xpix, &ypix);
1491 canvas_objtext(gl, xpix, ypix, 1, b);
1492 canvas_startmotion(glist_getcanvas(gl));
1493}
1494
1495void canvas_bng(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
1496{
1497 canvas_iemguis(gl, gensym("bng"));
1498}
1499
1500void canvas_toggle(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
1501{
1502 canvas_iemguis(gl, gensym("tgl"));
1503}
1504
1505void canvas_vslider(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
1506{
1507 canvas_iemguis(gl, gensym("vsl"));
1508}
1509
1510void canvas_hslider(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
1511{
1512 canvas_iemguis(gl, gensym("hsl"));
1513}
1514
1515void canvas_hdial(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
1516{
1517 canvas_iemguis(gl, gensym("hdl"));
1518}
1519
1520void canvas_vdial(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
1521{
1522 canvas_iemguis(gl, gensym("vdl"));
1523}
1524
1525void canvas_hradio(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
1526{
1527 canvas_iemguis(gl, gensym("hradio"));
1528}
1529
1530void canvas_vradio(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
1531{
1532 canvas_iemguis(gl, gensym("vradio"));
1533}
1534
1535void canvas_vumeter(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
1536{
1537 canvas_iemguis(gl, gensym("vu"));
1538}
1539
1540void canvas_mycnv(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
1541{
1542 canvas_iemguis(gl, gensym("cnv"));
1543}
1544
1545void canvas_numbox(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
1546{
1547 canvas_iemguis(gl, gensym("nbx"));
1548}
1549
1550/* iemlib */
1551
1552void canvas_objfor(t_glist *gl, t_text *x, int argc, t_atom *argv)
1553{
1554 x->te_width = 0; /* don't know it yet. */
1555 x->te_type = T_OBJECT;
1556 x->te_binbuf = binbuf_new();
1557 x->te_xpix = atom_getfloatarg(0, argc, argv);
1558 x->te_ypix = atom_getfloatarg(1, argc, argv);
1559 if (argc > 2) binbuf_restore(x->te_binbuf, argc-2, argv+2);
1560 glist_add(gl, &x->te_g);
1561}
1562
1563/* ---------------------- the "message" text item ------------------------ */
1564
1565typedef struct _messresponder
1566{
1567 t_pd mr_pd;
1568 t_outlet *mr_outlet;
1569} t_messresponder;
1570
1571typedef struct _message
1572{
1573 t_text m_text;
1574 t_messresponder m_messresponder;
1575 t_glist *m_glist;
1576 t_clock *m_clock;
1577} t_message;
1578
1579static t_class *message_class, *messresponder_class;
1580
1581static void messresponder_bang(t_messresponder *x)
1582{
1583 outlet_bang(x->mr_outlet);
1584}
1585
1586static void messresponder_float(t_messresponder *x, t_float f)
1587{
1588 outlet_float(x->mr_outlet, f);
1589}
1590
1591static void messresponder_symbol(t_messresponder *x, t_symbol *s)
1592{
1593 outlet_symbol(x->mr_outlet, s);
1594}
1595
1596static void messresponder_list(t_messresponder *x,
1597 t_symbol *s, int argc, t_atom *argv)
1598{
1599 outlet_list(x->mr_outlet, s, argc, argv);
1600}
1601
1602static void messresponder_anything(t_messresponder *x,
1603 t_symbol *s, int argc, t_atom *argv)
1604{
1605 outlet_anything(x->mr_outlet, s, argc, argv);
1606}
1607
1608static void message_bang(t_message *x)
1609{
1610 binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 0, 0);
1611}
1612
1613static void message_float(t_message *x, t_float f)
1614{
1615 t_atom at;
1616 SETFLOAT(&at, f);
1617 binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 1, &at);
1618}
1619
1620static void message_symbol(t_message *x, t_symbol *s)
1621{
1622 t_atom at;
1623 SETSYMBOL(&at, s);
1624 binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 1, &at);
1625}
1626
1627static void message_list(t_message *x, t_symbol *s, int argc, t_atom *argv)
1628{
1629 binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, argc, argv);
1630}
1631
1632static void message_set(t_message *x, t_symbol *s, int argc, t_atom *argv)
1633{
1634 binbuf_clear(x->m_text.te_binbuf);
1635 binbuf_add(x->m_text.te_binbuf, argc, argv);
1636 glist_retext(x->m_glist, &x->m_text);
1637}
1638
1639static void message_add2(t_message *x, t_symbol *s, int argc, t_atom *argv)
1640{
1641 binbuf_add(x->m_text.te_binbuf, argc, argv);
1642 glist_retext(x->m_glist, &x->m_text);
1643}
1644
1645static void message_add(t_message *x, t_symbol *s, int argc, t_atom *argv)
1646{
1647 binbuf_add(x->m_text.te_binbuf, argc, argv);
1648 binbuf_addsemi(x->m_text.te_binbuf);
1649 glist_retext(x->m_glist, &x->m_text);
1650}
1651
1652static void message_click(t_message *x,
1653 t_floatarg xpos, t_floatarg ypos, t_floatarg shift,
1654 t_floatarg ctrl, t_floatarg alt)
1655{
1656 message_float(x, 0);
1657 if (glist_isvisible(x->m_glist))
1658 {
1659 t_rtext *y = glist_findrtext(x->m_glist, &x->m_text);
1660 sys_vgui(".x%x.c itemconfigure %sR -width 5\n",
1661 glist_getcanvas(x->m_glist), rtext_gettag(y));
1662 clock_delay(x->m_clock, 120);
1663 }
1664}
1665
1666static void message_tick(t_message *x)
1667{
1668 if (glist_isvisible(x->m_glist))
1669 {
1670 t_rtext *y = glist_findrtext(x->m_glist, &x->m_text);
1671 sys_vgui(".x%x.c itemconfigure %sR -width 1\n",
1672 glist_getcanvas(x->m_glist), rtext_gettag(y));
1673 }
1674}
1675
1676static void message_free(t_message *x)
1677{
1678 clock_free(x->m_clock);
1679}
1680
1681void canvas_msg(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
1682{
1683 t_message *x = (t_message *)pd_new(message_class);
1684 x->m_messresponder.mr_pd = messresponder_class;
1685 x->m_messresponder.mr_outlet = outlet_new(&x->m_text, &s_float);
1686 x->m_text.te_width = 0; /* don't know it yet. */
1687 x->m_text.te_type = T_MESSAGE;
1688 x->m_text.te_binbuf = binbuf_new();
1689 x->m_glist = gl;
1690 x->m_clock = clock_new(x, (t_method)message_tick);
1691 if (argc > 1)
1692 {
1693 x->m_text.te_xpix = atom_getfloatarg(0, argc, argv);
1694 x->m_text.te_ypix = atom_getfloatarg(1, argc, argv);
1695 if (argc > 2) binbuf_restore(x->m_text.te_binbuf, argc-2, argv+2);
1696 glist_add(gl, &x->m_text.te_g);
1697 }
1698 else
1699 {
1700 int xpix, ypix;
1701 pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1);
1702 glist_noselect(gl);
1703 glist_getnextxy(gl, &xpix, &ypix);
1704 x->m_text.te_xpix = xpix-3;
1705 x->m_text.te_ypix = ypix-3;
1706 glist_add(gl, &x->m_text.te_g);
1707 glist_noselect(gl);
1708 glist_select(gl, &x->m_text.te_g);
1709 gobj_activate(&x->m_text.te_g, gl, 1);
1710 canvas_startmotion(glist_getcanvas(gl));
1711 }
1712}
1713
1714/* ---------------------- the "atom" text item ------------------------ */
1715
1716#define ATOMBUFSIZE 40
1717#define ATOM_LABELLEFT 0
1718#define ATOM_LABELRIGHT 1
1719#define ATOM_LABELUP 2
1720#define ATOM_LABELDOWN 3
1721
1722typedef struct _gatom
1723{
1724 t_text a_text;
1725 t_atom a_atom; /* this holds the value and the type */
1726 t_glist *a_glist; /* owning glist */
1727 t_float a_toggle; /* value to toggle to */
1728 t_float a_draghi; /* high end of drag range */
1729 t_float a_draglo; /* low end of drag range */
1730 t_symbol *a_label; /* symbol to show as label next to box */
1731 t_symbol *a_symfrom; /* "receive" name -- bind ourselvs to this */
1732 t_symbol *a_symto; /* "send" name -- send to this on output */
1733 char a_buf[ATOMBUFSIZE];/* string buffer for typing */
1734 char a_shift; /* was shift key down when dragging started? */
1735 char a_wherelabel; /* 0-3 for left, right, above, below */
1736 t_symbol *a_expanded_to; /* a_symto after $0, $1, ... expansion */
1737} t_gatom;
1738
1739 /* prepend "-" as necessary to avoid empty strings, so we can
1740 use them in Pd messages. A more complete solution would be
1741 to introduce some quoting mechanism; but then we'd be much more
1742 complicated. */
1743static t_symbol *gatom_escapit(t_symbol *s)
1744{
1745 if (!*s->s_name)
1746 return (gensym("-"));
1747 else if (*s->s_name == '-')
1748 {
1749 char shmo[100];
1750 shmo[0] = '-';
1751 strncpy(shmo+1, s->s_name, 99);
1752 shmo[99] = 0;
1753 return (gensym(shmo));
1754 }
1755 else return (iemgui_dollar2raute(s));
1756}
1757
1758 /* undo previous operation: strip leading "-" if found. */
1759static t_symbol *gatom_unescapit(t_symbol *s)
1760{
1761 if (*s->s_name == '-')
1762 return (gensym(s->s_name+1));
1763 else return (iemgui_raute2dollar(s));
1764}
1765
1766#if 0 /* ??? */
1767 /* expand leading $0, $1, etc. in the symbol */
1768static t_symbol *gatom_realizedollar(t_gatom *x, t_symbol *s)
1769{
1770 return (canvas_realizedollar(x->a_glist, s));
1771}
1772#endif
1773
1774static void gatom_retext(t_gatom *x, int senditup)
1775{
1776 binbuf_clear(x->a_text.te_binbuf);
1777 binbuf_add(x->a_text.te_binbuf, 1, &x->a_atom);
1778 if (senditup)
1779 glist_retext(x->a_glist, &x->a_text);
1780}
1781
1782static void gatom_set(t_gatom *x, t_symbol *s, int argc, t_atom *argv)
1783{
1784 t_atom oldatom = x->a_atom;
1785 int senditup = 0;
1786 if (!argc) return;
1787 if (x->a_atom.a_type == A_FLOAT)
1788 x->a_atom.a_w.w_float = atom_getfloat(argv),
1789 senditup = (x->a_atom.a_w.w_float != oldatom.a_w.w_float);
1790 else if (x->a_atom.a_type == A_SYMBOL)
1791 x->a_atom.a_w.w_symbol = atom_getsymbol(argv),
1792 senditup = (x->a_atom.a_w.w_symbol != oldatom.a_w.w_symbol);
1793 gatom_retext(x, senditup);
1794 x->a_buf[0] = 0;
1795}
1796
1797static void gatom_bang(t_gatom *x)
1798{
1799 if (x->a_atom.a_type == A_FLOAT)
1800 {
1801 if (x->a_text.te_outlet)
1802 outlet_float(x->a_text.te_outlet, x->a_atom.a_w.w_float);
1803 if (*x->a_expanded_to->s_name && x->a_expanded_to->s_thing)
1804 {
1805 if (x->a_symto == x->a_symfrom)
1806 pd_error(x,
1807 "%s: atom with same send/receive name (infinite loop)",
1808 x->a_symto->s_name);
1809 else pd_float(x->a_expanded_to->s_thing, x->a_atom.a_w.w_float);
1810 }
1811 }
1812 else if (x->a_atom.a_type == A_SYMBOL)
1813 {
1814 if (x->a_text.te_outlet)
1815 outlet_symbol(x->a_text.te_outlet, x->a_atom.a_w.w_symbol);
1816 if (*x->a_symto->s_name && x->a_expanded_to->s_thing)
1817 {
1818 if (x->a_symto == x->a_symfrom)
1819 pd_error(x,
1820 "%s: atom with same send/receive name (infinite loop)",
1821 x->a_symto->s_name);
1822 else pd_symbol(x->a_expanded_to->s_thing, x->a_atom.a_w.w_symbol);
1823 }
1824 }
1825}
1826
1827static void gatom_float(t_gatom *x, t_float f)
1828{
1829 t_atom at;
1830 SETFLOAT(&at, f);
1831 gatom_set(x, 0, 1, &at);
1832 gatom_bang(x);
1833}
1834
1835static void gatom_clipfloat(t_gatom *x, t_float f)
1836{
1837 if (x->a_draglo != 0 || x->a_draghi != 0)
1838 {
1839 if (f < x->a_draglo)
1840 f = x->a_draglo;
1841 if (f > x->a_draghi)
1842 f = x->a_draghi;
1843 }
1844 gatom_float(x, f);
1845}
1846
1847static void gatom_symbol(t_gatom *x, t_symbol *s)
1848{
1849 t_atom at;
1850 SETSYMBOL(&at, s);
1851 gatom_set(x, 0, 1, &at);
1852 gatom_bang(x);
1853}
1854
1855static void gatom_motion(void *z, t_floatarg dx, t_floatarg dy)
1856{
1857 t_gatom *x = (t_gatom *)z;
1858 if (dy == 0) return;
1859 if (x->a_atom.a_type == A_FLOAT)
1860 {
1861 if (x->a_shift)
1862 {
1863 double nval = x->a_atom.a_w.w_float - 0.01 * dy;
1864 double trunc = 0.01 * (floor(100. * nval + 0.5));
1865 if (trunc < nval + 0.0001 && trunc > nval - 0.0001) nval = trunc;
1866 gatom_clipfloat(x, nval);
1867 }
1868 else
1869 {
1870 double nval = x->a_atom.a_w.w_float - dy;
1871 double trunc = 0.01 * (floor(100. * nval + 0.5));
1872 if (trunc < nval + 0.0001 && trunc > nval - 0.0001) nval = trunc;
1873 trunc = floor(nval + 0.5);
1874 if (trunc < nval + 0.001 && trunc > nval - 0.001) nval = trunc;
1875 gatom_clipfloat(x, nval);
1876 }
1877 }
1878}
1879
1880static void gatom_key(void *z, t_floatarg f)
1881{
1882 t_gatom *x = (t_gatom *)z;
1883 int c = f;
1884 int len = strlen(x->a_buf);
1885 t_atom at;
1886 char sbuf[ATOMBUFSIZE + 4];
1887 if (c == 0)
1888 {
1889 /* we're being notified that no more keys will come for this grab */
1890 if (x->a_buf[0])
1891 gatom_retext(x, 1);
1892 return;
1893 }
1894 else if (c == ' ') return;
1895 else if (c == '\b')
1896 {
1897 if (len > 0)
1898 x->a_buf[len-1] = 0;
1899 goto redraw;
1900 }
1901 else if (c == '\n')
1902 {
1903 if (x->a_atom.a_type == A_FLOAT)
1904 x->a_atom.a_w.w_float = atof(x->a_buf);
1905 else if (x->a_atom.a_type == A_SYMBOL)
1906 x->a_atom.a_w.w_symbol = gensym(x->a_buf);
1907 else bug("gatom_key");
1908 gatom_bang(x);
1909 gatom_retext(x, 1);
1910 x->a_buf[0] = 0;
1911 }
1912 else if (len < (ATOMBUFSIZE-1))
1913 {
1914 /* for numbers, only let reasonable characters through */
1915 if ((x->a_atom.a_type == A_SYMBOL) ||
1916 (c >= '0' && c <= '9' || c == '.' || c == '-'
1917 || c == 'e' || c == 'E'))
1918 {
1919 x->a_buf[len] = c;
1920 x->a_buf[len+1] = 0;
1921 goto redraw;
1922 }
1923 }
1924 return;
1925redraw:
1926 /* LATER figure out how to avoid creating all these symbols! */
1927 sprintf(sbuf, "%s...", x->a_buf);
1928 SETSYMBOL(&at, gensym(sbuf));
1929 binbuf_clear(x->a_text.te_binbuf);
1930 binbuf_add(x->a_text.te_binbuf, 1, &at);
1931 glist_retext(x->a_glist, &x->a_text);
1932}
1933
1934static void gatom_click(t_gatom *x,
1935 t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
1936 t_floatarg alt)
1937{
1938 if (x->a_text.te_width == 1)
1939 {
1940 if (x->a_atom.a_type == A_FLOAT)
1941 gatom_float(x, (x->a_atom.a_w.w_float == 0));
1942 }
1943 else
1944 {
1945 if (alt)
1946 {
1947 if (x->a_atom.a_type != A_FLOAT) return;
1948 if (x->a_atom.a_w.w_float != 0)
1949 {
1950 x->a_toggle = x->a_atom.a_w.w_float;
1951 gatom_float(x, 0);
1952 return;
1953 }
1954 else gatom_float(x, x->a_toggle);
1955 }
1956 x->a_shift = shift;
1957 x->a_buf[0] = 0;
1958 glist_grab(x->a_glist, &x->a_text.te_g, gatom_motion, gatom_key,
1959 xpos, ypos);
1960 }
1961}
1962
1963 /* message back from dialog window */
1964static void gatom_param(t_gatom *x, t_symbol *sel, int argc, t_atom *argv)
1965{
1966 t_float width = atom_getfloatarg(0, argc, argv);
1967 t_float draglo = atom_getfloatarg(1, argc, argv);
1968 t_float draghi = atom_getfloatarg(2, argc, argv);
1969 t_symbol *label = gatom_unescapit(atom_getsymbolarg(3, argc, argv));
1970 t_float wherelabel = atom_getfloatarg(4, argc, argv);
1971 t_symbol *symfrom = gatom_unescapit(atom_getsymbolarg(5, argc, argv));
1972 t_symbol *symto = gatom_unescapit(atom_getsymbolarg(6, argc, argv));
1973
1974 gobj_vis(&x->a_text.te_g, x->a_glist, 0);
1975 if (!*symfrom->s_name && *x->a_symfrom->s_name)
1976 inlet_new(&x->a_text, &x->a_text.te_pd, 0, 0);
1977 else if (*symfrom->s_name && !*x->a_symfrom->s_name && x->a_text.te_inlet)
1978 {
1979 canvas_deletelinesforio(x->a_glist, &x->a_text,
1980 x->a_text.te_inlet, 0);
1981 inlet_free(x->a_text.te_inlet);
1982 }
1983 if (!*symto->s_name && *x->a_symto->s_name)
1984 outlet_new(&x->a_text, 0);
1985 else if (*symto->s_name && !*x->a_symto->s_name && x->a_text.te_outlet)
1986 {
1987 canvas_deletelinesforio(x->a_glist, &x->a_text,
1988 0, x->a_text.te_outlet);
1989 outlet_free(x->a_text.te_outlet);
1990 }
1991 if (draglo >= draghi)
1992 draglo = draghi = 0;
1993 x->a_draglo = draglo;
1994 x->a_draghi = draghi;
1995 if (width < 0)
1996 width = 4;
1997 else if (width > 80)
1998 width = 80;
1999 x->a_text.te_width = width;
2000 x->a_wherelabel = ((int)wherelabel & 3);
2001 x->a_label = label;
2002 if (*x->a_symfrom->s_name)
2003 pd_unbind(&x->a_text.te_pd,
2004 canvas_realizedollar(x->a_glist, x->a_symfrom));
2005 x->a_symfrom = symfrom;
2006 if (*x->a_symfrom->s_name)
2007 pd_bind(&x->a_text.te_pd,
2008 canvas_realizedollar(x->a_glist, x->a_symfrom));
2009 x->a_symto = symto;
2010 x->a_expanded_to = canvas_realizedollar(x->a_glist, x->a_symto);
2011 gobj_vis(&x->a_text.te_g, x->a_glist, 1);
2012
2013 /* glist_retext(x->a_glist, &x->a_text); */
2014}
2015
2016 /* ---------------- gatom-specific widget functions --------------- */
2017static void gatom_getwherelabel(t_gatom *x, t_glist *glist, int *xp, int *yp)
2018{
2019 int x1, y1, x2, y2, width, height;
2020 text_getrect(&x->a_text.te_g, glist, &x1, &y1, &x2, &y2);
2021 width = x2 - x1;
2022 height = y2 - y1;
2023 if (x->a_wherelabel == ATOM_LABELLEFT)
2024 {
2025 *xp = x1 - 3 -
2026 strlen(canvas_realizedollar(x->a_glist, x->a_label)->s_name) *
2027 sys_fontwidth(glist_getfont(glist));
2028 *yp = y1 + 2;
2029 }
2030 else if (x->a_wherelabel == ATOM_LABELRIGHT)
2031 {
2032 *xp = x2 + 2;
2033 *yp = y1 + 2;
2034 }
2035 else if (x->a_wherelabel == ATOM_LABELUP)
2036 {
2037 *xp = x1 - 1;
2038 *yp = y1 - 1 - sys_fontheight(glist_getfont(glist));;
2039 }
2040 else
2041 {
2042 *xp = x1 - 1;
2043 *yp = y2 + 3;
2044 }
2045}
2046
2047static void gatom_displace(t_gobj *z, t_glist *glist,
2048 int dx, int dy)
2049{
2050 t_gatom *x = (t_gatom*)z;
2051 text_displace(z, glist, dx, dy);
2052 sys_vgui(".x%x.c move %x.l %d %d\n", glist_getcanvas(glist),
2053 x, dx, dy);
2054}
2055
2056static void gatom_vis(t_gobj *z, t_glist *glist, int vis)
2057{
2058 t_gatom *x = (t_gatom*)z;
2059 text_vis(z, glist, vis);
2060 if (*x->a_label->s_name)
2061 {
2062 if (vis)
2063 {
2064 int x1, y1;
2065 gatom_getwherelabel(x, glist, &x1, &y1);
2066 sys_vgui("pdtk_text_new .x%x.c %x.l %f %f {%s} %d %s\n",
2067 glist_getcanvas(glist), x,
2068 (double)x1, (double)y1,
2069 canvas_realizedollar(x->a_glist, x->a_label)->s_name,
2070 sys_hostfontsize(glist_getfont(glist)),
2071 "black");
2072 }
2073 else sys_vgui(".x%x.c delete %x.l\n", glist_getcanvas(glist), x);
2074 }
2075}
2076
2077void canvas_atom(t_glist *gl, t_atomtype type,
2078 t_symbol *s, int argc, t_atom *argv)
2079{
2080 t_gatom *x = (t_gatom *)pd_new(gatom_class);
2081 t_atom at;
2082 x->a_text.te_width = 0; /* don't know it yet. */
2083 x->a_text.te_type = T_ATOM;
2084 x->a_text.te_binbuf = binbuf_new();
2085 x->a_glist = gl;
2086 x->a_atom.a_type = type;
2087 x->a_toggle = 1;
2088 x->a_draglo = 0;
2089 x->a_draghi = 0;
2090 x->a_wherelabel = 0;
2091 x->a_label = &s_;
2092 x->a_symfrom = &s_;
2093 x->a_symto = x->a_expanded_to = &s_;
2094 if (type == A_FLOAT)
2095 {
2096 x->a_atom.a_w.w_float = 0;
2097 x->a_text.te_width = 5;
2098 SETFLOAT(&at, 0);
2099 }
2100 else
2101 {
2102 x->a_atom.a_w.w_symbol = &s_symbol;
2103 x->a_text.te_width = 10;
2104 SETSYMBOL(&at, &s_symbol);
2105 }
2106 binbuf_add(x->a_text.te_binbuf, 1, &at);
2107 if (argc > 1)
2108 /* create from file. x, y, width, low-range, high-range, flags,
2109 label, receive-name, send-name */
2110 {
2111 x->a_text.te_xpix = atom_getfloatarg(0, argc, argv);
2112 x->a_text.te_ypix = atom_getfloatarg(1, argc, argv);
2113 x->a_text.te_width = atom_getintarg(2, argc, argv);
2114 /* sanity check because some very old patches have trash in this
2115 field... remove this in 2003 or so: */
2116 if (x->a_text.te_width < 0 || x->a_text.te_width > 500)
2117 x->a_text.te_width = 4;
2118 x->a_draglo = atom_getfloatarg(3, argc, argv);
2119 x->a_draghi = atom_getfloatarg(4, argc, argv);
2120 x->a_wherelabel = (((int)atom_getfloatarg(5, argc, argv)) & 3);
2121 x->a_label = gatom_unescapit(atom_getsymbolarg(6, argc, argv));
2122 x->a_symfrom = gatom_unescapit(atom_getsymbolarg(7, argc, argv));
2123 if (*x->a_symfrom->s_name)
2124 pd_bind(&x->a_text.te_pd,
2125 canvas_realizedollar(x->a_glist, x->a_symfrom));
2126
2127 x->a_symto = gatom_unescapit(atom_getsymbolarg(8, argc, argv));
2128 x->a_expanded_to = canvas_realizedollar(x->a_glist, x->a_symto);
2129 if (x->a_symto == &s_)
2130 outlet_new(&x->a_text,
2131 x->a_atom.a_type == A_FLOAT ? &s_float: &s_symbol);
2132 if (x->a_symfrom == &s_)
2133 inlet_new(&x->a_text, &x->a_text.te_pd, 0, 0);
2134 glist_add(gl, &x->a_text.te_g);
2135 }
2136 else
2137 {
2138 int xpix, ypix;
2139 outlet_new(&x->a_text,
2140 x->a_atom.a_type == A_FLOAT ? &s_float: &s_symbol);
2141 inlet_new(&x->a_text, &x->a_text.te_pd, 0, 0);
2142 pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1);
2143 glist_noselect(gl);
2144 glist_getnextxy(gl, &xpix, &ypix);
2145 x->a_text.te_xpix = xpix;
2146 x->a_text.te_ypix = ypix;
2147 glist_add(gl, &x->a_text.te_g);
2148 glist_noselect(gl);
2149 glist_select(gl, &x->a_text.te_g);
2150 canvas_startmotion(glist_getcanvas(gl));
2151 }
2152}
2153
2154void canvas_floatatom(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
2155{
2156 canvas_atom(gl, A_FLOAT, s, argc, argv);
2157}
2158
2159void canvas_symbolatom(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
2160{
2161 canvas_atom(gl, A_SYMBOL, s, argc, argv);
2162}
2163
2164static void gatom_free(t_gatom *x)
2165{
2166 if (*x->a_symfrom->s_name)
2167 pd_unbind(&x->a_text.te_pd,
2168 canvas_realizedollar(x->a_glist, x->a_symfrom));
2169 gfxstub_deleteforkey(x);
2170}
2171
2172static void gatom_properties(t_gobj *z, t_glist *owner)
2173{
2174 t_gatom *x = (t_gatom *)z;
2175 char buf[200];
2176 sprintf(buf, "pdtk_gatom_dialog %%s %d %g %g %d %s %s %s\n",
2177 x->a_text.te_width, x->a_draglo, x->a_draghi,
2178 x->a_wherelabel, gatom_escapit(x->a_label)->s_name,
2179 gatom_escapit(x->a_symfrom)->s_name,
2180 gatom_escapit(x->a_symto)->s_name);
2181 gfxstub_new(&x->a_text.te_pd, x, buf);
2182}
2183
2184
2185/* -------------------- widget behavior for text objects ------------ */
2186
2187static void text_getrect(t_gobj *z, t_glist *glist,
2188 int *xp1, int *yp1, int *xp2, int *yp2)
2189{
2190 t_text *x = (t_text *)z;
2191 int width, height, iscomment = (x->te_type == T_TEXT);
2192 float x1, y1, x2, y2;
2193
2194 /* for number boxes, we know width and height a priori, and should
2195 report them here so that graphs can get swelled to fit. */
2196
2197 if (x->te_type == T_ATOM && x->te_width > 0)
2198 {
2199 int font = glist_getfont(glist);
2200 int fontwidth = sys_fontwidth(font), fontheight = sys_fontheight(font);
2201 width = (x->te_width > 0 ? x->te_width : 6) * fontwidth + 2;
2202 height = fontheight + 1; /* borrowed from TMARGIN, etc, in g_rtext.c */
2203 }
2204 /* if we're invisible we don't know our size so we just lie about
2205 it. This is called on invisible boxes to establish order of inlets
2206 and possibly other reasons.
2207 To find out if the box is visible we can't just check the "vis"
2208 flag because we might be within the vis() routine and not have set
2209 that yet. So we check directly whether the "rtext" list has been
2210 built. LATER reconsider when "vis" flag should be on and off? */
2211
2212 else if (glist->gl_editor && glist->gl_editor->e_rtext)
2213 {
2214 t_rtext *y = glist_findrtext(glist, x);
2215 width = rtext_width(y);
2216 height = rtext_height(y) - (iscomment << 1);
2217 }
2218 else width = height = 10;
2219 x1 = text_xpix(x, glist);
2220 y1 = text_ypix(x, glist);
2221 x2 = x1 + width;
2222 y2 = y1 + height;
2223 y1 += iscomment;
2224 *xp1 = x1;
2225 *yp1 = y1;
2226 *xp2 = x2;
2227 *yp2 = y2;
2228}
2229
2230static void text_displace(t_gobj *z, t_glist *glist,
2231 int dx, int dy)
2232{
2233 t_text *x = (t_text *)z;
2234 x->te_xpix += dx;
2235 x->te_ypix += dy;
2236 if (glist_isvisible(glist))
2237 {
2238 t_rtext *y = glist_findrtext(glist, x);
2239 rtext_displace(y, dx, dy);
2240 text_drawborder(x, glist, rtext_gettag(y),
2241 rtext_width(y), rtext_height(y), 0);
2242 canvas_fixlinesfor(glist_getcanvas(glist), x);
2243 }
2244}
2245
2246static void text_select(t_gobj *z, t_glist *glist, int state)
2247{
2248 t_text *x = (t_text *)z;
2249 t_rtext *y = glist_findrtext(glist, x);
2250 rtext_select(y, state);
2251 if (glist_isvisible(glist) && text_shouldvis(x, glist))
2252 sys_vgui(".x%x.c itemconfigure %sR -fill %s\n", glist,
2253 rtext_gettag(y), (state? "blue" : "black"));
2254}
2255
2256static void text_activate(t_gobj *z, t_glist *glist, int state)
2257{
2258 t_text *x = (t_text *)z;
2259 t_rtext *y = glist_findrtext(glist, x);
2260 if (z->g_pd != gatom_class) rtext_activate(y, state);
2261}
2262
2263static void text_delete(t_gobj *z, t_glist *glist)
2264{
2265 t_text *x = (t_text *)z;
2266 canvas_deletelinesfor(glist, x);
2267}
2268
2269 /* return true if the text box should be drawn.
2270 We don't show object boxes inside graphs. */
2271int text_shouldvis(t_text *x, t_glist *glist)
2272{
2273 return (glist->gl_havewindow ||
2274 (x->te_pd != canvas_class && x->te_pd->c_wb != &text_widgetbehavior) ||
2275 (x->te_pd == canvas_class && (((t_glist *)x)->gl_isgraph)));
2276}
2277
2278static void text_vis(t_gobj *z, t_glist *glist, int vis)
2279{
2280 t_text *x = (t_text *)z;
2281 if (vis)
2282 {
2283 if (text_shouldvis(x, glist))
2284 {
2285 t_rtext *y = glist_findrtext(glist, x);
2286 if (x->te_type == T_ATOM)
2287 glist_retext(glist, x);
2288 text_drawborder(x, glist, rtext_gettag(y),
2289 rtext_width(y), rtext_height(y), 1);
2290 rtext_draw(y);
2291 }
2292 }
2293 else
2294 {
2295 t_rtext *y = glist_findrtext(glist, x);
2296 if (text_shouldvis(x, glist))
2297 {
2298 text_eraseborder(x, glist, rtext_gettag(y));
2299 rtext_erase(y);
2300 }
2301 }
2302}
2303
2304static int text_click(t_gobj *z, struct _glist *glist,
2305 int xpix, int ypix, int shift, int alt, int dbl, int doit)
2306{
2307 t_text *x = (t_text *)z;
2308 if (x->te_type == T_OBJECT)
2309 {
2310 t_symbol *clicksym = gensym("click");
2311 if (zgetfn(&x->te_pd, clicksym))
2312 {
2313 if (doit)
2314 pd_vmess(&x->te_pd, clicksym, "fffff",
2315 (double)xpix, (double)ypix,
2316 (double)shift, 0, (double)alt);
2317 return (1);
2318 }
2319 else return (0);
2320 }
2321 else if (x->te_type == T_ATOM)
2322 {
2323 if (doit)
2324 gatom_click((t_gatom *)x, (t_floatarg)xpix, (t_floatarg)ypix,
2325 (t_floatarg)shift, 0, (t_floatarg)alt);
2326 return (1);
2327 }
2328 else if (x->te_type == T_MESSAGE)
2329 {
2330 if (doit)
2331 message_click((t_message *)x, (t_floatarg)xpix, (t_floatarg)ypix,
2332 (t_floatarg)shift, 0, (t_floatarg)alt);
2333 return (1);
2334 }
2335 else return (0);
2336}
2337
2338void text_save(t_gobj *z, t_binbuf *b)
2339{
2340 t_text *x = (t_text *)z;
2341 if (x->te_type == T_OBJECT)
2342 {
2343 /* if we have a "saveto" method, and if we don't happen to be
2344 a canvas that's an abstraction, the saveto method does the work */
2345 if (zgetfn(&x->te_pd, gensym("saveto")) &&
2346 !((pd_class(&x->te_pd) == canvas_class) &&
2347 (canvas_isabstraction((t_canvas *)x)
2348 || canvas_istable((t_canvas *)x))))
2349 {
2350 mess1(&x->te_pd, gensym("saveto"), b);
2351 binbuf_addv(b, "ssii", gensym("#X"), gensym("restore"),
2352 (t_int)x->te_xpix, (t_int)x->te_ypix);
2353 }
2354 else /* otherwise just save the text */
2355 {
2356 binbuf_addv(b, "ssii", gensym("#X"), gensym("obj"),
2357 (t_int)x->te_xpix, (t_int)x->te_ypix);
2358 }
2359 binbuf_addbinbuf(b, x->te_binbuf);
2360 binbuf_addv(b, ";");
2361 }
2362 else if (x->te_type == T_MESSAGE)
2363 {
2364 binbuf_addv(b, "ssii", gensym("#X"), gensym("msg"),
2365 (t_int)x->te_xpix, (t_int)x->te_ypix);
2366 binbuf_addbinbuf(b, x->te_binbuf);
2367 binbuf_addv(b, ";");
2368 }
2369 else if (x->te_type == T_ATOM)
2370 {
2371 t_atomtype t = ((t_gatom *)x)->a_atom.a_type;
2372 t_symbol *sel = (t == A_SYMBOL ? gensym("symbolatom") :
2373 (t == A_FLOAT ? gensym("floatatom") : gensym("intatom")));
2374 t_symbol *label = gatom_escapit(((t_gatom *)x)->a_label);
2375 t_symbol *symfrom = gatom_escapit(((t_gatom *)x)->a_symfrom);
2376 t_symbol *symto = gatom_escapit(((t_gatom *)x)->a_symto);
2377 binbuf_addv(b, "ssiiifffsss", gensym("#X"), sel,
2378 (t_int)x->te_xpix, (t_int)x->te_ypix, (t_int)x->te_width,
2379 (double)((t_gatom *)x)->a_draglo,
2380 (double)((t_gatom *)x)->a_draghi,
2381 (double)((t_gatom *)x)->a_wherelabel,
2382 label, symfrom, symto);
2383 binbuf_addv(b, ";");
2384 }
2385 else
2386 {
2387 binbuf_addv(b, "ssii", gensym("#X"), gensym("text"),
2388 (t_int)x->te_xpix, (t_int)x->te_ypix);
2389 binbuf_addbinbuf(b, x->te_binbuf);
2390 binbuf_addv(b, ";");
2391 }
2392}
2393
2394 /* this one is for everyone but "gatoms"; it's imposed in m_class.c */
2395t_widgetbehavior text_widgetbehavior =
2396{
2397 text_getrect,
2398 text_displace,
2399 text_select,
2400 text_activate,
2401 text_delete,
2402 text_vis,
2403 text_click,
2404};
2405
2406static t_widgetbehavior gatom_widgetbehavior =
2407{
2408 text_getrect,
2409 gatom_displace,
2410 text_select,
2411 text_activate,
2412 text_delete,
2413 gatom_vis,
2414 text_click,
2415};
2416
2417/* -------------------- the "text" class ------------ */
2418
2419#ifdef MACOSX
2420#define EXTRAPIX 2
2421#else
2422#define EXTRAPIX 1
2423#endif
2424
2425 /* draw inlets and outlets for a text object or for a graph. */
2426void glist_drawiofor(t_glist *glist, t_object *ob, int firsttime,
2427 char *tag, int x1, int y1, int x2, int y2)
2428{
2429 int n = obj_noutlets(ob), nplus = (n == 1 ? 1 : n-1), i;
2430 int width = x2 - x1;
2431 for (i = 0; i < n; i++)
2432 {
2433 int onset = x1 + (width - IOWIDTH) * i / nplus;
2434 if (firsttime)
2435 sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %so%d\n",
2436 glist_getcanvas(glist),
2437 onset, y2 - 1,
2438 onset + IOWIDTH, y2,
2439 tag, i);
2440 else
2441 sys_vgui(".x%x.c coords %so%d %d %d %d %d\n",
2442 glist_getcanvas(glist), tag, i,
2443 onset, y2 - 1,
2444 onset + IOWIDTH, y2);
2445 }
2446 n = obj_ninlets(ob);
2447 nplus = (n == 1 ? 1 : n-1);
2448 for (i = 0; i < n; i++)
2449 {
2450 int onset = x1 + (width - IOWIDTH) * i / nplus;
2451 if (firsttime)
2452 sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %si%d\n",
2453 glist_getcanvas(glist),
2454 onset, y1,
2455 onset + IOWIDTH, y1 + EXTRAPIX,
2456 tag, i);
2457 else
2458 sys_vgui(".x%x.c coords %si%d %d %d %d %d\n",
2459 glist_getcanvas(glist), tag, i,
2460 onset, y1,
2461 onset + IOWIDTH, y1 + EXTRAPIX);
2462 }
2463}
2464
2465void text_drawborder(t_text *x, t_glist *glist,
2466 char *tag, int width2, int height2, int firsttime)
2467{
2468 t_object *ob;
2469 int x1, y1, x2, y2, width, height;
2470 text_getrect(&x->te_g, glist, &x1, &y1, &x2, &y2);
2471 width = x2 - x1;
2472 height = y2 - y1;
2473 if (x->te_type == T_OBJECT)
2474 {
2475 if (firsttime)
2476 sys_vgui(".x%x.c create line\
2477 %d %d %d %d %d %d %d %d %d %d -tags %sR\n",
2478 glist_getcanvas(glist),
2479 x1, y1, x2, y1, x2, y2, x1, y2, x1, y1, tag);
2480 else
2481 sys_vgui(".x%x.c coords %sR\
2482 %d %d %d %d %d %d %d %d %d %d\n",
2483 glist_getcanvas(glist), tag,
2484 x1, y1, x2, y1, x2, y2, x1, y2, x1, y1);
2485 }
2486 else if (x->te_type == T_MESSAGE)
2487 {
2488 if (firsttime)
2489 sys_vgui(".x%x.c create line\
2490 %d %d %d %d %d %d %d %d %d %d %d %d %d %d -tags %sR\n",
2491 glist_getcanvas(glist),
2492 x1, y1, x2+4, y1, x2, y1+4, x2, y2-4, x2+4, y2,
2493 x1, y2, x1, y1,
2494 tag);
2495 else
2496 sys_vgui(".x%x.c coords %sR\
2497 %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
2498 glist_getcanvas(glist), tag,
2499 x1, y1, x2+4, y1, x2, y1+4, x2, y2-4, x2+4, y2,
2500 x1, y2, x1, y1);
2501 }
2502 else if (x->te_type == T_ATOM)
2503 {
2504 if (firsttime)
2505 sys_vgui(".x%x.c create line\
2506 %d %d %d %d %d %d %d %d %d %d %d %d -tags %sR\n",
2507 glist_getcanvas(glist),
2508 x1, y1, x2-4, y1, x2, y1+4, x2, y2, x1, y2, x1, y1,
2509 tag);
2510 else
2511 sys_vgui(".x%x.c coords %sR\
2512 %d %d %d %d %d %d %d %d %d %d %d %d\n",
2513 glist_getcanvas(glist), tag,
2514 x1, y1, x2-4, y1, x2, y1+4, x2, y2, x1, y2, x1, y1);
2515 }
2516 /* draw inlets/outlets */
2517
2518 if (ob = pd_checkobject(&x->te_pd))
2519 glist_drawiofor(glist, ob, firsttime, tag, x1, y1, x2, y2);
2520}
2521
2522void glist_eraseiofor(t_glist *glist, t_object *ob, char *tag)
2523{
2524 int i, n;
2525 n = obj_noutlets(ob);
2526 for (i = 0; i < n; i++)
2527 sys_vgui(".x%x.c delete %so%d\n",
2528 glist_getcanvas(glist), tag, i);
2529 n = obj_ninlets(ob);
2530 for (i = 0; i < n; i++)
2531 sys_vgui(".x%x.c delete %si%d\n",
2532 glist_getcanvas(glist), tag, i);
2533}
2534
2535void text_eraseborder(t_text *x, t_glist *glist, char *tag)
2536{
2537 if (x->te_type == T_TEXT) return;
2538 sys_vgui(".x%x.c delete %sR\n",
2539 glist_getcanvas(glist), tag);
2540 glist_eraseiofor(glist, x, tag);
2541}
2542
2543 /* change text; if T_OBJECT, remake it. LATER we'll have an undo buffer
2544 which should be filled in here before making the change. */
2545
2546void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize)
2547{
2548 if (x->te_type == T_OBJECT)
2549 {
2550 t_binbuf *b = binbuf_new();
2551 int natom1, natom2;
2552 t_atom *vec1, *vec2;
2553 binbuf_text(b, buf, bufsize);
2554 natom1 = binbuf_getnatom(x->te_binbuf);
2555 vec1 = binbuf_getvec(x->te_binbuf);
2556 natom2 = binbuf_getnatom(b);
2557 vec2 = binbuf_getvec(b);
2558 /* special case: if pd args change just pass the message on. */
2559 if (natom1 >= 1 && natom2 >= 1 && vec1[0].a_type == A_SYMBOL
2560 && !strcmp(vec1[0].a_w.w_symbol->s_name, "pd") &&
2561 vec2[0].a_type == A_SYMBOL
2562 && !strcmp(vec2[0].a_w.w_symbol->s_name, "pd"))
2563 {
2564 typedmess(&x->te_pd, gensym("rename"), natom2-1, vec2+1);
2565 binbuf_free(x->te_binbuf);
2566 x->te_binbuf = b;
2567 }
2568 else /* normally, just destroy the old one and make a new one. */
2569 {
2570 int xwas = x->te_xpix, ywas = x->te_ypix;
2571 glist_delete(glist, &x->te_g);
2572 canvas_objtext(glist, xwas, ywas, 0, b);
2573 /* if it's an abstraction loadbang it here */
2574 if (newest && pd_class(newest) == canvas_class)
2575 canvas_loadbang((t_canvas *)newest);
2576 canvas_restoreconnections(glist_getcanvas(glist));
2577 }
2578 /* if we made a new "pd" or changed a window name,
2579 update window list */
2580 if (natom2 >= 1 && vec2[0].a_type == A_SYMBOL
2581 && !strcmp(vec2[0].a_w.w_symbol->s_name, "pd"))
2582 canvas_updatewindowlist();
2583 }
2584 else binbuf_text(x->te_binbuf, buf, bufsize);
2585}
2586
2587void g_text_setup(void)
2588{
2589 text_class = class_new(gensym("text"), 0, 0, sizeof(t_text),
2590 CLASS_NOINLET | CLASS_PATCHABLE, 0);
2591
2592 message_class = class_new(gensym("message"), 0, (t_method)message_free,
2593 sizeof(t_message), CLASS_PATCHABLE, 0);
2594 class_addbang(message_class, message_bang);
2595 class_addfloat(message_class, message_float);
2596 class_addsymbol(message_class, message_symbol);
2597 class_addlist(message_class, message_list);
2598 class_addanything(message_class, message_list);
2599
2600 class_addmethod(message_class, (t_method)message_click, gensym("click"),
2601 A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
2602 class_addmethod(message_class, (t_method)message_set, gensym("set"),
2603 A_GIMME, 0);
2604 class_addmethod(message_class, (t_method)message_add, gensym("add"),
2605 A_GIMME, 0);
2606 class_addmethod(message_class, (t_method)message_add2, gensym("add2"),
2607 A_GIMME, 0);
2608
2609 messresponder_class = class_new(gensym("messresponder"), 0, 0,
2610 sizeof(t_text), CLASS_PD, 0);
2611 class_addbang(messresponder_class, messresponder_bang);
2612 class_addfloat(messresponder_class, (t_method) messresponder_float);
2613 class_addsymbol(messresponder_class, messresponder_symbol);
2614 class_addlist(messresponder_class, messresponder_list);
2615 class_addanything(messresponder_class, messresponder_anything);
2616
2617 gatom_class = class_new(gensym("gatom"), 0, (t_method)gatom_free,
2618 sizeof(t_gatom), CLASS_NOINLET | CLASS_PATCHABLE, 0);
2619 class_addbang(gatom_class, gatom_bang);
2620 class_addfloat(gatom_class, gatom_float);
2621 class_addsymbol(gatom_class, gatom_symbol);
2622 class_addmethod(gatom_class, (t_method)gatom_set, gensym("set"),
2623 A_GIMME, 0);
2624 class_addmethod(gatom_class, (t_method)gatom_click, gensym("click"),
2625 A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
2626 class_addmethod(gatom_class, (t_method)gatom_param, gensym("param"),
2627 A_GIMME, 0);
2628 class_setwidget(gatom_class, &gatom_widgetbehavior);
2629 class_setpropertiesfn(gatom_class, gatom_properties);
2630}
2631
2632