From 73740b4700ac446aae9c5291754085db0f9941ab Mon Sep 17 00:00:00 2001 From: Jonathan Wilkes <jon.w.wilkes@gmail.com> Date: Fri, 23 Oct 2015 23:43:20 -0400 Subject: [PATCH] drill down on scrollbar logic, and add lots of comments to make it crystal clear what's going on --- pd/nw/pdgui.js | 61 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js index 7186abd35..f97adab67 100644 --- a/pd/nw/pdgui.js +++ b/pd/nw/pdgui.js @@ -2954,34 +2954,63 @@ function gui_undo_menu(cid, undo_text, redo_text) { } function do_getscroll(cid) { - var svg = get_item(cid, 'patchsvg'); + var bbox, width, height, min_width, min_height, x, y, + svg = get_item(cid, 'patchsvg'); // Not sure why I need to check for null here... I'm waiting for the // nw window to load before mapping the Pd canvas, so the patchsvg // should always exist. Perhaps I also need to set an event for // document.onload as well... if (svg === null) { return; } - var bbox = svg.getBBox(); - var width = bbox.x > 0 ? bbox.x + bbox.width : bbox.width, - height = bbox.y > 0 ? bbox.y + bbox.height : bbox.height; - if (width === 0) { - width = patchwin[cid].window.document.body.clientWidth; - } - if (height === 0) { - height = patchwin[cid].window.document.body.clientHeight; - } + bbox = svg.getBBox(); + // We try to do Pd-extended style canvas origins. That is, coord (0, 0) + // should be in the top-left corner unless there are objects with a + // negative x or y. + // To implement the Pd-l2ork behavior, the top-left of the canvas should + // always be the topmost, leftmost object. + width = bbox.x > 0 ? bbox.x + bbox.width : bbox.width, + height = bbox.y > 0 ? bbox.y + bbox.height : bbox.height; + x = bbox.x > 0 ? 0 : bbox.x, + y = bbox.y > 0 ? 0 : bbox.y; + + // The svg "overflow" attribute on an <svg> seems to be buggy-- for example, + // you can't trigger a mouseover event for a <rect> that is outside of the + // explicit bounds of the svg. + // To deal with this, we want to set the svg width/height to always be + // at least as large as the browser's viewport. There are a few ways to + // do this this, like documentElement.clientWidth, but window.innerWidth + // seems to give the best results. + // However, there is either a bug or some strange behavior regarding + // the viewport size: setting both the height and width of an <svg> to + // the viewport height/width will display the scrollbars. The height or + // width must be set to 4 less than the viewport size in order to keep + // the scrollbars from appearing. Here, we just subtract 4 from both + // of them. This could lead to some problems with event handlers but I + // haven't had a problem with it yet. + min_width = patchwin[cid].window.innerWidth - 4; + min_height = patchwin[cid].window.innerHeight - 4; + // Since we don't do any transformations on the patchsvg, // let's try just using ints for the height/width/viewBox // to keep things simple. width |= 0; // drop everything to the right of the decimal point height |= 0; + min_width |= 0; + min_height |= 0; + if (width < min_width) { + width = min_width; + } + // If the svg extends beyond the viewport, it might be nice to pad + // both the height/width and the x/y coords so that there is extra + // room for making connections and manipulating the objects. As it + // stands objects will be flush with the scrollbars and window + // edges. + if (height < min_height) { + height = min_height; + } configure_item(svg, { - viewBox: [bbox.x > 0 ? 0 : bbox.x, - bbox.y > 0 ? 0 : bbox.y, - width, - height] - .join(" "), + viewBox: [x, y, width, height].join(" "), width: width, - height: height + height: height }); } -- GitLab