Newer
Older
/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* g_7_guis.c written by Thomas Musil (c) IEM KUG Graz Austria 2000-2001 */
/* thanks to Miller Puckette, Guenther Geiger and Krzystof Czaja */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "m_pd.h"
#include "g_canvas.h"
Mathieu L Bouchard
committed
t_symbol *s_empty;
t_class *scalehandle_class;
Mathieu L Bouchard
committed
Mathieu L Bouchard
committed
int iemgui_color_hex[] = {
0xfcfcfc, 0xa0a0a0, 0x404040, 0xfce0e0, 0xfce0c0, 0xfcfcc8, 0xd8fcd8, 0xd8fcfc, 0xdce4fc, 0xf8d8fc,
0xe0e0e0, 0x7c7c7c, 0x202020, 0xfc2828, 0xfcac44, 0xe8e828, 0x14e814, 0x28f4f4, 0x3c50fc, 0xf430f0,
0xbcbcbc, 0x606060, 0x000000, 0x8c0808, 0x583000, 0x782814, 0x285014, 0x004450, 0x001488, 0x580050
Mathieu L Bouchard
committed
int iemgui_clip_size(int size) {return maxi(size,IEM_GUI_MINSIZE);}
int iemgui_clip_font(int size) {return maxi(size,IEM_FONT_MINSIZE);}
static void scalehandle_check_and_redraw(t_iemgui *x);
Mathieu L Bouchard
committed
static int iemgui_modulo_color(int col)
const int IEM_GUI_MAX_COLOR = 30;
Mathieu L Bouchard
committed
col %= IEM_GUI_MAX_COLOR;
if (col<0) col += IEM_GUI_MAX_COLOR;
return col;
}
t_symbol *iemgui_dollar2raute(t_symbol *s)
{
char buf[MAXPDSTRING+1], *s1, *s2;
if (strlen(s->s_name) >= MAXPDSTRING)
return (s);
for (s1 = s->s_name, s2 = buf; ; s1++, s2++)
{
if (*s1 == '$')
*s2 = '#';
else if (!(*s2 = *s1))
break;
}
return(gensym(buf));
}
t_symbol *iemgui_raute2dollar(t_symbol *s)
{
char buf[MAXPDSTRING+1], *s1, *s2;
if (strlen(s->s_name) >= MAXPDSTRING)
return (s);
for (s1 = s->s_name, s2 = buf; ; s1++, s2++)
{
if (*s1 == '#')
*s2 = '$';
else if (!(*s2 = *s1))
break;
}
return(gensym(buf));
}
Mathieu L Bouchard
committed
void iemgui_verify_snd_ne_rcv(t_iemgui *x)
Mathieu L Bouchard
committed
x->x_put_in2out =
!(iemgui_has_snd(x) && iemgui_has_rcv(x) && x->x_snd==x->x_rcv);
Mathieu L Bouchard
committed
t_symbol *iemgui_getfloatsym(t_atom *a)
Mathieu L Bouchard
committed
if (IS_A_SYMBOL(a,0)) return (atom_getsymbol(a));
if (IS_A_FLOAT(a,0)) {
char str[40];
sprintf(str, "%d", (int)atom_getint(a));
return gensym(str);
Mathieu L Bouchard
committed
return s_empty;
}
t_symbol *iemgui_getfloatsymarg(int i, int argc, t_atom *argv)
{
if (i>=0 && i<argc) return iemgui_getfloatsym(argv+i);
return s_empty;
Mathieu L Bouchard
committed
void iemgui_new_getnames(t_iemgui *x, int indx, t_atom *argv)
Mathieu L Bouchard
committed
x->x_snd = iemgui_getfloatsym(argv+indx+0);
x->x_rcv = iemgui_getfloatsym(argv+indx+1);
x->x_lab = iemgui_getfloatsym(argv+indx+2);
Mathieu L Bouchard
committed
else x->x_snd = x->x_rcv = x->x_lab = s_empty;
x->x_snd_unexpanded = x->x_rcv_unexpanded = x->x_lab_unexpanded = 0;
x->x_binbufindex = indx;
x->x_labelbindex = indx + 3;
Mathieu L Bouchard
committed
/* initialize a single symbol in unexpanded form. We reach into the
binbuf to grab them; if there's nothing there, set it to the
fallback; if still nothing, set to "empty". */
static void iemgui_init_sym2dollararg(t_iemgui *x, t_symbol **symp,
int indx, t_symbol *fallback)
{
if (!*symp)
{
Mathieu L Bouchard
committed
t_binbuf *b = x->x_obj.ob_binbuf;
if (binbuf_getnatom(b) > indx)
{
char buf[80];
atom_string(binbuf_getvec(b) + indx, buf, 80);
*symp = gensym(buf);
}
else if (fallback)
*symp = fallback;
Mathieu L Bouchard
committed
else *symp = s_empty;
Mathieu L Bouchard
committed
/* get the unexpanded versions of the symbols; initialize them if necessary. */
Mathieu L Bouchard
committed
void iemgui_all_sym2dollararg(t_iemgui *x, t_symbol **srlsym)
Mathieu L Bouchard
committed
iemgui_init_sym2dollararg(x, &x->x_snd_unexpanded, x->x_binbufindex+1, x->x_snd);
iemgui_init_sym2dollararg(x, &x->x_rcv_unexpanded, x->x_binbufindex+2, x->x_rcv);
iemgui_init_sym2dollararg(x, &x->x_lab_unexpanded, x->x_labelbindex, x->x_lab);
srlsym[0] = x->x_snd_unexpanded;
srlsym[1] = x->x_rcv_unexpanded;
srlsym[2] = x->x_lab_unexpanded;
Mathieu L Bouchard
committed
static int col2save(int col) {
return -1-(((0xfc0000 & col) >> 6)|((0xfc00 & col) >> 4)|((0xfc & col) >> 2));
}
Mathieu L Bouchard
committed
void iemgui_all_col2save(t_iemgui *x, int *bflcol)
Mathieu L Bouchard
committed
bflcol[0] = col2save(x->x_bcol);
bflcol[1] = col2save(x->x_fcol);
bflcol[2] = col2save(x->x_lcol);
Mathieu L Bouchard
committed
static int colfromload(int col) {
if(col)
Mathieu L Bouchard
committed
col = -1-col;
return ((col & 0x3f000) << 6)|((col & 0xfc0) << 4)|((col & 0x3f) << 2);
Mathieu L Bouchard
committed
return iemgui_color_hex[iemgui_modulo_color(col)];
}
Mathieu L Bouchard
committed
void iemgui_all_colfromload(t_iemgui *x, int *bflcol)
Mathieu L Bouchard
committed
{
Mathieu L Bouchard
committed
x->x_bcol = colfromload(bflcol[0]);
x->x_fcol = colfromload(bflcol[1]);
x->x_lcol = colfromload(bflcol[2]);
Mathieu L Bouchard
committed
static int iemgui_compatible_col(int i)
Mathieu L Bouchard
committed
return(iemgui_color_hex[(iemgui_modulo_color(i))]);
return((-1-i)&0xffffff);
}
void iemgui_all_raute2dollar(t_symbol **srlsym)
{
srlsym[0] = iemgui_raute2dollar(srlsym[0]);
srlsym[1] = iemgui_raute2dollar(srlsym[1]);
srlsym[2] = iemgui_raute2dollar(srlsym[2]);
}
Mathieu L Bouchard
committed
void iemgui_send(t_iemgui *x, t_symbol *s)
Ivica Bukvic
committed
if (s == &s_) s = s_empty; //tb: fix for empty label
Mathieu L Bouchard
committed
int oldsndrcvable=0;
if(iemgui_has_rcv(x)) oldsndrcvable += IEM_GUI_OLD_RCV_FLAG;
if(iemgui_has_snd(x)) oldsndrcvable += IEM_GUI_OLD_SND_FLAG;
Mathieu L Bouchard
committed
x->x_snd_unexpanded = snd;
x->x_snd = snd = canvas_realizedollar(x->x_glist, snd);
iemgui_verify_snd_ne_rcv(x);
Mathieu L Bouchard
committed
iemgui_draw_io(x, oldsndrcvable);
Mathieu L Bouchard
committed
void iemgui_receive(t_iemgui *x, t_symbol *s)
Ivica Bukvic
committed
if (s == &s_) s = s_empty; //tb: fix for empty label
Mathieu L Bouchard
committed
int oldsndrcvable=0;
if(iemgui_has_rcv(x)) oldsndrcvable += IEM_GUI_OLD_RCV_FLAG;
if(iemgui_has_snd(x)) oldsndrcvable += IEM_GUI_OLD_SND_FLAG;
Mathieu L Bouchard
committed
x->x_rcv_unexpanded = rcv;
rcv = canvas_realizedollar(x->x_glist, rcv);
Ivica Bukvic
committed
if(s!=s_empty)
Mathieu L Bouchard
committed
if(rcv!=x->x_rcv)
Mathieu L Bouchard
committed
if(iemgui_has_rcv(x))
pd_unbind((t_pd *)x, x->x_rcv);
x->x_rcv = rcv;
pd_bind((t_pd *)x, x->x_rcv);
Ivica Bukvic
committed
else if(s==s_empty && iemgui_has_rcv(x))
Mathieu L Bouchard
committed
pd_unbind((t_pd *)x, x->x_rcv);
x->x_rcv = rcv;
Mathieu L Bouchard
committed
iemgui_verify_snd_ne_rcv(x);
Mathieu L Bouchard
committed
iemgui_draw_io(x, oldsndrcvable);
Mathieu L Bouchard
committed
void iemgui_label(t_iemgui *x, t_symbol *s)
Mathieu L Bouchard
committed
if (s == &s_) s = s_empty; //tb: fix for empty label
t_symbol *lab = iemgui_raute2dollar(s);
x->x_lab_unexpanded = lab;
x->x_lab = lab = canvas_realizedollar(x->x_glist, lab);
Mathieu L Bouchard
committed
if(glist_isvisible(x->x_glist))
sys_vgui(".x%lx.c itemconfigure %lxLABEL -text {%s} \n",
Mathieu L Bouchard
committed
glist_getcanvas(x->x_glist), x,
s!=s_empty?x->x_lab->s_name:"");
gui_vmess("gui_iemgui_label_set", "xxs",
glist_getcanvas(x->x_glist),
x,
s != s_empty ? x->x_lab->s_name : "");
Mathieu L Bouchard
committed
iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_CONFIG);
Mathieu L Bouchard
committed
void iemgui_label_pos(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Mathieu L Bouchard
committed
x->x_ldx = atom_getintarg(0, ac, av);
x->x_ldy = atom_getintarg(1, ac, av);
Mathieu L Bouchard
committed
if(glist_isvisible(x->x_glist))
//sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
// glist_getcanvas(x->x_glist), x,
// text_xpix((t_object *)x,x->x_glist)+x->x_ldx,
// text_ypix((t_object *)x,x->x_glist)+x->x_ldy);
gui_vmess("gui_iemgui_label_coords", "xxii",
glist_getcanvas(x->x_glist),
x,
Mathieu L Bouchard
committed
iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_CONFIG);
Mathieu L Bouchard
committed
void iemgui_label_font(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Mathieu L Bouchard
committed
int f = atom_getintarg(0, ac, av);
Mathieu L Bouchard
committed
if (f<0 || f>2) f=0;
x->x_font_style = f;
Mathieu L Bouchard
committed
x->x_fontsize = maxi(atom_getintarg(1, ac, av),4);
Mathieu L Bouchard
committed
if(glist_isvisible(x->x_glist))
//sys_vgui(".x%lx.c itemconfigure %lxLABEL -font %s\n",
// glist_getcanvas(x->x_glist), x, iemgui_font(x));
gui_vmess("gui_iemgui_label_font", "xxssi",
glist_getcanvas(x->x_glist),
x,
iemgui_typeface(x),
sys_fontweight,
x->x_fontsize);
iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_CONFIG);
}
//Sans: 84 x 10 (14) -> 6 x 10 -> 1.0
//Helvetica: 70 x 10 (14) -> 5 x 10 -> 0.83333
//Times: 61 x 10 (14) -> 4.357 x 10 -> 0.72619; 0.735 appears to work better
// We use this global var to check when getrect should report label:
// It should report it when drawing inside gop to see if we truly fit.
// Otherwise we should not report it while inside gop to avoid label being
// misinterpreted as part of the "hot" area of a widget (e.g. toggle)
extern int gop_redraw;
void iemgui_label_getrect(t_iemgui x_gui, t_glist *x,
int *xp1, int *yp1, int *xp2, int *yp2)
{
//fprintf(stderr,"gop_redraw = %d\n", gop_redraw);
if (!gop_redraw)
{
//fprintf(stderr,"ignoring label\n");
}
t_float width_multiplier;
int label_x1;
int label_y1;
int label_x2;
int label_y2;
int actual_fontsize; //seems tk does its own thing when rendering
int actual_height;
if (x->gl_isgraph && !glist_istoplevel(x))
{
Mathieu L Bouchard
committed
if (x_gui.x_lab!=s_empty)
Mathieu L Bouchard
committed
switch(x_gui.x_font_style)
Mathieu L Bouchard
committed
case 1: width_multiplier = 0.83333; break;
case 2: width_multiplier = 0.735; break;
default: width_multiplier = 1.0; break;
Mathieu L Bouchard
committed
actual_fontsize = x_gui.x_fontsize;
actual_height = actual_fontsize;
Mathieu L Bouchard
committed
if (x_gui.x_font_style == 0 &&
(actual_fontsize == 8 || actual_fontsize == 13 ||
actual_fontsize % 10 == 1 || actual_fontsize % 10 == 6 ||
(actual_fontsize > 48 && actual_fontsize < 100 &&
(actual_fontsize %10 == 4 || actual_fontsize %10 == 9))))
{
actual_fontsize += 1;
}
Mathieu L Bouchard
committed
else if (x_gui.x_font_style == 1 && actual_fontsize >= 5 &&
actual_fontsize < 13 && actual_fontsize % 2 == 1)
actual_fontsize += 1;
Mathieu L Bouchard
committed
else if (x_gui.x_font_style == 2 && actual_fontsize >= 5 &&
actual_fontsize % 2 == 1)
actual_fontsize += 1;
if (actual_height == 9)
actual_height += 1;
//done with exceptions
width_multiplier = width_multiplier * (actual_fontsize * 0.6);
label_length = strlen(x_gui.x_lab->s_name);
label_x1 = *xp1 + x_gui.x_ldx;
label_y1 = *yp1 + x_gui.x_ldy - actual_height/2;
label_x2 = label_x1 + (label_length * width_multiplier);
label_y2 = label_y1 + actual_height*1.1;
//DEBUG
//fprintf(stderr,"%f %d %d\n", width_multiplier,
Mathieu L Bouchard
committed
// label_length, x_gui.x_font_style);
//sys_vgui(".x%lx.c delete iemguiDEBUG\n", x);
//sys_vgui(".x%lx.c create rectangle %d %d %d %d "
// "-tags iemguiDEBUG\n",
// x, label_x1, label_y1, label_x2, label_y2);
if (label_x1 < *xp1) *xp1 = label_x1;
if (label_x2 > *xp2) *xp2 = label_x2;
if (label_y1 < *yp1) *yp1 = label_y1;
if (label_y2 > *yp2) *yp2 = label_y2;
//DEBUG
//sys_vgui(".x%lx.c delete iemguiDEBUG\n", x);
//sys_vgui(".x%lx.c create rectangle %d %d %d %d "
// "-tags iemguiDEBUG\n", x, *xp1, *yp1, *xp2, *yp2);
}
}
}
Mathieu L Bouchard
committed
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
#if 0 // future way of reordering stuff for iemgui_shouldvis
/*
// some day when the object tagging is
// properly done for all GUI objects
glist_noselect(canvas);
glist_select(canvas, y);
t_gobj *yy = canvas->gl_list;
if (yy != y)
{
while (yy && yy->g_next != y)
yy = yy->g_next;
// now we have yy which is right before our y graph
t_rtext *yr = NULL;
if (yy)
{
yr = glist_findrtext(canvas, (t_text *)yy);
}
if (yr)
{
fprintf(stderr,"lower\n");
sys_vgui(".x%lx.c lower selected %s\n", canvas, rtext_gettag(yr));
sys_vgui(".x%lx.c raise selected %s\n", canvas, rtext_gettag(yr));
//canvas_raise_all_cords(canvas);
}
else
{
// fall back to legacy redraw for objects
// that are not patchable
fprintf(stderr,"lower fallback redraw\n");
canvas_redraw(canvas);
}
}
else
{
// we get here if we are supposed to go
// all the way to the bottom
fprintf(stderr,"lower to the bottom\n");
sys_vgui(".x%lx.c lower selected\n", canvas);
}
glist_noselect(canvas);
*/
#endif
Mathieu L Bouchard
committed
void iemgui_shouldvis(t_iemgui *x, int mode)
{
gop_redraw = 1;
Mathieu L Bouchard
committed
if(gobj_shouldvis((t_gobj *)x, x->x_glist))
Mathieu L Bouchard
committed
if (!x->x_vis)
{
//fprintf(stderr,"draw new %d\n", mode);
Mathieu L Bouchard
committed
iemgui_draw_new(x);
Mathieu L Bouchard
committed
canvas_fixlinesfor(glist_getcanvas(x->x_glist), (t_text*)x);
x->x_vis = 1;
if (x->x_glist != glist_getcanvas(x->x_glist))
{
/* if we are inside gop and just have had our object's
properties changed we'll adjust our layer position
to ensure that ordering is honored */
Mathieu L Bouchard
committed
t_canvas *canvas = glist_getcanvas(x->x_glist);
t_gobj *y = (t_gobj *)x->x_glist;
gobj_vis(y, canvas, 0);
gobj_vis(y, canvas, 1);
// reorder it visually
glist_redraw(canvas);
}
}
Mathieu L Bouchard
committed
//fprintf(stderr,"draw move x->x_w=%d\n", x->x_w);
Mathieu L Bouchard
committed
if (mode==IEM_GUI_DRAW_MODE_NEW) iemgui_draw_new( x);
else if (mode==IEM_GUI_DRAW_MODE_MOVE) iemgui_draw_move( x);
else if (mode==IEM_GUI_DRAW_MODE_CONFIG) iemgui_draw_config(x);
else bug("iemgui_shouldvis");
scalehandle_check_and_redraw(x);
Mathieu L Bouchard
committed
canvas_fixlinesfor(glist_getcanvas(x->x_glist), (t_text*)x);
Mathieu L Bouchard
committed
else if (x->x_vis)
{
//fprintf(stderr,"draw erase %d\n", mode);
Mathieu L Bouchard
committed
iemgui_draw_erase(x);
Ivica Bukvic
committed
x->x_vis = 0;
}
gop_redraw = 0;
Mathieu L Bouchard
committed
void iemgui_size(t_iemgui *x)
Mathieu L Bouchard
committed
if(glist_isvisible(x->x_glist))
iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_MOVE);
Mathieu L Bouchard
committed
void iemgui_delta(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Mathieu L Bouchard
committed
x->x_obj.te_xpix += atom_getintarg(0, ac, av);
x->x_obj.te_ypix += atom_getintarg(1, ac, av);
Mathieu L Bouchard
committed
if(glist_isvisible(x->x_glist))
iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_MOVE);
Mathieu L Bouchard
committed
void iemgui_pos(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Mathieu L Bouchard
committed
x->x_obj.te_xpix = atom_getintarg(0, ac, av);
x->x_obj.te_ypix = atom_getintarg(1, ac, av);
Mathieu L Bouchard
committed
if(glist_isvisible(x->x_glist))
iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_MOVE);
Mathieu L Bouchard
committed
void iemgui_color(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Mathieu L Bouchard
committed
x->x_bcol = iemgui_compatible_col(atom_getintarg(0, ac, av));
Mathieu L Bouchard
committed
x->x_fcol = iemgui_compatible_col(atom_getintarg(1, ac, av));
x->x_lcol = iemgui_compatible_col(atom_getintarg(2, ac, av));
Mathieu L Bouchard
committed
x->x_lcol = iemgui_compatible_col(atom_getintarg(1, ac, av));
if(glist_isvisible(x->x_glist))
Mathieu L Bouchard
committed
x->x_draw(x, x->x_glist, IEM_GUI_DRAW_MODE_CONFIG);
iemgui_label_draw_config(x);
}
}
void iemgui_displace(t_gobj *z, t_glist *glist, int dx, int dy)
{
Mathieu L Bouchard
committed
t_iemgui *x = (t_iemgui *)z;
x->x_obj.te_xpix += dx;
x->x_obj.te_ypix += dy;
iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_MOVE);
void iemgui_displace_withtag(t_gobj *z, t_glist *glist, int dx, int dy)
{
Mathieu L Bouchard
committed
t_iemgui *x = (t_iemgui *)z;
x->x_obj.te_xpix += dx;
x->x_obj.te_ypix += dy;
Mathieu L Bouchard
committed
//iemgui_draw_move(x);
canvas_fixlinesfor(glist_getcanvas(glist), (t_text *)z);
}
void iemgui_select(t_gobj *z, t_glist *glist, int selected)
{
Mathieu L Bouchard
committed
t_iemgui *x = (t_iemgui *)z;
Mathieu L Bouchard
committed
t_canvas *canvas=glist_getcanvas(glist);
if (selected)
x->x_selected = canvas;
else
x->x_selected = NULL;
//sys_vgui(".x%lx.c itemconfigure {x%lx&&border} -stroke %s\n", canvas, x,
// x->x_selected && x->x_glist == canvas ? selection_color : border_color);
gui_vmess("gui_text_select_color", "xx", canvas, x);
Mathieu L Bouchard
committed
x->x_draw((void *)z, glist, IEM_GUI_DRAW_MODE_SELECT);
Ivica Bukvic
committed
if (selected < 2)
{
scalehandle_draw(x);
}
else
{
// exception where we get rid of handles when moving tiny objects
// because tkpath's slowness sometimes makes mouse pointer go over
// a handle and messes things up. we only do this when using
// startmotion (see g_editor.c).
// LATER: get rid of this because we will deal with this better using
// the new toolkit.
scalehandle_draw_erase2(x);
}
Mathieu L Bouchard
committed
iemgui_label_draw_select(x);
iemgui_tag_selected(x);
}
void iemgui_delete(t_gobj *z, t_glist *glist)
{
canvas_deletelinesfor(glist, (t_text *)z);
}
void iemgui_vis(t_gobj *z, t_glist *glist, int vis)
{
Mathieu L Bouchard
committed
t_iemgui *x = (t_iemgui *)z;
if (gobj_shouldvis(z, glist))
{
if (vis)
Mathieu L Bouchard
committed
iemgui_draw_new(x);
Mathieu L Bouchard
committed
iemgui_draw_erase(x);
sys_unqueuegui(z);
}
Mathieu L Bouchard
committed
x->x_vis = vis;
Mathieu L Bouchard
committed
void iemgui_save(t_iemgui *x, t_symbol **srl, int *bflcol)
Mathieu L Bouchard
committed
if (srl) {
srl[0] = x->x_snd;
srl[1] = x->x_rcv;
srl[2] = x->x_lab;
}
iemgui_all_sym2dollararg(x, srl);
iemgui_all_col2save(x, bflcol);
Mathieu L Bouchard
committed
void iemgui_properties(t_iemgui *x, t_symbol **srl)
Mathieu L Bouchard
committed
srl[0] = x->x_snd;
srl[1] = x->x_rcv;
srl[2] = x->x_lab;
iemgui_all_sym2dollararg(x, srl);
srl[0] = iemgui_dollar2raute(srl[0]);
srl[1] = iemgui_dollar2raute(srl[1]);
srl[2] = iemgui_dollar2raute(srl[2]);
int iemgui_dialog(t_iemgui *x, int argc, t_atom *argv)
t_symbol *srl[3];
Mathieu L Bouchard
committed
x->x_loadinit = !!atom_getintarg(5, argc, argv);
srl[0] = iemgui_getfloatsymarg(7,argc,argv);
srl[1] = iemgui_getfloatsymarg(8,argc,argv);
srl[2] = iemgui_getfloatsymarg(9,argc,argv);
x->x_ldx = atom_getintarg(10, argc, argv);
x->x_ldy = atom_getintarg(11, argc, argv);
int f = atom_getintarg(12, argc, argv);
x->x_fontsize = maxi(atom_getintarg(13, argc, argv),4);
x->x_bcol = atom_getintarg(14, argc, argv) & 0xffffff;
x->x_fcol = atom_getintarg(15, argc, argv) & 0xffffff;
x->x_lcol = atom_getintarg(16, argc, argv) & 0xffffff;
int oldsndrcvable=0;
if(iemgui_has_rcv(x)) oldsndrcvable |= IEM_GUI_OLD_RCV_FLAG;
if(iemgui_has_snd(x)) oldsndrcvable |= IEM_GUI_OLD_SND_FLAG;
// replace ascii code 11 (\v or vertical tab) with spaces
// we do this so that the string with spaces can survive argc,argv
// conversion when coming from dialog side of things where it is parsed
char *c;
for(c = srl[2]->s_name; c != NULL && *c != '\0'; c++)
{
if(*c == '\v')
{
*c = ' ';
}
}
Mathieu L Bouchard
committed
x->x_snd_unexpanded=srl[0]; srl[0]=canvas_realizedollar(x->x_glist, srl[0]);
x->x_rcv_unexpanded=srl[1]; srl[1]=canvas_realizedollar(x->x_glist, srl[1]);
x->x_lab_unexpanded=srl[2]; srl[2]=canvas_realizedollar(x->x_glist, srl[2]);
if(srl[1]!=x->x_rcv)
Mathieu L Bouchard
committed
if(iemgui_has_rcv(x))
pd_unbind((t_pd *)x, x->x_rcv);
x->x_rcv = srl[1];
pd_bind((t_pd *)x, x->x_rcv);
Mathieu L Bouchard
committed
x->x_snd = srl[0];
x->x_lab = srl[2];
Mathieu L Bouchard
committed
if(f<0 || f>2) f=0;
Mathieu L Bouchard
committed
x->x_font_style = f;
iemgui_verify_snd_ne_rcv(x);
canvas_dirty(x->x_glist, 1);
return oldsndrcvable;
Mathieu L Bouchard
committed
void iem_inttosymargs(t_iemgui *x, int n)
Mathieu L Bouchard
committed
x->x_loadinit = (n >> 0);
x->x_locked = 0;
x->x_reverse = 0;
Mathieu L Bouchard
committed
int iem_symargstoint(t_iemgui *x)
Mathieu L Bouchard
committed
return ((x->x_loadinit & 1) << 0);
Mathieu L Bouchard
committed
void iem_inttofstyle(t_iemgui *x, int n)
Mathieu L Bouchard
committed
x->x_font_style = (n >> 0);
x->x_selected = NULL;
Mathieu L Bouchard
committed
x->x_finemoved = 0;
x->x_put_in2out = 0;
x->x_change = 0;
}
int iem_fstyletoint(t_iemgui *x)
Mathieu L Bouchard
committed
return ((x->x_font_style << 0) & 63);
char *iem_get_tag(t_canvas *glist, t_iemgui *iem_obj)
{
t_gobj *y = (t_gobj *)iem_obj;
t_object *ob = pd_checkobject(&y->g_pd);
/* GOP objects are unable to call findrtext
triggering consistency check error */
t_rtext *yyyy = NULL;
if (!glist->gl_isgraph || glist_istoplevel(glist))
yyyy = glist_findrtext(glist_getcanvas(glist), (t_text *)&ob->ob_g);
/* on GOP we cause segfault as text_gettag() returns bogus data */
if (yyyy) return(rtext_gettag(yyyy));
else return("bogus");
}
//----------------------------------------------------------------
Mathieu L Bouchard
committed
// SCALEHANDLE COMMON CODE (by Mathieu, refactored from existing code)
extern int gfxstub_haveproperties(void *key);
Mathieu L Bouchard
committed
int mini(int a, int b) {return a<b?a:b;}
int maxi(int a, int b) {return a>b?a:b;}
float minf(float a, float b) {return a<b?a:b;}
float maxf(float a, float b) {return a>b?a:b;}
// in all 20 cases :
// [bng], [tgl], [hradio], [vradio], [hsl], [vsl], [cnv], [nbx], [vu]
// for both scale & label, plus canvas' scale & move.
void scalehandle_bind(t_scalehandle *h) {
sys_vgui("bind %s <Button> {pd [concat %s _click 1 %%x %%y \\;]}\n",
h->h_pathname, h->h_bindsym->s_name);
sys_vgui("bind %s <ButtonRelease> {pd [concat %s _click 0 0 0 \\;]}\n",
h->h_pathname, h->h_bindsym->s_name);
sys_vgui("bind %s <Motion> {pd [concat %s _motion %%x %%y \\;]}\n",
h->h_pathname, h->h_bindsym->s_name);
}
// in 18 cases only, because canvas does not fit the pattern below.
Mathieu L Bouchard
committed
// canvas has no label handle and has a motion handle
// but in the case of canvas, the "iemgui" tag is added (it wasn't the case originally)
Mathieu L Bouchard
committed
void scalehandle_draw_select(t_scalehandle *h, int px, int py) {
char tags[128]; // BNG may need up to 100 chars in 64-bit mode, for example
Mathieu L Bouchard
committed
t_object *x = h->h_master;
t_canvas *canvas=glist_getcanvas(h->h_glist);
Mathieu L Bouchard
committed
//int px,py;
//t_class *c = pd_class((t_pd *)x);
//if (h->h_scale) {
// int x1,y1,x2,y2;
// c->c_wb->w_getrectfn((t_gobj *)x,canvas,&x1,&y1,&x2,&y2);
// px=x2-x1; py=y2-y1;
//} else if (c==canvas_class) {
//} else {
// px=x->x_ldx; py=x->x_ldy;
//}
const char *cursor = h->h_scale ? "bottom_right_corner" : "crosshair";
int sx = h->h_scale ? SCALEHANDLE_WIDTH : LABELHANDLE_WIDTH;
int sy = h->h_scale ? SCALEHANDLE_HEIGHT : LABELHANDLE_HEIGHT;
Mathieu L Bouchard
committed
scalehandle_draw_erase(h);
Ivica Bukvic
committed
Mathieu L Bouchard
committed
if (!h->h_vis) {
sys_vgui("canvas %s -width %d -height %d -bg $pd_colors(selection) -bd 0 "
"-cursor %s\n", h->h_pathname, sx, sy, cursor);
if (h->h_scale) {
Ivica Bukvic
committed
sprintf(tags,"x%lx %lxSCALE iemgui selected", (long)x,(long)x);
Mathieu L Bouchard
committed
} else {
Ivica Bukvic
committed
sprintf(tags,"x%lx %lx%s iemgui selected", (long)x,
Mathieu L Bouchard
committed
(long)x,pd_class((t_pd *)x)==canvas_class?"MOVE":"LABELH");
}
sys_vgui(".x%x.c create window %d %d -anchor nw -width %d -height %d "
"-window %s -tags {%s}\n", canvas,
x->te_xpix+px-sx, x->te_ypix+py-sy, sx, sy,
Mathieu L Bouchard
committed
h->h_pathname, tags);
scalehandle_bind(h);
h->h_vis = 1;
/* not yet (this is not supported by the current implementation) */
Mathieu L Bouchard
committed
}/* else {
Mathieu L Bouchard
committed
sys_vgui(".x%x.c coords %s %d %d\n", canvas, h->h_pathname,
x->te_xpix+px-sx, x->te_ypix+py-sy);
Mathieu L Bouchard
committed
sys_vgui("raise %s\n", h->h_pathname);
}*/
extern t_class *my_canvas_class;
Mathieu L Bouchard
committed
void scalehandle_draw_select2(t_iemgui *x) {
t_canvas *canvas=glist_getcanvas(x->x_glist);
Mathieu L Bouchard
committed
t_class *c = pd_class((t_pd *)x);
int sx,sy;
if (c==my_canvas_class) {
t_my_canvas *y = (t_my_canvas *)x;
sx=y->x_vis_w; sy=y->x_vis_h;
} else {
int x1,y1,x2,y2;
c->c_wb->w_getrectfn((t_gobj *)x,canvas,&x1,&y1,&x2,&y2);
sx=x2-x1; sy=y2-y1;
}
Mathieu L Bouchard
committed
scalehandle_draw_select(x->x_handle,sx-1,sy-1);
Mathieu L Bouchard
committed
if (x->x_lab!=s_empty)
Mathieu L Bouchard
committed
scalehandle_draw_select(x->x_lhandle,x->x_ldx,x->x_ldy);
Mathieu L Bouchard
committed
void scalehandle_draw_erase(t_scalehandle *h) {
t_canvas *canvas=glist_getcanvas(h->h_glist);
Mathieu L Bouchard
committed
if (!h->h_vis) return;
sys_vgui("destroy %s\n", h->h_pathname);
Ivica Bukvic
committed
sys_vgui(".x%lx.c delete %lx%s\n", canvas, h->h_master,
h->h_scale ? "SCALE" : pd_class((t_pd *)h->h_master)==canvas_class?"MOVE":"LABELH");
h->h_vis = 0;
Mathieu L Bouchard
committed
void scalehandle_draw_erase2(t_iemgui *x) {
Mathieu L Bouchard
committed
t_scalehandle *sh = (t_scalehandle *)(x->x_handle);
t_scalehandle *lh = (t_scalehandle *)(x->x_lhandle);
Mathieu L Bouchard
committed
if (sh->h_vis) scalehandle_draw_erase(sh);
if (lh->h_vis) scalehandle_draw_erase(lh);
Mathieu L Bouchard
committed
}
Mathieu L Bouchard
committed
void scalehandle_draw(t_iemgui *x) {
if (x->x_glist == glist_getcanvas(x->x_glist)) {
if(x->x_selected == x->x_glist) scalehandle_draw_select2(x);
else scalehandle_draw_erase2(x);
Mathieu L Bouchard
committed
}
Mathieu L Bouchard
committed
}
t_scalehandle *scalehandle_new(t_object *x, t_glist *glist, int scale, t_clickhandlefn chf, t_motionhandlefn mhf) {
t_scalehandle *h = (t_scalehandle *)pd_new(scalehandle_class);
Mathieu L Bouchard
committed
char buf[19]; // 3 + max size of %lx
h->h_master = x;
Mathieu L Bouchard
committed
h->h_glist = glist;
Mathieu L Bouchard
committed
sprintf(buf, "_h%lx", (t_int)h);
pd_bind((t_pd *)h, h->h_bindsym = gensym(buf));
sprintf(h->h_outlinetag, "h%lx", (t_int)h);
h->h_dragon = 0;
h->h_scale = scale;
//h->h_offset_x = 0; // unused (maybe keep for later)
//h->h_offset_y = 0; // unused (maybe keep for later)
Mathieu L Bouchard
committed
h->h_vis = 0;
Mathieu L Bouchard
committed
sprintf(h->h_pathname, ".x%lx.h%lx", (t_int)h->h_glist, (t_int)h);
h->h_clickfn = chf;
h->h_motionfn = mhf;
Mathieu L Bouchard
committed
return h;
}
void scalehandle_free(t_scalehandle *h) {
pd_unbind((t_pd *)h, h->h_bindsym);
pd_free((t_pd *)h);
Mathieu L Bouchard
committed
void properties_set_field_int(long props, const char *gui_field, int value) {
sys_vgui(".gfxstub%lx.%s delete 0 end\n", props, gui_field);
sys_vgui(".gfxstub%lx.%s insert 0 %d\n", props, gui_field, value);
};
void scalehandle_dragon_label(t_scalehandle *h, float f1, float f2) {
if (h->h_dragon && !h->h_scale)
{
t_iemgui *x = (t_iemgui *)(h->h_master);
int dx = (int)f1, dy = (int)f2;
h->h_dragx = dx;
h->h_dragy = dy;
int properties = gfxstub_haveproperties((void *)x);
if (properties)
{
int new_x = x->x_ldx + h->h_dragx;
int new_y = x->x_ldy + h->h_dragy;
Mathieu L Bouchard
committed
properties_set_field_int(properties,"label.xy.x_entry",new_x);
properties_set_field_int(properties,"label.xy.y_entry",new_y);
}
if (glist_isvisible(x->x_glist))
{
int xpos=text_xpix(&x->x_obj, x->x_glist);
int ypos=text_ypix(&x->x_obj, x->x_glist);
t_canvas *canvas=glist_getcanvas(x->x_glist);
sys_vgui(".x%lx.c coords %lxLABEL %d %d\n", canvas, x,
xpos+x->x_ldx + h->h_dragx,
ypos+x->x_ldy + h->h_dragy);
Mathieu L Bouchard
committed
}
}
}
void scalehandle_unclick_label(t_scalehandle *h) {
t_iemgui *x = (t_iemgui *)h->h_master;
canvas_apply_setundo(x->x_glist, (t_gobj *)x);
if (h->h_dragx || h->h_dragy)
{
x->x_ldx += h->h_dragx;
x->x_ldy += h->h_dragy;
canvas_dirty(x->x_glist, 1);
}
if (glist_isvisible(x->x_glist))
{
iemgui_select((t_gobj *)x, x->x_glist, 1);
canvas_fixlinesfor(x->x_glist, (t_text *)x);
Mathieu L Bouchard
committed
canvas_getscroll(x->x_glist);
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
}
}
void scalehandle_click_label(t_scalehandle *h) {
t_iemgui *x = (t_iemgui *)h->h_master;
if (glist_isvisible(x->x_glist))
{
sys_vgui("lower %s\n", h->h_pathname);
t_scalehandle *othersh = x->x_handle;
sys_vgui("lower .x%lx.h%lx\n",
(t_int)glist_getcanvas(x->x_glist), (t_int)othersh);
}
h->h_dragx = 0;
h->h_dragy = 0;
}
void scalehandle_getrect_master(t_scalehandle *h, int *x1, int *y1, int *x2, int *y2) {
t_iemgui *x = (t_iemgui *)h->h_master;
t_class *c = pd_class((t_pd *)x);
c->c_wb->w_getrectfn((t_gobj *)x,x->x_glist,x1,y1,x2,y2);
//printf("%s\n",c->c_name->s_name);
if (c==my_canvas_class) {
t_my_canvas *xx = (t_my_canvas *)x;
*x2=*x1+xx->x_vis_w;
*y2=*y1+xx->x_vis_h;
}
}
void scalehandle_click_scale(t_scalehandle *h) {
int x1,y1,x2,y2;
t_iemgui *x = (t_iemgui *)h->h_master;
scalehandle_getrect_master(h,&x1,&y1,&x2,&y2);
if (glist_isvisible(x->x_glist)) {
sys_vgui("lower %s\n", h->h_pathname);
sys_vgui(".x%x.c create prect %d %d %d %d -stroke $pd_colors(selection) -strokewidth 1 -tags %s\n",
x->x_glist, x1, y1, x2, y2, h->h_outlinetag);
}
h->h_dragx = 0;
h->h_dragy = 0;
}
Ivica Bukvic
committed
// here we don't need to use glist_getcanvas(t_canvas *)
// because scalehandle on iemgui objects appears only when
// they are on their own canvas
void scalehandle_unclick_scale(t_scalehandle *h) {
t_iemgui *x = (t_iemgui *)h->h_master;
sys_vgui(".x%x.c delete %s\n", x->x_glist, h->h_outlinetag);
Mathieu L Bouchard
committed
iemgui_io_draw_move(x);
iemgui_select((t_gobj *)x, x->x_glist, 1);
canvas_fixlinesfor(x->x_glist, (t_text *)x);
Mathieu L Bouchard
committed
canvas_getscroll(x->x_glist);
}
void scalehandle_drag_scale(t_scalehandle *h) {
int x1,y1,x2,y2;
t_iemgui *x = (t_iemgui *)h->h_master;
scalehandle_getrect_master(h,&x1,&y1,&x2,&y2);
if (glist_isvisible(x->x_glist)) {
sys_vgui(".x%x.c coords %s %d %d %d %d\n", x->x_glist, h->h_outlinetag,
x1, y1, x2+h->h_dragx, y2+h->h_dragy);
}
}
static void scalehandle_clickhook(t_scalehandle *h, t_floatarg f,
t_floatarg xxx, t_floatarg yyy)
{
h->h_offset_x=xxx;
h->h_offset_y=yyy;
h->h_clickfn(h,f);
}
static void scalehandle_motionhook(t_scalehandle *h,
t_floatarg f1, t_floatarg f2)
{
h->h_motionfn(h,f1-h->h_offset_x,f2-h->h_offset_y);
}
Mathieu L Bouchard
committed
void iemgui__clickhook3(t_scalehandle *sh, int newstate) {
if (!sh->h_dragon && newstate && sh->h_scale)
scalehandle_click_scale(sh);
else if (sh->h_dragon && newstate == 0 && !sh->h_scale)
scalehandle_unclick_label(sh);
else if (!sh->h_dragon && newstate && !sh->h_scale)
scalehandle_click_label(sh);
sh->h_dragon = newstate;
}
// function for updating of handles on iemgui objects
// we don't need glist_getcanvas() because handles are only
// drawn when object is selected on its canvas (instead of GOP)
static void scalehandle_check_and_redraw(t_iemgui *x)
{
if(x->x_selected == x->x_glist)
Mathieu L Bouchard
committed
scalehandle_draw_select2(x);
}
Mathieu L Bouchard
committed
//----------------------------------------------------------------
// IEMGUI refactor (by Mathieu)
Mathieu L Bouchard
committed
void iemgui_tag_selected(t_iemgui *x) {
t_canvas *canvas=glist_getcanvas(x->x_glist);
Mathieu L Bouchard
committed
if(x->x_selected)
//sys_vgui(".x%lx.c addtag selected withtag x%lx\n", canvas, x);
gui_vmess("gui_gobj_select", "xx", canvas, x);
Mathieu L Bouchard
committed
else
//sys_vgui(".x%lx.c dtag x%lx selected\n", canvas, x);
gui_vmess("gui_gobj_deselect", "xx", canvas, x);
Mathieu L Bouchard
committed
}
Mathieu L Bouchard
committed
void iemgui_label_draw_new(t_iemgui *x) {
Mathieu L Bouchard
committed
t_canvas *canvas=glist_getcanvas(x->x_glist);
Mathieu L Bouchard
committed
int x1=text_xpix(&x->x_obj, x->x_glist);
int y1=text_ypix(&x->x_obj, x->x_glist);
//sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
// "-font %s -fill #%6.6x -tags {%lxLABEL x%lx text iemgui}\n",
// canvas, x1+x->x_ldx, y1+x->x_ldy,
// x->x_lab!=s_empty?x->x_lab->s_name:"",
// iemgui_font(x), x->x_lcol, x, x);
sprintf(col, "#%6.6x", x->x_lcol);
gui_vmess("gui_iemgui_label_new", "xxiissssi",
canvas,
x,
x->x_ldx,
x->x_ldy,
col,
x->x_lab != s_empty ? x->x_lab->s_name : "",
iemgui_typeface(x),
sys_fontweight,
x->x_fontsize);
Mathieu L Bouchard
committed
}
Ivica Bukvic
committed
Mathieu L Bouchard
committed
void iemgui_label_draw_move(t_iemgui *x) {
t_canvas *canvas=glist_getcanvas(x->x_glist);
Mathieu L Bouchard
committed
int x1=text_xpix(&x->x_obj, x->x_glist);
int y1=text_ypix(&x->x_obj, x->x_glist);
//sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",