Commit 642a4fde authored by Jonathan Wilkes's avatar Jonathan Wilkes
Browse files

add constrain for cnv, graph, standardize all iemguis and dodge outlets

parent 39fd0093
......@@ -233,25 +233,50 @@ var canvas_events = (function() {
return false;
},
mousedown: function(evt) {
var target_id;
var target_id, resize_type;
if (target_is_scrollbar(evt)) {
return;
} else if (evt.target.classList.contains("clickable_resize_handle")) {
} else if (evt.target.parentNode &&
evt.target.parentNode.classList
.contains("clickable_resize_handle")) {
draggable_label =
evt.target.classList.contains("move_handle");
evt.target.parentNode.classList.contains("move_handle");
// get id ("x123456etcgobj" without the "x" or "gobj")
target_id = (draggable_label ? "_l" : "_s") +
evt.target.parentNode.id.slice(0,-4).slice(1);
evt.target.parentNode.parentNode.id.slice(0,-4).slice(1);
last_draggable_x = evt.pageX + svg_view.x;
last_draggable_y = evt.pageY + svg_view.y;
pdgui.pdsend(target_id, "_click", 1,
// Nasty-- we have to forward magic values from g_canvas.h
// defines in order to get the correct constrain behavior.
if (evt.target.classList.contains("constrain_top_right")) {
resize_type = 7; // CURSOR_EDITMODE_RESIZE_X
} else if (evt.target.classList
.contains("constrain_bottom_right")) {
resize_type = 10; // CURSOR_EDITMODE_RESIZE_Y
} else if (draggable_label) {
resize_type = 11; // CURSOR_EDITMODE_MOVE
} else {
resize_type = 8; // CURSOR_EDITMODE_RESIZE
}
// Even nastier-- we now must turn off the cursor styles
// so that moving the pointer outside the hotspot doesn't
// cause the cursor to change. This happens for the
// drag handle to move the gop red rectangle. Unlike
// the label handles, it doesn't get immediately
// destroyed upon receiving its callback below.
pdgui.toggle_drag_handle_cursors(evt.target.parentNode,
!!draggable_label, false);
pdgui.pdsend(target_id, "_click", resize_type,
(evt.pageX + svg_view.x),
(evt.pageY + svg_view.y));
canvas_events.iemgui_label_drag();
return;
}
// tk events (and, therefore, Pd evnets) are one greater
// tk events (and, therefore, Pd events) are one greater
// than html5...
var b = evt.button + 1;
var mod, match_elem;
......@@ -472,16 +497,6 @@ var canvas_events = (function() {
last_draggable_x = evt.pageX + svg_view.x;
last_draggable_y = evt.pageY + svg_view.y;
if (!is_canvas_gop_rect) {
// This is bad-- we should be translating
// here so that the logic doesn't depend on the shape
// type we chose in pdgui (here, it's "line").
handle_elem.x1.baseVal.value += dx;
handle_elem.y1.baseVal.value += dy;
handle_elem.x2.baseVal.value += dx;
handle_elem.y2.baseVal.value += dy;
}
pdgui.pdsend(target_id, "_motion",
(evt.pageX + svg_view.x),
(evt.pageY + svg_view.y));
......@@ -491,6 +506,19 @@ var canvas_events = (function() {
// Set last state (none doesn't count as a state)
//pdgui.post("previous state is "
// + canvas_events.get_previous_state());
var label_handle = document.querySelector(".move_handle");
var cnv_resize_handle =
document.querySelector(".cnv_resize_handle");
// Restore our cursor bindings for any drag handles that
// happen to exist
if (label_handle) {
pdgui.toggle_drag_handle_cursors(label_handle,
true, true);
}
if (cnv_resize_handle) {
pdgui.toggle_drag_handle_cursors(cnv_resize_handle,
false, true);
}
canvas_events[canvas_events.get_previous_state()]();
},
dropdown_menu_keydown: function(evt) {
......
......@@ -1472,7 +1472,8 @@ function gui_canvas_cursor(cid, pd_event_type) {
case "cursor_editmode_resize":
c = "ew-resize";
break;
case "cursor_editmode_resize_bottom_right": c = "se-resize";
case "cursor_editmode_resize_bottom_right":
c = "se-resize";
break;
case "cursor_scroll":
c = "all-scroll";
......@@ -1480,6 +1481,9 @@ function gui_canvas_cursor(cid, pd_event_type) {
case "cursor_editmode_resize_vert":
c = "ns-resize";
break;
case "cursor_editmode_move":
c = "move";
break;
}
patch.style.cursor = c;
});
......@@ -2024,7 +2028,7 @@ var gui = (function() {
return {
append: !w ? null_fn: function(cb) {
var frag = w.window.document.createDocumentFragment();
frag = cb(frag, w.window);
frag = cb(frag, w.window, c[cid]);
last_thing.appendChild(frag);
return c[cid];
},
......@@ -3242,12 +3246,29 @@ function gui_iemgui_label_font(cid, tag, fontname, fontweight, fontsize) {
});
}
function toggle_drag_handle_cursors(e, is_label, state) {
e.querySelector(".constrain_top_right").style.cursor =
state ? "ew-resize" : "";
e.querySelector(".constrain_bottom_right").style.cursor =
state ? "ns-resize" : "";
e.querySelector(".unconstrained").style.cursor =
state ? (is_label ? "move" : "se-resize") : "";
}
exports.toggle_drag_handle_cursors = toggle_drag_handle_cursors;
// Show or hide little handle for dragging around iemgui labels
function gui_iemgui_label_show_drag_handle(cid, tag, state, x, y, cnv_resize) {
if (state !== 0) {
gui(cid).get_gobj(tag)
.append(function(frag) {
var rect;
.append(function(frag, w) {
var g, rect, top_right, bottom_right;
g = create_item(cid, "g", {
class: (cid === tag) ? "gop_drag_handle move_handle border" :
cnv_resize !== 0 ? "cnv_resize_handle border" :
"label_drag_handle move_handle border",
transform: "matrix(1, 0, 0, 1, 0, 0)"
});
// Here we use a "line" shape so that we can control its color
// using the "border" class (for iemguis) or the "gop_rect" class
// for the graph-on-parent rectangle anchor. In both cases the
......@@ -3255,28 +3276,59 @@ function gui_iemgui_label_show_drag_handle(cid, tag, state, x, y, cnv_resize) {
// to define than a "rect" for that case.
rect = create_item(cid, "line", {
x1: x,
y1: y + 3,
y1: y,
x2: x,
y2: y + 10,
"stroke-width": 7,
class: (cid === tag) ? "gop_drag_handle move_handle gop_rect" :
cnv_resize !== 0 ? "cnv_resize_handle border" :
"label_drag_handle move_handle border"
y2: y + 14,
"stroke-width": 14,
class: "unconstrained"
});
g.classList.add("clickable_resize_handle");
top_right = create_item(cid, "rect", {
x: x + 1.5,
y: y + 0.5,
width: 5,
height: 7,
fill: "black",
"fill-opacity": "0",
class: "constrain_top_right"
});
rect.classList.add("clickable_resize_handle");
frag.appendChild(rect);
bottom_right = create_item(cid, "rect", {
x: x - 6.5,
y: y + 8.5,
width: 7,
height: 5,
fill: "black",
"fill-opacity": "0",
class: "constrain_bottom_right"
});
g.appendChild(rect);
g.appendChild(top_right);
g.appendChild(bottom_right);
// Quick hack for cursors on mouse-over. We only add them if
// we're not already dragging a label or resizing an iemgui.
// Apparently I didn't register all these edge-case event states
// in canvas_events. States like "iemgui_label_drag" actually
// just get registered as state "none". So we just check for "none"
// here and assume it means we're in the middle of dragging.
// If not we go ahead and set our cursor styles.
if (w.canvas_events.get_state() != "none") {
toggle_drag_handle_cursors(g, cnv_resize === 0, true);
}
frag.appendChild(g);
return frag;
});
} else {
gui(cid).get_gobj(tag, function(e) {
var rect =
var g =
e.getElementsByClassName((cid === tag) ? "gop_drag_handle" :
cnv_resize !== 0 ? "cnv_resize_handle" :
"label_drag_handle")[0];
//rect = get_item(cid, "clickable_resize_handle");
// Need to check for null here...
if (rect) {
rect.parentNode.removeChild(rect);
if (g) {
g.parentNode.removeChild(g);
} else {
post("error: couldn't delete the iemgui drag handle!");
}
......@@ -3284,6 +3336,15 @@ function gui_iemgui_label_show_drag_handle(cid, tag, state, x, y, cnv_resize) {
}
}
function gui_iemgui_label_displace_drag_handle(cid, tag, dx, dy) {
gui(cid).get_gobj(tag)
.q(".label_drag_handle", function(e) {
var t = e.transform.baseVal.getItem(0);
t.matrix.e += dx;
t.matrix.f += dy;
});
}
function gui_mycanvas_new(cid,tag,color,x1,y1,x2_vis,y2_vis,x2,y2) {
gui(cid).get_gobj(tag)
.append(function(frag) {
......
......@@ -246,7 +246,7 @@ void iemgui_label_pos(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
{
x->x_ldx = atom_getintarg(0, ac, av);
x->x_ldy = atom_getintarg(1, ac, av);
if(glist_isvisible(x->x_glist))
if (glist_isvisible(x->x_glist))
{
int x1 = x->x_ldx;
int y1 = x->x_ldy;
......@@ -474,7 +474,7 @@ void iemgui_pos(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
{
x->x_obj.te_xpix = atom_getintarg(0, ac, av);
x->x_obj.te_ypix = atom_getintarg(1, ac, av);
if(glist_isvisible(x->x_glist))
if (glist_isvisible(x->x_glist))
iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_MOVE);
}
......@@ -488,7 +488,7 @@ void iemgui_color(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
}
else
x->x_lcol = iemgui_compatible_col(atom_getintarg(1, ac, av));
if(glist_isvisible(x->x_glist))
if (glist_isvisible(x->x_glist))
{
x->x_draw(x, x->x_glist, IEM_GUI_DRAW_MODE_CONFIG);
iemgui_label_draw_config(x);
......@@ -713,7 +713,7 @@ void scalehandle_draw_select2(t_iemgui *x)
{
t_canvas *canvas=glist_getcanvas(x->x_glist);
t_class *c = pd_class((t_pd *)x);
int sx,sy;
int sx, sy;
if (c == my_canvas_class)
{
t_my_canvas *y = (t_my_canvas *)x;
......@@ -722,24 +722,27 @@ void scalehandle_draw_select2(t_iemgui *x)
}
else
{
int x1,y1,x2,y2;
c->c_wb->w_getrectfn((t_gobj *)x,canvas,&x1,&y1,&x2,&y2);
int x1, y1, x2, y2;
c->c_wb->w_getrectfn((t_gobj *)x,canvas, &x1, &y1, &x2, &y2);
//iemgui_getrect_draw(x, &x1, &y1, &x2, &y2);
sx=x2-x1; sy=y2-y1;
sx = x2 - x1; sy = y2 - y1;
}
/* we're not drawing the scalehandle for the actual iemgui-- just
the one for the label. */
the one for the label. Special case for [cnv] which for some reason
allows a smaller selection area than its painted rectangle. */
if (c == my_canvas_class)
scalehandle_draw_select(x->x_handle,sx+8,sy+3);
scalehandle_draw_select(x->x_handle,
(int)(sx + SCALEHANDLE_WIDTH * 1.5) + 1,
sy + SCALEHANDLE_HEIGHT);
if (x->x_lab != s_empty)
scalehandle_draw_select(x->x_lhandle,x->x_ldx,x->x_ldy);
scalehandle_draw_select(x->x_lhandle, x->x_ldx + 5, x->x_ldy + 10);
}
void scalehandle_draw_erase(t_scalehandle *h)
{
//t_canvas *canvas = glist_getcanvas(h->h_glist);
if (!h->h_vis) return;
gui_vmess("gui_iemgui_label_show_drag_handle", "xxiiii",
gui_vmess("gui_iemgui_label_show_drag_handle", "xxiiiii",
h->h_glist, h->h_master, 0, 0, 0, h->h_scale);
h->h_vis = 0;
}
......@@ -817,8 +820,10 @@ void scalehandle_dragon_label(t_scalehandle *h, float mouse_x, float mouse_y)
if (h->h_dragon && !h->h_scale)
{
t_iemgui *x = (t_iemgui *)(h->h_master);
int dx = (int)mouse_x - (int)h->h_offset_x,
dy = (int)mouse_y - (int)h->h_offset_y;
int dx = (h->h_constrain == CURSOR_EDITMODE_RESIZE_Y) ? 0 :
(int)mouse_x - (int)h->h_offset_x,
dy = (h->h_constrain == CURSOR_EDITMODE_RESIZE_X) ? 0 :
(int)mouse_y - (int)h->h_offset_y;
h->h_dragx = dx;
h->h_dragy = dy;
......@@ -844,6 +849,11 @@ void scalehandle_dragon_label(t_scalehandle *h, float mouse_x, float mouse_y)
x,
x->x_ldx,
x->x_ldy);
gui_vmess("gui_iemgui_label_displace_drag_handle", "xxii",
canvas,
x,
dx,
dy);
}
}
}
......@@ -917,6 +927,16 @@ void scalehandle_drag_scale(t_scalehandle *h) {
static void scalehandle_clickhook(t_scalehandle *h, t_floatarg f,
t_floatarg xxx, t_floatarg yyy)
{
/* The label scalehandles do an end run around canvas_doclick,
which is where the cursor gets set. So we go ahead and set
the cursor here, too. "f" is our cursor number as defined
by the CURSOR_* macros in canvas.h */
canvas_setcursor(h->h_glist, (int)f);
/* We also go ahead and set h_constrain here so we don't have
to do it separately for each widget. Any widget that wants
to constrain movement along an axis can just check that
field against the CURSOR_* values in the motionhook callback. */
h->h_constrain = f;
h->h_offset_x = xxx;
h->h_offset_y = yyy;
h->h_clickfn(h, f);
......@@ -1042,7 +1062,7 @@ void iemgui_label_draw_config(t_iemgui *x)
if (x->x_selected == canvas && x->x_glist == canvas)
{
t_scalehandle *lh = (t_scalehandle *)(x->x_lhandle);
if (x->x_lab==s_empty)
if (x->x_lab == s_empty)
scalehandle_draw_erase(x->x_lhandle);
else if (lh->h_vis == 0)
scalehandle_draw_select(lh,x->x_ldx,x->x_ldy);
......
......@@ -27,10 +27,10 @@
#define SCALE_NUM_MINHEIGHT 8
#define SCALE_GOP_MINWIDTH 12
#define SCALE_GOP_MINHEIGHT 12
#define SCALEHANDLE_WIDTH 5
#define SCALEHANDLE_HEIGHT 5
#define LABELHANDLE_WIDTH 5
#define LABELHANDLE_HEIGHT 5
#define SCALEHANDLE_WIDTH 14
#define SCALEHANDLE_HEIGHT 14
#define LABELHANDLE_WIDTH 14
#define LABELHANDLE_HEIGHT 14
typedef void (*t_iemfunptr)(void *x, t_glist *glist, int mode);
......@@ -46,7 +46,7 @@ typedef struct _scalehandle
t_object *h_master;
t_glist *h_glist; // this is the canvas to draw on. Note that when objects are edited, "glist" and "canvas" mean the same.
t_symbol *h_bindsym;
int h_scale; // bool
int h_scale;
char h_pathname[37]; // max size for ".x%lx.h%lx" = 5+4*sizeof(long)
char h_outlinetag[18]; // max size for "h%lx" = 2+2*sizeof(long)
int h_dragon; // bool
......
......@@ -340,6 +340,10 @@ void linetraverser_skipobject(t_linetraverser *t)
/* -------------------- the canvas object -------------------------- */
int glist_valid = 10000;
void canvasgop__clickhook(t_scalehandle *sh, int newstate);
void canvasgop__motionhook(t_scalehandle *sh,t_floatarg f1, t_floatarg f2);
extern void glist_setlastxy(t_glist *gl, int xval, int yval);
void glist_init(t_glist *x)
{
/* zero out everyone except "pd" field */
......@@ -348,11 +352,13 @@ void glist_init(t_glist *x)
x->gl_valid = ++glist_valid;
x->gl_xlabel = (t_symbol **)t_getbytes(0);
x->gl_ylabel = (t_symbol **)t_getbytes(0);
}
void canvasgop__clickhook(t_scalehandle *sh, int newstate);
void canvasgop__motionhook(t_scalehandle *sh,t_floatarg f1, t_floatarg f2);
extern void glist_setlastxy(t_glist *gl, int xval, int yval);
//dpsaha@vt.edu gop resize (refactored by mathieu)
x->x_handle = scalehandle_new((t_object *)x, x, 1,
canvasgop__clickhook, canvasgop__motionhook);
x->x_mhandle = scalehandle_new((t_object *)x, x, 0,
canvasgop__clickhook, canvasgop__motionhook);
}
/* These globals are used to set state for the "canvas" field in a
struct. We try below to make sure they only get set for the toplevel
......@@ -488,12 +494,6 @@ t_canvas *canvas_new(void *dummy, t_symbol *sel, int argc, t_atom *argv)
x->gl_zoom = zoom;
pd_pushsym(&x->gl_pd);
//dpsaha@vt.edu gop resize (refactored by mathieu)
x->x_handle = scalehandle_new((t_object *)x, x, 1,
canvasgop__clickhook,canvasgop__motionhook);
x->x_mhandle = scalehandle_new((t_object *)x, x, 0,
canvasgop__clickhook,canvasgop__motionhook);
x->u_queue = canvas_undo_init(x);
//glist_setlastxy(x, 20, 20);
......@@ -2320,11 +2320,13 @@ void canvasgop_checksize(t_canvas *x)
void canvasgop__clickhook(t_scalehandle *sh, int newstate)
{
t_canvas *x = (t_canvas *)(sh->h_master);
/* Now set constrain to newstate, which is one of:
CURSOR_EDITMODE_RESIZE_X - horizontal resizing
CURSOR_EDITMODE_RESIZE_Y - vertical resizing
CURSOR_EDITMODE_RESIZE - free resizing */
sh->h_constrain = newstate;
/* So ugly: if the user is dragging the bottom right-hand corner of
a gop subcanvas on the parent, we already set an undo event for it.
So we only add one here for resizing the gop red rectangle, or for
moving it with the red scalehandle. */
if (sh->h_scale != 1)
canvas_undo_add(x, 8, "apply", canvas_undo_set_canvas(x));
/* We're abusing h_scale to differentiate between clicking gop red
rectangle and clicking the corner of a subcanvas on the parent */
......@@ -2339,10 +2341,6 @@ void canvasgop__clickhook(t_scalehandle *sh, int newstate)
}
else if (sh->h_scale == 2) /* resize gop hook for (red) gop rect */
{
/* So ugly: if the user is dragging the bottom right-hand corner of
a gop subcanvas on the parent, we already set an undo event for it.
So we only add one here for dragging the gop red rectangle. */
canvas_undo_add(x, 8, "apply", canvas_undo_set_canvas(x));
/* Store an adjustment for difference between the initial
pointer position-- which is within five pixels or so-- and the
bottom right-hand corner. Otherwise we'd get a "jump" from the
......@@ -2353,6 +2351,7 @@ void canvasgop__clickhook(t_scalehandle *sh, int newstate)
We could alternatively use dx/dy, but then the pointer position
would stray when the user attempts to drag past the minimum
width/height of the rectangle. */
sh->h_adjust_x = sh->h_offset_x - (x->gl_xmargin + x->gl_pixwidth);
sh->h_adjust_y = sh->h_offset_y - (x->gl_ymargin + x->gl_pixheight);
......@@ -2466,13 +2465,13 @@ void canvasgop__motionhook(t_scalehandle *sh, t_floatarg mouse_x,
properties_set_field_int(properties,
"y_margin",x->gl_ymargin + dy);
}
if (sh->h_constrain == 1 || !sh->h_constrain)
if (sh->h_constrain != CURSOR_EDITMODE_RESIZE_Y)
x->gl_xmargin += dx;
if (sh->h_constrain == -1 || !sh->h_constrain)
if (sh->h_constrain != CURSOR_EDITMODE_RESIZE_X)
x->gl_ymargin += dy;
int x1 = x->gl_xmargin, x2 = x1+x->gl_pixwidth;
int y1 = x->gl_ymargin, y2 = y1+x->gl_pixheight;
int x1 = x->gl_xmargin, x2 = x1 + x->gl_pixwidth;
int y1 = x->gl_ymargin, y2 = y1 + x->gl_pixheight;
gui_vmess("gui_canvas_redrect_coords", "xiiii",
x, x1, y1, x2, y2);
......
......@@ -407,6 +407,7 @@ struct _parentwidgetbehavior
#define CURSOR_EDITMODE_RESIZE 8
#define CURSOR_SCROLL 9
#define CURSOR_EDITMODE_RESIZE_Y 10
#define CURSOR_EDITMODE_MOVE 11
EXTERN void canvas_setcursor(t_glist *x, unsigned int cursornum);
extern t_canvas *canvas_editing; /* last canvas to start text edting */
......
......@@ -2191,7 +2191,8 @@ static char *cursorlist[] = {
"cursor_editmode_resize",
"cursor_editmode_resize_bottom_right",
"cursor_scroll",
"cursor_editmode_resize_vert"
"cursor_editmode_resize_vert",
"cursor_editmode_move"
};
void canvas_setcursor(t_canvas *x, unsigned int cursornum)
......@@ -3162,20 +3163,25 @@ static int text_resizing_hotspot(t_canvas *x, t_object *ob, int xpos, int ypos,
{
/* stay out of the way of outlet in the bottom right-hand corner */
int offset = (obj_noutlets(ob) > 1) ? -4 : 0;
/* We also want to disquality [bng], [tgl], [hradio] and [vradio]
from horiz and vert anchors. These widgets only have one
/* We want to disable horiz and vert anchors for [bng], [tgl],
[hradio] and [vradio]. These widgets only have one
dimension that can be resized-- the other is handled
automatically. */
int can_constrain = (ob->ob_pd->c_name != gensym("bng") &&
int can_resize_x = (ob->ob_pd->c_name != gensym("bng") &&
ob->ob_pd->c_name != gensym("tgl") &&
ob->ob_pd->c_name != gensym("hradio") &&
ob->ob_pd->c_name != gensym("vradio"));
if (can_constrain &&
xpos >= x2 - 4 && ypos <= y2 + offset - 10 && ypos > y2 - 24)
int can_resize_y = can_resize_x &&
(ob->ob_pd->c_name != gensym("vsl") || x2 - x1 > 15) &&
(ob->ob_pd->c_name != gensym("hsl") || x2 - x1 > 15);
if (can_resize_x &&
xpos >= x2 - 4 && ypos <= y2 + offset - 10 && ypos > y2 + offset - 24)
return CURSOR_EDITMODE_RESIZE_X;
else if (xpos >= x2 - 4 && ypos <= y2 + offset && ypos > y2 - 10)
else if (xpos >= x2 - 4 && ypos <= y2 + offset && ypos > y2 + offset - 10)
return CURSOR_EDITMODE_RESIZE;
else if (can_constrain &&
else if (can_resize_y &&
xpos >= x2 - 12 &&
ypos >= y2 + offset - 5 &&
ypos <= y2 + offset)
......@@ -3214,8 +3220,8 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which,
t_gobj *yclick = NULL;
t_object *ob;
fprintf(stderr,"MAIN canvas_doclick %d %d %d %d %d\n",
xpos, ypos, which, mod, doit);
//fprintf(stderr,"MAIN canvas_doclick %d %d %d %d %d\n",
// xpos, ypos, which, mod, doit);
if (!x->gl_editor)
{
......@@ -3262,10 +3268,10 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which,
to let go */
if (doit)
{
fprintf(stderr,"doit %d\n", x->gl_editor->e_onmotion);
//fprintf(stderr,"doit %d\n", x->gl_editor->e_onmotion);
if (x->gl_editor->e_onmotion == MA_MOVE)
{
fprintf(stderr,"letting go of objects\n");
//fprintf(stderr,"letting go of objects\n");
t_selection *sel;
for (sel = x->gl_editor->e_selection; sel; sel = sel->sel_next)
{
......@@ -3347,7 +3353,7 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which,
/* We've got a special case for handling the gop red rectangle. In that
case we want all other click actions to take precedence, so we run
the checks here first so we can keep the same conditional ordering
Purr Data has always had. */
we've had for ages. */
if (y)
{
ob = pd_checkobject(&y->g_pd);
......@@ -3421,41 +3427,46 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which,
glist_noselect(x);
glist_select(x, y);
}
x->gl_editor->e_onmotion = MA_RESIZE;
x->gl_editor->e_xwas = x1;
x->gl_editor->e_ywas = y1;
x->gl_editor->e_xnew = xpos;
x->gl_editor->e_ynew = ypos;
/* For normal text objects/atom boxes we just go ahead
and set an undo point here. GUI objects have their
own click callback where they do this. */
if (default_type)
/* For normal text objects/atom boxes, subpatches and
graphs we just go ahead and set an undo point here.
GUI objects have their own click callback where they
do this. */
int isgraph = (ob->ob_pd == canvas_class &&
((t_canvas *)ob)->gl_isgraph);
if (default_type || isgraph)
canvas_undo_add(x, 6, "resize",
canvas_undo_set_apply(x, glist_getindex(x, y)));
/* Scalehandle callbacks */
if (ob->ob_pd == canvas_class &&
((t_canvas *)ob)->gl_isgraph)
if (isgraph)
{
t_pd *sh = (t_pd *)((t_canvas *)ob)->x_handle;
t_scalehandle *sh = ((t_canvas *)ob)->x_handle;
/* Special case: we're abusing the value of h_scale
to differentiate between this case and the case
of clicking the red gop rectangle. */
((t_scalehandle *)sh)->h_scale = 1;
pd_vmess(sh, gensym("_click"), "fff",