Automatically Resize [bpatcher]

I’ve recently been piecing together a performance patch and using the [bpatcher] object to hold multiple instances of the same subpatch. As I think of new things to add into the subpatch I find it a bit annoying having to shuffle the [bpatcher] view around so the new user interface objects fit in. Presentation mode helps but to make things really simple I wrote this javascript which I can drop into the subpatch to do all the hard work for me. It automatically resizes and repositions the [bpatcher] view when everything loads. This way I don’t have to make any changes by hand, it saves me some time and lets me concentrate on the project work. If you’re using presentation mode you should give it a positive number argument so it knows to look out for only the objects you need, otherwise it uses every object on the canvas to calculate the dimensions.

// lh.bpresize.js

var edges;
var mode = (jsarguments[1]>0);
var obj;

function loadbang() {
    if (!max.loadbangdisabled) {
        bang();
    }
}

function bang() {
    edges = [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY];
    this.patcher.apply(iter);
    move = [edges[0]*-1,edges[1]*-1];
    size = [edges[2]-edges[0],edges[3]-edges[1]];
    if (this.patcher.box) {
        this.patcher.box.message("offset",move);
        a = this.patcher.box.rect;
        this.patcher.box.rect = [a[0],a[1],size[0]+a[0],size[1]+a[1]];
    }
}

function iter(a) {
    obj = a;
    if (mode) {
        if (a.getattr("presentation")) {
            calc();
        }
    } else {
        calc();
    }
}

function calc() {
    if (mode) {
        attr = "presentation_rect";
    } else {
        attr = "patching_rect";
    }
    for (i=0; i<2; i++) {
        if(obj.getattr(attr)[i]<edges[i]) {
            edges[i] = obj.getattr(attr)[i];
        }
    }
    for (i=2; i<4; i++) {
        if(obj.getattr(attr)[i]+obj.getattr(attr)[i-2]>edges[i]) {
            edges[i] = obj.getattr(attr)[i]+obj.getattr(attr)[i-2];
        }
    }
}

function setmode(x) {
    mode = (x>0);
}

// EOF

There’s no helpfile as once the [js] is placed in the patch you can more or less forget about it. You can retrigger the positioning with a “bang” if you’ve moved or resized the [bpatcher] by hand and you can set the presentation/patching mode with the “setmode” message (I’ve never actually used this it might be necessary at some point). As always, if you find it useful or have any problems with it at all then please let me know.

About these ads

7 Comments

  1. Posted May 18, 2011 at 00:03 | Permalink | Reply

    very useful article

    cheers

    ( :

  2. Dan Nigrin
    Posted November 14, 2011 at 14:55 | Permalink | Reply

    Luke, this seems really helpful – but I can’t get it to work! I put a [js lh.bpresize.js 1] in my subpatcher, that I use (in presentatin mode) within a bpatcher in my top level patch. I loadbang the js too. But when I open my top level patch, the bpatcher is resized to a very small size, and the offsets are not adjusted correctly to show my UI elements… What am I doing wrong?

    • Posted November 16, 2011 at 12:12 | Permalink | Reply

      The first thing to check is that the subpatch is set to open in presentation mode from the patcher inspector. If that’s done I’m not sure what the problem is. What objects in your patch have you added to presentation mode? Perhaps try sending me the patches you’re using zipped up so I can take a look, if you want to do that my email is luke[at]physicsvschemistry[dot]com.

  3. Dan Nigrin
    Posted November 23, 2011 at 15:43 | Permalink | Reply

    Ah, that’s what the problem was – in my test, I just had some non-UI-focused objects in my subpatch (just a bunch of print objects). When I inserted some UI-focused objects (e.g. some pictctrls), then it worked. But I noticed that the resizing only works to properly display the UI-type objects, not other objects (e.g. in my test case, the print objects) that I may have also included in the presentation mode display…

  4. Dan Nigrin
    Posted November 23, 2011 at 15:52 | Permalink | Reply

    Also, I note that it resizes the bpatcher properly for non-presentation mode in the top level patch; I’d prefer it to resize it correctly for presentation mode. But I presume that’s an easy change in the javascript code, which I will look at… Thanks again!!

  5. Posted January 28, 2012 at 16:57 | Permalink | Reply

    How can I do the opposite? In other words, suppose a bpatcher contains a textedit field. If I resize the bpatcher, I would like the contained textedit field (and other contained objects) to be resized by some proportion?

    • Posted January 29, 2012 at 23:19 | Permalink | Reply

      The [quebec] external which can be found at the link below will report when the patcher/[bpatcher] is being resized. You can then use this to poll [thispatcher] to get the window size information and use this to scale the objects in your patch.

      http://cycling74.com/toolbox/bechamel-tralala/

Post a Comment

Required fields are marked *

*
*

Follow

Get every new post delivered to your Inbox.