Commit a827d25f authored by Ivica Ico Bukvic's avatar Ivica Ico Bukvic Committed by Hans-Christoph Steiner
Browse files

Added undo/redo for creating objects

parent 26948fa9
......@@ -431,6 +431,8 @@ static const char *canvas_undo_name;
void canvas_setundo(t_canvas *x, t_undofn undofn, void *buf,
const char *name)
{
//fprintf(stderr,"canvas_setundo %lx\n", (t_int)x);
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. */
......@@ -1318,6 +1320,86 @@ void canvas_canvas_setundo(t_canvas *x)
canvas_setundo(x, canvas_undo_canvas_apply, canvas_undo_set_canvas(x), "apply");
}
/* --------- 8. create ----------- */
typedef struct _undo_create
{
int u_index; /* index of the created object object */
t_binbuf *u_objectbuf; /* the object cleared or typed into */
t_binbuf *u_reconnectbuf; /* connections into and out of object */
} t_undo_create;
void *canvas_undo_set_create(t_canvas *x)
{
t_gobj *y, *last;
t_linetraverser t;
t_outconnect *oc;
t_undo_create *buf = (t_undo_create *)getbytes(sizeof(*buf));
buf->u_index = glist_getindex(x, 0) - 1;
int nnotsel= glist_selectionindex(x, 0, 0);
buf->u_objectbuf = binbuf_new();
for (y = x->gl_list; y; y = y->g_next)
{
if (glist_isselected(x, y)) {
//fprintf(stderr,"saving object\n");
gobj_save(y, buf->u_objectbuf);
}
}
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);
}
}
return (buf);
}
void canvas_undo_create(t_canvas *x, void *z, int action)
{
t_undo_create *buf = z;
t_gobj *y;
//fprintf(stderr,"canvas = %lx buf->u_index = %d\n", (t_int)x, buf->u_index);
if (action == UNDO_UNDO)
{
glist_noselect(x);
y = glist_nth(x, buf->u_index);
glist_select(x, y);
canvas_doclear(x);
}
else if (action == UNDO_REDO)
{
pd_bind(&x->gl_pd, gensym("#X"));
binbuf_eval(buf->u_objectbuf, 0, 0, 0);
pd_unbind(&x->gl_pd, gensym("#X"));
pd_bind(&x->gl_pd, gensym("#X"));
binbuf_eval(buf->u_reconnectbuf, 0, 0, 0);
pd_unbind(&x->gl_pd, gensym("#X"));
y = glist_nth(x, buf->u_index);
glist_select(x, y);
}
else if (action == UNDO_FREE) {
binbuf_free(buf->u_objectbuf);
binbuf_free(buf->u_reconnectbuf);
t_freebytes(buf, sizeof(*buf));
}
}
/* ------------------------ event handling ------------------------ */
static char *cursorlist[] = {
......@@ -3229,49 +3311,31 @@ void canvas_restoreconnections(t_canvas *x)
static t_binbuf *canvas_docopy(t_canvas *x)
{
//fprintf(stderr,"docopy\n");
//fprintf(stderr,"canvas_docopy\n");
t_gobj *y, *last;
t_linetraverser t;
t_outconnect *oc;
t_binbuf *b = binbuf_new();
//int c = 0;
for (y = x->gl_list; y; y = y->g_next)
{
if (glist_isselected(x, y)) {
//c++;
//fprintf(stderr, "saving object num %d\n", c);
//fprintf(stderr, "saving object >.x%lx<\n", (t_int)y);
/* introduce redundant comment to avoid recreation of old abstractions
with the same canvas id which results in all commands being registered
multiple times--apparently after much searching it appears that this
is yet another bug in tcl/tk which means that canvas tries to do some
kind of caching behind the curtains resulting in objects not always
having unique ids, contrary to tcl/tk's canvas man page */
/*if (c==1) {
binbuf_addv(b, "ssiis;", gensym("#X"), gensym("text"),
(int)((t_text *)y)->te_xpix-30, (int)((t_text *)y)->te_ypix-30, gensym("tcltksucks"));
}*/
//fprintf(stderr,"saving object\n");
gobj_save(y, b);
}
}
//fprintf(stderr,"done saving objects\n");
linetraverser_start(&t, x);
//c = 0;
while (oc = linetraverser_next(&t))
{
//fprintf(stderr,"found some lines %d %d\n", glist_isselected(x, &t.tr_ob->ob_g), glist_isselected(x, &t.tr_ob2->ob_g));
if (glist_isselected(x, &t.tr_ob->ob_g)
&& glist_isselected(x, &t.tr_ob2->ob_g))
{
//fprintf(stderr, "lines need to be copied\n");
//c = 1;
//fprintf(stderr,"saving lines leading into selected object\n");
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);
// glist_selectionindex(x, &t.tr_ob->ob_g, 1)+1, t.tr_outno,
// glist_selectionindex(x, &t.tr_ob2->ob_g, 1)+1, t.tr_inno);
}
}
//if (!c) fprintf(stderr, "no lines copied\n");
return (b);
}
......@@ -3290,7 +3354,7 @@ static void canvas_copyfromexternalbuffer(t_canvas *x, t_symbol *s, int ac, t_at
binbuf_add(copy_binbuf, ac, av);
binbuf_addsemi(copy_binbuf);
} else {
//probably should resize window size here...
//probably should resize window size and position here...
//fprintf(stderr,"ignoring canvas\n");
}
}
......
......@@ -29,17 +29,27 @@ void canvas_drawredrect(t_canvas *x, int doit);
void glist_add(t_glist *x, t_gobj *y)
{
t_object *ob;
//fprintf(stderr,"glist_add %lx %d\n", (t_int)x, (x->gl_editor ? 1 : 0));
t_object *ob;
y->g_next = 0;
int index = 0;
if (!x->gl_list) x->gl_list = y;
else
{
t_gobj *y2;
for (y2 = x->gl_list; y2->g_next; y2 = y2->g_next);
for (y2 = x->gl_list; y2->g_next; y2 = y2->g_next)
index++;
y2->g_next = y;
}
if (x->gl_editor && (ob = pd_checkobject(&y->g_pd)))
if (x->gl_editor && (ob = pd_checkobject(&y->g_pd))) {
rtext_new(x, ob);
//let's now set up create undo
//glist_select(x, y);
//canvas_setundo(x, canvas_undo_create, canvas_undo_set_create(x, index),
// "create");
//glist_noselect(x);
}
if (x->gl_editor && x->gl_isgraph && !x->gl_goprect
&& pd_checkobject(&y->g_pd))
{
......
......@@ -30,7 +30,10 @@ t_widgetbehavior text_widgetbehavior;
static char *invalid_fill = "\"#ffdddd\"";
EXTERN void canvas_apply_setundo(t_canvas *x, t_gobj *y);
extern void canvas_apply_setundo(t_canvas *x, t_gobj *y);
extern void canvas_setundo(t_canvas *x, t_undofn undofn, void *buf, const char *name);
extern void *canvas_undo_set_create(t_canvas *x);
extern void canvas_undo_create(t_canvas *x, void *z, int action);
/* ----------------- the "text" object. ------------------ */
......@@ -89,7 +92,7 @@ void canvas_getargs(int *argcp, t_atom **argvp);
static void canvas_objtext(t_glist *gl, int xpix, int ypix, int selected,
t_binbuf *b)
{
//fprintf(stderr,"objtext\n");
//fprintf(stderr,"canvas_objtext\n");
t_text *x;
int argc;
t_atom *argv;
......@@ -202,6 +205,7 @@ void canvas_howputnew(t_canvas *x, int *connectp, int *xpixp, int *ypixp,
void canvas_obj(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
//fprintf(stderr,"canvas_obj\n");
t_text *x;
if (argc >= 2)
{
......@@ -224,6 +228,7 @@ void canvas_obj(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
if (connectme)
canvas_connect(gl, indx, 0, nobj, 0);
else canvas_startmotion(glist_getcanvas(gl));
canvas_setundo(gl, canvas_undo_create, canvas_undo_set_create(gl), "create");
}
}
......@@ -265,6 +270,7 @@ void canvas_iemguis(t_glist *gl, t_symbol *guiobjname)
//glist_getnextxy(gl, &xpix, &ypix);
//canvas_objtext(gl, xpix, ypix, 1, b);
else canvas_startmotion(glist_getcanvas(gl));
canvas_setundo(gl, canvas_undo_create, canvas_undo_set_create(gl), "create");
}
void canvas_bng(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
......@@ -535,6 +541,7 @@ void canvas_msg(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
if (connectme)
canvas_connect(gl, indx, 0, nobj, 0);
else canvas_startmotion(glist_getcanvas(gl));
canvas_setundo(gl, canvas_undo_create, canvas_undo_set_create(gl), "create");
}
}
......@@ -921,6 +928,7 @@ static void gatom_vis(t_gobj *z, t_glist *glist, int vis)
void canvas_atom(t_glist *gl, t_atomtype type,
t_symbol *s, int argc, t_atom *argv)
{
//fprintf(stderr,"canvas_atom\n");
t_gatom *x = (t_gatom *)pd_new(gatom_class);
t_atom at;
x->a_text.te_width = 0; /* don't know it yet. */
......@@ -993,6 +1001,7 @@ void canvas_atom(t_glist *gl, t_atomtype type,
if (connectme)
canvas_connect(gl, indx, 0, nobj, 0);
else canvas_startmotion(glist_getcanvas(gl));
canvas_setundo(gl, canvas_undo_create, canvas_undo_set_create(gl), "create");
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment