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 thoughts on “Automatically Resize [bpatcher]

  1. 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?

    • 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.

  2. 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…

  3. 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!!

  4. 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?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s