g_mycanvas.c 13 KB
Newer Older
Miller Puckette's avatar
Miller Puckette committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/* 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 "m_pd.h"
#include "g_canvas.h"
#include "g_all_guis.h"
#include <math.h>

16 17 18
extern int gfxstub_haveproperties(void *key);
void my_canvas_draw_select(t_my_canvas* x, t_glist* glist);

Miller Puckette's avatar
Miller Puckette committed
19
t_widgetbehavior my_canvas_widgetbehavior;
20
/*static*/ t_class *my_canvas_class;
Miller Puckette's avatar
Miller Puckette committed
21 22 23 24

void my_canvas_draw_new(t_my_canvas *x, t_glist *glist)
{
    t_canvas *canvas=glist_getcanvas(glist);
25 26 27
    int x1=text_xpix(&x->x_gui.x_obj, glist);
    int y1=text_ypix(&x->x_gui.x_obj, glist);

28
    gui_vmess("gui_gobj_new", "xxsiii", canvas,
29
        x, "iemgui", x1, y1, glist_istoplevel(canvas));
30
    gui_vmess("gui_mycanvas_new", "xxxiiiiii", canvas,
Jonathan Wilkes's avatar
Jonathan Wilkes committed
31
        x, x->x_gui.x_bcol, x1, y1, x1+x->x_vis_w, y1+x->x_vis_h,
Jonathan Wilkes's avatar
Jonathan Wilkes committed
32
        x1+x->x_gui.x_w, y1+x->x_gui.x_h);
Miller Puckette's avatar
Miller Puckette committed
33 34 35 36
}

void my_canvas_draw_move(t_my_canvas *x, t_glist *glist)
{
37 38
    t_canvas *canvas=glist_getcanvas(glist);
    if (!glist_isvisible(canvas)) return;
39 40
    int x1=text_xpix(&x->x_gui.x_obj, glist);
    int y1=text_ypix(&x->x_gui.x_obj, glist);
41
    iemgui_base_draw_move(&x->x_gui);
42 43
    gui_vmess("gui_mycanvas_coords", "xxiiii",
        canvas, x,
44
        x->x_vis_w, x->x_vis_h, x->x_gui.x_w, x->x_gui.x_h);
Miller Puckette's avatar
Miller Puckette committed
45 46 47 48 49
}

void my_canvas_draw_config(t_my_canvas* x, t_glist* glist)
{
    t_canvas *canvas=glist_getcanvas(glist);
50 51
    int isselected;
    isselected = x->x_gui.x_selected == canvas && x->x_gui.x_glist == canvas;
52
    gui_vmess("gui_mycanvas_update", "xxxi",
Jonathan Wilkes's avatar
Jonathan Wilkes committed
53
        canvas, x, x->x_gui.x_bcol, isselected);
Miller Puckette's avatar
Miller Puckette committed
54 55 56 57
}

void my_canvas_draw_select(t_my_canvas* x, t_glist* glist)
{
Jonathan Wilkes's avatar
Jonathan Wilkes committed
58
    /* No longer needed */
59 60
}

61
static void my_canvas__clickhook(t_scalehandle *sh, int newstate)
62
{
Ivica Bukvic's avatar
Ivica Bukvic committed
63
    t_my_canvas *x = (t_my_canvas *)(sh->h_master);
64
    if (newstate)
65 66
    {
        canvas_apply_setundo(x->x_gui.x_glist, (t_gobj *)x);
67 68
        if (!sh->h_scale)
            scalehandle_click_label(sh);
69
    }
70
    sh->h_dragon = newstate;
71 72
}

73
static void my_canvas__motionhook(t_scalehandle *sh, t_floatarg mouse_x, t_floatarg mouse_y)
74
{
75
    if (sh->h_scale)
76
    {
Ivica Bukvic's avatar
Ivica Bukvic committed
77
        t_my_canvas *x = (t_my_canvas *)(sh->h_master);
78 79
        int dx = (int)(mouse_x - sh->h_offset_x),
            dy = (int)(mouse_y - sh->h_offset_y);
80 81
        dx = maxi(dx,1-x->x_vis_w);
        dy = maxi(dy,1-x->x_vis_h);        
Ivica Bukvic's avatar
Ivica Bukvic committed
82 83
        sh->h_dragx = dx;
        sh->h_dragy = dy;
84
        scalehandle_drag_scale(sh);
Ivica Bukvic's avatar
Ivica Bukvic committed
85

86 87 88 89 90 91 92 93 94
        x->x_gui.x_w += dx;
        x->x_gui.x_h += dy;

        if (glist_isvisible(x->x_gui.x_glist))
        {
            my_canvas_draw_move(x, x->x_gui.x_glist);
            scalehandle_unclick_scale(sh);
        }

Ivica Bukvic's avatar
Ivica Bukvic committed
95 96 97
        int properties = gfxstub_haveproperties((void *)x);
        if (properties)
        {
98 99
            int new_w = x->x_vis_w + sh->h_dragx;
            int new_h = x->x_vis_h + sh->h_dragy;
100 101 102
            properties_set_field_int(properties,"rng.min_ent",new_w);
            properties_set_field_int(properties,"rng.max_ent",new_h);

Ivica Bukvic's avatar
Ivica Bukvic committed
103 104 105
            int min = (new_w < new_h ? new_w : new_h);
            if (min <= x->x_gui.x_w)
            {
106
                properties_set_field_int(properties,"dim.w_ent",min);
Ivica Bukvic's avatar
Ivica Bukvic committed
107 108 109
            }
        }
    }
110
    scalehandle_dragon_label(sh,mouse_x, mouse_y);
Miller Puckette's avatar
Miller Puckette committed
111 112 113 114
}

void my_canvas_draw(t_my_canvas *x, t_glist *glist, int mode)
{
115 116 117 118
    if(mode == IEM_GUI_DRAW_MODE_MOVE)        my_canvas_draw_move(x, glist);
    else if(mode == IEM_GUI_DRAW_MODE_NEW)    my_canvas_draw_new(x, glist);
    else if(mode == IEM_GUI_DRAW_MODE_SELECT) my_canvas_draw_select(x, glist);
    else if(mode == IEM_GUI_DRAW_MODE_CONFIG) my_canvas_draw_config(x, glist);
Miller Puckette's avatar
Miller Puckette committed
119 120 121 122
}

/* ------------------------ cnv widgetbehaviour----------------------------- */

Ivica Bukvic's avatar
Ivica Bukvic committed
123 124
static void my_canvas_getrect(t_gobj *z, t_glist *glist,
    int *xp1, int *yp1, int *xp2, int *yp2)
Miller Puckette's avatar
Miller Puckette committed
125 126 127 128 129
{
    t_my_canvas *x = (t_my_canvas *)z;
    
    *xp1 = text_xpix(&x->x_gui.x_obj, glist);
    *yp1 = text_ypix(&x->x_gui.x_obj, glist);
130
    if (!glist_istoplevel(glist) || !glist->gl_edit)
Ivica Bukvic's avatar
Ivica Bukvic committed
131 132
    {
        //if we are trying to calculate visibility of a widget inside a GOP
133
        //or are calculating getrect during runtime
Ivica Bukvic's avatar
Ivica Bukvic committed
134 135 136 137 138 139 140 141 142
        *xp2 = *xp1 + x->x_vis_w;
        *yp2 = *yp1 + x->x_vis_h;
    }
    else
    {
        *xp2 = *xp1 + x->x_gui.x_w;
        *yp2 = *yp1 + x->x_gui.x_h;
    }
    iemgui_label_getrect(x->x_gui, glist, xp1, yp1, xp2, yp2);
Miller Puckette's avatar
Miller Puckette committed
143 144 145 146 147 148 149 150
}

static void my_canvas_save(t_gobj *z, t_binbuf *b)
{
    t_my_canvas *x = (t_my_canvas *)z;
    int bflcol[3];
    t_symbol *srl[3];
    iemgui_save(&x->x_gui, srl, bflcol);
151 152 153 154 155 156
    binbuf_addv(b, "ssiisiiisssiiiiiii;", gensym("#X"),gensym("obj"),
        (int)x->x_gui.x_obj.te_xpix, (int)x->x_gui.x_obj.te_ypix,
        gensym("cnv"), x->x_gui.x_w, x->x_vis_w, x->x_vis_h,
        srl[0], srl[1], srl[2], x->x_gui.x_ldx, x->x_gui.x_ldy,
        iem_fstyletoint(&x->x_gui), x->x_gui.x_fontsize,
        bflcol[0], bflcol[2], iem_symargstoint(&x->x_gui));
Miller Puckette's avatar
Miller Puckette committed
157 158 159 160 161
}

static void my_canvas_properties(t_gobj *z, t_glist *owner)
{
    t_my_canvas *x = (t_my_canvas *)z;
162
    char buf[800], *gfx_tag;
Miller Puckette's avatar
Miller Puckette committed
163 164 165
    t_symbol *srl[3];

    iemgui_properties(&x->x_gui, srl);
Miller Puckette's avatar
Miller Puckette committed
166
    sprintf(buf, "pdtk_iemgui_dialog %%s |cnv| \
Miller Puckette's avatar
Miller Puckette committed
167 168 169
            ------selectable_dimensions(pix):------ %d %d size: 0.0 0.0 empty \
            ------visible_rectangle(pix)(pix):------ %d width: %d height: %d \
            %d empty empty %d %d empty %d \
Ivica Ico Bukvic's avatar
Ivica Ico Bukvic committed
170 171
            {%s} {%s} \
            {%s} %d %d \
Miller Puckette's avatar
Miller Puckette committed
172 173 174 175 176 177 178
            %d %d \
            %d %d %d\n",
            x->x_gui.x_w, 1,
            x->x_vis_w, x->x_vis_h, 0,/*no_schedule*/
            -1, -1, -1, -1,/*no linlog, no init, no multi*/
            srl[0]->s_name, srl[1]->s_name,
            srl[2]->s_name, x->x_gui.x_ldx, x->x_gui.x_ldy,
179
            x->x_gui.x_font_style, x->x_gui.x_fontsize,
Miller Puckette's avatar
Miller Puckette committed
180
            0xffffff & x->x_gui.x_bcol, -1/*no frontcolor*/, 0xffffff & x->x_gui.x_lcol);
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
    //gfxstub_new(&x->x_gui.x_obj.ob_pd, x, buf);

    gfx_tag = gfxstub_new2(&x->x_gui.x_obj.ob_pd, x);
    /* todo: send along the x/y of the object here so we can
       create the window in the right place */

    gui_start_vmess("gui_iemgui_dialog", "s", gfx_tag);
    gui_start_array();

    gui_s("type");           gui_s("cnv");
    gui_s("selection-size"); gui_i(x->x_gui.x_w);
    gui_s("visible-width");  gui_i(x->x_vis_w);
    gui_s("visible-height"); gui_i(x->x_vis_h);
    gui_s("minimum-size");   gui_i(IEM_GUI_MINSIZE);

    gui_s("range-schedule"); // no idea what this is...
    gui_i(0);

    gui_s("send-symbol"); gui_s(srl[0]->s_name);
    gui_s("receive-symbol"); gui_s(srl[1]->s_name);
    gui_s("label"); gui_s(srl[2]->s_name);
    gui_s("x-offset"); gui_i(x->x_gui.x_ldx);
    gui_s("y-offset");  gui_i(x->x_gui.x_ldy);
    gui_s("font-style"); gui_i(x->x_gui.x_font_style);
    gui_s("font-size"); gui_i(x->x_gui.x_fontsize);
    gui_s("background-color"); gui_i(0xffffff & x->x_gui.x_bcol);
    gui_s("foreground-color"); gui_i(0xffffff & x->x_gui.x_fcol);
    gui_s("label-color"); gui_i(0xffffff & x->x_gui.x_lcol);
    
    gui_end_array();
    gui_end_vmess();
Miller Puckette's avatar
Miller Puckette committed
212 213 214 215
}

static void my_canvas_get_pos(t_my_canvas *x)
{
216
    if(iemgui_has_snd(&x->x_gui) && x->x_gui.x_snd->s_thing)
Miller Puckette's avatar
Miller Puckette committed
217 218 219 220 221 222 223 224 225
    {
        x->x_at[0].a_w.w_float = text_xpix(&x->x_gui.x_obj, x->x_gui.x_glist);
        x->x_at[1].a_w.w_float = text_ypix(&x->x_gui.x_obj, x->x_gui.x_glist);
        pd_list(x->x_gui.x_snd->s_thing, &s_list, 2, x->x_at);
    }
}

static void my_canvas_dialog(t_my_canvas *x, t_symbol *s, int argc, t_atom *argv)
{
226
    //printf("cnv_dialog: selected=%d\n",x->x_gui.x_selected);
227 228
    if (atom_getintarg(19, argc, argv))
        canvas_apply_setundo(x->x_gui.x_glist, (t_gobj *)x);
229
    //printf("cnv_dialog: selected=%d\n",x->x_gui.x_selected);
230 231 232 233
    x->x_gui.x_h =
    x->x_gui.x_w = maxi(atom_getintarg(0, argc, argv),1);
    x->x_vis_w = maxi(atom_getintarg(2, argc, argv),1);
    x->x_vis_h = maxi(atom_getintarg(3, argc, argv),1);
234
    iemgui_dialog(&x->x_gui, argc, argv);
235
    x->x_gui.x_loadinit = 0;
236
    iemgui_draw_config(&x->x_gui);
237
    iemgui_shouldvis(&x->x_gui, IEM_GUI_DRAW_MODE_MOVE);
238
    scalehandle_draw(&x->x_gui);
239
    scrollbar_update(x->x_gui.x_glist);
Miller Puckette's avatar
Miller Puckette committed
240 241 242 243 244 245 246 247 248 249
}

static void my_canvas_size(t_my_canvas *x, t_symbol *s, int ac, t_atom *av)
{
    int i = (int)atom_getintarg(0, ac, av);

    if(i < 1)
        i = 1;
    x->x_gui.x_w = i;
    x->x_gui.x_h = i;
250
    iemgui_size(&x->x_gui);
Miller Puckette's avatar
Miller Puckette committed
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
}

static void my_canvas_vis_size(t_my_canvas *x, t_symbol *s, int ac, t_atom *av)
{
    int i;

    i = (int)atom_getintarg(0, ac, av);
    if(i < 1)
        i = 1;
    x->x_vis_w = i;
    if(ac > 1)
    {
        i = (int)atom_getintarg(1, ac, av);
        if(i < 1)
            i = 1;
    }
    x->x_vis_h = i;
268
    if(glist_isvisible(x->x_gui.x_glist)) iemgui_draw_move(&x->x_gui);
Miller Puckette's avatar
Miller Puckette committed
269 270 271 272 273 274 275
}

static void *my_canvas_new(t_symbol *s, int argc, t_atom *argv)
{
    t_my_canvas *x = (t_my_canvas *)pd_new(my_canvas_class);
    int bflcol[]={-233017, -1, -66577};
    int a=IEM_GUI_DEFAULTSIZE, w=100, h=60;
Mathieu L Bouchard's avatar
Mathieu L Bouchard committed
276
    int ldx=20, ldy=12, i=0;
Miller Puckette's avatar
Miller Puckette committed
277 278
    int fs=14;

279 280
    iem_inttosymargs(&x->x_gui, 0);
    iem_inttofstyle(&x->x_gui, 0);
Miller Puckette's avatar
Miller Puckette committed
281 282 283 284

    if(((argc >= 10)&&(argc <= 13))
       &&IS_A_FLOAT(argv,0)&&IS_A_FLOAT(argv,1)&&IS_A_FLOAT(argv,2))
    {
285 286 287
        a = maxi(atom_getintarg(0, argc, argv),1);
        w = maxi(atom_getintarg(1, argc, argv),1);
        h = maxi(atom_getintarg(2, argc, argv),1);
Miller Puckette's avatar
Miller Puckette committed
288
    }
Ivica Bukvic's avatar
Ivica Bukvic committed
289 290
    if((argc >= 12) && (IS_A_SYMBOL(argv,3) || IS_A_FLOAT(argv,3)) &&
        (IS_A_SYMBOL(argv,4) || IS_A_FLOAT(argv,4)))
Miller Puckette's avatar
Miller Puckette committed
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
    {
        i = 2;
        iemgui_new_getnames(&x->x_gui, 3, argv);
    }
    else if((argc == 11)&&(IS_A_SYMBOL(argv,3)||IS_A_FLOAT(argv,3)))
    {
        i = 1;
        iemgui_new_getnames(&x->x_gui, 3, argv);
    }
    else iemgui_new_getnames(&x->x_gui, 3, 0);

    if(((argc >= 10)&&(argc <= 13))
       &&(IS_A_SYMBOL(argv,i+3)||IS_A_FLOAT(argv,i+3))&&IS_A_FLOAT(argv,i+4)
       &&IS_A_FLOAT(argv,i+5)&&IS_A_FLOAT(argv,i+6)
       &&IS_A_FLOAT(argv,i+7)&&IS_A_FLOAT(argv,i+8)
       &&IS_A_FLOAT(argv,i+9))
    {
            /* disastrously, the "label" sits in a different part of the
            message.  So we have to track its location separately (in
            the slot x_labelbindex) and initialize it specially here. */
311
        iemgui_getfloatsym(argv+i+3);
Miller Puckette's avatar
Miller Puckette committed
312
        x->x_gui.x_labelbindex = i+4;
313 314
        ldx = atom_getintarg(i+4, argc, argv);
        ldy = atom_getintarg(i+5, argc, argv);
315
        iem_inttofstyle(&x->x_gui, atom_getintarg(i+6, argc, argv));
316 317 318
        fs = atom_getintarg(i+7, argc, argv);
        bflcol[0] = atom_getintarg(i+8, argc, argv);
        bflcol[2] = atom_getintarg(i+9, argc, argv);
Miller Puckette's avatar
Miller Puckette committed
319 320 321
    }
    if((argc == 13)&&IS_A_FLOAT(argv,i+10))
    {
322
        iem_inttosymargs(&x->x_gui, atom_getintarg(i+10, argc, argv));
Miller Puckette's avatar
Miller Puckette committed
323 324 325
    }
    x->x_gui.x_draw = (t_iemfunptr)my_canvas_draw;
    x->x_gui.x_glist = (t_glist *)canvas_getcurrent();
326
    x->x_gui.x_h = x->x_gui.x_w = a;
Miller Puckette's avatar
Miller Puckette committed
327 328
    x->x_vis_w = w;
    x->x_vis_h = h;
329 330
    if (x->x_gui.x_font_style<0 || x->x_gui.x_font_style>2) x->x_gui.x_font_style=0;
    if (iemgui_has_rcv(&x->x_gui))
Miller Puckette's avatar
Miller Puckette committed
331 332 333 334 335 336 337 338 339 340
        pd_bind(&x->x_gui.x_obj.ob_pd, x->x_gui.x_rcv);
    x->x_gui.x_ldx = ldx;
    x->x_gui.x_ldy = ldy;
    if(fs < 4)
        fs = 4;
    x->x_gui.x_fontsize = fs;
    iemgui_all_colfromload(&x->x_gui, bflcol);
    x->x_at[0].a_type = A_FLOAT;
    x->x_at[1].a_type = A_FLOAT;
    iemgui_verify_snd_ne_rcv(&x->x_gui);
341

342
    x->x_gui.x_handle = scalehandle_new((t_object *)x,x->x_gui.x_glist,1,my_canvas__clickhook,my_canvas__motionhook);
343
    x->x_gui.x_lhandle = scalehandle_new((t_object *)x,x->x_gui.x_glist,0,my_canvas__clickhook,my_canvas__motionhook);
Ivica Bukvic's avatar
Ivica Bukvic committed
344
    x->x_gui.x_obj.te_iemgui = 1;
345

346
    x->x_gui.legacy_x = 0;
347
    x->x_gui.legacy_y = 1;
348

Miller Puckette's avatar
Miller Puckette committed
349 350 351 352 353
    return (x);
}

static void my_canvas_ff(t_my_canvas *x)
{
354
    if(iemgui_has_rcv(&x->x_gui))
Miller Puckette's avatar
Miller Puckette committed
355 356
        pd_unbind(&x->x_gui.x_obj.ob_pd, x->x_gui.x_rcv);
    gfxstub_deleteforkey(x);
357

358 359
    if (x->x_gui. x_handle) scalehandle_free(x->x_gui. x_handle);
    if (x->x_gui.x_lhandle) scalehandle_free(x->x_gui.x_lhandle);
Miller Puckette's avatar
Miller Puckette committed
360 361 362 363 364
}

void g_mycanvas_setup(void)
{
    my_canvas_class = class_new(gensym("cnv"), (t_newmethod)my_canvas_new,
Ivica Bukvic's avatar
Ivica Bukvic committed
365 366 367 368 369 370 371
        (t_method)my_canvas_ff, sizeof(t_my_canvas), CLASS_NOINLET, A_GIMME, 0);
    class_addcreator((t_newmethod)my_canvas_new,
        gensym("my_canvas"), A_GIMME, 0);
    class_addmethod(my_canvas_class, (t_method)my_canvas_dialog,
        gensym("dialog"), A_GIMME, 0);
    class_addmethod(my_canvas_class, (t_method)my_canvas_size,
        gensym("size"), A_GIMME, 0);
372
    iemgui_class_addmethods(my_canvas_class);
Ivica Bukvic's avatar
Ivica Bukvic committed
373 374 375 376
    class_addmethod(my_canvas_class, (t_method)my_canvas_vis_size,
        gensym("vis_size"), A_GIMME, 0);
    class_addmethod(my_canvas_class, (t_method)my_canvas_get_pos,
        gensym("get_pos"), 0);
Miller Puckette's avatar
Miller Puckette committed
377

378
    wb_init(&my_canvas_widgetbehavior,my_canvas_getrect,0);
Miller Puckette's avatar
Miller Puckette committed
379 380 381 382 383
    class_setwidget(my_canvas_class, &my_canvas_widgetbehavior);
    class_sethelpsymbol(my_canvas_class, gensym("my_canvas"));
    class_setsavefn(my_canvas_class, my_canvas_save);
    class_setpropertiesfn(my_canvas_class, my_canvas_properties);
}