Articles

Stupid JS Tricks

It doesn't have quite the same ring as Letterman's "Stupid Pet Tricks" but you get the point... This hopefully periodic new column will attempt to get Max's JavaScript object, JS, to jump through a few hoops and garner our applause. The idea is similar to Andrew Benson's excellent Jitter Recipe's. So let's get started...

Stupid JS Trick #1: Resizing Your Abstraction's Patcher Interface

The method discussed here for resizing patcher windows and bpatcher boxes is used in the Jamoma project. This screenshot shows the same patcher (Jamoma's limiter~ module) loaded as a plain object and in a bpatcher.

Here's the challenge: we want to create an abstraction (a Max patch that is loaded as an object in another patch). When the user double-clicks our object, it should open an interface window. Rather than having to remember to manually resize the window tediously every time we save the abstraction, we want to have it happen automatically. And just to make things more interesting, let's say that we want to have this little JS gizmo inside of another abstraction inside of the abstraction.

Drum roll please...

var my_width = 200;  // number of pixels wide and/or high...
var my_height = 350; // dimensions include scroll bars if present...

function loadbang()
{
    // get the patch's window:
    var grandparent_window = this.patcher.parentpatcher.wind;
    // get the patch's object box:
    var grandparent_patch = grandparent_window.assoc;
    if(grandparent_patch.box){
        grandparent_window.size = [my_width, my_height];
        // remove the scroll bars:
        grandparent_window.hasgrow = 0;
    }
}

After mulling this over briefly (all of the functions are documented in the "Javascript in Max" PDF that is in the Max documentation), we can make a couple of improvements. Namely, what happens if a user loads our abstraction in a bpatcher? Ideally, we want the bpatcher to be automatically sized too. How do we do that?

The code below is an amended version of what we did above. We test to see if we are in a bpatcher using a questionable method where we see how high the object box is, and assume it is not a normal object if the height is more than 50 pixels. Unless you use a really big font in your Max objects, or your bpatcher is really short, then this should work.

var my_width = 200;  // number of pixels wide and/or high...
var my_height = 350; // dimensions include scroll bars if present...

function loadbang()
{
    // get the patch's window:
    var grandparent_window = this.patcher.parentpatcher.wind;
    // get the patch's object box:
    var grandparent_patch = grandparent_window.assoc;
    if(grandparent_patch.box){
        if((grandparent_patch.box.rect[3]
                - grandparent_patch.box.rect[1]) < 50){
            // we are in patcher context...
            grandparent_window.size = [my_width, my_height];
            // remove the scroll bars
            grandparent_window.hasgrow = 0;
        }
        else{    // we are in bpatcher context...
            var left = grandparent_patch.box.rect[0];
            var top = grandparent_patch.box.rect[1];
            var right = left + my_width;
            var bottom = top + my_height;
            grandparent_patch.box.rect = [left, top, right, bottom];
        }
    }
}

Enjoy!

by Timothy Place on 2006年4月14日 17:50

Creative Commons License