diff options
| author | Peter D'Hoye <peter.dhoye@gmail.com> | 2009-05-24 21:28:16 +0000 |
|---|---|---|
| committer | Peter D'Hoye <peter.dhoye@gmail.com> | 2009-05-24 21:28:16 +0000 |
| commit | 526b5580dabbfed7cfe5439dc3a90ec727f563c2 (patch) | |
| tree | 22b1af92348785daad16714ee5e2b633017e0e48 /apps/plugins/pdbox/PDa/src/g_editor.c | |
| parent | 4f2dfcc01b260d946044ef2b6af5fe36cb772c8d (diff) | |
| download | rockbox-526b5580dabbfed7cfe5439dc3a90ec727f563c2.zip rockbox-526b5580dabbfed7cfe5439dc3a90ec727f563c2.tar.gz rockbox-526b5580dabbfed7cfe5439dc3a90ec727f563c2.tar.bz2 rockbox-526b5580dabbfed7cfe5439dc3a90ec727f563c2.tar.xz | |
Cut the files in half and it might work better (note to self: check your tree is really clean before patching)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21070 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/g_editor.c')
| -rw-r--r-- | apps/plugins/pdbox/PDa/src/g_editor.c | 2273 |
1 files changed, 0 insertions, 2273 deletions
diff --git a/apps/plugins/pdbox/PDa/src/g_editor.c b/apps/plugins/pdbox/PDa/src/g_editor.c index a1dea79..1190739 100644 --- a/apps/plugins/pdbox/PDa/src/g_editor.c +++ b/apps/plugins/pdbox/PDa/src/g_editor.c @@ -2272,2277 +2272,4 @@ void g_editor_setup(void) /* -------------- copy buffer ------------------ */ copy_binbuf = binbuf_new(); } -/* Copyright (c) 1997-2001 Miller Puckette and others. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -#include <stdlib.h> -#include <stdio.h> -#include "m_pd.h" -#include "m_imp.h" -#include "s_stuff.h" -#include "g_canvas.h" -#include <string.h> - -void glist_readfrombinbuf(t_glist *x, t_binbuf *b, char *filename, - int selectem); - -void open_via_helppath(const char *name, const char *dir); -char *class_gethelpdir(t_class *c); - -/* ------------------ forward declarations --------------- */ -static void canvas_doclear(t_canvas *x); -static void glist_setlastxy(t_glist *gl, int xval, int yval); -static void glist_donewloadbangs(t_glist *x); -static t_binbuf *canvas_docopy(t_canvas *x); -static void canvas_dopaste(t_canvas *x, t_binbuf *b); -static void canvas_paste(t_canvas *x); -static void canvas_clearline(t_canvas *x); -static t_binbuf *copy_binbuf; - -/* ---------------- generic widget behavior ------------------------- */ - -void gobj_getrect(t_gobj *x, t_glist *glist, int *x1, int *y1, - int *x2, int *y2) -{ - if (x->g_pd->c_wb && x->g_pd->c_wb->w_getrectfn) - (*x->g_pd->c_wb->w_getrectfn)(x, glist, x1, y1, x2, y2); -} -void gobj_displace(t_gobj *x, t_glist *glist, int dx, int dy) -{ - if (x->g_pd->c_wb && x->g_pd->c_wb->w_displacefn) - (*x->g_pd->c_wb->w_displacefn)(x, glist, dx, dy); -} - -void gobj_select(t_gobj *x, t_glist *glist, int state) -{ - if (x->g_pd->c_wb && x->g_pd->c_wb->w_selectfn) - (*x->g_pd->c_wb->w_selectfn)(x, glist, state); -} - -void gobj_activate(t_gobj *x, t_glist *glist, int state) -{ - if (x->g_pd->c_wb && x->g_pd->c_wb->w_activatefn) - (*x->g_pd->c_wb->w_activatefn)(x, glist, state); -} - -void gobj_delete(t_gobj *x, t_glist *glist) -{ - if (x->g_pd->c_wb && x->g_pd->c_wb->w_deletefn) - (*x->g_pd->c_wb->w_deletefn)(x, glist); -} - -void gobj_vis(t_gobj *x, struct _glist *glist, int flag) -{ - if (x->g_pd->c_wb && x->g_pd->c_wb->w_visfn) - (*x->g_pd->c_wb->w_visfn)(x, glist, flag); -} - -int gobj_click(t_gobj *x, struct _glist *glist, - int xpix, int ypix, int shift, int alt, int dbl, int doit) -{ - if (x->g_pd->c_wb && x->g_pd->c_wb->w_clickfn) - return ((*x->g_pd->c_wb->w_clickfn)(x, - glist, xpix, ypix, shift, alt, dbl, doit)); - else return (0); -} - -/* ------------------------ managing the selection ----------------- */ - -void glist_selectline(t_glist *x, t_outconnect *oc, int index1, - int outno, int index2, int inno) -{ - if (x->gl_editor) - { - glist_noselect(x); - x->gl_editor->e_selectedline = 1; - x->gl_editor->e_selectline_index1 = index1; - x->gl_editor->e_selectline_outno = outno; - x->gl_editor->e_selectline_index2 = index2; - x->gl_editor->e_selectline_inno = inno; - x->gl_editor->e_selectline_tag = oc; - sys_vgui(".x%x.c itemconfigure l%x -fill blue\n", - x, x->gl_editor->e_selectline_tag); - } -} - -void glist_deselectline(t_glist *x) -{ - if (x->gl_editor) - { - x->gl_editor->e_selectedline = 0; - sys_vgui(".x%x.c itemconfigure l%x -fill black\n", - x, x->gl_editor->e_selectline_tag); - } -} - -int glist_isselected(t_glist *x, t_gobj *y) -{ - if (x->gl_editor) - { - t_selection *sel; - for (sel = x->gl_editor->e_selection; sel; sel = sel->sel_next) - if (sel->sel_what == y) return (1); - } - return (0); -} - - /* call this for unselected objects only */ -void glist_select(t_glist *x, t_gobj *y) -{ - if (x->gl_editor) - { - t_selection *sel = (t_selection *)getbytes(sizeof(*sel)); - if (x->gl_editor->e_selectedline) - glist_deselectline(x); - /* LATER #ifdef out the following check */ - if (glist_isselected(x, y)) bug("glist_select"); - sel->sel_next = x->gl_editor->e_selection; - sel->sel_what = y; - x->gl_editor->e_selection = sel; - gobj_select(y, x, 1); - } -} - - /* call this for selected objects only */ -void glist_deselect(t_glist *x, t_gobj *y) -{ - int fixdsp = 0; - static int reenter = 0; - if (reenter) return; - reenter = 1; - if (x->gl_editor) - { - t_selection *sel, *sel2; - t_rtext *z = 0; - if (!glist_isselected(x, y)) bug("glist_deselect"); - if (x->gl_editor->e_textedfor) - { - t_rtext *fuddy = glist_findrtext(x, (t_text *)y); - if (x->gl_editor->e_textedfor == fuddy) - { - if (x->gl_editor->e_textdirty) - { - z = fuddy; - canvas_stowconnections(glist_getcanvas(x)); - } - gobj_activate(y, x, 0); - } - if (zgetfn(&y->g_pd, gensym("dsp"))) - fixdsp = 1; - } - if ((sel = x->gl_editor->e_selection)->sel_what == y) - { - x->gl_editor->e_selection = x->gl_editor->e_selection->sel_next; - gobj_select(sel->sel_what, x, 0); - freebytes(sel, sizeof(*sel)); - } - else - { - for (sel = x->gl_editor->e_selection; sel2 = sel->sel_next; - sel = sel2) - { - if (sel2->sel_what == y) - { - sel->sel_next = sel2->sel_next; - gobj_select(sel2->sel_what, x, 0); - freebytes(sel2, sizeof(*sel2)); - break; - } - } - } - if (z) - { - char *buf; - int bufsize; - - rtext_gettext(z, &buf, &bufsize); - text_setto((t_text *)y, x, buf, bufsize); - canvas_fixlinesfor(glist_getcanvas(x), (t_text *)y); - x->gl_editor->e_textedfor = 0; - } - if (fixdsp) - canvas_update_dsp(); - } - reenter = 0; -} - -void glist_noselect(t_glist *x) -{ - if (x->gl_editor) - { - while (x->gl_editor->e_selection) - glist_deselect(x, x->gl_editor->e_selection->sel_what); - if (x->gl_editor->e_selectedline) - glist_deselectline(x); - } -} - -void glist_selectall(t_glist *x) -{ - if (x->gl_editor) - { - glist_noselect(x); - if (x->gl_list) - { - t_selection *sel = (t_selection *)getbytes(sizeof(*sel)); - t_gobj *y = x->gl_list; - x->gl_editor->e_selection = sel; - sel->sel_what = y; - gobj_select(y, x, 1); - while (y = y->g_next) - { - t_selection *sel2 = (t_selection *)getbytes(sizeof(*sel2)); - sel->sel_next = sel2; - sel = sel2; - sel->sel_what = y; - gobj_select(y, x, 1); - } - sel->sel_next = 0; - } - } -} - - /* get the index of a gobj in a glist. If y is zero, return the - total number of objects. */ -int glist_getindex(t_glist *x, t_gobj *y) -{ - t_gobj *y2; - int indx; - - for (y2 = x->gl_list, indx = 0; y2 && y2 != y; y2 = y2->g_next) - indx++; - return (indx); -} - - /* get the index of the object, among selected items, if "selected" - is set; otherwise, among unselected ones. If y is zero, just - counts the selected or unselected objects. */ -int glist_selectionindex(t_glist *x, t_gobj *y, int selected) -{ - t_gobj *y2; - int indx; - - for (y2 = x->gl_list, indx = 0; y2 && y2 != y; y2 = y2->g_next) - if (selected == glist_isselected(x, y2)) - indx++; - return (indx); -} - -static t_gobj *glist_nth(t_glist *x, int n) -{ - t_gobj *y; - int indx; - for (y = x->gl_list, indx = 0; y; y = y->g_next, indx++) - if (indx == n) - return (y); - return (0); -} - -/* ------------------- support for undo/redo -------------------------- */ - -static t_undofn canvas_undo_fn; /* current undo function if any */ -static int canvas_undo_whatnext; /* whether we can now UNDO or REDO */ -static void *canvas_undo_buf; /* data private to the undo function */ -static t_canvas *canvas_undo_canvas; /* which canvas we can undo on */ -static const char *canvas_undo_name; - -void canvas_setundo(t_canvas *x, t_undofn undofn, void *buf, - const char *name) -{ - int hadone = 0; - /* blow away the old undo information. In one special case the - old undo info is re-used; if so we shouldn't free it here. */ - if (canvas_undo_fn && canvas_undo_buf && (buf != canvas_undo_buf)) - { - (*canvas_undo_fn)(canvas_undo_canvas, canvas_undo_buf, UNDO_FREE); - hadone = 1; - } - canvas_undo_canvas = x; - canvas_undo_fn = undofn; - canvas_undo_buf = buf; - canvas_undo_whatnext = UNDO_UNDO; - canvas_undo_name = name; - if (x && glist_isvisible(x) && glist_istoplevel(x)) - /* enable undo in menu */ - sys_vgui("pdtk_undomenu .x%x %s no\n", x, name); - else if (hadone) - sys_vgui("pdtk_undomenu nobody no no\n"); -} - - /* clear undo if it happens to be for the canvas x. - (but if x is 0, clear it regardless of who owns it.) */ -void canvas_noundo(t_canvas *x) -{ - if (!x || (x == canvas_undo_canvas)) - canvas_setundo(0, 0, 0, "foo"); -} - -static void canvas_undo(t_canvas *x) -{ - if (x != canvas_undo_canvas) - bug("canvas_undo 1"); - else if (canvas_undo_whatnext != UNDO_UNDO) - bug("canvas_undo 2"); - else - { - /* post("undo"); */ - (*canvas_undo_fn)(canvas_undo_canvas, canvas_undo_buf, UNDO_UNDO); - /* enable redo in menu */ - if (glist_isvisible(x) && glist_istoplevel(x)) - sys_vgui("pdtk_undomenu .x%x no %s\n", x, canvas_undo_name); - canvas_undo_whatnext = UNDO_REDO; - } -} - -static void canvas_redo(t_canvas *x) -{ - if (x != canvas_undo_canvas) - bug("canvas_undo 1"); - else if (canvas_undo_whatnext != UNDO_REDO) - bug("canvas_undo 2"); - else - { - /* post("redo"); */ - (*canvas_undo_fn)(canvas_undo_canvas, canvas_undo_buf, UNDO_REDO); - /* enable undo in menu */ - if (glist_isvisible(x) && glist_istoplevel(x)) - sys_vgui("pdtk_undomenu .x%x %s no\n", x, canvas_undo_name); - canvas_undo_whatnext = UNDO_UNDO; - } -} - -/* ------- specific undo methods: 1. connect and disconnect -------- */ - -typedef struct _undo_connect -{ - int u_index1; - int u_outletno; - int u_index2; - int u_inletno; -} t_undo_connect; - -static void *canvas_undo_set_disconnect(t_canvas *x, - int index1, int outno, int index2, int inno) -{ - t_undo_connect *buf = (t_undo_connect *)getbytes(sizeof(*buf)); - buf->u_index1 = index1; - buf->u_outletno = outno; - buf->u_index2 = index2; - buf->u_inletno = inno; - return (buf); -} - -void canvas_disconnect(t_canvas *x, - float index1, float outno, float index2, float inno) -{ - t_linetraverser t; - t_outconnect *oc; - linetraverser_start(&t, x); - while (oc = linetraverser_next(&t)) - { - int srcno = canvas_getindex(x, &t.tr_ob->ob_g); - int sinkno = canvas_getindex(x, &t.tr_ob2->ob_g); - if (srcno == index1 && t.tr_outno == outno && - sinkno == index2 && t.tr_inno == inno) - { - sys_vgui(".x%x.c delete l%x\n", x, oc); - obj_disconnect(t.tr_ob, t.tr_outno, t.tr_ob2, t.tr_inno); - break; - } - } -} - -static void canvas_undo_disconnect(t_canvas *x, void *z, int action) -{ - t_undo_connect *buf = z; - if (action == UNDO_UNDO) - { - canvas_connect(x, buf->u_index1, buf->u_outletno, - buf->u_index2, buf->u_inletno); - } - else if (action == UNDO_REDO) - { - canvas_disconnect(x, buf->u_index1, buf->u_outletno, - buf->u_index2, buf->u_inletno); - } - else if (action == UNDO_FREE) - t_freebytes(buf, sizeof(*buf)); -} - - /* connect just calls disconnect actions backward... */ -static void *canvas_undo_set_connect(t_canvas *x, - int index1, int outno, int index2, int inno) -{ - return (canvas_undo_set_disconnect(x, index1, outno, index2, inno)); -} - -static void canvas_undo_connect(t_canvas *x, void *z, int action) -{ - int myaction; - if (action == UNDO_UNDO) - myaction = UNDO_REDO; - else if (action == UNDO_REDO) - myaction = UNDO_UNDO; - else myaction = action; - canvas_undo_disconnect(x, z, myaction); -} - -/* ---------- ... 2. cut, clear, and typing into objects: -------- */ - -#define UCUT_CUT 1 /* operation was a cut */ -#define UCUT_CLEAR 2 /* .. a clear */ -#define UCUT_TEXT 3 /* text typed into a box */ - -typedef struct _undo_cut -{ - t_binbuf *u_objectbuf; /* the object cleared or typed into */ - t_binbuf *u_reconnectbuf; /* connections into and out of object */ - t_binbuf *u_redotextbuf; /* buffer to paste back for redo if TEXT */ - int u_mode; /* from flags above */ -} t_undo_cut; - -static void *canvas_undo_set_cut(t_canvas *x, int mode) -{ - t_undo_cut *buf; - t_gobj *y; - t_linetraverser t; - t_outconnect *oc; - int nnotsel= glist_selectionindex(x, 0, 0); - buf = (t_undo_cut *)getbytes(sizeof(*buf)); - buf->u_mode = mode; - buf->u_redotextbuf = 0; - - /* store connections into/out of the selection */ - buf->u_reconnectbuf = binbuf_new(); - linetraverser_start(&t, x); - while (oc = linetraverser_next(&t)) - { - int issel1 = glist_isselected(x, &t.tr_ob->ob_g); - int issel2 = glist_isselected(x, &t.tr_ob2->ob_g); - if (issel1 != issel2) - { - binbuf_addv(buf->u_reconnectbuf, "ssiiii;", - gensym("#X"), gensym("connect"), - (issel1 ? nnotsel : 0) - + glist_selectionindex(x, &t.tr_ob->ob_g, issel1), - t.tr_outno, - (issel2 ? nnotsel : 0) + - glist_selectionindex(x, &t.tr_ob2->ob_g, issel2), - t.tr_inno); - } - } - if (mode == UCUT_TEXT) - { - buf->u_objectbuf = canvas_docopy(x); - } - else if (mode == UCUT_CUT) - { - buf->u_objectbuf = 0; - } - else if (mode == UCUT_CLEAR) - { - buf->u_objectbuf = canvas_docopy(x); - } - return (buf); -} - -static void canvas_undo_cut(t_canvas *x, void *z, int action) -{ - t_undo_cut *buf = z; - int mode = buf->u_mode; - if (action == UNDO_UNDO) - { - if (mode == UCUT_CUT) - canvas_dopaste(x, copy_binbuf); - else if (mode == UCUT_CLEAR) - canvas_dopaste(x, buf->u_objectbuf); - else if (mode == UCUT_TEXT) - { - t_gobj *y1, *y2; - glist_noselect(x); - for (y1 = x->gl_list; y2 = y1->g_next; y1 = y2) - ; - if (y1) - { - if (!buf->u_redotextbuf) - { - glist_noselect(x); - glist_select(x, y1); - buf->u_redotextbuf = canvas_docopy(x); - glist_noselect(x); - } - glist_delete(x, y1); - } - canvas_dopaste(x, buf->u_objectbuf); - } - pd_bind(&x->gl_pd, gensym("#X")); - binbuf_eval(buf->u_reconnectbuf, 0, 0, 0); - pd_unbind(&x->gl_pd, gensym("#X")); - } - else if (action == UNDO_REDO) - { - if (mode == UCUT_CUT || mode == UCUT_CLEAR) - canvas_doclear(x); - else if (mode == UCUT_TEXT) - { - t_gobj *y1, *y2; - for (y1 = x->gl_list; y2 = y1->g_next; y1 = y2) - ; - if (y1) - glist_delete(x, y1); - canvas_dopaste(x, buf->u_redotextbuf); - pd_bind(&x->gl_pd, gensym("#X")); - binbuf_eval(buf->u_reconnectbuf, 0, 0, 0); - pd_unbind(&x->gl_pd, gensym("#X")); - } - } - else if (action == UNDO_FREE) - { - if (buf->u_objectbuf) - binbuf_free(buf->u_objectbuf); - if (buf->u_reconnectbuf) - binbuf_free(buf->u_reconnectbuf); - if (buf->u_redotextbuf) - binbuf_free(buf->u_redotextbuf); - t_freebytes(buf, sizeof(*buf)); - } -} - -/* --------- 3. motion, including "tidy up" and stretching ----------- */ - -typedef struct _undo_move_elem -{ - int e_index; - int e_xpix; - int e_ypix; -} t_undo_move_elem; - -typedef struct _undo_move -{ - t_undo_move_elem *u_vec; - int u_n; -} t_undo_move; - -static int canvas_undo_already_set_move; - -static void *canvas_undo_set_move(t_canvas *x, int selected) -{ - int x1, y1, x2, y2, i, indx; - t_gobj *y; - t_undo_move *buf = (t_undo_move *)getbytes(sizeof(*buf)); - buf->u_n = selected ? glist_selectionindex(x, 0, 1) : glist_getindex(x, 0); - buf->u_vec = (t_undo_move_elem *)getbytes(sizeof(*buf->u_vec) * - (selected ? glist_selectionindex(x, 0, 1) : glist_getindex(x, 0))); - if (selected) - { - for (y = x->gl_list, i = indx = 0; y; y = y->g_next, indx++) - if (glist_isselected(x, y)) - { - gobj_getrect(y, x, &x1, &y1, &x2, &y2); - buf->u_vec[i].e_index = indx; - buf->u_vec[i].e_xpix = x1; - buf->u_vec[i].e_ypix = y1; - i++; - } - } - else - { - for (y = x->gl_list, indx = 0; y; y = y->g_next, indx++) - { - gobj_getrect(y, x, &x1, &y1, &x2, &y2); - buf->u_vec[indx].e_index = indx; - buf->u_vec[indx].e_xpix = x1; - buf->u_vec[indx].e_ypix = y1; - } - } - canvas_undo_already_set_move = 1; - return (buf); -} - -static void canvas_undo_move(t_canvas *x, void *z, int action) -{ - t_undo_move *buf = z; - if (action == UNDO_UNDO || action == UNDO_REDO) - { - int i; - for (i = 0; i < buf->u_n; i++) - { - int x1, y1, x2, y2, newx, newy; - t_gobj *y; - newx = buf->u_vec[i].e_xpix; - newy = buf->u_vec[i].e_ypix; - y = glist_nth(x, buf->u_vec[i].e_index); - if (y) - { - gobj_getrect(y, x, &x1, &y1, &x2, &y2); - gobj_displace(y, x, newx-x1, newy - y1); - buf->u_vec[i].e_xpix = x1; - buf->u_vec[i].e_ypix = y1; - } - } - } - else if (action == UNDO_FREE) - { - t_freebytes(buf->u_vec, buf->u_n * sizeof(*buf->u_vec)); - t_freebytes(buf, sizeof(*buf)); - } -} - -/* --------- 4. paste (also duplicate) ----------- */ - -typedef struct _undo_paste -{ - int u_index; /* index of first object pasted */ -} t_undo_paste; - -static void *canvas_undo_set_paste(t_canvas *x) -{ - t_undo_paste *buf = (t_undo_paste *)getbytes(sizeof(*buf)); - buf->u_index = glist_getindex(x, 0); - return (buf); -} - -static void canvas_undo_paste(t_canvas *x, void *z, int action) -{ - t_undo_paste *buf = z; - if (action == UNDO_UNDO) - { - t_gobj *y; - glist_noselect(x); - for (y = glist_nth(x, buf->u_index); y; y = y->g_next) - glist_select(x, y); - canvas_doclear(x); - } - else if (action == UNDO_REDO) - { - t_selection *sel; - canvas_dopaste(x, copy_binbuf); - /* if it was "duplicate" have to re-enact the displacement. */ - if (canvas_undo_name && canvas_undo_name[0] == 'd') - for (sel = x->gl_editor->e_selection; sel; sel = sel->sel_next) - gobj_displace(sel->sel_what, x, 10, 10); - } -else if (action == UNDO_FREE) - t_freebytes(buf, sizeof(*buf)); -} - - /* recursively check for abstractions to reload as result of a save. - Don't reload the one we just saved ("except") though. */ - /* LATER try to do the same trick for externs. */ -static void glist_doreload(t_glist *gl, t_symbol *name, t_symbol *dir, - t_gobj *except) -{ - t_gobj *g; - int i, nobj = glist_getindex(gl, 0); /* number of objects */ - for (g = gl->gl_list, i = 0; g && i < nobj; i++) - { - if (g != except && pd_class(&g->g_pd) == canvas_class && - canvas_isabstraction((t_canvas *)g) && - ((t_canvas *)g)->gl_name == name && - canvas_getdir((t_canvas *)g) == dir) - { - /* we're going to remake the object, so "g" will go stale. - Get its index here, and afterward restore g. Also, the - replacement will be at teh end of the list, so we don't - do g = g->g_next in this case. */ - int j = glist_getindex(gl, g); - if (!gl->gl_havewindow) - canvas_vis(glist_getcanvas(gl), 1); - glist_noselect(gl); - glist_select(gl, g); - canvas_setundo(gl, canvas_undo_cut, - canvas_undo_set_cut(gl, UCUT_CLEAR), "clear"); - canvas_doclear(gl); - canvas_undo(gl); - glist_noselect(gl); - g = glist_nth(gl, j); - } - else - { - if (g != except && pd_class(&g->g_pd) == canvas_class) - glist_doreload((t_canvas *)g, name, dir, except); - g = g->g_next; - } - } -} - - /* call canvas_doreload on everyone */ -void canvas_reload(t_symbol *name, t_symbol *dir, t_gobj *except) -{ - t_canvas *x; - /* find all root canvases */ - for (x = canvas_list; x; x = x->gl_next) - glist_doreload(x, name, dir, except); -} - -/* ------------------------ event handling ------------------------ */ - -#define CURSOR_RUNMODE_NOTHING 0 -#define CURSOR_RUNMODE_CLICKME 1 -#define CURSOR_RUNMODE_THICKEN 2 -#define CURSOR_RUNMODE_ADDPOINT 3 -#define CURSOR_EDITMODE_NOTHING 4 -#define CURSOR_EDITMODE_CONNECT 5 -#define CURSOR_EDITMODE_DISCONNECT 6 - -static char *cursorlist[] = { -#ifdef MSW - "right_ptr", /* CURSOR_RUNMODE_NOTHING */ -#else - "left_ptr", /* CURSOR_RUNMODE_NOTHING */ -#endif - "arrow", /* CURSOR_RUNMODE_CLICKME */ - "sb_v_double_arrow", /* CURSOR_RUNMODE_THICKEN */ - "plus", /* CURSOR_RUNMODE_ADDPOINT */ - "hand2", /* CURSOR_EDITMODE_NOTHING */ - "circle", /* CURSOR_EDITMODE_CONNECT */ - "X_cursor" /* CURSOR_EDITMODE_DISCONNECT */ -}; - -void canvas_setcursor(t_canvas *x, unsigned int cursornum) -{ - static t_canvas *xwas; - static unsigned int cursorwas; - if (cursornum >= sizeof(cursorlist)/sizeof *cursorlist) - { - bug("canvas_setcursor"); - return; - } - if (xwas != x || cursorwas != cursornum) - { - sys_vgui(".x%x configure -cursor %s\n", x, cursorlist[cursornum]); - xwas = x; - cursorwas = cursornum; - } -} - - /* check if a point lies in a gobj. */ -int canvas_hitbox(t_canvas *x, t_gobj *y, int xpos, int ypos, - int *x1p, int *y1p, int *x2p, int *y2p) -{ - int x1, y1, x2, y2; - t_text *ob; - if ((ob = pd_checkobject(&y->g_pd)) && - !text_shouldvis(ob, x)) - return (0); - gobj_getrect(y, x, &x1, &y1, &x2, &y2); - if (xpos >= x1 && xpos <= x2 && ypos >= y1 && ypos <= y2) - { - *x1p = x1; - *y1p = y1; - *x2p = x2; - *y2p = y2; - return (1); - } - else return (0); -} - - /* find the last gobj, if any, containing the point. */ -static t_gobj *canvas_findhitbox(t_canvas *x, int xpos, int ypos, - int *x1p, int *y1p, int *x2p, int *y2p) -{ - t_gobj *y, *rval = 0; - for (y = x->gl_list; y; y = y->g_next) - { - if (canvas_hitbox(x, y, xpos, ypos, x1p, y1p, x2p, y2p)) - rval = y; - } - return (rval); -} - - /* right-clicking on a canvas object pops up a menu. */ -static void canvas_rightclick(t_canvas *x, int xpos, int ypos, t_gobj *y) -{ - int canprop, canopen; - canprop = (!y || (y && class_getpropertiesfn(pd_class(&y->g_pd)))); - canopen = (y && zgetfn(&y->g_pd, gensym("menu-open"))); - sys_vgui("pdtk_canvas_popup .x%x %d %d %d %d\n", - x, xpos, ypos, canprop, canopen); -} - - /* tell GUI to create a properties dialog on the canvas. We tell - the user the negative of the "pixel" y scale to make it appear to grow - naturally upward, whereas pixels grow downward. */ -static void canvas_properties(t_glist *x) -{ - char graphbuf[200]; - sprintf(graphbuf, "pdtk_canvas_dialog %%s %g %g %g %g \n", - glist_dpixtodx(x, 1), -glist_dpixtody(x, 1), - (float)glist_isgraph(x), (float)x->gl_stretch); - gfxstub_new(&x->gl_pd, x, graphbuf); -} - - -void canvas_setgraph(t_glist *x, int flag) -{ - if (!flag && glist_isgraph(x)) - { - if (x->gl_owner && !x->gl_loading && glist_isvisible(x->gl_owner)) - gobj_vis(&x->gl_gobj, x->gl_owner, 0); - x->gl_isgraph = 0; - if (x->gl_owner && !x->gl_loading && glist_isvisible(x->gl_owner)) - { - gobj_vis(&x->gl_gobj, x->gl_owner, 1); - canvas_fixlinesfor(x->gl_owner, &x->gl_obj); - } - } - else if (flag && !glist_isgraph(x)) - { - if (x->gl_pixwidth <= 0) - x->gl_pixwidth = GLIST_DEFGRAPHWIDTH; - - if (x->gl_pixheight <= 0) - x->gl_pixheight = GLIST_DEFGRAPHHEIGHT; - - if (x->gl_owner && !x->gl_loading && glist_isvisible(x->gl_owner)) - gobj_vis(&x->gl_gobj, x->gl_owner, 0); - x->gl_isgraph = 1; - /* if (x->gl_owner && glist_isvisible(x->gl_owner)) - canvas_vis(x, 1); */ - if (x->gl_loading && x->gl_owner && glist_isvisible(x->gl_owner)) - canvas_create_editor(x, 1); - if (x->gl_owner && !x->gl_loading && glist_isvisible(x->gl_owner)) - { - gobj_vis(&x->gl_gobj, x->gl_owner, 1); - canvas_fixlinesfor(x->gl_owner, &x->gl_obj); - } - } -} - - /* called from the gui when "OK" is selected on the canvas properties - dialog. Again we negate "y" scale. */ -static void canvas_donecanvasdialog(t_glist *x, t_floatarg xperpix, - t_floatarg yperpix, t_floatarg fgraphme) -{ - int graphme = (fgraphme != 0), redraw = 0; - yperpix = -yperpix; - if (xperpix == 0) - xperpix = 1; - if (yperpix == 0) - yperpix = 1; - canvas_setgraph(x, graphme); - if (!x->gl_isgraph && (xperpix != glist_dpixtodx(x, 1))) - { - if (xperpix > 0) - { - x->gl_x1 = 0; - x->gl_x2 = xperpix; - } - else - { - x->gl_x1 = -xperpix * (x->gl_screenx2 - x->gl_screenx1); - x->gl_x2 = x->gl_x1 + xperpix; - } - redraw = 1; - } - if (!x->gl_isgraph && (yperpix != glist_dpixtody(x, 1))) - { - if (yperpix > 0) - { - x->gl_y1 = 0; - x->gl_y2 = yperpix; - } - else - { - x->gl_y1 = -yperpix * (x->gl_screeny2 - x->gl_screeny1); - x->gl_y2 = x->gl_y1 + yperpix; - } - redraw = 1; - } - if (redraw) - canvas_redraw(x); -} - - /* called from the gui when a popup menu comes back with "properties," - "open," or "help." */ -static void canvas_done_popup(t_canvas *x, float which, float xpos, float ypos) -{ - char pathbuf[MAXPDSTRING], namebuf[MAXPDSTRING]; - t_gobj *y; - for (y = x->gl_list; y; y = y->g_next) - { - int x1, y1, x2, y2; - if (canvas_hitbox(x, y, xpos, ypos, &x1, &y1, &x2, &y2)) - { - if (which == 0) /* properties */ - { - if (!class_getpropertiesfn(pd_class(&y->g_pd))) - continue; - (*class_getpropertiesfn(pd_class(&y->g_pd)))(y, x); - return; - } - else if (which == 1) /* open */ - { - if (!zgetfn(&y->g_pd, gensym("menu-open"))) - continue; - vmess(&y->g_pd, gensym("menu-open"), ""); - return; - } - else /* help */ - { - char *dir; - if (pd_class(&y->g_pd) == canvas_class && - canvas_isabstraction((t_canvas *)y)) - { - t_object *ob = (t_object *)y; - int ac = binbuf_getnatom(ob->te_binbuf); - t_atom *av = binbuf_getvec(ob->te_binbuf); - if (ac < 1) - return; - atom_string(av, namebuf, MAXPDSTRING); - dir = canvas_getdir((t_canvas *)y)->s_name; - } - else - { - strcpy(namebuf, class_gethelpname(pd_class(&y->g_pd))); - dir = class_gethelpdir(pd_class(&y->g_pd)); - } - if (strcmp(namebuf + strlen(namebuf) - 3, ".pd")) - strcat(namebuf, ".pd"); - open_via_helppath(namebuf, dir); - return; - } - } - } - if (which == 0) - canvas_properties(x); - else if (which == 2) - { - strcpy(pathbuf, sys_libdir->s_name); - strcat(pathbuf, "/doc/5.reference/0.INTRO.txt"); - sys_vgui("menu_opentext %s\n", pathbuf); - } -} - -#define NOMOD 0 -#define SHIFTMOD 1 -#define CTRLMOD 2 -#define ALTMOD 4 -#define RIGHTCLICK 8 - -/* on one-button-mouse machines, you can use double click to - mean right click (which gets the popup menu.) Do this for Mac. */ -#ifdef MACOSX -#define SIMULATERIGHTCLICK -#endif - -#ifdef SIMULATERIGHTCLICK -static double canvas_upclicktime; -static int canvas_upx, canvas_upy; -#define DCLICKINTERVAL 0.25 -#endif - - /* mouse click */ -void canvas_doclick(t_canvas *x, int xpos, int ypos, int which, - int mod, int doit) -{ - t_gobj *y; - int shiftmod, runmode, altmod, rightclick; - int x1, y1, x2, y2, clickreturned = 0; - - if (!x->gl_editor) - { - bug("editor"); - return; - } - - shiftmod = (mod & SHIFTMOD); - runmode = ((mod & CTRLMOD) || (!x->gl_edit)); - altmod = (mod & ALTMOD); - rightclick = (mod & RIGHTCLICK); - - canvas_undo_already_set_move = 0; - - /* if keyboard was grabbed, notify grabber and cancel the grab */ - if (doit && x->gl_editor->e_grab && x->gl_editor->e_keyfn) - { - (* x->gl_editor->e_keyfn) (x->gl_editor->e_grab, 0); - glist_grab(x, 0, 0, 0, 0, 0); - } - -#ifdef SIMULATERIGHTCLICK - if (doit && !runmode && xpos == canvas_upx && ypos == canvas_upy && - sys_getrealtime() - canvas_upclicktime < DCLICKINTERVAL) - rightclick = 1; -#endif - - x->gl_editor->e_lastmoved = 0; - if (doit) - { - x->gl_editor->e_grab = 0; - x->gl_editor->e_onmotion = MA_NONE; - } - /* post("click %d %d %d %d", xpos, ypos, which, mod); */ - - if (x->gl_editor->e_onmotion != MA_NONE) - return; - - x->gl_editor->e_xwas = xpos; - x->gl_editor->e_ywas = ypos; - - if (runmode && !rightclick) - { - for (y = x->gl_list; y; y = y->g_next) - { - /* check if the object wants to be clicked */ - if (canvas_hitbox(x, y, xpos, ypos, &x1, &y1, &x2, &y2) - && (clickreturned = gobj_click(y, x, xpos, ypos, - shiftmod, altmod, 0, doit))) - break; - } - if (!doit) - { - if (y) - canvas_setcursor(x, clickreturned); - else canvas_setcursor(x, CURSOR_RUNMODE_NOTHING); - } - return; - } - /* if not a runmode left click, fall here. */ - if (y = canvas_findhitbox(x, xpos, ypos, &x1, &y1, &x2, &y2)) - { - t_object *ob = pd_checkobject(&y->g_pd); - /* check you're in the rectangle */ - ob = pd_checkobject(&y->g_pd); - if (rightclick) - canvas_rightclick(x, xpos, ypos, y); - else if (shiftmod) - { - if (doit) - { - t_rtext *rt; - if (ob && (rt = x->gl_editor->e_textedfor) && - rt == glist_findrtext(x, ob)) - { - rtext_mouse(rt, xpos - x1, ypos - y1, RTEXT_SHIFT); - x->gl_editor->e_onmotion = MA_DRAGTEXT; - x->gl_editor->e_xwas = x1; - x->gl_editor->e_ywas = y1; - } - else - { - if (glist_isselected(x, y)) - glist_deselect(x, y); - else glist_select(x, y); - } - } - } - else - { - /* look for an outlet */ - int noutlet; - if (ob && (noutlet = obj_noutlets(ob)) && ypos >= y2-4) - { - int width = x2 - x1; - int nout1 = (noutlet > 1 ? noutlet - 1 : 1); - int closest = ((xpos-x1) * (nout1) + width/2)/width; - int hotspot = x1 + - (width - IOWIDTH) * closest / (nout1); - if (closest < noutlet && - xpos >= (hotspot-1) && xpos <= hotspot + (IOWIDTH+1)) - { - if (doit) - { - int issignal = obj_issignaloutlet(ob, closest); - x->gl_editor->e_onmotion = MA_CONNECT; - x->gl_editor->e_xwas = xpos; - x->gl_editor->e_ywas = ypos; - sys_vgui( - ".x%x.c create line %d %d %d %d -width %d -tags x\n", - x, xpos, ypos, xpos, ypos, - (issignal ? 2 : 1)); - } - else canvas_setcursor(x, CURSOR_EDITMODE_CONNECT); - } - else if (doit) - goto nooutletafterall; - } - /* not in an outlet; select and move */ - else if (doit) - { - t_rtext *rt; - /* check if the box is being text edited */ - nooutletafterall: - if (ob && (rt = x->gl_editor->e_textedfor) && - rt == glist_findrtext(x, ob)) - { - rtext_mouse(rt, xpos - x1, ypos - y1, RTEXT_DOWN); - x->gl_editor->e_onmotion = MA_DRAGTEXT; - x->gl_editor->e_xwas = x1; - x->gl_editor->e_ywas = y1; - } - else - { - /* otherwise select and drag to displace */ - if (!glist_isselected(x, y)) - { - glist_noselect(x); - glist_select(x, y); - } - x->gl_editor->e_onmotion = MA_MOVE; - } - } - else canvas_setcursor(x, CURSOR_EDITMODE_NOTHING); - } - return; - } - /* if right click doesn't hit any boxes, call rightclick - routine anyway */ - if (rightclick) - canvas_rightclick(x, xpos, ypos, 0); - - /* if not an editing action, and if we didn't hit a - box, set cursor and return */ - if (runmode || rightclick) - { - canvas_setcursor(x, CURSOR_RUNMODE_NOTHING); - return; - } - /* having failed to find a box, we try lines now. */ - if (!runmode && !altmod && !shiftmod) - { - t_linetraverser t; - t_outconnect *oc; - float fx = xpos, fy = ypos; - t_glist *glist2 = glist_getcanvas(x); - linetraverser_start(&t, glist2); - while (oc = linetraverser_next(&t)) - { - float lx1 = t.tr_lx1, ly1 = t.tr_ly1, - lx2 = t.tr_lx2, ly2 = t.tr_ly2; - float area = (lx2 - lx1) * (fy - ly1) - - (ly2 - ly1) * (fx - lx1); - float dsquare = (lx2-lx1) * (lx2-lx1) + (ly2-ly1) * (ly2-ly1); - if (area * area >= 50 * dsquare) continue; - if ((lx2-lx1) * (fx-lx1) + (ly2-ly1) * (fy-ly1) < 0) continue; - if ((lx2-lx1) * (lx2-fx) + (ly2-ly1) * (ly2-fy) < 0) continue; - if (doit) - { - glist_selectline(glist2, oc, - canvas_getindex(glist2, &t.tr_ob->ob_g), t.tr_outno, - canvas_getindex(glist2, &t.tr_ob2->ob_g), t.tr_inno); - } - canvas_setcursor(x, CURSOR_EDITMODE_DISCONNECT); - return; - } - } - canvas_setcursor(x, CURSOR_EDITMODE_NOTHING); - if (doit) - { - if (!shiftmod) glist_noselect(x); - sys_vgui(".x%x.c create rectangle %d %d %d %d -tags x\n", - x, xpos, ypos, xpos, ypos); - x->gl_editor->e_xwas = xpos; - x->gl_editor->e_ywas = ypos; - x->gl_editor->e_onmotion = MA_REGION; - } -} - -void canvas_mousedown(t_canvas *x, t_floatarg xpos, t_floatarg ypos, - t_floatarg which, t_floatarg mod) -{ - canvas_doclick(x, xpos, ypos, which, mod, 1); -} - -int canvas_isconnected (t_canvas *x, t_text *ob1, int n1, - t_text *ob2, int n2) -{ - t_linetraverser t; - t_outconnect *oc; - linetraverser_start(&t, x); - while (oc = linetraverser_next(&t)) - if (t.tr_ob == ob1 && t.tr_outno == n1 && - t.tr_ob2 == ob2 && t.tr_inno == n2) - return (1); - return (0); -} - -void canvas_doconnect(t_canvas *x, int xpos, int ypos, int which, int doit) -{ - int x11, y11, x12, y12; - t_gobj *y1; - int x21, y21, x22, y22; - t_gobj *y2; - int xwas = x->gl_editor->e_xwas, - ywas = x->gl_editor->e_ywas; - if (doit) sys_vgui(".x%x.c delete x\n", x); - else sys_vgui(".x%x.c coords x %d %d %d %d\n", - x, x->gl_editor->e_xwas, - x->gl_editor->e_ywas, xpos, ypos); - - if ((y1 = canvas_findhitbox(x, xwas, ywas, &x11, &y11, &x12, &y12)) - && (y2 = canvas_findhitbox(x, xpos, ypos, &x21, &y21, &x22, &y22))) - { - t_object *ob1 = pd_checkobject(&y1->g_pd); - t_object *ob2 = pd_checkobject(&y2->g_pd); - int noutlet1, ninlet2; - if (ob1 && ob2 && ob1 != ob2 && - (noutlet1 = obj_noutlets(ob1)) - && (ninlet2 = obj_ninlets(ob2))) - { - int width1 = x12 - x11, closest1, hotspot1; - int width2 = x22 - x21, closest2, hotspot2; - int lx1, lx2, ly1, ly2; - t_outconnect *oc; - - if (noutlet1 > 1) - { - closest1 = ((xwas-x11) * (noutlet1-1) + width1/2)/width1; - hotspot1 = x11 + - (width1 - IOWIDTH) * closest1 / (noutlet1-1); - } - else closest1 = 0, hotspot1 = x11; - - if (ninlet2 > 1) - { - closest2 = ((xpos-x21) * (ninlet2-1) + width2/2)/width2; - hotspot2 = x21 + - (width2 - IOWIDTH) * closest2 / (ninlet2-1); - } - else closest2 = 0, hotspot2 = x21; - - if (closest1 >= noutlet1) - closest1 = noutlet1 - 1; - if (closest2 >= ninlet2) - closest2 = ninlet2 - 1; - - if (canvas_isconnected (x, ob1, closest1, ob2, closest2)) - { - canvas_setcursor(x, CURSOR_EDITMODE_NOTHING); - return; - } - if (obj_issignaloutlet(ob1, closest1) && - !obj_issignalinlet(ob2, closest2)) - { - if (doit) - error("can't connect signal outlet to control inlet"); - canvas_setcursor(x, CURSOR_EDITMODE_NOTHING); - return; - } - if (doit) - { - oc = obj_connect(ob1, closest1, ob2, closest2); - lx1 = x11 + (noutlet1 > 1 ? - ((x12-x11-IOWIDTH) * closest1)/(noutlet1-1) : 0) - + IOMIDDLE; - ly1 = y12; - lx2 = x21 + (ninlet2 > 1 ? - ((x22-x21-IOWIDTH) * closest2)/(ninlet2-1) : 0) - + IOMIDDLE; - ly2 = y21; - sys_vgui(".x%x.c create line %d %d %d %d -width %d -tags l%x\n", - glist_getcanvas(x), - lx1, ly1, lx2, ly2, - (obj_issignaloutlet(ob1, closest1) ? 2 : 1), oc); - canvas_setundo(x, canvas_undo_connect, - canvas_undo_set_connect(x, - canvas_getindex(x, &ob1->ob_g), closest1, - canvas_getindex(x, &ob2->ob_g), closest2), - "connect"); - } - else canvas_setcursor(x, CURSOR_EDITMODE_CONNECT); - return; - } - } - canvas_setcursor(x, CURSOR_EDITMODE_NOTHING); -} - -void canvas_selectinrect(t_canvas *x, int lox, int loy, int hix, int hiy) -{ - t_gobj *y; - for (y = x->gl_list; y; y = y->g_next) - { - int x1, y1, x2, y2; - gobj_getrect(y, x, &x1, &y1, &x2, &y2); - if (hix >= x1 && lox <= x2 && hiy >= y1 && loy <= y2 - && !glist_isselected(x, y)) - glist_select(x, y); - } -} - -static void canvas_doregion(t_canvas *x, int xpos, int ypos, int doit) -{ - if (doit) - { - int lox, loy, hix, hiy; - if (x->gl_editor->e_xwas < xpos) - lox = x->gl_editor->e_xwas, hix = xpos; - else hix = x->gl_editor->e_xwas, lox = xpos; - if (x->gl_editor->e_ywas < ypos) - loy = x->gl_editor->e_ywas, hiy = ypos; - else hiy = x->gl_editor->e_ywas, loy = ypos; - canvas_selectinrect(x, lox, loy, hix, hiy); - sys_vgui(".x%x.c delete x\n", x); - x->gl_editor->e_onmotion = 0; - } - else sys_vgui(".x%x.c coords x %d %d %d %d\n", - x, x->gl_editor->e_xwas, - x->gl_editor->e_ywas, xpos, ypos); -} - -void canvas_mouseup(t_canvas *x, - t_floatarg fxpos, t_floatarg fypos, t_floatarg fwhich) -{ - t_gobj *y; - - int xpos = fxpos, ypos = fypos, which = fwhich; - - if (!x->gl_editor) - { - bug("editor"); - return; - } - -#ifdef SIMULATERIGHTCLICK - canvas_upclicktime = sys_getrealtime(); - canvas_upx = xpos; - canvas_upy = ypos; -#endif - - if (x->gl_editor->e_onmotion == MA_CONNECT) - canvas_doconnect(x, xpos, ypos, which, 1); - else if (x->gl_editor->e_onmotion == MA_REGION) - canvas_doregion(x, xpos, ypos, 1); - else if (x->gl_editor->e_onmotion == MA_MOVE) - { - /* after motion, if there's only one item selected, activate it */ - if (x->gl_editor->e_selection && - !(x->gl_editor->e_selection->sel_next)) - gobj_activate(x->gl_editor->e_selection->sel_what, - x, 1); - } - else if (x->gl_editor->e_onmotion == MA_PASSOUT) - x->gl_editor->e_onmotion = 0; - x->gl_editor->e_onmotion = MA_NONE; - - -#if 1 - /* GG misused the (unused) dbl parameter to tell if mouseup */ - - for (y = x->gl_list; y; y = y->g_next) { - int x1, y1, x2, y2, clickreturned = 0; - - /* check if the object wants to be clicked */ - if (canvas_hitbox(x, y, xpos, ypos, &x1, &y1, &x2, &y2) - && (clickreturned = gobj_click(y, x, xpos, ypos, - 0, 0, 1, 0))) - break; - } -#endif - - -} - - /* displace the selection by (dx, dy) pixels */ -static void canvas_displaceselection(t_canvas *x, int dx, int dy) -{ - t_selection *y; - int resortin = 0, resortout = 0; - if (!canvas_undo_already_set_move) - { - canvas_setundo(x, canvas_undo_move, canvas_undo_set_move(x, 1), - "motion"); - canvas_undo_already_set_move = 1; - } - for (y = x->gl_editor->e_selection; y; y = y->sel_next) - { - t_class *cl = pd_class(&y->sel_what->g_pd); - gobj_displace(y->sel_what, x, dx, dy); - if (cl == vinlet_class) resortin = 1; - else if (cl == voutlet_class) resortout = 1; - } - if (resortin) canvas_resortinlets(x); - if (resortout) canvas_resortoutlets(x); - canvas_dirty(x, 1); -} - - /* this routine is called whenever a key is pressed or released. "x" - may be zero if there's no current canvas. The first argument is true or - fals for down/up; the second one is either a symbolic key name (e.g., - "Right" or an Ascii key number. */ -void canvas_key(t_canvas *x, t_symbol *s, int ac, t_atom *av) -{ - static t_symbol *keynumsym, *keyupsym, *keynamesym; - int keynum, fflag; - t_symbol *gotkeysym; - - int down, shift; - - if (ac < 3) - return; - if (!x->gl_editor) - { - bug("editor"); - return; - } - canvas_undo_already_set_move = 0; - down = (atom_getfloat(av) != 0); /* nonzero if it's a key down */ - shift = (atom_getfloat(av+2) != 0); /* nonzero if shift-ed */ - if (av[1].a_type == A_SYMBOL) - gotkeysym = av[1].a_w.w_symbol; - else if (av[1].a_type == A_FLOAT) - { - char buf[3]; - sprintf(buf, "%c", (int)(av[1].a_w.w_float)); - gotkeysym = gensym(buf); - } - else gotkeysym = gensym("?"); - fflag = (av[0].a_type == A_FLOAT ? av[0].a_w.w_float : 0); - keynum = (av[1].a_type == A_FLOAT ? av[1].a_w.w_float : 0); - if (keynum == '\\' || keynum == '{' || keynum == '}') - { - post("%c: dropped", (int)keynum); - return; - } - if (keynum == '\r') keynum = '\n'; - if (av[1].a_type == A_SYMBOL && - !strcmp(av[1].a_w.w_symbol->s_name, "Return")) - keynum = '\n'; - if (!keynumsym) - { - keynumsym = gensym("#key"); - keyupsym = gensym("#keyup"); - keynamesym = gensym("#keyname"); - } -#ifdef MACOSX - if (keynum == 30) - keynum = 0, gotkeysym = gensym("Up"); - else if (keynum == 31) - keynum = 0, gotkeysym = gensym("Down"); - else if (keynum == 28) - keynum = 0, gotkeysym = gensym("Left"); - else if (keynum == 29) - keynum = 0, gotkeysym = gensym("Right"); -#endif - if (keynumsym->s_thing && down) - pd_float(keynumsym->s_thing, (float)keynum); - if (keyupsym->s_thing && !down) - pd_float(keyupsym->s_thing, (float)keynum); - if (keynamesym->s_thing) - { - t_atom at[2]; - at[0] = av[0]; - SETFLOAT(at, down); - SETSYMBOL(at+1, gotkeysym); - pd_list(keynamesym->s_thing, 0, 2, at); - } - if (!x->gl_editor) /* if that 'invis'ed the window, we'd better stop. */ - return; - if (x && down) - { - /* if an object has "grabbed" keys just send them on */ - if (x->gl_editor->e_grab - && x->gl_editor->e_keyfn && keynum) - (* x->gl_editor->e_keyfn) - (x->gl_editor->e_grab, (float)keynum); - /* if a text editor is open send it on */ - else if (x->gl_editor->e_textedfor) - { - if (!x->gl_editor->e_textdirty) - { - canvas_setundo(x, canvas_undo_cut, - canvas_undo_set_cut(x, UCUT_TEXT), "typing"); - } - rtext_key(x->gl_editor->e_textedfor, - (int)keynum, gotkeysym); - if (x->gl_editor->e_textdirty) - canvas_dirty(x, 1); - } - /* check for backspace or clear */ - else if (keynum == 8 || keynum == 127) - { - if (x->gl_editor->e_selectedline) - canvas_clearline(x); - else if (x->gl_editor->e_selection) - { - canvas_setundo(x, canvas_undo_cut, - canvas_undo_set_cut(x, UCUT_CLEAR), "clear"); - canvas_doclear(x); - } - } - /* check for arrow keys */ - else if (!strcmp(gotkeysym->s_name, "Up")) - canvas_displaceselection(x, 0, shift ? -10 : -1); - else if (!strcmp(gotkeysym->s_name, "Down")) - canvas_displaceselection(x, 0, shift ? 10 : 1); - else if (!strcmp(gotkeysym->s_name, "Left")) - canvas_displaceselection(x, shift ? -10 : -1, 0); - else if (!strcmp(gotkeysym->s_name, "Right")) - canvas_displaceselection(x, shift ? 10 : 1, 0); - } -} - -void canvas_motion(t_canvas *x, t_floatarg xpos, t_floatarg ypos, - t_floatarg fmod) -{ - /* post("motion %d %d", xpos, ypos); */ - int mod = fmod; - if (!x->gl_editor) - { - bug("editor"); - return; - } - glist_setlastxy(x, xpos, ypos); - if (x->gl_editor->e_onmotion == MA_MOVE) - { - canvas_displaceselection(x, - xpos - x->gl_editor->e_xwas, ypos - x->gl_editor->e_ywas); - x->gl_editor->e_xwas = xpos; - x->gl_editor->e_ywas = ypos; - } - else if (x->gl_editor->e_onmotion == MA_REGION) - canvas_doregion(x, xpos, ypos, 0); - else if (x->gl_editor->e_onmotion == MA_CONNECT) - canvas_doconnect(x, xpos, ypos, 0, 0); - else if (x->gl_editor->e_onmotion == MA_PASSOUT) - { - if (!x->gl_editor->e_motionfn) - bug("e_motionfn"); - (*x->gl_editor->e_motionfn)(&x->gl_editor->e_grab->g_pd, - xpos - x->gl_editor->e_xwas, - ypos - x->gl_editor->e_ywas); - x->gl_editor->e_xwas = xpos; - x->gl_editor->e_ywas = ypos; - } - else if (x->gl_editor->e_onmotion == MA_DRAGTEXT) - { - t_rtext *rt = x->gl_editor->e_textedfor; - if (rt) - rtext_mouse(rt, xpos - x->gl_editor->e_xwas, - ypos - x->gl_editor->e_ywas, RTEXT_DRAG); - } - else canvas_doclick(x, xpos, ypos, 0, mod, 0); - - x->gl_editor->e_lastmoved = 1; -} - -void canvas_startmotion(t_canvas *x) -{ - int xval, yval; - if (!x->gl_editor) return; - glist_getnextxy(x, &xval, &yval); - if (xval == 0 && yval == 0) return; - x->gl_editor->e_onmotion = MA_MOVE; - x->gl_editor->e_xwas = xval; - x->gl_editor->e_ywas = yval; -} - -/* ----------------------------- window stuff ----------------------- */ - -void canvas_print(t_canvas *x, t_symbol *s) -{ - if (*s->s_name) sys_vgui(".x%x.c postscript -file %s\n", x, s->s_name); - else sys_vgui(".x%x.c postscript -file x.ps\n", x); -} - -void canvas_menuclose(t_canvas *x, t_floatarg force) -{ - if (x->gl_owner) - canvas_vis(x, 0); - else if ((force != 0) || (!x->gl_dirty)) - pd_free(&x->gl_pd); - else sys_vgui("pdtk_check {This window has been modified. Close anyway?}\ - {.x%x menuclose 1;\n}\n", x); -} - - /* put up a dialog which may call canvas_font back to do the work */ -static void canvas_menufont(t_canvas *x) -{ - char buf[80]; - t_canvas *x2 = canvas_getrootfor(x); - gfxstub_deleteforkey(x2); - sprintf(buf, "pdtk_canvas_dofont %%s %d\n", x2->gl_font); - gfxstub_new(&x2->gl_pd, &x2->gl_pd, buf); -} - -static int canvas_find_index1, canvas_find_index2; -static t_binbuf *canvas_findbuf; -int binbuf_match(t_binbuf *inbuf, t_binbuf *searchbuf); - - /* find an atom or string of atoms */ -static int canvas_dofind(t_canvas *x, int *myindex1p) -{ - t_gobj *y; - int myindex1 = *myindex1p, myindex2; - if (myindex1 >= canvas_find_index1) - { - for (y = x->gl_list, myindex2 = 0; y; - y = y->g_next, myindex2++) - { - t_object *ob = 0; - if (ob = pd_checkobject(&y->g_pd)) - { - if (binbuf_match(ob->ob_binbuf, canvas_findbuf)) - { - if (myindex1 > canvas_find_index1 || - myindex1 == canvas_find_index1 && - myindex2 > canvas_find_index2) - { - canvas_find_index1 = myindex1; - canvas_find_index2 = myindex2; - glist_noselect(x); - canvas_vis(x, 1); - canvas_editmode(x, 1.); - glist_select(x, y); - return (1); - } - } - } - } - } - for (y = x->gl_list, myindex2 = 0; y; y = y->g_next, myindex2++) - { - if (pd_class(&y->g_pd) == canvas_class) - { - (*myindex1p)++; - if (canvas_dofind((t_canvas *)y, myindex1p)) - return (1); - } - } - return (0); -} - -static void canvas_find(t_canvas *x, t_symbol *s, int ac, t_atom *av) -{ - int myindex1 = 0, i; - for (i = 0; i < ac; i++) - { - if (av[i].a_type == A_SYMBOL) - { - if (!strcmp(av[i].a_w.w_symbol->s_name, "_semi_")) - SETSEMI(&av[i]); - else if (!strcmp(av[i].a_w.w_symbol->s_name, "_comma_")) - SETCOMMA(&av[i]); - } - } - if (!canvas_findbuf) - canvas_findbuf = binbuf_new(); - binbuf_clear(canvas_findbuf); - binbuf_add(canvas_findbuf, ac, av); - canvas_find_index1 = 0; - canvas_find_index2 = -1; - canvas_whichfind = x; - if (!canvas_dofind(x, &myindex1)) - { - binbuf_print(canvas_findbuf); - post("... couldn't find"); - } -} - -static void canvas_find_again(t_canvas *x) -{ - int myindex1 = 0; - if (!canvas_findbuf || !canvas_whichfind) - return; - if (!canvas_dofind(canvas_whichfind, &myindex1)) - { - binbuf_print(canvas_findbuf); - post("... couldn't find"); - } -} - -static void canvas_find_parent(t_canvas *x) -{ - if (x->gl_owner) - canvas_vis(glist_getcanvas(x->gl_owner), 1); -} - -static int glist_dofinderror(t_glist *gl, void *error_object) -{ - t_gobj *g; - for (g = gl->gl_list; g; g = g->g_next) - { - if ((void *)g == error_object) - { - /* got it... now show it. */ - glist_noselect(gl); - canvas_vis(glist_getcanvas(gl), 1); - canvas_editmode(glist_getcanvas(gl), 1.); - glist_select(gl, g); - return (1); - } - else if (g->g_pd == canvas_class) - { - if (glist_dofinderror((t_canvas *)g, error_object)) - return (1); - } - } - return (0); -} - -void canvas_finderror(void *error_object) -{ - t_canvas *x; - /* find all root canvases */ - for (x = canvas_list; x; x = x->gl_next) - { - if (glist_dofinderror(x, error_object)) - return; - } - post("... sorry, I couldn't find the source of that error."); -} - -void canvas_stowconnections(t_canvas *x) -{ - t_gobj *selhead = 0, *seltail = 0, *nonhead = 0, *nontail = 0, *y, *y2; - t_linetraverser t; - t_outconnect *oc; - if (!x->gl_editor) return; - /* split list to "selected" and "unselected" parts */ - for (y = x->gl_list; y; y = y2) - { - y2 = y->g_next; - if (glist_isselected(x, y)) - { - if (seltail) - { - seltail->g_next = y; - seltail = y; - y->g_next = 0; - } - else - { - selhead = seltail = y; - seltail->g_next = 0; - } - } - else - { - if (nontail) - { - nontail->g_next = y; - nontail = y; - y->g_next = 0; - } - else - { - nonhead = nontail = y; - nontail->g_next = 0; - } - } - } - /* move the selected part to the end */ - if (!nonhead) x->gl_list = selhead; - else x->gl_list = nonhead, nontail->g_next = selhead; - - /* add connections to binbuf */ - binbuf_clear(x->gl_editor->e_connectbuf); - linetraverser_start(&t, x); - while (oc = linetraverser_next(&t)) - { - int s1 = glist_isselected(x, &t.tr_ob->ob_g); - int s2 = glist_isselected(x, &t.tr_ob2->ob_g); - if (s1 != s2) - binbuf_addv(x->gl_editor->e_connectbuf, "ssiiii;", - gensym("#X"), gensym("connect"), - glist_getindex(x, &t.tr_ob->ob_g), t.tr_outno, - glist_getindex(x, &t.tr_ob2->ob_g), t.tr_inno); - } -} - -void canvas_restoreconnections(t_canvas *x) -{ - pd_bind(&x->gl_pd, gensym("#X")); - binbuf_eval(x->gl_editor->e_connectbuf, 0, 0, 0); - pd_unbind(&x->gl_pd, gensym("#X")); -} - -static t_binbuf *canvas_docopy(t_canvas *x) -{ - t_gobj *y; - t_linetraverser t; - t_outconnect *oc; - t_binbuf *b = binbuf_new(); - for (y = x->gl_list; y; y = y->g_next) - { - if (glist_isselected(x, y)) - gobj_save(y, b); - } - linetraverser_start(&t, x); - while (oc = linetraverser_next(&t)) - { - if (glist_isselected(x, &t.tr_ob->ob_g) - && glist_isselected(x, &t.tr_ob2->ob_g)) - { - binbuf_addv(b, "ssiiii;", gensym("#X"), gensym("connect"), - glist_selectionindex(x, &t.tr_ob->ob_g, 1), t.tr_outno, - glist_selectionindex(x, &t.tr_ob2->ob_g, 1), t.tr_inno); - } - } - return (b); -} - -static void canvas_copy(t_canvas *x) -{ - if (!x->gl_editor || !x->gl_editor->e_selection) - return; - binbuf_free(copy_binbuf); - copy_binbuf = canvas_docopy(x); -} - -static void canvas_clearline(t_canvas *x) -{ - if (x->gl_editor->e_selectedline) - { - canvas_disconnect(x, x->gl_editor->e_selectline_index1, - x->gl_editor->e_selectline_outno, - x->gl_editor->e_selectline_index2, - x->gl_editor->e_selectline_inno); - canvas_setundo(x, canvas_undo_disconnect, - canvas_undo_set_disconnect(x, - x->gl_editor->e_selectline_index1, - x->gl_editor->e_selectline_outno, - x->gl_editor->e_selectline_index2, - x->gl_editor->e_selectline_inno), - "disconnect"); - } -} - -extern t_pd *newest; -static void canvas_doclear(t_canvas *x) -{ - t_gobj *y, *y2; - int dspstate; - - dspstate = canvas_suspend_dsp(); - if (x->gl_editor->e_selectedline) - { - canvas_disconnect(x, x->gl_editor->e_selectline_index1, - x->gl_editor->e_selectline_outno, - x->gl_editor->e_selectline_index2, - x->gl_editor->e_selectline_inno); - canvas_setundo(x, canvas_undo_disconnect, - canvas_undo_set_disconnect(x, - x->gl_editor->e_selectline_index1, - x->gl_editor->e_selectline_outno, - x->gl_editor->e_selectline_index2, - x->gl_editor->e_selectline_inno), - "disconnect"); - } - /* if text is selected, deselecting it might remake the - object. So we deselect it and hunt for a "new" object on - the glist to reselect. */ - if (x->gl_editor->e_textedfor) - { - newest = 0; - glist_noselect(x); - if (newest) - { - for (y = x->gl_list; y; y = y->g_next) - if (&y->g_pd == newest) glist_select(x, y); - } - } - while (1) /* this is pretty wierd... should rewrite it */ - { - for (y = x->gl_list; y; y = y2) - { - y2 = y->g_next; - if (glist_isselected(x, y)) - { - glist_delete(x, y); -#if 0 - if (y2) post("cut 5 %x %x", y2, y2->g_next); - else post("cut 6"); -#endif - goto next; - } - } - goto restore; - next: ; - } -restore: - canvas_resume_dsp(dspstate); - canvas_dirty(x, 1); -} - -static void canvas_cut(t_canvas *x) -{ - if (x->gl_editor && x->gl_editor->e_selectedline) - canvas_clearline(x); - else if (x->gl_editor && x->gl_editor->e_selection) - { - canvas_setundo(x, canvas_undo_cut, - canvas_undo_set_cut(x, UCUT_CUT), "cut"); - canvas_copy(x); - canvas_doclear(x); - } -} - -static int paste_onset; -static t_canvas *paste_canvas; - -static void glist_donewloadbangs(t_glist *x) -{ - if (x->gl_editor) - { - t_selection *sel; - for (sel = x->gl_editor->e_selection; sel; sel = sel->sel_next) - if (pd_class(&sel->sel_what->g_pd) == canvas_class) - canvas_loadbang((t_canvas *)(&sel->sel_what->g_pd)); - } -} - -static void canvas_dopaste(t_canvas *x, t_binbuf *b) -{ - t_gobj *newgobj, *last, *g2; - int dspstate = canvas_suspend_dsp(), nbox, count; - - canvas_editmode(x, 1.); - glist_noselect(x); - for (g2 = x->gl_list, nbox = 0; g2; g2 = g2->g_next) nbox++; - - paste_onset = nbox; - paste_canvas = x; - - pd_bind(&x->gl_pd, gensym("#X")); - binbuf_eval(b, 0, 0, 0); - pd_unbind(&x->gl_pd, gensym("#X")); - for (g2 = x->gl_list, count = 0; g2; g2 = g2->g_next, count++) - if (count >= nbox) - glist_select(x, g2); - paste_canvas = 0; - canvas_resume_dsp(dspstate); - canvas_dirty(x, 1); - glist_donewloadbangs(x); -} - -static void canvas_paste(t_canvas *x) -{ - canvas_setundo(x, canvas_undo_paste, canvas_undo_set_paste(x), "paste"); - canvas_dopaste(x, copy_binbuf); -} - -static void canvas_duplicate(t_canvas *x) -{ - if (x->gl_editor->e_onmotion == MA_NONE) - { - t_selection *y; - canvas_copy(x); - canvas_setundo(x, canvas_undo_paste, canvas_undo_set_paste(x), - "duplicate"); - canvas_dopaste(x, copy_binbuf); - for (y = x->gl_editor->e_selection; y; y = y->sel_next) - gobj_displace(y->sel_what, x, - 10, 10); - canvas_dirty(x, 1); - } -} - -static void canvas_selectall(t_canvas *x) -{ - t_gobj *y; - if (!x->gl_edit) - canvas_editmode(x, 1); - for (y = x->gl_list; y; y = y->g_next) - { - if (!glist_isselected(x, y)) - glist_select(x, y); - } -} - -void canvas_connect(t_canvas *x, t_floatarg fwhoout, t_floatarg foutno, - t_floatarg fwhoin, t_floatarg finno) -{ - int whoout = fwhoout, outno = foutno, whoin = fwhoin, inno = finno; - t_gobj *src = 0, *sink = 0; - t_object *objsrc, *objsink; - t_outconnect *oc; - int nin = whoin, nout = whoout; - if (paste_canvas == x) whoout += paste_onset, whoin += paste_onset; - for (src = x->gl_list; whoout; src = src->g_next, whoout--) - if (!src->g_next) goto bad; /* bug fix thanks to Hannes */ - for (sink = x->gl_list; whoin; sink = sink->g_next, whoin--) - if (!sink->g_next) goto bad; - if (!(objsrc = pd_checkobject(&src->g_pd)) || - !(objsink = pd_checkobject(&sink->g_pd))) - goto bad; - if (!(oc = obj_connect(objsrc, outno, objsink, inno))) goto bad; - if (glist_isvisible(x)) - { - sys_vgui(".x%x.c create line %d %d %d %d -width %d -tags l%x\n", - glist_getcanvas(x), 0, 0, 0, 0, - (obj_issignaloutlet(objsrc, outno) ? 2 : 1),oc); - canvas_fixlinesfor(x, objsrc); - } - return; - -bad: - post("%s %d %d %d %d (%s->%s) connection failed", - x->gl_name->s_name, nout, outno, nin, inno, - (src? class_getname(pd_class(&src->g_pd)) : "???"), - (sink? class_getname(pd_class(&sink->g_pd)) : "???")); -} - -#define XTOLERANCE 4 -#define YTOLERANCE 3 -#define NHIST 15 - - /* LATER might have to speed this up */ -static void canvas_tidy(t_canvas *x) -{ - t_gobj *y, *y2, *y3; - int ax1, ay1, ax2, ay2, bx1, by1, bx2, by2; - int histogram[NHIST], *ip, i, besthist, bestdist; - /* if nobody is selected, this means do it to all boxes; - othewise just the selection */ - int all = (x->gl_editor ? (x->gl_editor->e_selection == 0) : 1); - - canvas_setundo(x, canvas_undo_move, canvas_undo_set_move(x, !all), - "motion"); - - /* tidy horizontally */ - for (y = x->gl_list; y; y = y->g_next) - if (all || glist_isselected(x, y)) - { - gobj_getrect(y, x, &ax1, &ay1, &ax2, &ay2); - - for (y2 = x->gl_list; y2; y2 = y2->g_next) - if (all || glist_isselected(x, y2)) - { - gobj_getrect(y2, x, &bx1, &by1, &bx2, &by2); - if (by1 <= ay1 + YTOLERANCE && by1 >= ay1 - YTOLERANCE && - bx1 < ax1) - goto nothorizhead; - } - - for (y2 = x->gl_list; y2; y2 = y2->g_next) - if (all || glist_isselected(x, y2)) - { - gobj_getrect(y2, x, &bx1, &by1, &bx2, &by2); - if (by1 <= ay1 + YTOLERANCE && by1 >= ay1 - YTOLERANCE - && by1 != ay1) - gobj_displace(y2, x, 0, ay1-by1); - } - nothorizhead: ; - } - /* tidy vertically. First guess the user's favorite vertical spacing */ - for (i = NHIST, ip = histogram; i--; ip++) *ip = 0; - for (y = x->gl_list; y; y = y->g_next) - if (all || glist_isselected(x, y)) - { - gobj_getrect(y, x, &ax1, &ay1, &ax2, &ay2); - for (y2 = x->gl_list; y2; y2 = y2->g_next) - if (all || glist_isselected(x, y2)) - { - gobj_getrect(y2, x, &bx1, &by1, &bx2, &by2); - if (bx1 <= ax1 + XTOLERANCE && bx1 >= ax1 - XTOLERANCE) - { - int distance = by1-ay2; - if (distance >= 0 && distance < NHIST) - histogram[distance]++; - } - } - } - for (i = 1, besthist = 0, bestdist = 4, ip = histogram + 1; - i < (NHIST-1); i++, ip++) - { - int hit = ip[-1] + 2 * ip[0] + ip[1]; - if (hit > besthist) - { - besthist = hit; - bestdist = i; - } - } - post("best vertical distance %d", bestdist); - for (y = x->gl_list; y; y = y->g_next) - if (all || glist_isselected(x, y)) - { - int keep = 1; - gobj_getrect(y, x, &ax1, &ay1, &ax2, &ay2); - for (y2 = x->gl_list; y2; y2 = y2->g_next) - if (all || glist_isselected(x, y2)) - { - gobj_getrect(y2, x, &bx1, &by1, &bx2, &by2); - if (bx1 <= ax1 + XTOLERANCE && bx1 >= ax1 - XTOLERANCE && - ay1 >= by2 - 10 && ay1 < by2 + NHIST) - goto nothead; - } - while (keep) - { - keep = 0; - for (y2 = x->gl_list; y2; y2 = y2->g_next) - if (all || glist_isselected(x, y2)) - { - gobj_getrect(y2, x, &bx1, &by1, &bx2, &by2); - if (bx1 <= ax1 + XTOLERANCE && bx1 >= ax1 - XTOLERANCE && - by1 > ay1 && by1 < ay2 + NHIST) - { - int vmove = ay2 + bestdist - by1; - gobj_displace(y2, x, ax1-bx1, vmove); - ay1 = by1 + vmove; - ay2 = by2 + vmove; - keep = 1; - break; - } - } - } - nothead: ; - } - canvas_dirty(x, 1); -} - -static void canvas_texteditor(t_canvas *x) -{ - t_rtext *foo; - char *buf; - int bufsize; - if (foo = x->gl_editor->e_textedfor) - rtext_gettext(foo, &buf, &bufsize); - else buf = "", bufsize = 0; - sys_vgui("pdtk_pd_texteditor {%.*s}\n", bufsize, buf); - -} - -void glob_key(void *dummy, t_symbol *s, int ac, t_atom *av) -{ - /* canvas_editing can be zero; canvas_key checks for that */ - canvas_key(canvas_editing, s, ac, av); -} - -void canvas_editmode(t_canvas *x, t_floatarg fyesplease) -{ - int yesplease = fyesplease; - if (yesplease && x->gl_edit) - return; - x->gl_edit = !x->gl_edit; - if (x->gl_edit && glist_isvisible(x) && glist_istoplevel(x)) - canvas_setcursor(x, CURSOR_EDITMODE_NOTHING); - else - { - glist_noselect(x); - if (glist_isvisible(x) && glist_istoplevel(x)) - canvas_setcursor(x, CURSOR_RUNMODE_NOTHING); - } - sys_vgui("pdtk_canvas_editval .x%x %d\n", - glist_getcanvas(x), x->gl_edit); -} - - /* called by canvas_font below */ -static void canvas_dofont(t_canvas *x, t_floatarg font, t_floatarg xresize, - t_floatarg yresize) -{ - t_gobj *y; - x->gl_font = font; - if (xresize != 1 || yresize != 1) - { - canvas_setundo(x, canvas_undo_move, canvas_undo_set_move(x, 0), - "motion"); - for (y = x->gl_list; y; y = y->g_next) - { - int x1, x2, y1, y2, nx1, ny1; - gobj_getrect(y, x, &x1, &y1, &x2, &y2); - nx1 = x1 * xresize + 0.5; - ny1 = y1 * yresize + 0.5; - gobj_displace(y, x, nx1-x1, ny1-y1); - } - } - if (glist_isvisible(x)) - glist_redraw(x); - for (y = x->gl_list; y; y = y->g_next) - if (pd_class(&y->g_pd) == canvas_class - && !canvas_isabstraction((t_canvas *)y)) - canvas_dofont((t_canvas *)y, font, xresize, yresize); -} - - /* canvas_menufont calls up a TK dialog which calls this back */ -static void canvas_font(t_canvas *x, t_floatarg font, t_floatarg resize, - t_floatarg whichresize) -{ - float realresize, realresx = 1, realresy = 1; - t_canvas *x2 = canvas_getrootfor(x); - if (!resize) realresize = 1; - else - { - if (resize < 20) resize = 20; - if (resize > 500) resize = 500; - realresize = resize * 0.01; - } - if (whichresize != 3) realresx = realresize; - if (whichresize != 2) realresy = realresize; - canvas_dofont(x2, font, realresx, realresy); - sys_defaultfont = font; -} - -static t_glist *canvas_last_glist; -static int canvas_last_glist_x, canvas_last_glist_y; - -void glist_getnextxy(t_glist *gl, int *xpix, int *ypix) -{ - if (canvas_last_glist == gl) - *xpix = canvas_last_glist_x, *ypix = canvas_last_glist_y; - else *xpix = *ypix = 40; -} - -static void glist_setlastxy(t_glist *gl, int xval, int yval) -{ - canvas_last_glist = gl; - canvas_last_glist_x = xval; - canvas_last_glist_y = yval; -} - - -void g_editor_setup(void) -{ -/* ------------------------ events ---------------------------------- */ - class_addmethod(canvas_class, (t_method)canvas_mousedown, gensym("mouse"), - A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); - class_addmethod(canvas_class, (t_method)canvas_mouseup, gensym("mouseup"), - A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); - class_addmethod(canvas_class, (t_method)canvas_key, gensym("key"), - A_GIMME, A_NULL); - class_addmethod(canvas_class, (t_method)canvas_motion, gensym("motion"), - A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); - -/* ------------------------ menu actions ---------------------------- */ - class_addmethod(canvas_class, (t_method)canvas_menuclose, - gensym("menuclose"), A_DEFFLOAT, 0); - class_addmethod(canvas_class, (t_method)canvas_cut, - gensym("cut"), A_NULL); - class_addmethod(canvas_class, (t_method)canvas_copy, - gensym("copy"), A_NULL); - class_addmethod(canvas_class, (t_method)canvas_paste, - gensym("paste"), A_NULL); - class_addmethod(canvas_class, (t_method)canvas_duplicate, - gensym("duplicate"), A_NULL); - class_addmethod(canvas_class, (t_method)canvas_selectall, - gensym("selectall"), A_NULL); - class_addmethod(canvas_class, (t_method)canvas_undo, - gensym("undo"), A_NULL); - class_addmethod(canvas_class, (t_method)canvas_redo, - gensym("redo"), A_NULL); - class_addmethod(canvas_class, (t_method)canvas_tidy, - gensym("tidy"), A_NULL); - class_addmethod(canvas_class, (t_method)canvas_texteditor, - gensym("texteditor"), A_NULL); - class_addmethod(canvas_class, (t_method)canvas_editmode, - gensym("editmode"), A_DEFFLOAT, A_NULL); - class_addmethod(canvas_class, (t_method)canvas_print, - gensym("print"), A_SYMBOL, A_NULL); - class_addmethod(canvas_class, (t_method)canvas_menufont, - gensym("menufont"), A_NULL); - class_addmethod(canvas_class, (t_method)canvas_font, - gensym("font"), A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); - class_addmethod(canvas_class, (t_method)canvas_find, - gensym("find"), A_GIMME, A_NULL); - class_addmethod(canvas_class, (t_method)canvas_find_again, - gensym("findagain"), A_NULL); - class_addmethod(canvas_class, (t_method)canvas_find_parent, - gensym("findparent"), A_NULL); - class_addmethod(canvas_class, (t_method)canvas_done_popup, - gensym("done-popup"), A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); - class_addmethod(canvas_class, (t_method)canvas_donecanvasdialog, - gensym("donecanvasdialog"), A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); - class_addmethod(canvas_class, (t_method)glist_arraydialog, - gensym("arraydialog"), A_SYMBOL, A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); - -/* -------------- connect method used in reading files ------------------ */ - class_addmethod(canvas_class, (t_method)canvas_connect, - gensym("connect"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); - - class_addmethod(canvas_class, (t_method)canvas_disconnect, - gensym("disconnect"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); -/* -------------- copy buffer ------------------ */ - copy_binbuf = binbuf_new(); -} |