Commit 908c52ab authored by Jonathan Wilkes's avatar Jonathan Wilkes
Browse files

Merge branch 'drawimage-x-y-fix'

parents ff8afc1c dff2f629
......@@ -3760,6 +3760,7 @@ function gui_drawimage_vis(cid, x, y, obj, data, seqno, parent_tag) {
len = image_array.length,
i,
image_container,
xy_container,
obj_tag = "draw" + obj.slice(1) + "." + data.slice(1);
if (len < 1) {
return;
......@@ -3768,6 +3769,19 @@ function gui_drawimage_vis(cid, x, y, obj, data, seqno, parent_tag) {
if (seqno >= len || seqno < 0) {
seqno %= len;
}
// Since sprites can have lots of images we don't want to
// set props on each one of them every time the user changes
// an attribute's value. So we use a "g" to receive all the
// relevant changes.
// Unfortunately "g" doesn't have x/y attys. So it can't propagate
// those values down to the child images. Thus we have to add
// another "g" as a parent and manually convert x/y changes
// the user makes to a transform. (And we can't use the inner g's
// transform because the user can set their own transform there.)
xy_container = create_item(cid, "g", {
id: obj_tag + "xy",
transform: "translate(" + x + "," + y + ")"
});
image_container = create_item(cid, "g", {
id: obj_tag
});
......@@ -3784,7 +3798,8 @@ function gui_drawimage_vis(cid, x, y, obj, data, seqno, parent_tag) {
image_array[i].data);
image_container.appendChild(item);
}
frag.appendChild(image_container);
xy_container.appendChild(image_container);
frag.appendChild(xy_container);
// Hack to set correct width and height
for (i = 0; i < len; i++) {
img_size_setter(cid, obj_tag+i, pd_cache.get(obj)[i].type,
......@@ -3794,6 +3809,14 @@ function gui_drawimage_vis(cid, x, y, obj, data, seqno, parent_tag) {
});
}
// Hack
function gui_drawimage_xy(cid, obj, data, x, y) {
var obj_tag = "draw" + obj.slice(1) + "." + data.slice(1);
gui(cid).get_elem(obj_tag + "xy", {
transform: "translate(" + x + "," + y + ")"
});
}
function gui_drawimage_index(cid, obj, data, index) {
var obj_tag = "draw" + obj.slice(1) + "." + data.slice(1);
gui(cid).get_elem(obj_tag, function(image_container) {
......
......@@ -1210,7 +1210,7 @@ typedef struct _draw
typedef struct _drawimage
{
t_object x_obj;
t_fielddesc x_value; /* todo: rename to index */
t_fielddesc x_index;
t_fielddesc x_vis;
t_symbol *x_img;
t_float x_w;
......@@ -1964,6 +1964,18 @@ void svg_sendupdate(t_svg *x, t_canvas *c, t_symbol *s,
gui_vmess("gui_drawimage_index", "xxxi",
glist_getcanvas(c), parent, data, drawimage_getindex(parent, template, data));
}
else if (s == gensym("image_xy"))
{
/* Hack to deal with x/y for sprite/image. They have an extra
container so that we don't have to deal with changing each
image in the sequence here. */
gui_vmess("gui_drawimage_xy", "xxxff",
glist_getcanvas(c), parent, data,
x->x_x.a_flag ?
fielddesc_getcoord(&x->x_x.a_attr, template, data, 0) : 0,
x->x_y.a_flag ?
fielddesc_getcoord(&x->x_y.a_attr, template, data, 0) : 0);
}
else if (s == gensym("viewbox"))
{
gui_start_vmess("gui_draw_viewbox", "xss",
......@@ -3991,10 +4003,10 @@ static void svg_togui(t_svg *x, t_template *template, t_word *data)
gui_f(fielddesc_getcoord(&x->x_rx.a_attr, template, data, 0));
}
if (x->x_ry.a_flag)
{
{
gui_s(x->x_type == gensym("ellipse") ? "ry" : "y2");
gui_f(fielddesc_getcoord(&x->x_ry.a_attr, template, data, 0));
}
}
if (x->x_x.a_flag)
{
gui_s(x->x_type == gensym("rect") || x->x_type == gensym("svg") ? "x" :
......@@ -8013,6 +8025,7 @@ static void *drawimage_new(t_symbol *classsym, int argc, t_atom *argv)
x->x_flags = flags;
x->x_attr = (t_pd *)sa;
fielddesc_setfloat_const(&x->x_vis, 1);
fielddesc_setfloat_const(&x->x_index, 1);
x->x_canvas = canvas_getcurrent();
t_symbol *dir = canvas_getdir(x->x_canvas);
if (argc && argv->a_type == A_SYMBOL)
......@@ -8026,11 +8039,12 @@ static void *drawimage_new(t_symbol *classsym, int argc, t_atom *argv)
/* outlet for event notifications */
outlet_new(&x->x_obj, &s_anything);
/* [drawimage] allocates memory for an image or image sequence
while the object is creating. The corresponding scalar gets
drawn as a canvas image item using the "parent" tk image as
the source. ".x%lx" is the name for the parent tk image and
".x%lx.i" is the tag given to a scalar's canvas image item.
/* [drawimage] allocates memory for an image or image sequence in
the GUI. When we "vis" the scalar we fetch the data from the
loaded images in the sequence. Then we can change the image shown
by just sending an index to the GUI where it displays that particular
image in the sequence without having to touch I/O or even parse
image data and render a new image.
*/
gui_vmess("gui_drawimage_new", "xssi",
x,
......@@ -8044,13 +8058,12 @@ void drawimage_size(t_drawimage *x, t_float w, t_float h)
{
x->x_w = w;
x->x_h = h;
//post("w is %g and h is %g", w, h);
}
static int drawimage_getindex(void *z, t_template *template, t_word *data)
{
t_drawimage *x = (t_drawimage *)z;
int index = (int)fielddesc_getcoord(&x->x_value, template, data, 1);
int index = (int)fielddesc_getcoord(&x->x_index, template, data, 1);
return (index);
}
......@@ -8063,7 +8076,7 @@ static void drawimage_index(t_drawimage *x, t_symbol *s, int argc,
if (!(x->x_flags & DRAW_SPRITE))
post("drawimage warning: sequence variable is only "
"used with drawsprite");
fielddesc_setfloatarg(&x->x_value, argc, argv);
fielddesc_setfloatarg(&x->x_index, argc, argv);
svg_update((t_svg *)x->x_attr, gensym("index"));
}
}
......@@ -8089,19 +8102,30 @@ void drawimage_symbol(t_drawimage *x, t_symbol *s)
attributes to the parent <g> for convenience, but <g> has no x/y atty.
We could just forward everything to the child <image> element, but that
could get clunky when dealing with large image sequences. So for now we
just disallow setting the x/y with the knowledge that the user can get
the same functionality using a transform. */
static void drawimage_x(t_drawimage *x, t_symbol *s, int argc,
t_atom *argv)
{
pd_error(x, "draw: x attribute for image type not supported");
}
could get clunky when dealing with large image sequences.
static void drawimage_y(t_drawimage *x, t_symbol *s, int argc,
So for now we hack around this by adding a <g> above our parent <g>, then
converting the x/y in the GUI to a transform for that <g>. This is ugly
and gets in the way of the interface built here, but it should work.
*/
static void drawimage_xy(t_drawimage *x, t_symbol *s, int argc,
t_atom *argv)
{
pd_error(x, "draw: y attribute for image type not supported");
t_svg *sa = (t_svg *)x->x_attr;
t_svg_attr *attr = svg_getattr(sa, s);
if (!attr)
{
pd_error(x, "draw: can't find attribute %s", s->s_name);
return;
}
if (argc < 1)
attr->a_flag = 0;
else if (argv[0].a_type == A_FLOAT || argv[0].a_type == A_SYMBOL)
{
fielddesc_setfloatarg(&attr->a_attr, argc, argv);
attr->a_flag = 1;
svg_update(sa, gensym("image_xy"));
}
}
static void drawimage_anything(t_drawimage *x, t_symbol *s, int argc,
......@@ -8262,7 +8286,7 @@ static void drawimage_vis(t_gobj *z, t_glist *glist, t_glist *parentglist,
yloc,
x,
data,
(int)fielddesc_getfloat(&x->x_value, template, data, 0),
(int)fielddesc_getfloat(&x->x_index, template, data, 0),
parent_tagbuf);
gui_start_vmess("gui_draw_configure_all", "xs",
......@@ -8296,7 +8320,7 @@ static void drawimage_motion(void *z, t_floatarg dx, t_floatarg dy)
{
t_drawimage *x = (t_drawimage *)z;
t_svg *sa = (t_svg *)x->x_attr;
t_fielddesc *f = &x->x_value;
t_fielddesc *f = &x->x_index;
t_atom at;
if (!gpointer_check(&drawimage_motion_gpointer, 0))
{
......@@ -8408,7 +8432,7 @@ static int drawimage_click(t_gobj *z, t_glist *glist,
data, template, basex, basey,
&x1, &y1, &x2, &y2);
if (xpix >= x1 && xpix <= x2 && ypix >= y1 && ypix <= y2
&& x->x_value.fd_var &&
&& x->x_index.fd_var &&
fielddesc_getfloat(&x->x_vis, template, data, 0))
{
if (doit)
......@@ -8420,7 +8444,7 @@ static int drawimage_click(t_gobj *z, t_glist *glist,
drawimage_motion_array = ap;
drawimage_motion_firstkey = 1;
drawimage_motion_ycumulative =
fielddesc_getfloat(&x->x_value, template, data, 0);
fielddesc_getfloat(&x->x_index, template, data, 0);
drawimage_motion_sprite = ((x->x_flags & DRAW_SPRITE) != 0);
if (drawimage_motion_scalar)
gpointer_setglist(&drawimage_motion_gpointer,
......@@ -8457,15 +8481,12 @@ static void drawimage_free(t_drawimage *x)
static void drawimage_setup(void)
{
/* we need drawimage_class in order to get
a different set of widget behavior than
draw_class. But we also want to use the
[draw shape] syntax for consistency. So
for class_new we set the constructor to
zero and call drawimage_new from inside
draw_new. This way the user has to type
"draw image" or "draw sprite" to create
the objects. */
/* we need drawimage_class in order to get a different set of
widget behavior than draw_class. But we also want to use the
[draw shape] syntax for consistency. So for class_new we set
the constructor to zero and call drawimage_new from inside
draw_new. This way the user has to type "draw image" or "draw sprite"
to create the objects. */
drawimage_class = class_new(gensym("drawimage"),
0, (t_method)drawimage_free,
sizeof(t_drawimage), 0, A_GIMME, 0);
......@@ -8476,9 +8497,9 @@ static void drawimage_setup(void)
gensym("size"), A_FLOAT, A_FLOAT, 0);
class_addmethod(drawimage_class, (t_method)drawimage_index,
gensym("index"), A_GIMME, 0);
class_addmethod(drawimage_class, (t_method)drawimage_x,
class_addmethod(drawimage_class, (t_method)drawimage_xy,
gensym("x"), A_GIMME, 0);
class_addmethod(drawimage_class, (t_method)drawimage_y,
class_addmethod(drawimage_class, (t_method)drawimage_xy,
gensym("y"), A_GIMME, 0);
class_addanything(drawimage_class, drawimage_anything);
class_setparentwidget(drawimage_class, &drawimage_widgetbehavior);
......@@ -8589,6 +8610,12 @@ void svg_parentwidgettogui(t_gobj *z, t_scalar *sc, t_glist *owner,
gui_vmess("gui_drawimage_index", "xxxi",
glist_getcanvas(owner), x, data,
drawimage_getindex(x, template, data));
gui_vmess("gui_drawimage_xy", "xxxff",
glist_getcanvas(owner), x, data,
fielddesc_getcoord(&((t_svg *)x->x_attr)->x_x.a_attr,
template, data, 0),
fielddesc_getcoord(&((t_svg *)x->x_attr)->x_y.a_attr,
template, data, 0));
}
else if (pd_class(&z->g_pd) == curve_class)
{
......
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