diff --git a/externals/miXed/cyclone/sickle/Scope.c b/externals/miXed/cyclone/sickle/Scope.c index b5c6aa5e91ea8db22bd2fa5cb0df4ee54cef621a..33b8b76f2298d7776a021366a11f8a8cebe963e4 100644 --- a/externals/miXed/cyclone/sickle/Scope.c +++ b/externals/miXed/cyclone/sickle/Scope.c @@ -106,9 +106,8 @@ typedef struct _scope int x_frozen; t_clock *x_clock; t_pd *x_handle; - - int scale_offset_x; - int scale_offset_y; + int scale_offset_x; + int scale_offset_y; } t_scope; typedef struct _scopehandle @@ -118,6 +117,9 @@ typedef struct _scopehandle t_symbol *h_bindsym; char h_pathname[64]; char h_outlinetag[64]; + int h_adjust_x; + int h_adjust_y; + int h_constrain; int h_dragon; int h_dragx; int h_dragy; @@ -992,49 +994,16 @@ static void scope_tick(t_scope *x) scope_clear(x, 1); } -static void scopehandle__clickhook(t_scopehandle *sh, t_floatarg f, t_floatarg xxx, t_floatarg yyy) +extern void canvas_apply_setundo(t_canvas *x, t_gobj *y); +static void scopehandle__clickhook(t_scopehandle *sh, t_floatarg f, + t_floatarg xxx, t_floatarg yyy) { - t_scope *x = sh->h_master; - - //if (xxx) x->scale_offset_x = xxx; - //if (yyy) x->scale_offset_y = yyy; - - //int newstate = (int)f; - //if (sh->h_dragon && newstate == 0) - //{ - // /* done dragging */ - // t_canvas *cv; - // if (sh->h_dragx || sh->h_dragy) - // { - // x->x_width = x->x_width + sh->h_dragx - x->scale_offset_x; - // x->x_height = x->x_height + sh->h_dragy - x->scale_offset_y; - // } - // if (cv = scope_isvisible(x)) - // { - // sys_vgui(".x%x.c delete %s\n", cv, sh->h_outlinetag); - // scope_revis(x, cv); - // sys_vgui("destroy %s\n", sh->h_pathname); - // scope_select((t_gobj *)x, x->x_glist, 1); - // canvas_fixlinesfor(x->x_glist, (t_text *)x); /* 2nd inlet */ - // } - //} - //else if (!sh->h_dragon && newstate) - //{ - // /* dragging */ - // t_canvas *cv; - // if (cv = scope_isvisible(x)) - // { - // int x1, y1, x2, y2; - // scope_getrect((t_gobj *)x, x->x_glist, &x1, &y1, &x2, &y2); - // sys_vgui("lower %s\n", sh->h_pathname); - // sys_vgui(".x%x.c create rectangle %d %d %d %d\ - // -outline $select_color -width %f -tags %s\n", - // cv, x1, y1, x2, y2, SCOPE_SELBDWIDTH, sh->h_outlinetag); - // } - // sh->h_dragx = 0; - // sh->h_dragy = 0; - //} + /* Use constrained dragging. See g_canvas.c clickhook */ + sh->h_constrain = (int)f; + sh->h_adjust_x = xxx - (((t_object *)x)->te_xpix + x->x_width); + sh->h_adjust_y = yyy - (((t_object *)x)->te_ypix + x->x_height); + canvas_apply_setundo(x->x_glist, (t_gobj *)x); sh->h_dragon = f; } @@ -1042,10 +1011,13 @@ static void scopehandle__motionhook(t_scopehandle *sh, t_floatarg mouse_x, t_floatarg mouse_y) { t_scope *x = (t_scope *)(sh->h_master); - int x1, y1, x2, y2, width, height; - scope_getrect((t_gobj *)x, x->x_glist, &x1, &y1, &x2, &y2); - width = mouse_x - x1; - height = mouse_y - y1; + int width = (sh->h_constrain == CURSOR_EDITMODE_RESIZE_Y) ? + x->x_width : + (int)mouse_x - text_xpix((t_text *)x, x->x_glist) - sh->h_adjust_x; + int height = (sh->h_constrain == CURSOR_EDITMODE_RESIZE_X) ? + x->x_height : + (int)mouse_y - text_ypix((t_text *)x, x->x_glist) - sh->h_adjust_y; + x->x_width = width < SCOPE_MINWIDTH ? SCOPE_MINWIDTH : width; x->x_height = height < SCOPE_MINHEIGHT ? SCOPE_MINHEIGHT : height; @@ -1058,25 +1030,6 @@ static void scopehandle__motionhook(t_scopehandle *sh, scope_vis((t_gobj *)x, x->x_glist, 0); scope_vis((t_gobj *)x, x->x_glist, 1); } - //if (sh->h_dragon) - //{ - // t_scope *x = sh->h_master; - // int dx = (int)f1, dy = (int)f2; - // int x1, y1, x2, y2, newx, newy; - // scope_getrect((t_gobj *)x, x->x_glist, &x1, &y1, &x2, &y2); - // newx = x2 - x->scale_offset_x + dx; - // newy = y2 - x->scale_offset_y + dy; - - // if (newx > x1 + SCOPE_MINWIDTH && newy > y1 + SCOPE_MINHEIGHT) - // { - // t_canvas *cv; - // if (cv = scope_isvisible(x)) - // sys_vgui(".x%x.c coords %s %d %d %d %d\n", - // cv, sh->h_outlinetag, x1, y1, newx, newy); - // sh->h_dragx = dx; - // sh->h_dragy = dy; - // } - //} } /* wrapper method for forwarding "scopehandle" data */ @@ -1157,8 +1110,8 @@ static void *scope_new(t_symbol *s, int ac, t_atom *av) sprintf(sh->h_outlinetag, "h%x", (int)sh); sh->h_dragon = 0; - x->scale_offset_x = 0; - x->scale_offset_y = 0; + x->scale_offset_x = 0; + x->scale_offset_y = 0; return (x); } diff --git a/externals/unauthorized/grid.c b/externals/unauthorized/grid.c index da3c56ab1ea165cef34ecd6829ef457ef494156e..557436d7b482190d06ce4b57c5167e09907f2dfb 100644 --- a/externals/unauthorized/grid.c +++ b/externals/unauthorized/grid.c @@ -696,39 +696,43 @@ static void grid_bang(t_grid *x) { static void grid__clickhook(t_scalehandle *sh, int newstate) { t_grid *x = (t_grid *)(sh->h_master); - if (newstate) - { - canvas_apply_setundo(x->x_glist, (t_gobj *)x); - } + /* Use constrained dragging-- see g_canvas.c clickhook */ + sh->h_constrain = newstate; + sh->h_adjust_x = sh->h_offset_x - + (((t_object *)x)->te_xpix + x->x_width); + sh->h_adjust_y = sh->h_offset_y - + (((t_object *)x)->te_ypix + x->x_height); + canvas_apply_setundo(x->x_glist, (t_gobj *)x); sh->h_dragon = newstate; } static void grid__motionhook(t_scalehandle *sh, t_floatarg mouse_x, t_floatarg mouse_y) { - if (sh->h_scale) + t_grid *x = (t_grid *)(sh->h_master); + int width = (sh->h_constrain == CURSOR_EDITMODE_RESIZE_Y) ? + x->x_width : + (int)mouse_x - text_xpix(&x->x_obj, x->x_glist) - sh->h_adjust_x; + int height = (sh->h_constrain == CURSOR_EDITMODE_RESIZE_X) ? + x->x_height : + (int)mouse_y - text_ypix(&x->x_obj, x->x_glist) - sh->h_adjust_y; + int minw = MIN_GRID_WIDTH, + minh = MIN_GRID_HEIGHT; + x->x_width = width < minw ? minw : width; + x->x_height = height < minh ? minh : height; + if (glist_isvisible(x->x_glist)) { - t_grid *x = (t_grid *)(sh->h_master); - int width = mouse_x - text_xpix(&x->x_obj, x->x_glist), - height = mouse_y - text_ypix(&x->x_obj, x->x_glist), - minw = MIN_GRID_WIDTH, - minh = MIN_GRID_HEIGHT; - x->x_width = width < minw ? minw : width; - x->x_height = height < minh ? minh : height; - if (glist_isvisible(x->x_glist)) - { - grid_draw_configure(x, x->x_glist); - //scalehandle_unclick_scale(sh); - } + grid_draw_configure(x, x->x_glist); + //scalehandle_unclick_scale(sh); + } - int properties = gfxstub_haveproperties((void *)x); - if (properties) - { - int new_w = x->x_width + sh->h_dragx; - int new_h = x->x_height + sh->h_dragy; - properties_set_field_int(properties,"width",new_w); - properties_set_field_int(properties,"height",new_h); - } + int properties = gfxstub_haveproperties((void *)x); + if (properties) + { + int new_w = x->x_width + sh->h_dragx; + int new_h = x->x_height + sh->h_dragy; + properties_set_field_int(properties,"width",new_w); + properties_set_field_int(properties,"height",new_h); } } @@ -737,8 +741,9 @@ static void grid_click_for_resizing(t_grid *x, t_floatarg f, t_floatarg xxx, t_floatarg yyy) { t_scalehandle *sh = (t_scalehandle *)x->x_handle; + sh->h_offset_x = (int)xxx; + sh->h_offset_y = (int)yyy; grid__clickhook(sh, f); -// grid__clickhook(sh, f, xxx, yyy); } /* another wrapper for forwarding "scalehandle" motion data */ diff --git a/pd/nw/pd_canvas.js b/pd/nw/pd_canvas.js index db54bda82cc9a561b3f0fe2187b9920661862f20..1e9c770a326da00b48b7bd5e1f77a5c35706dc0d 100644 --- a/pd/nw/pd_canvas.js +++ b/pd/nw/pd_canvas.js @@ -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) { diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js index 97d0fa3a013323cee5624eadf55911722285334c..260ace1ea2a0c7e0dfccc8c5f09a700554ad5cfc 100644 --- a/pd/nw/pdgui.js +++ b/pd/nw/pdgui.js @@ -1472,11 +1472,18 @@ 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"; break; + case "cursor_editmode_resize_vert": + c = "ns-resize"; + break; + case "cursor_editmode_move": + c = "move"; + break; } patch.style.cursor = c; }); @@ -2021,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]; }, @@ -3239,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 @@ -3252,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!"); } @@ -3281,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) { diff --git a/pd/src/g_all_guis.c b/pd/src/g_all_guis.c index c2381e0f12f3d6d283868cf82e2c936143a31ef7..e7701ab1eeea56ed29098ecfb3ab040f2b7f2ad3 100644 --- a/pd/src/g_all_guis.c +++ b/pd/src/g_all_guis.c @@ -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; } @@ -783,7 +786,10 @@ t_scalehandle *scalehandle_new(t_object *x, t_glist *glist, int scale, h->h_scale = scale; h->h_offset_x = 0; h->h_offset_y = 0; + h->h_adjust_x = 0; + h->h_adjust_y = 0; h->h_vis = 0; + h->h_constrain = 0; sprintf(h->h_pathname, ".x%lx.h%lx", (t_int)h->h_glist, (t_int)h); h->h_clickfn = chf; h->h_motionfn = mhf; @@ -814,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; @@ -841,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); } } } @@ -914,15 +927,25 @@ void scalehandle_drag_scale(t_scalehandle *h) { static void scalehandle_clickhook(t_scalehandle *h, t_floatarg f, t_floatarg xxx, t_floatarg yyy) { - h->h_offset_x=xxx; - h->h_offset_y=yyy; - h->h_clickfn(h,f); + /* 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); } static void scalehandle_motionhook(t_scalehandle *h, t_floatarg f1, t_floatarg f2) { - h->h_motionfn(h,f1,f2); + h->h_motionfn(h, f1, f2); // Now set the offset to the new mouse position h->h_offset_x = f1; h->h_offset_y = f2; @@ -948,7 +971,8 @@ static void scalehandle_check_and_redraw(t_iemgui *x) //---------------------------------------------------------------- // IEMGUI refactor (by Mathieu) -void iemgui_tag_selected(t_iemgui *x) { +void iemgui_tag_selected(t_iemgui *x) +{ t_canvas *canvas=glist_getcanvas(x->x_glist); if (x->x_selected) gui_vmess("gui_gobj_select", "xx", canvas, x); @@ -956,7 +980,8 @@ void iemgui_tag_selected(t_iemgui *x) { gui_vmess("gui_gobj_deselect", "xx", canvas, x); } -void iemgui_label_draw_new(t_iemgui *x) { +void iemgui_label_draw_new(t_iemgui *x) +{ char col[8]; t_canvas *canvas=glist_getcanvas(x->x_glist); int x1=text_xpix(&x->x_obj, x->x_glist)+x->legacy_x; @@ -994,7 +1019,8 @@ void iemgui_label_draw_move(t_iemgui *x) x->x_ldy + x->legacy_y); } -void iemgui_label_draw_config(t_iemgui *x) { +void iemgui_label_draw_config(t_iemgui *x) +{ char col[8]; t_canvas *canvas=glist_getcanvas(x->x_glist); if (x->x_selected == canvas && x->x_glist == canvas) @@ -1036,14 +1062,15 @@ 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); } } -void iemgui_label_draw_select(t_iemgui *x) { +void iemgui_label_draw_select(t_iemgui *x) +{ t_canvas *canvas=glist_getcanvas(x->x_glist); if (x->x_selected == canvas && x->x_glist == canvas) { @@ -1070,9 +1097,10 @@ void iemgui_draw_io(t_iemgui *x, int old_sr_flags) t_canvas *canvas=glist_getcanvas(x->x_glist); if (x->x_glist != canvas) return; // is gop t_class *c = pd_class((t_pd *)x); - if (c==my_numbox_class && ((t_my_numbox *)x)->x_hide_frame > 1) return; //sigh - - if (!(old_sr_flags&4) && !glist_isvisible(canvas)) { + if (c == my_numbox_class && ((t_my_numbox *)x)->x_hide_frame > 1) + return; //sigh + if (!(old_sr_flags&4) && !glist_isvisible(canvas)) + { return; } if (c==my_canvas_class) return; @@ -1087,7 +1115,9 @@ void iemgui_draw_io(t_iemgui *x, int old_sr_flags) n = 0; int a=old_sr_flags&IEM_GUI_OLD_SND_FLAG; int b=x->x_snd!=s_empty; - //fprintf(stderr,"%lx SND: old_sr_flags=%d SND_FLAG=%d || OUTCOME: OLD_SND_FLAG=%d not_empty=%d\n", (t_int)x, old_sr_flags, IEM_GUI_OLD_SND_FLAG, a, b); + //fprintf(stderr, "%lx SND: old_sr_flags=%d SND_FLAG=%d || " + // "OUTCOME: OLD_SND_FLAG=%d not_empty=%d\n", + // (t_int)x, old_sr_flags, IEM_GUI_OLD_SND_FLAG, a, b); if (a && !b) { @@ -1136,7 +1166,8 @@ void iemgui_draw_io(t_iemgui *x, int old_sr_flags) } } -void iemgui_io_draw_move(t_iemgui *x) { +void iemgui_io_draw_move(t_iemgui *x) +{ char tagbuf[MAXPDSTRING]; t_canvas *canvas=glist_getcanvas(x->x_glist); t_class *c = pd_class((t_pd *)x); @@ -1180,13 +1211,15 @@ void iemgui_io_draw_move(t_iemgui *x) { } } -void iemgui_base_draw_new(t_iemgui *x) { +void iemgui_base_draw_new(t_iemgui *x) +{ t_canvas *canvas=glist_getcanvas(x->x_glist); t_class *c = pd_class((t_pd *)x); - int x1,y1,x2,y2,gr=gop_redraw; gop_redraw=0; - c->c_wb->w_getrectfn((t_gobj *)x,x->x_glist,&x1,&y1,&x2,&y2); + int x1, y1, x2, y2, gr = gop_redraw; + gop_redraw = 0; + c->c_wb->w_getrectfn((t_gobj *)x, x->x_glist, &x1, &y1, &x2, &y2); //iemgui_getrect_draw(x, &x1, &y1, &x2, &y2); - gop_redraw=gr; + gop_redraw = gr; char colorbuf[MAXPDSTRING]; sprintf(colorbuf, "#%6.6x", x->x_bcol); gui_vmess("gui_gobj_new", "xxsiii", canvas, x, @@ -1203,7 +1236,8 @@ void iemgui_base_draw_new(t_iemgui *x) { canvas, x, colorbuf); } -void iemgui_base_draw_move(t_iemgui *x) { +void iemgui_base_draw_move(t_iemgui *x) +{ t_canvas *canvas=glist_getcanvas(x->x_glist); t_class *c = pd_class((t_pd *)x); int x1,y1,x2,y2,gr=gop_redraw; gop_redraw=0; @@ -1214,8 +1248,8 @@ void iemgui_base_draw_move(t_iemgui *x) { canvas, x, x1, y1, x2, y2); } -void iemgui_base_draw_config(t_iemgui *x) { - +void iemgui_base_draw_config(t_iemgui *x) +{ t_canvas *canvas=glist_getcanvas(x->x_glist); char fcol[8]; sprintf(fcol,"#%6.6x", x->x_fcol); char tagbuf[MAXPDSTRING]; @@ -1225,44 +1259,52 @@ void iemgui_base_draw_config(t_iemgui *x) { canvas, x, bcol); } -void iemgui_draw_update(t_iemgui *x, t_glist *glist) { +void iemgui_draw_update(t_iemgui *x, t_glist *glist) +{ x->x_draw(x, x->x_glist, IEM_GUI_DRAW_MODE_UPDATE); } -void iemgui_draw_new(t_iemgui *x) { +void iemgui_draw_new(t_iemgui *x) +{ x->x_draw(x, x->x_glist, IEM_GUI_DRAW_MODE_NEW); iemgui_label_draw_new(x); iemgui_draw_io(x,7); - canvas_raise_all_cords(glist_getcanvas(x->x_glist)); // used to be inside x_draw + // used to be inside x_draw... + canvas_raise_all_cords(glist_getcanvas(x->x_glist)); } -void iemgui_draw_config(t_iemgui *x) { +void iemgui_draw_config(t_iemgui *x) +{ x->x_draw(x, x->x_glist, IEM_GUI_DRAW_MODE_CONFIG); iemgui_label_draw_config(x); //iemgui_base_draw_config(x); // can't } -void iemgui_draw_move(t_iemgui *x) { +void iemgui_draw_move(t_iemgui *x) +{ x->x_draw(x, x->x_glist, IEM_GUI_DRAW_MODE_MOVE); iemgui_label_draw_move(x); //iemgui_base_draw_move(x); // can't iemgui_io_draw_move(x); } -void iemgui_draw_erase(t_iemgui *x) { +void iemgui_draw_erase(t_iemgui *x) +{ t_canvas *canvas=glist_getcanvas(x->x_glist); gui_vmess("gui_gobj_erase", "xx", canvas, x); scalehandle_draw_erase2(x); } -void scrollbar_update(t_glist *glist) { +void scrollbar_update(t_glist *glist) +{ //ico@bukvic.net 100518 update scrollbars when object potentially //exceeds window size t_canvas *canvas=(t_canvas *)glist_getcanvas(glist); canvas_getscroll(canvas); } -void wb_init(t_widgetbehavior *wb, t_getrectfn gr, t_clickfn cl) { +void wb_init(t_widgetbehavior *wb, t_getrectfn gr, t_clickfn cl) +{ wb->w_getrectfn = gr; wb->w_displacefn = iemgui_displace; wb->w_selectfn = iemgui_select; @@ -1273,13 +1315,15 @@ void wb_init(t_widgetbehavior *wb, t_getrectfn gr, t_clickfn cl) { wb->w_displacefnwtag = iemgui_displace_withtag; } -const char *iemgui_typeface(t_iemgui *x) { +const char *iemgui_typeface(t_iemgui *x) +{ int f = x->x_font_style; if(f == 0) return sys_font; if(f == 1) return "helvetica"; if(f == 2) return "times"; return "invalid-font"; } + // this uses a static buffer, so don't use it twice in the same sys_vgui. // the static buffer could be replaced by a malloc when sys_vgui is replaced // by something that frees that memory. @@ -1287,7 +1331,9 @@ const char *iemgui_typeface(t_iemgui *x) { separate arg so we don't have to parse on the gui side. Once we check to make sure all iemguis work without it we can safely remove it */ -const char *iemgui_font(t_iemgui *x) { + +const char *iemgui_font(t_iemgui *x) +{ static char buf[64]; sprintf(buf, "{{%s} -%d %s}", iemgui_typeface(x), x->x_fontsize, sys_fontweight); return buf; @@ -1295,7 +1341,8 @@ const char *iemgui_font(t_iemgui *x) { void iemgui_init(t_iemgui *x, t_floatarg f) {x->x_loadinit = f!=0.0;} -void iemgui_class_addmethods(t_class *c) { +void iemgui_class_addmethods(t_class *c) +{ class_addmethod(c, (t_method)iemgui_delta, gensym("delta"), A_GIMME, 0); class_addmethod(c, (t_method)iemgui_pos, @@ -1314,7 +1361,8 @@ void iemgui_class_addmethods(t_class *c) { gensym("label_font"), A_GIMME, 0); } -void g_iemgui_setup (void) { +void g_iemgui_setup (void) +{ s_empty = gensym("empty"); scalehandle_class = class_new(gensym("_scalehandle"), 0, 0, sizeof(t_scalehandle), CLASS_PD, 0); @@ -1330,16 +1378,21 @@ const char *border_color = "$pd_colors(iemgui_border)"; #define GET_OUTLET t_outlet *out = x->x_obj.ob_outlet; /* can't use int o because there's not obj_nth_outlet function */ #define SEND_BY_SYMBOL (iemgui_has_snd(x) && x->x_snd->s_thing && (!chk_putin || x->x_put_in2out)) -void iemgui_out_bang(t_iemgui *x, int o, int chk_putin) { +void iemgui_out_bang(t_iemgui *x, int o, int chk_putin) +{ GET_OUTLET outlet_bang(out); if(SEND_BY_SYMBOL) pd_bang(x->x_snd->s_thing); } -void iemgui_out_float(t_iemgui *x, int o, int chk_putin, t_float f) { + +void iemgui_out_float(t_iemgui *x, int o, int chk_putin, t_float f) +{ GET_OUTLET outlet_float(out,f); if(SEND_BY_SYMBOL) pd_float(x->x_snd->s_thing,f); } -void iemgui_out_list(t_iemgui *x, int o, int chk_putin, t_symbol *s, int argc, t_atom *argv) { - GET_OUTLET outlet_list(out,s,argc,argv); - if(SEND_BY_SYMBOL) pd_list(x->x_snd->s_thing,s,argc,argv); -} +void iemgui_out_list(t_iemgui *x, int o, int chk_putin, t_symbol *s, + int argc, t_atom *argv) +{ + GET_OUTLET outlet_list(out, s, argc, argv); + if (SEND_BY_SYMBOL) pd_list(x->x_snd->s_thing, s, argc, argv); +} diff --git a/pd/src/g_all_guis.h b/pd/src/g_all_guis.h index 81549d3e194f97f19ae2c3c3e0fc3ffd134f3dfc..a9d6768a01fd1c9b5504d2ffa4fd38840f53097a 100644 --- a/pd/src/g_all_guis.h +++ b/pd/src/g_all_guis.h @@ -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 @@ -54,6 +54,9 @@ typedef struct _scalehandle int h_dragy; int h_offset_x; int h_offset_y; + int h_adjust_x; + int h_adjust_y; + int h_constrain; int h_vis; // bool t_clickhandlefn h_clickfn; t_motionhandlefn h_motionfn; diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c index 47b5ebfcd446dca1ebdeea6dff22508db1ee8c5b..00cb8c93d8fec11e10074c66682756c512f6bdba 100644 --- a/pd/src/g_canvas.c +++ b/pd/src/g_canvas.c @@ -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,10 +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); @@ -985,7 +987,7 @@ void canvas_free(t_canvas *x) if (x->gl_editor) canvas_destroy_editor(x); /* bug workaround; should already be gone*/ - if (x-> x_handle) scalehandle_free( x->x_handle); + if (x->x_handle) scalehandle_free(x->x_handle); if (x->x_mhandle) scalehandle_free(x->x_mhandle); canvas_unbind(x); @@ -2318,108 +2320,50 @@ void canvasgop_checksize(t_canvas *x) void canvasgop__clickhook(t_scalehandle *sh, int newstate) { t_canvas *x = (t_canvas *)(sh->h_master); - if (sh->h_dragon && newstate == 0) - { - /* done dragging */ - if(sh->h_scale) //enter if resize_gop hook - { - canvas_undo_add(x, 8, "apply", canvas_undo_set_canvas(x)); - if (sh->h_dragx || sh->h_dragy) - { - x->gl_pixwidth += sh->h_dragx; - x->gl_pixheight += sh->h_dragy; - // check if the text is not hidden. if so, make minimum - // width and height based retrieved from getrect. - if (!x->gl_hidetext) - { - int x1=0, y1=0, x2=0, y2=0; - if (x->gl_owner) - { - gobj_getrect((t_gobj*)x, x->gl_owner, - &x1, &y1, &x2, &y2); - } - else - { - graph_checkgop_rect((t_gobj*)x, x, &x1, &y1, &x2, &y2); - } - if (x2-x1 > x->gl_pixwidth) x->gl_pixwidth = x2-x1; - if (y2-y1 > x->gl_pixheight) x->gl_pixheight = y2-y1; - } - canvas_dirty(x, 1); - } - - // can't remove this update because the text size check above is not in motionhook - int properties = gfxstub_haveproperties((void *)x); - if (properties) - { - properties_set_field_int(properties,"x_pix",x->gl_pixwidth); - properties_set_field_int(properties,"y_pix",x->gl_pixheight); - } + /* 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)); - if (glist_isvisible(x)) - { - /* Still not sure what this is doing... */ - //sys_vgui(".x%x.c delete %s\n", x, sh->h_outlinetag); - canvasgop_draw_move(x,1); - canvas_fixlinesfor(x, (t_text *)x); - scrollbar_update(x); - } - } - else //enter if move_gop hook - { - // this block is similar to scalehandle_unclick_label but not enough - // We've actually removed scalehandle_unclick_label everywhere, so - // check to see whether this can be removed as well... - canvas_undo_add(x, 8, "apply", canvas_undo_set_canvas(x)); - if (sh->h_dragx || sh->h_dragy) - { - x->gl_xmargin += sh->h_dragx; - x->gl_ymargin += sh->h_dragy; - canvas_dirty(x, 1); - } - if (glist_isvisible(x)) - { - canvasgop_draw_move(x,1); - canvas_fixlinesfor(x, (t_text *)x); - scrollbar_update(x); - } - } + /* We're abusing h_scale to differentiate between clicking gop red + rectangle and clicking the corner of a subcanvas on the parent */ + if (sh->h_scale == 1) /* clicking corner of gop subcanvas on parent */ + { + /* This is for clicking on the bottom right-hand corner of the + gop canvas when it's displayed on the parent canvas. */ + sh->h_adjust_x = sh->h_offset_x - + (((t_object *)x)->te_xpix + x->gl_pixwidth); + sh->h_adjust_y = sh->h_offset_y - + (((t_object *)x)->te_ypix + x->gl_pixheight); } - else if (!sh->h_dragon && newstate) + else if (sh->h_scale == 2) /* resize gop hook for (red) gop rect */ { - /* set undo */ - 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 + the current dimensions to the pointer offset. Such a jump would + become noticeable with constrained dragging, as the constrained + dimension would initially jump to the pointer position. - if(sh->h_scale) //enter if resize_gop hook - { - /* We could port this, but it might be better to wait until we - just move the scalehandle stuff directly to the GUI... */ - //sys_vgui("lower %s\n", sh->h_pathname); - - //delete GOP rect where it started from - /* Doesn't look like we're using this anymore, so no need to - port it. */ - //sys_vgui(".x%lx.c delete GOP\n", x); - //sys_vgui(".x%x.c create rectangle %d %d %d %d " - // "-outline $pd_colors(selection) -width 1 -tags %s\n", - // x, x->gl_xmargin, x->gl_ymargin, - // x->gl_xmargin + x->gl_pixwidth, - // x->gl_ymargin + x->gl_pixheight, sh->h_outlinetag); - } - else //enter if move_gop hook - { - //scalehandle_draw_erase(sh,x); - /* Same as above... */ - //sys_vgui("lower %s\n", sh->h_pathname); + 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. */ - //delete GOP_resblob when moving the whole GOP - //sys_vgui(".x%lx.c delete %lxSCALE\n", x, x); - } - sh->h_dragx = 0; - sh->h_dragy = 0; + 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); + + /* We could port this, but it might be better to wait until we + just move the scalehandle stuff directly to the GUI... */ + //sys_vgui("lower %s\n", sh->h_pathname); + } + else /* move_gop hook */ + { + /* Same as above... */ + //sys_vgui("lower %s\n", sh->h_pathname); } - sh->h_dragon = newstate; } void canvasgop__motionhook(t_scalehandle *sh, t_floatarg mouse_x, @@ -2428,51 +2372,111 @@ void canvasgop__motionhook(t_scalehandle *sh, t_floatarg mouse_x, t_canvas *x = (t_canvas *)(sh->h_master); int dx = (int)mouse_x - sh->h_offset_x, dy = (int)mouse_y - sh->h_offset_y; - - if (sh->h_dragon) - { - if (sh->h_scale) //enter if resize_gop hook + + if (sh->h_scale == 1) /* resize the gop on the parent */ + { + int tmpx1 = 0, tmpy1 = 0, tmpx2 = 0, tmpy2 = 0; + int tmp_x_final = 0, tmp_y_final = 0; + /* The member h_glist currently points our current glist x. I think + that is being used to draw the gop red rect move anchor atm. So + rather than muck around with that code, we just set a pointer to + whatever our toplevel is here: */ + t_glist *owner = canvas_getrootfor(x); + /* Just unvis the object, then vis it once we've done our + mutation and checks */ + gobj_vis((t_gobj *)x, owner, 0); + /* struct _glist has its own member e_xnew for storing our offset. + At some point we need to refactor since our t_scalehandle has + members for storing offsets already. */ + x->gl_pixwidth = (sh->h_constrain == CURSOR_EDITMODE_RESIZE_Y) ? + x->gl_pixwidth : + (int)mouse_x - ((t_object *)x)->te_xpix - sh->h_adjust_x; + x->gl_pixheight = (sh->h_constrain == CURSOR_EDITMODE_RESIZE_X) ? + x->gl_pixheight : + (int)mouse_y - ((t_object *)x)->te_ypix - sh->h_adjust_y; + /* If the box text is not hidden then it sets a lower boundary for + box size... */ + graph_checkgop_rect((t_gobj *)x, owner, &tmpx1, &tmpy1, &tmpx2, + &tmpy2); + tmpx1 = ((t_object *)x)->te_xpix; + tmpy1 = ((t_object *)x)->te_ypix; + //fprintf(stderr,"%d %d %d %d\n", tmpx1, tmpy1, tmpx2, tmpy2); + if (!x->gl_hidetext) { - int width = mouse_x - x->gl_xmargin, - height = mouse_y - x->gl_ymargin; - x->gl_pixwidth = width = maxi(SCALE_GOP_MINWIDTH, width); - x->gl_pixheight = height = maxi(SCALE_GOP_MINHEIGHT, height); - gui_vmess("gui_canvas_redrect_coords", "xiiii", - x, - x->gl_xmargin, - x->gl_ymargin, - x->gl_xmargin + width, - x->gl_ymargin + height); - int properties = gfxstub_haveproperties((void *)x); - if (properties) - { - properties_set_field_int(properties, - "x_pix",x->gl_pixwidth + sh->h_dragx); - properties_set_field_int(properties, - "y_pix",x->gl_pixheight + sh->h_dragy); - } + tmp_x_final = tmpx2 - tmpx1; + tmp_y_final = tmpy2 - tmpy1; } - else //enter if move_gop hook + else { - int properties = gfxstub_haveproperties((void *)x); - if (properties) - { - properties_set_field_int(properties, - "x_margin",x->gl_xmargin + dx); + tmp_x_final = tmpx2; + tmp_y_final = tmpy2; + } + if (tmp_x_final > x->gl_pixwidth) + x->gl_pixwidth = tmp_x_final; + if (tmp_y_final > x->gl_pixheight) + x->gl_pixheight = tmp_y_final; + owner->gl_editor->e_xnew = mouse_x; + owner->gl_editor->e_ynew = mouse_y; + canvas_fixlinesfor(owner, (t_text *)x); + gobj_vis((t_gobj *)x, owner, 1); + canvas_dirty(owner, 1); + + int properties = gfxstub_haveproperties((void *)x); + if (properties) + { + properties_set_field_int(properties, + "x_pix",x->gl_pixwidth + sh->h_dragx); + properties_set_field_int(properties, + "y_pix",x->gl_pixheight + sh->h_dragy); + } + } + else if (sh->h_scale == 2) /* resize_gop red rect hook */ + { + int width = (sh->h_constrain == CURSOR_EDITMODE_RESIZE_Y) ? + x->gl_pixwidth : + (int)mouse_x - x->gl_xmargin - sh->h_adjust_x; + int height = (sh->h_constrain == CURSOR_EDITMODE_RESIZE_X) ? + x->gl_pixheight : + (int)mouse_y - x->gl_ymargin - sh->h_adjust_y; + x->gl_pixwidth = width = maxi(SCALE_GOP_MINWIDTH, width); + x->gl_pixheight = height = maxi(SCALE_GOP_MINHEIGHT, height); + gui_vmess("gui_canvas_redrect_coords", "xiiii", + x, + x->gl_xmargin, + x->gl_ymargin, + x->gl_xmargin + width, + x->gl_ymargin + height); + int properties = gfxstub_haveproperties((void *)x); + if (properties) + { + properties_set_field_int(properties, + "x_pix",x->gl_pixwidth + sh->h_dragx); + properties_set_field_int(properties, + "y_pix",x->gl_pixheight + sh->h_dragy); + } + } + else /* move_gop hook */ + { + int properties = gfxstub_haveproperties((void *)x); + if (properties) + { + properties_set_field_int(properties, + "x_margin",x->gl_xmargin + dx); properties_set_field_int(properties, - "y_margin",x->gl_ymargin + dy); - } + "y_margin",x->gl_ymargin + dy); + } + if (sh->h_constrain != CURSOR_EDITMODE_RESIZE_Y) x->gl_xmargin += dx; + 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); - sh->h_dragx = dx; - sh->h_dragy = dy; - } + gui_vmess("gui_canvas_redrect_coords", "xiiii", + x, x1, y1, x2, y2); + sh->h_dragx = dx; + sh->h_dragy = dy; } } diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h index a08ef13d6376186e2b7338957fa1219b352b35f2..3393d8017b9818df87611822609fd7262cf03a95 100644 --- a/pd/src/g_canvas.h +++ b/pd/src/g_canvas.h @@ -403,9 +403,11 @@ struct _parentwidgetbehavior #define CURSOR_EDITMODE_NOTHING 4 #define CURSOR_EDITMODE_CONNECT 5 #define CURSOR_EDITMODE_DISCONNECT 6 -#define CURSOR_EDITMODE_RESIZE 7 -#define CURSOR_EDITMODE_RESIZE_BOTTOM_RIGHT 8 +#define CURSOR_EDITMODE_RESIZE_X 7 +#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 */ diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c index 1dbcad0b6468e50b2e63b971aff515a98fedf5af..f22c8db010dd58218c0c27cd1ad7d05c07d5891b 100644 --- a/pd/src/g_editor.c +++ b/pd/src/g_editor.c @@ -2190,7 +2190,9 @@ static char *cursorlist[] = { "cursor_editmode_disconnect", "cursor_editmode_resize", "cursor_editmode_resize_bottom_right", - "cursor_scroll" + "cursor_scroll", + "cursor_editmode_resize_vert", + "cursor_editmode_move" }; void canvas_setcursor(t_canvas *x, unsigned int cursornum) @@ -3128,6 +3130,69 @@ void canvas_done_popup(t_canvas *x, t_float which, t_float xpos, open_via_helppath("intro.pd", canvas_getdir((t_canvas *)x)->s_name); } +extern t_class *my_canvas_class; // for ignoring runtime clicks and resizing + +/* For triggering text_widgetbehavior objects, graphs, atom/dropdown, iemgui and + comment resizing */ +static int text_resizing_hotspot(t_canvas *x, t_object *ob, int xpos, int ypos, + int x1, int y1, int x2, int y2, int *typep) +{ + /* No resizing anchor in k12 mode, plus sanity checks */ + if (sys_k12_mode || !ob || x->gl_editor->e_textedfor || xpos > x2 || + ypos > y2) + return 0; + *typep = 0; + /* objects that can only be resized along x-axis: regular text + objects, atom boxes, and canvas without gop checked */ + if (ob->te_pd->c_wb == &text_widgetbehavior || + ob->te_type == T_ATOM || + (ob->ob_pd == canvas_class && !((t_canvas *)ob)->gl_isgraph)) + { + if (xpos >= x2 - 4 && ypos < y2 - 4 && ypos > y1 + 4) + { + *typep = 1; + return CURSOR_EDITMODE_RESIZE_X; + } + } + + /* gop canvases, gop red rectangle, scope, grid, iemguis except [cnv] */ + if ((ob->te_iemgui && ob->ob_pd != my_canvas_class) || + ob->ob_pd == canvas_class || + ob->ob_pd->c_name == gensym("Scope~") || + ob->ob_pd->c_name == gensym("grid")) + { + /* stay out of the way of outlet in the bottom right-hand corner */ + int offset = (obj_noutlets(ob) > 1) ? -4 : 0; + /* 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_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")); + + 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 + offset - 10) + return CURSOR_EDITMODE_RESIZE; + else if (can_resize_y && + xpos >= x2 - 12 && + ypos >= y2 + offset - 5 && + ypos <= y2 + offset) + return CURSOR_EDITMODE_RESIZE_Y; + else + return 0; + } + else + return 0; +} + #define NOMOD 0 #define SHIFTMOD 1 #define CTRLMOD 2 @@ -3138,8 +3203,6 @@ static double canvas_upclicktime; static int canvas_upx, canvas_upy; #define DCLICKINTERVAL 0.25 -extern t_class *my_canvas_class; // for ignoring runtime clicks - /* mouse click */ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which, int mod, int doit) @@ -3151,7 +3214,8 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which, array_garray = NULL; t_gobj *y; - int shiftmod, runmode, altmod, doublemod = 0, rightclick; + int shiftmod, runmode, altmod, doublemod = 0, rightclick, + in_text_resizing_hotspot, default_type; int x1=0, y1=0, x2=0, y2=0, clickreturned = 0; t_gobj *yclick = NULL; t_object *ob; @@ -3282,14 +3346,34 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which, } return; } + /* if in editmode click, fall here. */ - if (y = canvas_findhitbox(x, xpos, ypos, &x1, &y1, &x2, &y2)) + /* check you're in the rectangle */ + y = canvas_findhitbox(x, xpos, ypos, &x1, &y1, &x2, &y2); + /* 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 + we've had for ages. */ + if (y) { - /* check you're in the rectangle */ ob = pd_checkobject(&y->g_pd); + in_text_resizing_hotspot = text_resizing_hotspot(x, ob, xpos, ypos, + x1, y1, x2, y2, &default_type); + } + else + { + in_text_resizing_hotspot = text_resizing_hotspot(x, &x->gl_obj, + xpos, ypos, x->gl_xmargin, x->gl_ymargin, + x->gl_xmargin + x->gl_pixwidth, + x->gl_ymargin + x->gl_pixheight, &default_type); + } + + if (y) + { if (rightclick) canvas_rightclick(x, xpos, ypos, y); - else if (shiftmod && x->gl_editor->canvas_cnct_outlet_tag[0] == 0) + else if (shiftmod && + x->gl_editor->canvas_cnct_outlet_tag[0] == 0) { //selection (only if we are not hovering above an outlet) if (doit) @@ -3332,74 +3416,64 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which, extends well past the bounds of the bbox. For that reason we have a virtual waterfall of conditionals flowing all the way to the GUI just handle resizing a stupid rectangle. - - Also, the following conditional is way too complex. */ - if (ob && (ob->te_iemgui - && pd_class((t_pd *)ob) != my_canvas_class - || pd_class(&ob->te_pd)->c_name == gensym("Scope~") - || pd_class(&ob->te_pd)->c_name == gensym("grid")) - && xpos >= x2-4 && ypos > y2-6) + if (in_text_resizing_hotspot) { if (doit) { - 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; - if (ob->te_iemgui) - { - t_pd *sh = (t_pd *)((t_iemgui *)ob)->x_handle; - pd_vmess(sh, gensym("_click"), "fff", - (t_float)1, (t_float)xpos, (t_float)ypos); - } - else - { - pd_vmess((t_pd *)ob, gensym("_click_for_resizing"), - "fff", (t_float)1, (t_float)xpos, (t_float)ypos); - } - } - else - { - canvas_setcursor(x, - CURSOR_EDITMODE_RESIZE_BOTTOM_RIGHT); - } - canvas_check_nlet_highlights(x); - } - else if (!sys_k12_mode && ob && !x->gl_editor->e_textedfor && - (ob->te_pd->c_wb == &text_widgetbehavior || - ob->te_type == T_ATOM || - ob->ob_pd == canvas_class) && - xpos >= x2-4 && ypos < y2-4 && ypos > y1+4) - { - if (doit) - { - if (!glist_isselected(x, y) || x->gl_editor->e_selection->sel_next) + if (!glist_isselected(x, y) || + x->gl_editor->e_selection->sel_next) { 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; - canvas_undo_add(x, 6, "resize", - canvas_undo_set_apply(x, glist_getindex(x, y))); - } - else - { - if (ob->ob_pd != canvas_class || - !((t_canvas *)ob)->gl_isgraph) + /* 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 (isgraph) { - canvas_setcursor(x, CURSOR_EDITMODE_RESIZE); + 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. */ + sh->h_scale = 1; + pd_vmess(&sh->h_pd, gensym("_click"), "fff", + (t_float)in_text_resizing_hotspot, + (t_float)xpos, (t_float)ypos); } - else + else if (ob->te_iemgui) { - canvas_setcursor(x, - CURSOR_EDITMODE_RESIZE_BOTTOM_RIGHT); + t_scalehandle *sh = ((t_iemgui *)ob)->x_handle; + pd_vmess(&sh->h_pd, gensym("_click"), "fff", + (t_float)in_text_resizing_hotspot, + (t_float)xpos, (t_float)ypos); } + else if (!default_type) + { + /* Scope~ and grid */ + pd_vmess(&ob->ob_pd, gensym("_click_for_resizing"), + "fff", (t_float)in_text_resizing_hotspot, + (t_float)xpos, (t_float)ypos); + } + } + else + { + canvas_setcursor(x, in_text_resizing_hotspot); canvas_check_nlet_highlights(x); } } @@ -3616,13 +3690,9 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which, // end jsarlo } return; - } else if (x->gl_isgraph && x->gl_goprect && - xpos <= x->gl_xmargin + x->gl_pixwidth + 4 && - xpos >= x->gl_xmargin + x->gl_pixwidth - 2 && - ypos <= x->gl_ymargin + x->gl_pixheight + 4 && - ypos > x->gl_ymargin + x->gl_pixheight - 2) + } + else if (in_text_resizing_hotspot) /* red gop rectangle */ { - // refactor the if into a function call... if (doit) { x->gl_editor->e_onmotion = MA_RESIZE; @@ -3630,14 +3700,18 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which, x->gl_editor->e_ywas = y1; x->gl_editor->e_xnew = xpos; x->gl_editor->e_ynew = ypos; - t_pd *sh = (t_pd *)x->x_handle; // scale handle + t_pd *sh = (t_pd *)((t_canvas *)x)->x_handle; // scale handle + /* Special case-- we abuse the value of h_scale to differentiate + between clicking the corner of a subcanvas and resizing a + red gop rectangle. */ + ((t_scalehandle *)sh)->h_scale = 2; pd_vmess(sh, gensym("_click"), "fff", - (t_float)1, (t_float)xpos, (t_float)ypos); + (t_float)in_text_resizing_hotspot, (t_float)xpos, + (t_float)ypos); } else { - canvas_setcursor(x, - CURSOR_EDITMODE_RESIZE_BOTTOM_RIGHT); + canvas_setcursor(x, in_text_resizing_hotspot); } canvas_check_nlet_highlights(x); return; @@ -5192,7 +5266,7 @@ void canvas_key(t_canvas *x, t_symbol *s, int ac, t_atom *av) pd_vmess(&x->gl_pd, gensym("motion"), "fff", (double)canvas_last_glist_x, (double)canvas_last_glist_y, - (double)(glob_shift+glob_ctrl*2+glob_alt*4)); + (double)(glob_shift + glob_ctrl * 2 + glob_alt * 4)); } extern void graph_checkgop_rect(t_gobj *z, t_glist *glist, @@ -5293,35 +5367,9 @@ void canvas_motion(t_canvas *x, t_floatarg xpos, t_floatarg ypos, } else if (ob && ob->ob_pd == canvas_class) { - int tmpx1 = 0, tmpy1 = 0, tmpx2 = 0, tmpy2 = 0; - int tmp_x_final = 0, tmp_y_final = 0; - gobj_vis(y1, x, 0); - ((t_canvas *)ob)->gl_pixwidth += xpos - x->gl_editor->e_xnew; - ((t_canvas *)ob)->gl_pixheight += ypos - x->gl_editor->e_ynew; - graph_checkgop_rect((t_gobj *)ob, x, &tmpx1, &tmpy1, &tmpx2, - &tmpy2); - tmpx1 = ob->te_xpix; - tmpy1 = ob->te_ypix; - //fprintf(stderr,"%d %d %d %d\n", tmpx1, tmpy1, tmpx2, tmpy2); - if (!((t_canvas *)ob)->gl_hidetext) - { - tmp_x_final = tmpx2 - tmpx1; - tmp_y_final = tmpy2 - tmpy1; - } - else - { - tmp_x_final = tmpx2; - tmp_y_final = tmpy2; - } - if (tmp_x_final > ((t_canvas *)ob)->gl_pixwidth) - ((t_canvas *)ob)->gl_pixwidth = tmp_x_final; - if (tmp_y_final > ((t_canvas *)ob)->gl_pixheight) - ((t_canvas *)ob)->gl_pixheight = tmp_y_final; - x->gl_editor->e_xnew = xpos; - x->gl_editor->e_ynew = ypos; - canvas_fixlinesfor(x, ob); - gobj_vis(y1, x, 1); - canvas_dirty(x, 1); + t_pd *sh = (t_pd *)((t_canvas *)ob)->x_handle; + pd_vmess(sh, gensym("_motion"), "ff", (t_float)xpos, + (t_float)ypos); } else if (ob && ob->te_iemgui) { diff --git a/pd/src/g_mycanvas.c b/pd/src/g_mycanvas.c index d33cb46edb3a060e810644b868d4e71d685cc435..16acb2533a14793b12c55cb79956f9b5dcf33ae8 100644 --- a/pd/src/g_mycanvas.c +++ b/pd/src/g_mycanvas.c @@ -69,6 +69,15 @@ static void my_canvas__clickhook(t_scalehandle *sh, int newstate) if (!sh->h_scale) scalehandle_click_label(sh); } + if (sh->h_scale) + { + sh->h_adjust_x = sh->h_offset_x - + (((t_object *)x)->te_xpix + x->x_vis_w); + sh->h_adjust_y = sh->h_offset_y - + (((t_object *)x)->te_ypix + x->x_vis_h); + /* Hack to set the cursor since we're doing and end-run + around canas_doclick here */ + } sh->h_dragon = newstate; } @@ -77,16 +86,19 @@ static void my_canvas__motionhook(t_scalehandle *sh, t_floatarg mouse_x, t_float if (sh->h_scale) { t_my_canvas *x = (t_my_canvas *)(sh->h_master); - int dx = (int)(mouse_x - sh->h_offset_x), - dy = (int)(mouse_y - sh->h_offset_y); - dx = maxi(dx,1-x->x_vis_w); - dy = maxi(dy,1-x->x_vis_h); - sh->h_dragx = dx; - sh->h_dragy = dy; - scalehandle_drag_scale(sh); - x->x_vis_w += dx; - x->x_vis_h += dy; + int width = (sh->h_constrain == CURSOR_EDITMODE_RESIZE_Y) ? + x->x_vis_w : + (int)mouse_x - text_xpix(&x->x_gui.x_obj, x->x_gui.x_glist) - + sh->h_adjust_x; + int height = (sh->h_constrain == CURSOR_EDITMODE_RESIZE_X) ? + x->x_vis_h : + (int)mouse_y - text_ypix(&x->x_gui.x_obj, x->x_gui.x_glist) - + sh->h_adjust_y; + x->x_vis_w = maxi(width, IEM_GUI_MINSIZE); + x->x_vis_h = maxi(height, IEM_GUI_MINSIZE); + + scalehandle_drag_scale(sh); if (glist_isvisible(x->x_gui.x_glist)) { @@ -97,19 +109,11 @@ static void my_canvas__motionhook(t_scalehandle *sh, t_floatarg mouse_x, t_float int properties = gfxstub_haveproperties((void *)x); if (properties) { - int new_w = x->x_vis_w + sh->h_dragx; - int new_h = x->x_vis_h + sh->h_dragy; - properties_set_field_int(properties,"rng.min_ent",new_w); - properties_set_field_int(properties,"rng.max_ent",new_h); - - int min = (new_w < new_h ? new_w : new_h); - if (min <= x->x_gui.x_w) - { - properties_set_field_int(properties,"dim.w_ent",min); - } + properties_set_field_int(properties,"rng.min_ent",width); + properties_set_field_int(properties,"rng.max_ent",height); } } - scalehandle_dragon_label(sh,mouse_x, mouse_y); + scalehandle_dragon_label(sh, mouse_x, mouse_y); } void my_canvas_draw(t_my_canvas *x, t_glist *glist, int mode) diff --git a/pd/src/g_slider.c b/pd/src/g_slider.c index 5421df81fdaaff18954b9f6e56194c9b144c4ad4..320a45a99320d997f135484076d29538380e6a34 100644 --- a/pd/src/g_slider.c +++ b/pd/src/g_slider.c @@ -113,25 +113,36 @@ static void slider_draw_config(t_slider *x, t_glist *glist) static void slider__clickhook(t_scalehandle *sh, int newstate) { t_slider *x = (t_slider *)(sh->h_master); - if (newstate) + if (sh->h_scale) { - canvas_apply_setundo(x->x_gui.x_glist, (t_gobj *)x); - if (!sh->h_scale) - scalehandle_click_label(sh); + sh->h_adjust_x = sh->h_offset_x - + (((t_object *)x)->te_xpix + x->x_gui.x_w); + sh->h_adjust_y = sh->h_offset_y - + (((t_object *)x)->te_ypix + x->x_gui.x_h); } + else + scalehandle_click_label(sh); + canvas_apply_setundo(x->x_gui.x_glist, (t_gobj *)x); sh->h_dragon = newstate; } void slider_check_length(t_slider *x, int w); -static void slider__motionhook(t_scalehandle *sh, t_floatarg mouse_x, t_floatarg mouse_y) +static void slider__motionhook(t_scalehandle *sh, t_floatarg mouse_x, + t_floatarg mouse_y) { if (sh->h_scale) { t_slider *x = (t_slider *)(sh->h_master); - int width = mouse_x - text_xpix(&x->x_gui.x_obj, x->x_gui.x_glist), - height = mouse_y - text_ypix(&x->x_gui.x_obj, x->x_gui.x_glist), - minx = x->x_orient ? IEM_GUI_MINSIZE : IEM_SL_MINSIZE, + int width = (sh->h_constrain == CURSOR_EDITMODE_RESIZE_Y) ? + x->x_gui.x_w : + (int)mouse_x - text_xpix(&x->x_gui.x_obj, x->x_gui.x_glist) - + sh->h_adjust_x; + int height = (sh->h_constrain == CURSOR_EDITMODE_RESIZE_X) ? + x->x_gui.x_h : + (int)mouse_y - text_ypix(&x->x_gui.x_obj, x->x_gui.x_glist) - + sh->h_adjust_y; + int minx = x->x_orient ? IEM_GUI_MINSIZE : IEM_SL_MINSIZE, miny = x->x_orient ? IEM_SL_MINSIZE : IEM_GUI_MINSIZE; x->x_gui.x_w = maxi(width, minx); x->x_gui.x_h = maxi(height, miny); diff --git a/pd/src/g_vumeter.c b/pd/src/g_vumeter.c index 0d6e7f5dcd5a52e26682820dabc9f2d8219da49e..d1693a08a7301963780c8fd23a32e8b75d395206 100644 --- a/pd/src/g_vumeter.c +++ b/pd/src/g_vumeter.c @@ -265,12 +265,16 @@ static void vu_draw_select(t_vu* x,t_glist* glist) static void vu__clickhook(t_scalehandle *sh, int newstate) { t_vu *x = (t_vu *)(sh->h_master); - if (newstate) + if (sh->h_scale) { - canvas_apply_setundo(x->x_gui.x_glist, (t_gobj *)x); - if (!sh->h_scale) - scalehandle_click_label(sh); + sh->h_adjust_x = sh->h_offset_x - + (((t_object *)x)->te_xpix + x->x_gui.x_w); + sh->h_adjust_y = sh->h_offset_y - + (((t_object *)x)->te_ypix + x->x_gui.x_h); } + else + scalehandle_click_label(sh); + canvas_apply_setundo(x->x_gui.x_glist, (t_gobj *)x); sh->h_dragon = newstate; } @@ -279,10 +283,14 @@ static void vu__motionhook(t_scalehandle *sh, t_floatarg mouse_x, t_floatarg mou if (sh->h_scale) { t_vu *x = (t_vu *)(sh->h_master); - int width = ((int)mouse_x) - - text_xpix(&x->x_gui.x_obj, x->x_gui.x_glist), - height = ((int)mouse_y) - - text_ypix(&x->x_gui.x_obj, x->x_gui.x_glist); + int width = (sh->h_constrain == CURSOR_EDITMODE_RESIZE_Y) ? + x->x_gui.x_w : + (int)mouse_x - text_xpix(&x->x_gui.x_obj, x->x_gui.x_glist) - + sh->h_adjust_x; + int height = (sh->h_constrain == CURSOR_EDITMODE_RESIZE_X) ? + x->x_gui.x_h : + (int)mouse_y - text_ypix(&x->x_gui.x_obj, x->x_gui.x_glist) - + sh->h_adjust_y; width = maxi(width, 8);