A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 1510 lines 42 kB view raw
1/* Copyright (c) 1997-1999 Miller Puckette. 2* For information on usage and redistribution, and for a DISCLAIMER OF ALL 3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ 4 5/* changes by Thomas Musil IEM KUG Graz Austria 2001 */ 6/* the methods for calling the gui-objects from menu are implemented */ 7/* all changes are labeled with iemlib */ 8 9#include "m_pd.h" 10#include "m_imp.h" 11#include "s_stuff.h" 12#include "t_tk.h" 13#include "g_canvas.h" 14 15#ifdef ROCKBOX 16#include "plugin.h" 17#include "../../pdbox.h" 18#else /* ROCKBOX */ 19#include <stdlib.h> 20#include <stdio.h> 21#include <string.h> 22#include <math.h> 23#endif /* ROCKBOX */ 24 25static t_class *text_class; 26static t_class *message_class; 27static t_class *gatom_class; 28static void text_vis(t_gobj *z, t_glist *glist, int vis); 29static void text_displace(t_gobj *z, t_glist *glist, 30 int dx, int dy); 31static void text_getrect(t_gobj *z, t_glist *glist, 32 int *xp1, int *yp1, int *xp2, int *yp2); 33 34void canvas_startmotion(t_canvas *x); 35t_widgetbehavior text_widgetbehavior; 36 37/* ----------------- the "text" object. ------------------ */ 38 39 /* add a "text" object (comment) to a glist. While this one goes for any glist, 40 the other 3 below are for canvases only. (why?) This is called 41 without args if invoked from the GUI; otherwise at least x and y 42 are provided. */ 43 44void glist_text(t_glist *gl, t_symbol *s, int argc, t_atom *argv) 45{ 46 t_text *x = (t_text *)pd_new(text_class); 47 t_atom at; 48 49#ifdef ROCKBOX 50 (void) s; 51#endif 52 53 x->te_width = 0; /* don't know it yet. */ 54 x->te_type = T_TEXT; 55 x->te_binbuf = binbuf_new(); 56 if (argc > 1) 57 { 58 x->te_xpix = atom_getfloatarg(0, argc, argv); 59 x->te_ypix = atom_getfloatarg(1, argc, argv); 60 if (argc > 2) binbuf_restore(x->te_binbuf, argc-2, argv+2); 61 else 62 { 63 SETSYMBOL(&at, gensym("comment")); 64 binbuf_restore(x->te_binbuf, 1, &at); 65 } 66 glist_add(gl, &x->te_g); 67 } 68 else 69 { 70 int xpix, ypix; 71 pd_vmess((t_pd *)glist_getcanvas(gl), gensym("editmode"), "i", 1); 72 SETSYMBOL(&at, gensym("comment")); 73 glist_noselect(gl); 74 glist_getnextxy(gl, &xpix, &ypix); 75 x->te_xpix = glist_pixelstox(gl, xpix-3); 76 x->te_ypix = glist_pixelstoy(gl, ypix-3); 77 binbuf_restore(x->te_binbuf, 1, &at); 78 glist_add(gl, &x->te_g); 79 glist_noselect(gl); 80 glist_select(gl, &x->te_g); 81 /* it would be nice to "activate" here, but then the second, 82 "put-me-down" click changes the text selection, which is quite 83 irritating, so I took this back out. It's OK in messages 84 and objects though since there's no text in them at menu 85 creation. */ 86 /* gobj_activate(&x->te_g, gl, 1); */ 87 canvas_startmotion(glist_getcanvas(gl)); 88 } 89} 90 91/* ----------------- the "object" object. ------------------ */ 92 93extern t_pd *newest; 94void canvas_getargs(int *argcp, t_atom **argvp); 95 96static void canvas_objtext(t_glist *gl, int xpix, int ypix, int selected, 97 t_binbuf *b) 98{ 99 t_text *x; 100 int argc; 101 t_atom *argv; 102 newest = 0; 103 canvas_setcurrent((t_canvas *)gl); 104 canvas_getargs(&argc, &argv); 105 binbuf_eval(b, &pd_objectmaker, argc, argv); 106 if (binbuf_getnatom(b)) 107 { 108 if (!newest) 109 { 110 binbuf_print(b); 111 post("... couldn't create"); 112 x = 0; 113 } 114 else if (!(x = pd_checkobject(newest))) 115 { 116 binbuf_print(b); 117 post("... didn't return a patchable object"); 118 } 119 } 120 else x = 0; 121 if (!x) 122 { 123 124 /* LATER make the color reflect this */ 125 x = (t_text *)pd_new(text_class); 126 } 127 x->te_binbuf = b; 128 x->te_xpix = xpix; 129 x->te_ypix = ypix; 130 x->te_width = 0; 131 x->te_type = T_OBJECT; 132 glist_add(gl, &x->te_g); 133 if (selected) 134 { 135 /* this is called if we've been created from the menu. */ 136 glist_select(gl, &x->te_g); 137 gobj_activate(&x->te_g, gl, 1); 138 } 139 if (pd_class(&x->ob_pd) == vinlet_class) 140 canvas_resortinlets(glist_getcanvas(gl)); 141 if (pd_class(&x->ob_pd) == voutlet_class) 142 canvas_resortoutlets(glist_getcanvas(gl)); 143 canvas_unsetcurrent((t_canvas *)gl); 144} 145 146 /* object creation routine. These are called without any arguments if 147 they're invoked from the 148 gui; when pasting or restoring from a file, we get at least x and y. */ 149 150void canvas_obj(t_glist *gl, t_symbol *s, int argc, t_atom *argv) 151{ 152#ifdef ROCKBOX 153 (void) s; 154#else 155 t_text *x; 156#endif 157 158 if (argc >= 2) 159 { 160 t_binbuf *b = binbuf_new(); 161 binbuf_restore(b, argc-2, argv+2); 162 canvas_objtext(gl, atom_getintarg(0, argc, argv), 163 atom_getintarg(1, argc, argv), 0, b); 164 } 165 else 166 { 167 t_binbuf *b = binbuf_new(); 168 int xpix, ypix; 169 pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1); 170 glist_noselect(gl); 171 glist_getnextxy(gl, &xpix, &ypix); 172 canvas_objtext(gl, xpix, ypix, 1, b); 173 canvas_startmotion(glist_getcanvas(gl)); 174 } 175} 176 177/* make an object box for an object that's already there. */ 178 179/* iemlib */ 180void canvas_iemguis(t_glist *gl, t_symbol *guiobjname) 181{ 182 t_atom at; 183 t_binbuf *b = binbuf_new(); 184 int xpix, ypix; 185 186 pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1); 187 glist_noselect(gl); 188 SETSYMBOL(&at, guiobjname); 189 binbuf_restore(b, 1, &at); 190 glist_getnextxy(gl, &xpix, &ypix); 191 canvas_objtext(gl, xpix, ypix, 1, b); 192 canvas_startmotion(glist_getcanvas(gl)); 193} 194 195void canvas_bng(t_glist *gl, t_symbol *s, int argc, t_atom *argv) 196{ 197#ifdef ROCKBOX 198 (void) s; 199 (void) argc; 200 (void) argv; 201#endif 202 canvas_iemguis(gl, gensym("bng")); 203} 204 205void canvas_toggle(t_glist *gl, t_symbol *s, int argc, t_atom *argv) 206{ 207#ifdef ROCKBOX 208 (void) s; 209 (void) argc; 210 (void) argv; 211#endif 212 canvas_iemguis(gl, gensym("tgl")); 213} 214 215void canvas_vslider(t_glist *gl, t_symbol *s, int argc, t_atom *argv) 216{ 217#ifdef ROCKBOX 218 (void) s; 219 (void) argc; 220 (void) argv; 221#endif 222 canvas_iemguis(gl, gensym("vsl")); 223} 224 225void canvas_hslider(t_glist *gl, t_symbol *s, int argc, t_atom *argv) 226{ 227#ifdef ROCKBOX 228 (void) s; 229 (void) argc; 230 (void) argv; 231#endif 232 canvas_iemguis(gl, gensym("hsl")); 233} 234 235void canvas_hdial(t_glist *gl, t_symbol *s, int argc, t_atom *argv) 236{ 237#ifdef ROCKBOX 238 (void) s; 239 (void) argc; 240 (void) argv; 241#endif 242 canvas_iemguis(gl, gensym("hdl")); 243} 244 245void canvas_vdial(t_glist *gl, t_symbol *s, int argc, t_atom *argv) 246{ 247#ifdef ROCKBOX 248 (void) s; 249 (void) argc; 250 (void) argv; 251#endif 252 canvas_iemguis(gl, gensym("vdl")); 253} 254 255void canvas_hradio(t_glist *gl, t_symbol *s, int argc, t_atom *argv) 256{ 257#ifdef ROCKBOX 258 (void) s; 259 (void) argc; 260 (void) argv; 261#endif 262 canvas_iemguis(gl, gensym("hradio")); 263} 264 265void canvas_vradio(t_glist *gl, t_symbol *s, int argc, t_atom *argv) 266{ 267#ifdef ROCKBOX 268 (void) s; 269 (void) argc; 270 (void) argv; 271#endif 272 canvas_iemguis(gl, gensym("vradio")); 273} 274 275void canvas_vumeter(t_glist *gl, t_symbol *s, int argc, t_atom *argv) 276{ 277#ifdef ROCKBOX 278 (void) s; 279 (void) argc; 280 (void) argv; 281#endif 282 canvas_iemguis(gl, gensym("vu")); 283} 284 285void canvas_mycnv(t_glist *gl, t_symbol *s, int argc, t_atom *argv) 286{ 287#ifdef ROCKBOX 288 (void) s; 289 (void) argc; 290 (void) argv; 291#endif 292 canvas_iemguis(gl, gensym("cnv")); 293} 294 295void canvas_numbox(t_glist *gl, t_symbol *s, int argc, t_atom *argv) 296{ 297#ifdef ROCKBOX 298 (void) s; 299 (void) argc; 300 (void) argv; 301#endif 302 canvas_iemguis(gl, gensym("nbx")); 303} 304 305/* iemlib */ 306 307void canvas_objfor(t_glist *gl, t_text *x, int argc, t_atom *argv) 308{ 309 x->te_width = 0; /* don't know it yet. */ 310 x->te_type = T_OBJECT; 311 x->te_binbuf = binbuf_new(); 312 x->te_xpix = atom_getfloatarg(0, argc, argv); 313 x->te_ypix = atom_getfloatarg(1, argc, argv); 314 if (argc > 2) binbuf_restore(x->te_binbuf, argc-2, argv+2); 315 glist_add(gl, &x->te_g); 316} 317 318/* ---------------------- the "message" text item ------------------------ */ 319 320typedef struct _messresponder 321{ 322 t_pd mr_pd; 323 t_outlet *mr_outlet; 324} t_messresponder; 325 326typedef struct _message 327{ 328 t_text m_text; 329 t_messresponder m_messresponder; 330 t_glist *m_glist; 331 t_clock *m_clock; 332} t_message; 333 334static t_class *message_class, *messresponder_class; 335 336static void messresponder_bang(t_messresponder *x) 337{ 338 outlet_bang(x->mr_outlet); 339} 340 341static void messresponder_float(t_messresponder *x, t_float f) 342{ 343 outlet_float(x->mr_outlet, f); 344} 345 346static void messresponder_symbol(t_messresponder *x, t_symbol *s) 347{ 348 outlet_symbol(x->mr_outlet, s); 349} 350 351static void messresponder_list(t_messresponder *x, 352 t_symbol *s, int argc, t_atom *argv) 353{ 354 outlet_list(x->mr_outlet, s, argc, argv); 355} 356 357static void messresponder_anything(t_messresponder *x, 358 t_symbol *s, int argc, t_atom *argv) 359{ 360 outlet_anything(x->mr_outlet, s, argc, argv); 361} 362 363static void message_bang(t_message *x) 364{ 365 binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 0, 0); 366} 367 368static void message_float(t_message *x, t_float f) 369{ 370 t_atom at; 371 SETFLOAT(&at, f); 372 binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 1, &at); 373} 374 375static void message_symbol(t_message *x, t_symbol *s) 376{ 377 t_atom at; 378 SETSYMBOL(&at, s); 379 binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 1, &at); 380} 381 382static void message_list(t_message *x, t_symbol *s, int argc, t_atom *argv) 383{ 384#ifdef ROCKBOX 385 (void) s; 386#endif 387 binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, argc, argv); 388} 389 390static void message_set(t_message *x, t_symbol *s, int argc, t_atom *argv) 391{ 392#ifdef ROCKBOX 393 (void) s; 394#endif 395 binbuf_clear(x->m_text.te_binbuf); 396 binbuf_add(x->m_text.te_binbuf, argc, argv); 397 glist_retext(x->m_glist, &x->m_text); 398} 399 400static void message_add2(t_message *x, t_symbol *s, int argc, t_atom *argv) 401{ 402#ifdef ROCKBOX 403 (void) s; 404#endif 405 binbuf_add(x->m_text.te_binbuf, argc, argv); 406 glist_retext(x->m_glist, &x->m_text); 407} 408 409static void message_add(t_message *x, t_symbol *s, int argc, t_atom *argv) 410{ 411#ifdef ROCKBOX 412 (void) s; 413#endif 414 binbuf_add(x->m_text.te_binbuf, argc, argv); 415 binbuf_addsemi(x->m_text.te_binbuf); 416 glist_retext(x->m_glist, &x->m_text); 417} 418 419static void message_click(t_message *x, 420 t_floatarg xpos, t_floatarg ypos, t_floatarg shift, 421 t_floatarg ctrl, t_floatarg alt) 422{ 423#ifdef ROCKBOX 424 (void) xpos; 425 (void) ypos; 426 (void) shift; 427 (void) ctrl; 428 (void) alt; 429#endif 430 message_float(x, 0); 431 if (glist_isvisible(x->m_glist)) 432 { 433#ifndef ROCKBOX 434 t_rtext *y = glist_findrtext(x->m_glist, &x->m_text); 435 sys_vgui(".x%x.c itemconfigure %sR -width 5\n", 436 glist_getcanvas(x->m_glist), rtext_gettag(y)); 437#endif 438 clock_delay(x->m_clock, 120); 439 } 440} 441 442static void message_tick(t_message *x) 443{ 444 if (glist_isvisible(x->m_glist)) 445 { 446#ifndef ROCKBOX 447 t_rtext *y = glist_findrtext(x->m_glist, &x->m_text); 448 sys_vgui(".x%x.c itemconfigure %sR -width 1\n", 449 glist_getcanvas(x->m_glist), rtext_gettag(y)); 450#endif 451 } 452} 453 454static void message_free(t_message *x) 455{ 456 clock_free(x->m_clock); 457} 458 459void canvas_msg(t_glist *gl, t_symbol *s, int argc, t_atom *argv) 460{ 461#ifdef ROCKBOX 462 (void) s; 463#endif 464 t_message *x = (t_message *)pd_new(message_class); 465 x->m_messresponder.mr_pd = messresponder_class; 466 x->m_messresponder.mr_outlet = outlet_new(&x->m_text, &s_float); 467 x->m_text.te_width = 0; /* don't know it yet. */ 468 x->m_text.te_type = T_MESSAGE; 469 x->m_text.te_binbuf = binbuf_new(); 470 x->m_glist = gl; 471 x->m_clock = clock_new(x, (t_method)message_tick); 472 if (argc > 1) 473 { 474 x->m_text.te_xpix = atom_getfloatarg(0, argc, argv); 475 x->m_text.te_ypix = atom_getfloatarg(1, argc, argv); 476 if (argc > 2) binbuf_restore(x->m_text.te_binbuf, argc-2, argv+2); 477 glist_add(gl, &x->m_text.te_g); 478 } 479 else 480 { 481 int xpix, ypix; 482 pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1); 483 glist_noselect(gl); 484 glist_getnextxy(gl, &xpix, &ypix); 485 x->m_text.te_xpix = xpix-3; 486 x->m_text.te_ypix = ypix-3; 487 glist_add(gl, &x->m_text.te_g); 488 glist_noselect(gl); 489 glist_select(gl, &x->m_text.te_g); 490 gobj_activate(&x->m_text.te_g, gl, 1); 491 canvas_startmotion(glist_getcanvas(gl)); 492 } 493} 494 495/* ---------------------- the "atom" text item ------------------------ */ 496 497#define ATOMBUFSIZE 40 498#define ATOM_LABELLEFT 0 499#define ATOM_LABELRIGHT 1 500#define ATOM_LABELUP 2 501#define ATOM_LABELDOWN 3 502 503typedef struct _gatom 504{ 505 t_text a_text; 506 t_atom a_atom; /* this holds the value and the type */ 507 t_glist *a_glist; /* owning glist */ 508 t_float a_toggle; /* value to toggle to */ 509 t_float a_draghi; /* high end of drag range */ 510 t_float a_draglo; /* low end of drag range */ 511 t_symbol *a_label; /* symbol to show as label next to box */ 512 t_symbol *a_symfrom; /* "receive" name -- bind ourselvs to this */ 513 t_symbol *a_symto; /* "send" name -- send to this on output */ 514 char a_buf[ATOMBUFSIZE];/* string buffer for typing */ 515 char a_shift; /* was shift key down when dragging started? */ 516 char a_wherelabel; /* 0-3 for left, right, above, below */ 517 t_symbol *a_expanded_to; /* a_symto after $0, $1, ... expansion */ 518} t_gatom; 519 520 /* prepend "-" as necessary to avoid empty strings, so we can 521 use them in Pd messages. A more complete solution would be 522 to introduce some quoting mechanism; but then we'd be much more 523 complicated. */ 524static t_symbol *gatom_escapit(t_symbol *s) 525{ 526 if (!*s->s_name) 527 return (gensym("-")); 528 else if (*s->s_name == '-') 529 { 530 char shmo[100]; 531 shmo[0] = '-'; 532 strncpy(shmo+1, s->s_name, 99); 533 shmo[99] = 0; 534 return (gensym(shmo)); 535 } 536 else return (iemgui_dollar2raute(s)); 537} 538 539 /* undo previous operation: strip leading "-" if found. */ 540static t_symbol *gatom_unescapit(t_symbol *s) 541{ 542 if (*s->s_name == '-') 543 return (gensym(s->s_name+1)); 544 else return (iemgui_raute2dollar(s)); 545} 546 547#if 0 /* ??? */ 548 /* expand leading $0, $1, etc. in the symbol */ 549static t_symbol *gatom_realizedollar(t_gatom *x, t_symbol *s) 550{ 551 return (canvas_realizedollar(x->a_glist, s)); 552} 553#endif 554 555static void gatom_retext(t_gatom *x, int senditup) 556{ 557 binbuf_clear(x->a_text.te_binbuf); 558 binbuf_add(x->a_text.te_binbuf, 1, &x->a_atom); 559 if (senditup) 560 glist_retext(x->a_glist, &x->a_text); 561} 562 563static void gatom_set(t_gatom *x, t_symbol *s, int argc, t_atom *argv) 564{ 565 t_atom oldatom = x->a_atom; 566 int senditup = 0; 567#ifdef ROCKBOX 568 (void) s; 569#endif 570 if (!argc) return; 571 if (x->a_atom.a_type == A_FLOAT) 572 x->a_atom.a_w.w_float = atom_getfloat(argv), 573 senditup = (x->a_atom.a_w.w_float != oldatom.a_w.w_float); 574 else if (x->a_atom.a_type == A_SYMBOL) 575 x->a_atom.a_w.w_symbol = atom_getsymbol(argv), 576 senditup = (x->a_atom.a_w.w_symbol != oldatom.a_w.w_symbol); 577 gatom_retext(x, senditup); 578 x->a_buf[0] = 0; 579} 580 581static void gatom_bang(t_gatom *x) 582{ 583 if (x->a_atom.a_type == A_FLOAT) 584 { 585 if (x->a_text.te_outlet) 586 outlet_float(x->a_text.te_outlet, x->a_atom.a_w.w_float); 587 if (*x->a_expanded_to->s_name && x->a_expanded_to->s_thing) 588 { 589 if (x->a_symto == x->a_symfrom) 590 pd_error(x, 591 "%s: atom with same send/receive name (infinite loop)", 592 x->a_symto->s_name); 593 else pd_float(x->a_expanded_to->s_thing, x->a_atom.a_w.w_float); 594 } 595 } 596 else if (x->a_atom.a_type == A_SYMBOL) 597 { 598 if (x->a_text.te_outlet) 599 outlet_symbol(x->a_text.te_outlet, x->a_atom.a_w.w_symbol); 600 if (*x->a_symto->s_name && x->a_expanded_to->s_thing) 601 { 602 if (x->a_symto == x->a_symfrom) 603 pd_error(x, 604 "%s: atom with same send/receive name (infinite loop)", 605 x->a_symto->s_name); 606 else pd_symbol(x->a_expanded_to->s_thing, x->a_atom.a_w.w_symbol); 607 } 608 } 609} 610 611static void gatom_float(t_gatom *x, t_float f) 612{ 613 t_atom at; 614 SETFLOAT(&at, f); 615 gatom_set(x, 0, 1, &at); 616 gatom_bang(x); 617} 618 619static void gatom_clipfloat(t_gatom *x, t_float f) 620{ 621 if (x->a_draglo != 0 || x->a_draghi != 0) 622 { 623 if (f < x->a_draglo) 624 f = x->a_draglo; 625 if (f > x->a_draghi) 626 f = x->a_draghi; 627 } 628 gatom_float(x, f); 629} 630 631static void gatom_symbol(t_gatom *x, t_symbol *s) 632{ 633 t_atom at; 634 SETSYMBOL(&at, s); 635 gatom_set(x, 0, 1, &at); 636 gatom_bang(x); 637} 638 639static void gatom_motion(void *z, t_floatarg dx, t_floatarg dy) 640{ 641#ifdef ROCKBOX 642 (void) dx; 643#endif 644 t_gatom *x = (t_gatom *)z; 645 if (dy == 0) return; 646 if (x->a_atom.a_type == A_FLOAT) 647 { 648 if (x->a_shift) 649 { 650 double nval = x->a_atom.a_w.w_float - 0.01 * dy; 651 double trunc = 0.01 * (floor(100. * nval + 0.5)); 652 if (trunc < nval + 0.0001 && trunc > nval - 0.0001) nval = trunc; 653 gatom_clipfloat(x, nval); 654 } 655 else 656 { 657 double nval = x->a_atom.a_w.w_float - dy; 658 double trunc = 0.01 * (floor(100. * nval + 0.5)); 659 if (trunc < nval + 0.0001 && trunc > nval - 0.0001) nval = trunc; 660 trunc = floor(nval + 0.5); 661 if (trunc < nval + 0.001 && trunc > nval - 0.001) nval = trunc; 662 gatom_clipfloat(x, nval); 663 } 664 } 665} 666 667static void gatom_key(void *z, t_floatarg f) 668{ 669 t_gatom *x = (t_gatom *)z; 670 int c = f; 671 int len = strlen(x->a_buf); 672 t_atom at; 673 char sbuf[ATOMBUFSIZE + 4]; 674 if (c == 0) 675 { 676 /* we're being notified that no more keys will come for this grab */ 677 if (x->a_buf[0]) 678 gatom_retext(x, 1); 679 return; 680 } 681 else if (c == ' ') return; 682 else if (c == '\b') 683 { 684 if (len > 0) 685 x->a_buf[len-1] = 0; 686 goto redraw; 687 } 688 else if (c == '\n') 689 { 690 if (x->a_atom.a_type == A_FLOAT) 691 x->a_atom.a_w.w_float = atof(x->a_buf); 692 else if (x->a_atom.a_type == A_SYMBOL) 693 x->a_atom.a_w.w_symbol = gensym(x->a_buf); 694 else bug("gatom_key"); 695 gatom_bang(x); 696 gatom_retext(x, 1); 697 x->a_buf[0] = 0; 698 } 699 else if (len < (ATOMBUFSIZE-1)) 700 { 701 /* for numbers, only let reasonable characters through */ 702 if ((x->a_atom.a_type == A_SYMBOL) || 703 ((c >= '0' && c <= '9') || c == '.' || c == '-' 704 || c == 'e' || c == 'E')) 705 { 706 x->a_buf[len] = c; 707 x->a_buf[len+1] = 0; 708 goto redraw; 709 } 710 } 711 return; 712redraw: 713 /* LATER figure out how to avoid creating all these symbols! */ 714#ifdef ROCKBOX 715 snprintf(sbuf, sizeof(sbuf), "%s...", x->a_buf); 716#else /* ROCKBOX */ 717 sprintf(sbuf, "%s...", x->a_buf); 718#endif 719 SETSYMBOL(&at, gensym(sbuf)); 720 binbuf_clear(x->a_text.te_binbuf); 721 binbuf_add(x->a_text.te_binbuf, 1, &at); 722 glist_retext(x->a_glist, &x->a_text); 723} 724 725static void gatom_click(t_gatom *x, 726 t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl, 727 t_floatarg alt) 728{ 729#ifdef ROCKBOX 730 (void) ctrl; 731#endif 732 if (x->a_text.te_width == 1) 733 { 734 if (x->a_atom.a_type == A_FLOAT) 735 gatom_float(x, (x->a_atom.a_w.w_float == 0)); 736 } 737 else 738 { 739 if (alt) 740 { 741 if (x->a_atom.a_type != A_FLOAT) return; 742 if (x->a_atom.a_w.w_float != 0) 743 { 744 x->a_toggle = x->a_atom.a_w.w_float; 745 gatom_float(x, 0); 746 return; 747 } 748 else gatom_float(x, x->a_toggle); 749 } 750 x->a_shift = shift; 751 x->a_buf[0] = 0; 752 glist_grab(x->a_glist, &x->a_text.te_g, gatom_motion, gatom_key, 753 xpos, ypos); 754 } 755} 756 757 /* message back from dialog window */ 758static void gatom_param(t_gatom *x, t_symbol *sel, int argc, t_atom *argv) 759{ 760 t_float width = atom_getfloatarg(0, argc, argv); 761 t_float draglo = atom_getfloatarg(1, argc, argv); 762 t_float draghi = atom_getfloatarg(2, argc, argv); 763 t_symbol *label = gatom_unescapit(atom_getsymbolarg(3, argc, argv)); 764 t_float wherelabel = atom_getfloatarg(4, argc, argv); 765 t_symbol *symfrom = gatom_unescapit(atom_getsymbolarg(5, argc, argv)); 766 t_symbol *symto = gatom_unescapit(atom_getsymbolarg(6, argc, argv)); 767 768#ifdef ROCKBOX 769 (void) sel; 770#endif 771 772 gobj_vis(&x->a_text.te_g, x->a_glist, 0); 773 if (!*symfrom->s_name && *x->a_symfrom->s_name) 774 inlet_new(&x->a_text, &x->a_text.te_pd, 0, 0); 775 else if (*symfrom->s_name && !*x->a_symfrom->s_name && x->a_text.te_inlet) 776 { 777 canvas_deletelinesforio(x->a_glist, &x->a_text, 778 x->a_text.te_inlet, 0); 779 inlet_free(x->a_text.te_inlet); 780 } 781 if (!*symto->s_name && *x->a_symto->s_name) 782 outlet_new(&x->a_text, 0); 783 else if (*symto->s_name && !*x->a_symto->s_name && x->a_text.te_outlet) 784 { 785 canvas_deletelinesforio(x->a_glist, &x->a_text, 786 0, x->a_text.te_outlet); 787 outlet_free(x->a_text.te_outlet); 788 } 789 if (draglo >= draghi) 790 draglo = draghi = 0; 791 x->a_draglo = draglo; 792 x->a_draghi = draghi; 793 if (width < 0) 794 width = 4; 795 else if (width > 80) 796 width = 80; 797 x->a_text.te_width = width; 798 x->a_wherelabel = ((int)wherelabel & 3); 799 x->a_label = label; 800 if (*x->a_symfrom->s_name) 801 pd_unbind(&x->a_text.te_pd, 802 canvas_realizedollar(x->a_glist, x->a_symfrom)); 803 x->a_symfrom = symfrom; 804 if (*x->a_symfrom->s_name) 805 pd_bind(&x->a_text.te_pd, 806 canvas_realizedollar(x->a_glist, x->a_symfrom)); 807 x->a_symto = symto; 808 x->a_expanded_to = canvas_realizedollar(x->a_glist, x->a_symto); 809 gobj_vis(&x->a_text.te_g, x->a_glist, 1); 810 811 /* glist_retext(x->a_glist, &x->a_text); */ 812} 813 814 /* ---------------- gatom-specific widget functions --------------- */ 815static void gatom_getwherelabel(t_gatom *x, t_glist *glist, int *xp, int *yp) 816{ 817 int x1, y1, x2, y2 /*, width, height */; 818 text_getrect(&x->a_text.te_g, glist, &x1, &y1, &x2, &y2); 819 /* width = x2 - x1; */ 820 /* height = y2 - y1; */ 821 if (x->a_wherelabel == ATOM_LABELLEFT) 822 { 823 *xp = x1 - 3 - 824 strlen(canvas_realizedollar(x->a_glist, x->a_label)->s_name) * 825#ifdef ROCKBOX 826 8; 827#else 828 sys_fontwidth(glist_getfont(glist)); 829#endif 830 *yp = y1 + 2; 831 } 832 else if (x->a_wherelabel == ATOM_LABELRIGHT) 833 { 834 *xp = x2 + 2; 835 *yp = y1 + 2; 836 } 837 else if (x->a_wherelabel == ATOM_LABELUP) 838 { 839 *xp = x1 - 1; 840#ifdef ROCKBOX 841 *yp = y1 - 1 - 10; 842#else 843 *yp = y1 - 1 - sys_fontheight(glist_getfont(glist));; 844#endif 845 } 846 else 847 { 848 *xp = x1 - 1; 849 *yp = y2 + 3; 850 } 851} 852 853static void gatom_displace(t_gobj *z, t_glist *glist, 854 int dx, int dy) 855{ 856#ifndef ROCKBOX 857 t_gatom *x = (t_gatom*)z; 858#endif 859 text_displace(z, glist, dx, dy); 860#ifndef ROCKBOX 861 sys_vgui(".x%x.c move %x.l %d %d\n", glist_getcanvas(glist), 862 x, dx, dy); 863#endif 864} 865 866static void gatom_vis(t_gobj *z, t_glist *glist, int vis) 867{ 868 t_gatom *x = (t_gatom*)z; 869 text_vis(z, glist, vis); 870 if (*x->a_label->s_name) 871 { 872 if (vis) 873 { 874 int x1, y1; 875 gatom_getwherelabel(x, glist, &x1, &y1); 876#ifndef ROCKBOX 877 sys_vgui("pdtk_text_new .x%x.c %x.l %f %f {%s} %d %s\n", 878 glist_getcanvas(glist), x, 879 (double)x1, (double)y1, 880 canvas_realizedollar(x->a_glist, x->a_label)->s_name, 881 sys_hostfontsize(glist_getfont(glist)), 882 "black"); 883#endif 884 } 885#ifndef ROCKBOX 886 else sys_vgui(".x%x.c delete %x.l\n", glist_getcanvas(glist), x); 887#endif 888 } 889} 890 891void canvas_atom(t_glist *gl, t_atomtype type, 892 t_symbol *s, int argc, t_atom *argv) 893{ 894 t_gatom *x = (t_gatom *)pd_new(gatom_class); 895 t_atom at; 896 897#ifdef ROCKBOX 898 (void) s; 899#endif 900 901 x->a_text.te_width = 0; /* don't know it yet. */ 902 x->a_text.te_type = T_ATOM; 903 x->a_text.te_binbuf = binbuf_new(); 904 x->a_glist = gl; 905 x->a_atom.a_type = type; 906 x->a_toggle = 1; 907 x->a_draglo = 0; 908 x->a_draghi = 0; 909 x->a_wherelabel = 0; 910 x->a_label = &s_; 911 x->a_symfrom = &s_; 912 x->a_symto = x->a_expanded_to = &s_; 913 if (type == A_FLOAT) 914 { 915 x->a_atom.a_w.w_float = 0; 916 x->a_text.te_width = 5; 917 SETFLOAT(&at, 0); 918 } 919 else 920 { 921 x->a_atom.a_w.w_symbol = &s_symbol; 922 x->a_text.te_width = 10; 923 SETSYMBOL(&at, &s_symbol); 924 } 925 binbuf_add(x->a_text.te_binbuf, 1, &at); 926 if (argc > 1) 927 /* create from file. x, y, width, low-range, high-range, flags, 928 label, receive-name, send-name */ 929 { 930 x->a_text.te_xpix = atom_getfloatarg(0, argc, argv); 931 x->a_text.te_ypix = atom_getfloatarg(1, argc, argv); 932 x->a_text.te_width = atom_getintarg(2, argc, argv); 933 /* sanity check because some very old patches have trash in this 934 field... remove this in 2003 or so: */ 935 if (x->a_text.te_width < 0 || x->a_text.te_width > 500) 936 x->a_text.te_width = 4; 937 x->a_draglo = atom_getfloatarg(3, argc, argv); 938 x->a_draghi = atom_getfloatarg(4, argc, argv); 939 x->a_wherelabel = (((int)atom_getfloatarg(5, argc, argv)) & 3); 940 x->a_label = gatom_unescapit(atom_getsymbolarg(6, argc, argv)); 941 x->a_symfrom = gatom_unescapit(atom_getsymbolarg(7, argc, argv)); 942 if (*x->a_symfrom->s_name) 943 pd_bind(&x->a_text.te_pd, 944 canvas_realizedollar(x->a_glist, x->a_symfrom)); 945 946 x->a_symto = gatom_unescapit(atom_getsymbolarg(8, argc, argv)); 947 x->a_expanded_to = canvas_realizedollar(x->a_glist, x->a_symto); 948 if (x->a_symto == &s_) 949 outlet_new(&x->a_text, 950 x->a_atom.a_type == A_FLOAT ? &s_float: &s_symbol); 951 if (x->a_symfrom == &s_) 952 inlet_new(&x->a_text, &x->a_text.te_pd, 0, 0); 953 glist_add(gl, &x->a_text.te_g); 954 } 955 else 956 { 957 int xpix, ypix; 958 outlet_new(&x->a_text, 959 x->a_atom.a_type == A_FLOAT ? &s_float: &s_symbol); 960 inlet_new(&x->a_text, &x->a_text.te_pd, 0, 0); 961 pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1); 962 glist_noselect(gl); 963 glist_getnextxy(gl, &xpix, &ypix); 964 x->a_text.te_xpix = xpix; 965 x->a_text.te_ypix = ypix; 966 glist_add(gl, &x->a_text.te_g); 967 glist_noselect(gl); 968 glist_select(gl, &x->a_text.te_g); 969 canvas_startmotion(glist_getcanvas(gl)); 970 } 971} 972 973void canvas_floatatom(t_glist *gl, t_symbol *s, int argc, t_atom *argv) 974{ 975 canvas_atom(gl, A_FLOAT, s, argc, argv); 976} 977 978void canvas_symbolatom(t_glist *gl, t_symbol *s, int argc, t_atom *argv) 979{ 980 canvas_atom(gl, A_SYMBOL, s, argc, argv); 981} 982 983static void gatom_free(t_gatom *x) 984{ 985 if (*x->a_symfrom->s_name) 986 pd_unbind(&x->a_text.te_pd, 987 canvas_realizedollar(x->a_glist, x->a_symfrom)); 988#ifndef ROCKBOX 989 gfxstub_deleteforkey(x); 990#endif 991} 992 993static void gatom_properties(t_gobj *z, t_glist *owner) 994{ 995#ifdef ROCKBOX 996 (void) z; 997 (void) owner; 998#else /* ROCKBOX */ 999 t_gatom *x = (t_gatom *)z; 1000 char buf[200]; 1001 sprintf(buf, "pdtk_gatom_dialog %%s %d %g %g %d %s %s %s\n", 1002 x->a_text.te_width, x->a_draglo, x->a_draghi, 1003 x->a_wherelabel, gatom_escapit(x->a_label)->s_name, 1004 gatom_escapit(x->a_symfrom)->s_name, 1005 gatom_escapit(x->a_symto)->s_name); 1006 gfxstub_new(&x->a_text.te_pd, x, buf); 1007#endif /* ROCKBOX */ 1008} 1009 1010 1011/* -------------------- widget behavior for text objects ------------ */ 1012 1013static void text_getrect(t_gobj *z, t_glist *glist, 1014 int *xp1, int *yp1, int *xp2, int *yp2) 1015{ 1016 t_text *x = (t_text *)z; 1017 int width, height, iscomment = (x->te_type == T_TEXT); 1018 float x1, y1, x2, y2; 1019 1020 /* for number boxes, we know width and height a priori, and should 1021 report them here so that graphs can get swelled to fit. */ 1022 1023 if (x->te_type == T_ATOM && x->te_width > 0) 1024 { 1025#ifdef ROCKBOX 1026 int fontwidth = 8, fontheight = 10; 1027#else 1028 int font = glist_getfont(glist); 1029 int fontwidth = sys_fontwidth(font), fontheight = sys_fontheight(font); 1030#endif 1031 width = (x->te_width > 0 ? x->te_width : 6) * fontwidth + 2; 1032 height = fontheight + 1; /* borrowed from TMARGIN, etc, in g_rtext.c */ 1033 } 1034 /* if we're invisible we don't know our size so we just lie about 1035 it. This is called on invisible boxes to establish order of inlets 1036 and possibly other reasons. 1037 To find out if the box is visible we can't just check the "vis" 1038 flag because we might be within the vis() routine and not have set 1039 that yet. So we check directly whether the "rtext" list has been 1040 built. LATER reconsider when "vis" flag should be on and off? */ 1041 1042 else if (glist->gl_editor && glist->gl_editor->e_rtext) 1043 { 1044 t_rtext *y = glist_findrtext(glist, x); 1045 width = rtext_width(y); 1046 height = rtext_height(y) - (iscomment << 1); 1047 } 1048 else width = height = 10; 1049 x1 = text_xpix(x, glist); 1050 y1 = text_ypix(x, glist); 1051 x2 = x1 + width; 1052 y2 = y1 + height; 1053 y1 += iscomment; 1054 *xp1 = x1; 1055 *yp1 = y1; 1056 *xp2 = x2; 1057 *yp2 = y2; 1058} 1059 1060static void text_displace(t_gobj *z, t_glist *glist, 1061 int dx, int dy) 1062{ 1063 t_text *x = (t_text *)z; 1064 x->te_xpix += dx; 1065 x->te_ypix += dy; 1066 if (glist_isvisible(glist)) 1067 { 1068 t_rtext *y = glist_findrtext(glist, x); 1069 rtext_displace(y, dx, dy); 1070 text_drawborder(x, glist, rtext_gettag(y), 1071 rtext_width(y), rtext_height(y), 0); 1072 canvas_fixlinesfor(glist_getcanvas(glist), x); 1073 } 1074} 1075 1076static void text_select(t_gobj *z, t_glist *glist, int state) 1077{ 1078 t_text *x = (t_text *)z; 1079 t_rtext *y = glist_findrtext(glist, x); 1080 rtext_select(y, state); 1081 if (glist_isvisible(glist) && text_shouldvis(x, glist)) 1082#ifdef ROCKBOX 1083 { 1084 } 1085#else /* ROCKBOX */ 1086 sys_vgui(".x%x.c itemconfigure %sR -fill %s\n", glist, 1087 rtext_gettag(y), (state? "blue" : "black")); 1088#endif /* ROCKBOX */ 1089} 1090 1091static void text_activate(t_gobj *z, t_glist *glist, int state) 1092{ 1093 t_text *x = (t_text *)z; 1094 t_rtext *y = glist_findrtext(glist, x); 1095 if (z->g_pd != gatom_class) rtext_activate(y, state); 1096} 1097 1098static void text_delete(t_gobj *z, t_glist *glist) 1099{ 1100 t_text *x = (t_text *)z; 1101 canvas_deletelinesfor(glist, x); 1102} 1103 1104 /* return true if the text box should be drawn. 1105 We don't show object boxes inside graphs. */ 1106int text_shouldvis(t_text *x, t_glist *glist) 1107{ 1108 return (glist->gl_havewindow || 1109 (x->te_pd != canvas_class && x->te_pd->c_wb != &text_widgetbehavior) || 1110 (x->te_pd == canvas_class && (((t_glist *)x)->gl_isgraph))); 1111} 1112 1113static void text_vis(t_gobj *z, t_glist *glist, int vis) 1114{ 1115 t_text *x = (t_text *)z; 1116 if (vis) 1117 { 1118 if (text_shouldvis(x, glist)) 1119 { 1120 t_rtext *y = glist_findrtext(glist, x); 1121 if (x->te_type == T_ATOM) 1122 glist_retext(glist, x); 1123 text_drawborder(x, glist, rtext_gettag(y), 1124 rtext_width(y), rtext_height(y), 1); 1125 rtext_draw(y); 1126 } 1127 } 1128 else 1129 { 1130 t_rtext *y = glist_findrtext(glist, x); 1131 if (text_shouldvis(x, glist)) 1132 { 1133 text_eraseborder(x, glist, rtext_gettag(y)); 1134 rtext_erase(y); 1135 } 1136 } 1137} 1138 1139static int text_click(t_gobj *z, struct _glist *glist, 1140 int xpix, int ypix, int shift, int alt, int dbl, int doit) 1141{ 1142#ifdef ROCKBOX 1143 (void) glist; 1144 (void) dbl; 1145#endif 1146 t_text *x = (t_text *)z; 1147 if (x->te_type == T_OBJECT) 1148 { 1149 t_symbol *clicksym = gensym("click"); 1150 if (zgetfn(&x->te_pd, clicksym)) 1151 { 1152 if (doit) 1153 pd_vmess(&x->te_pd, clicksym, "fffff", 1154 (double)xpix, (double)ypix, 1155 (double)shift, 0, (double)alt); 1156 return (1); 1157 } 1158 else return (0); 1159 } 1160 else if (x->te_type == T_ATOM) 1161 { 1162 if (doit) 1163 gatom_click((t_gatom *)x, (t_floatarg)xpix, (t_floatarg)ypix, 1164 (t_floatarg)shift, 0, (t_floatarg)alt); 1165 return (1); 1166 } 1167 else if (x->te_type == T_MESSAGE) 1168 { 1169 if (doit) 1170 message_click((t_message *)x, (t_floatarg)xpix, (t_floatarg)ypix, 1171 (t_floatarg)shift, 0, (t_floatarg)alt); 1172 return (1); 1173 } 1174 else return (0); 1175} 1176 1177void text_save(t_gobj *z, t_binbuf *b) 1178{ 1179 t_text *x = (t_text *)z; 1180 if (x->te_type == T_OBJECT) 1181 { 1182 /* if we have a "saveto" method, and if we don't happen to be 1183 a canvas that's an abstraction, the saveto method does the work */ 1184 if (zgetfn(&x->te_pd, gensym("saveto")) && 1185 !((pd_class(&x->te_pd) == canvas_class) && 1186 (canvas_isabstraction((t_canvas *)x) 1187 || canvas_istable((t_canvas *)x)))) 1188 { 1189 mess1(&x->te_pd, gensym("saveto"), b); 1190 binbuf_addv(b, "ssii", gensym("#X"), gensym("restore"), 1191 (t_int)x->te_xpix, (t_int)x->te_ypix); 1192 } 1193 else /* otherwise just save the text */ 1194 { 1195 binbuf_addv(b, "ssii", gensym("#X"), gensym("obj"), 1196 (t_int)x->te_xpix, (t_int)x->te_ypix); 1197 } 1198 binbuf_addbinbuf(b, x->te_binbuf); 1199 binbuf_addv(b, ";"); 1200 } 1201 else if (x->te_type == T_MESSAGE) 1202 { 1203 binbuf_addv(b, "ssii", gensym("#X"), gensym("msg"), 1204 (t_int)x->te_xpix, (t_int)x->te_ypix); 1205 binbuf_addbinbuf(b, x->te_binbuf); 1206 binbuf_addv(b, ";"); 1207 } 1208 else if (x->te_type == T_ATOM) 1209 { 1210 t_atomtype t = ((t_gatom *)x)->a_atom.a_type; 1211 t_symbol *sel = (t == A_SYMBOL ? gensym("symbolatom") : 1212 (t == A_FLOAT ? gensym("floatatom") : gensym("intatom"))); 1213 t_symbol *label = gatom_escapit(((t_gatom *)x)->a_label); 1214 t_symbol *symfrom = gatom_escapit(((t_gatom *)x)->a_symfrom); 1215 t_symbol *symto = gatom_escapit(((t_gatom *)x)->a_symto); 1216 binbuf_addv(b, "ssiiifffsss", gensym("#X"), sel, 1217 (t_int)x->te_xpix, (t_int)x->te_ypix, (t_int)x->te_width, 1218 (double)((t_gatom *)x)->a_draglo, 1219 (double)((t_gatom *)x)->a_draghi, 1220 (double)((t_gatom *)x)->a_wherelabel, 1221 label, symfrom, symto); 1222 binbuf_addv(b, ";"); 1223 } 1224 else 1225 { 1226 binbuf_addv(b, "ssii", gensym("#X"), gensym("text"), 1227 (t_int)x->te_xpix, (t_int)x->te_ypix); 1228 binbuf_addbinbuf(b, x->te_binbuf); 1229 binbuf_addv(b, ";"); 1230 } 1231} 1232 1233 /* this one is for everyone but "gatoms"; it's imposed in m_class.c */ 1234t_widgetbehavior text_widgetbehavior = 1235{ 1236 text_getrect, 1237 text_displace, 1238 text_select, 1239 text_activate, 1240 text_delete, 1241 text_vis, 1242 text_click, 1243}; 1244 1245static t_widgetbehavior gatom_widgetbehavior = 1246{ 1247 text_getrect, 1248 gatom_displace, 1249 text_select, 1250 text_activate, 1251 text_delete, 1252 gatom_vis, 1253 text_click, 1254}; 1255 1256/* -------------------- the "text" class ------------ */ 1257 1258#ifdef MACOSX 1259#define EXTRAPIX 2 1260#else 1261#define EXTRAPIX 1 1262#endif 1263 1264 /* draw inlets and outlets for a text object or for a graph. */ 1265void glist_drawiofor(t_glist *glist, t_object *ob, int firsttime, 1266 char *tag, int x1, int y1, int x2, int y2) 1267{ 1268#ifdef ROCKBOX 1269 (void) glist; 1270 (void) ob; 1271 (void) firsttime; 1272 (void) tag; 1273 (void) x1; 1274 (void) y1; 1275 (void) x2; 1276 (void) y2; 1277#else /* ROCKBOX */ 1278 int n = obj_noutlets(ob), i; 1279 int width = x2 - x1; 1280 int nplus = (n == 1 ? 1 : n-1); 1281 1282 for (i = 0; i < n; i++) 1283 { 1284 int onset = x1 + (width - IOWIDTH) * i / nplus; 1285 if (firsttime) 1286 sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %so%d\n", 1287 glist_getcanvas(glist), 1288 onset, y2 - 1, 1289 onset + IOWIDTH, y2, 1290 tag, i); 1291 else 1292 sys_vgui(".x%x.c coords %so%d %d %d %d %d\n", 1293 glist_getcanvas(glist), tag, i, 1294 onset, y2 - 1, 1295 onset + IOWIDTH, y2); 1296 } 1297 1298 n = obj_ninlets(ob); 1299 nplus = (n == 1 ? 1 : n-1); 1300 for (i = 0; i < n; i++) 1301 { 1302 int onset = x1 + (width - IOWIDTH) * i / nplus; 1303 if (firsttime) 1304 sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %si%d\n", 1305 glist_getcanvas(glist), 1306 onset, y1, 1307 onset + IOWIDTH, y1 + EXTRAPIX, 1308 tag, i); 1309 else 1310 sys_vgui(".x%x.c coords %si%d %d %d %d %d\n", 1311 glist_getcanvas(glist), tag, i, 1312 onset, y1, 1313 onset + IOWIDTH, y1 + EXTRAPIX); 1314 } 1315#endif /* ROCKBOX */ 1316} 1317 1318void text_drawborder(t_text *x, t_glist *glist, 1319 char *tag, int width2, int height2, int firsttime) 1320{ 1321 t_object *ob; 1322 int x1, y1, x2, y2 /* , width, height */; 1323 1324#ifdef ROCKBOX 1325 (void) width2; 1326 (void) height2; 1327#endif 1328 1329 text_getrect(&x->te_g, glist, &x1, &y1, &x2, &y2); 1330 /* width = x2 - x1; */ 1331 /* height = y2 - y1; */ 1332 if (x->te_type == T_OBJECT) 1333 { 1334#ifndef ROCKBOX 1335 if (firsttime) 1336 sys_vgui(".x%x.c create line\ 1337 %d %d %d %d %d %d %d %d %d %d -tags %sR\n", 1338 glist_getcanvas(glist), 1339 x1, y1, x2, y1, x2, y2, x1, y2, x1, y1, tag); 1340 else 1341 sys_vgui(".x%x.c coords %sR\ 1342 %d %d %d %d %d %d %d %d %d %d\n", 1343 glist_getcanvas(glist), tag, 1344 x1, y1, x2, y1, x2, y2, x1, y2, x1, y1); 1345#endif 1346 } 1347 else if (x->te_type == T_MESSAGE) 1348 { 1349#ifndef ROCKBOX 1350 if (firsttime) 1351 sys_vgui(".x%x.c create line\ 1352 %d %d %d %d %d %d %d %d %d %d %d %d %d %d -tags %sR\n", 1353 glist_getcanvas(glist), 1354 x1, y1, x2+4, y1, x2, y1+4, x2, y2-4, x2+4, y2, 1355 x1, y2, x1, y1, 1356 tag); 1357 else 1358 sys_vgui(".x%x.c coords %sR\ 1359 %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", 1360 glist_getcanvas(glist), tag, 1361 x1, y1, x2+4, y1, x2, y1+4, x2, y2-4, x2+4, y2, 1362 x1, y2, x1, y1); 1363#endif 1364 } 1365 else if (x->te_type == T_ATOM) 1366 { 1367#ifndef ROCKBOX 1368 if (firsttime) 1369 sys_vgui(".x%x.c create line\ 1370 %d %d %d %d %d %d %d %d %d %d %d %d -tags %sR\n", 1371 glist_getcanvas(glist), 1372 x1, y1, x2-4, y1, x2, y1+4, x2, y2, x1, y2, x1, y1, 1373 tag); 1374 else 1375 sys_vgui(".x%x.c coords %sR\ 1376 %d %d %d %d %d %d %d %d %d %d %d %d\n", 1377 glist_getcanvas(glist), tag, 1378 x1, y1, x2-4, y1, x2, y1+4, x2, y2, x1, y2, x1, y1); 1379#endif 1380 } 1381 /* draw inlets/outlets */ 1382 1383 if ((ob = pd_checkobject(&x->te_pd))) 1384 glist_drawiofor(glist, ob, firsttime, tag, x1, y1, x2, y2); 1385} 1386 1387void glist_eraseiofor(t_glist *glist, t_object *ob, char *tag) 1388{ 1389 int i, n; 1390#ifdef ROCKBOX 1391 (void) glist; 1392 (void) tag; 1393#endif 1394 n = obj_noutlets(ob); 1395 for (i = 0; i < n; i++) 1396#ifdef ROCKBOX 1397 ; 1398#else /* ROCKBOX */ 1399 sys_vgui(".x%x.c delete %so%d\n", 1400 glist_getcanvas(glist), tag, i); 1401#endif /* ROCKBOX */ 1402 n = obj_ninlets(ob); 1403 for (i = 0; i < n; i++) 1404#ifdef ROCKBOX 1405 ; 1406#else /* ROCKBOX */ 1407 sys_vgui(".x%x.c delete %si%d\n", 1408 glist_getcanvas(glist), tag, i); 1409#endif /* ROCKBOX */ 1410} 1411 1412void text_eraseborder(t_text *x, t_glist *glist, char *tag) 1413{ 1414 if (x->te_type == T_TEXT) return; 1415#ifndef ROCKBOX 1416 sys_vgui(".x%x.c delete %sR\n", 1417 glist_getcanvas(glist), tag); 1418#endif 1419 glist_eraseiofor(glist, x, tag); 1420} 1421 1422 /* change text; if T_OBJECT, remake it. LATER we'll have an undo buffer 1423 which should be filled in here before making the change. */ 1424 1425void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize) 1426{ 1427 if (x->te_type == T_OBJECT) 1428 { 1429 t_binbuf *b = binbuf_new(); 1430 int natom1, natom2; 1431 t_atom *vec1, *vec2; 1432 binbuf_text(b, buf, bufsize); 1433 natom1 = binbuf_getnatom(x->te_binbuf); 1434 vec1 = binbuf_getvec(x->te_binbuf); 1435 natom2 = binbuf_getnatom(b); 1436 vec2 = binbuf_getvec(b); 1437 /* special case: if pd args change just pass the message on. */ 1438 if (natom1 >= 1 && natom2 >= 1 && vec1[0].a_type == A_SYMBOL 1439 && !strcmp(vec1[0].a_w.w_symbol->s_name, "pd") && 1440 vec2[0].a_type == A_SYMBOL 1441 && !strcmp(vec2[0].a_w.w_symbol->s_name, "pd")) 1442 { 1443 typedmess(&x->te_pd, gensym("rename"), natom2-1, vec2+1); 1444 binbuf_free(x->te_binbuf); 1445 x->te_binbuf = b; 1446 } 1447 else /* normally, just destroy the old one and make a new one. */ 1448 { 1449 int xwas = x->te_xpix, ywas = x->te_ypix; 1450 glist_delete(glist, &x->te_g); 1451 canvas_objtext(glist, xwas, ywas, 0, b); 1452 /* if it's an abstraction loadbang it here */ 1453 if (newest && pd_class(newest) == canvas_class) 1454 canvas_loadbang((t_canvas *)newest); 1455 canvas_restoreconnections(glist_getcanvas(glist)); 1456 } 1457 /* if we made a new "pd" or changed a window name, 1458 update window list */ 1459 if (natom2 >= 1 && vec2[0].a_type == A_SYMBOL 1460 && !strcmp(vec2[0].a_w.w_symbol->s_name, "pd")) 1461 canvas_updatewindowlist(); 1462 } 1463 else binbuf_text(x->te_binbuf, buf, bufsize); 1464} 1465 1466void g_text_setup(void) 1467{ 1468 text_class = class_new(gensym("text"), 0, 0, sizeof(t_text), 1469 CLASS_NOINLET | CLASS_PATCHABLE, 0); 1470 1471 message_class = class_new(gensym("message"), 0, (t_method)message_free, 1472 sizeof(t_message), CLASS_PATCHABLE, 0); 1473 class_addbang(message_class, message_bang); 1474 class_addfloat(message_class, message_float); 1475 class_addsymbol(message_class, message_symbol); 1476 class_addlist(message_class, message_list); 1477 class_addanything(message_class, message_list); 1478 1479 class_addmethod(message_class, (t_method)message_click, gensym("click"), 1480 A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); 1481 class_addmethod(message_class, (t_method)message_set, gensym("set"), 1482 A_GIMME, 0); 1483 class_addmethod(message_class, (t_method)message_add, gensym("add"), 1484 A_GIMME, 0); 1485 class_addmethod(message_class, (t_method)message_add2, gensym("add2"), 1486 A_GIMME, 0); 1487 1488 messresponder_class = class_new(gensym("messresponder"), 0, 0, 1489 sizeof(t_text), CLASS_PD, 0); 1490 class_addbang(messresponder_class, messresponder_bang); 1491 class_addfloat(messresponder_class, (t_method) messresponder_float); 1492 class_addsymbol(messresponder_class, messresponder_symbol); 1493 class_addlist(messresponder_class, messresponder_list); 1494 class_addanything(messresponder_class, messresponder_anything); 1495 1496 gatom_class = class_new(gensym("gatom"), 0, (t_method)gatom_free, 1497 sizeof(t_gatom), CLASS_NOINLET | CLASS_PATCHABLE, 0); 1498 class_addbang(gatom_class, gatom_bang); 1499 class_addfloat(gatom_class, gatom_float); 1500 class_addsymbol(gatom_class, gatom_symbol); 1501 class_addmethod(gatom_class, (t_method)gatom_set, gensym("set"), 1502 A_GIMME, 0); 1503 class_addmethod(gatom_class, (t_method)gatom_click, gensym("click"), 1504 A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); 1505 class_addmethod(gatom_class, (t_method)gatom_param, gensym("param"), 1506 A_GIMME, 0); 1507 class_setwidget(gatom_class, &gatom_widgetbehavior); 1508 class_setpropertiesfn(gatom_class, gatom_properties); 1509} 1510